diff --git a/.claude/skills/cmtat/SKILL.md b/.claude/skills/cmtat/SKILL.md
deleted file mode 100644
index 481f97e7..00000000
--- a/.claude/skills/cmtat/SKILL.md
+++ /dev/null
@@ -1,125 +0,0 @@
-# CMTAT Codebase Summary
-
-**CMTAT** (CMTA Token) is a **security token framework** for tokenizing real-world financial assets on EVM-compatible blockchains. It's developed by the Capital Markets and Technology Association (CMTA).
-
-**Version:** 3.1.0 | **License:** MPL-2.0 | **Solidity:** 0.8.33
-
----
-
-## Directory Structure
-
-```
-contracts/
-├── modules/ # Core smart contract logic
-│ ├── internal/ # Internal implementations
-│ └── wrapper/ # Public-facing modules
-│ ├── core/ # ERC20, Pause, Enforcement, Validation
-│ ├── extensions/ # Documents, Snapshots
-│ ├── options/ # Debt, ERC2771, Cross-chain
-│ └── security/ # Access control
-├── deployment/ # Pre-composed contract variants
-├── interfaces/ # ERC standards & custom interfaces
-└── mocks/ # Test helpers
-test/ # 3,078 tests (~99% coverage)
-doc/ # Specs & audit reports
-```
-
----
-
-## Key Modules
-
-| Category | Modules | Purpose |
-|----------|---------|---------|
-| **Core** | ERC20Base, Mint, Burn, Pause, Enforcement, Validation | Basic token operations |
-| **Extensions** | Snapshot, Document, ExtraInformation | Dividends, legal docs, metadata |
-| **Options** | Debt, ERC2771, ERC1363, CrossChain, Allowlist, ERC7551 | Bonds, gasless tx, multi-chain, KYC |
-| **Security** | AccessControl | RBAC with roles (MINTER, BURNER, PAUSER, ENFORCER) |
-
----
-
-## Deployment Variants
-
-- **Standalone** - Immutable, no proxy
-- **Upgradeable** - Transparent/Beacon/UUPS proxy patterns
-- **Light** - Minimal for stablecoins
-- **Allowlist** - Whitelist-based transfers (KYC)
-- **Debt** - Bond-specific fields (maturity, coupon)
-- **DebtEngine** - Debt with external engine
-- **ERC-7551** - German eWpG compliance
-- **ERC-1363** - transferAndCall support
-
----
-
-## Architecture Highlights
-
-1. **Modular composition** - Mix-and-match features via inheritance
-2. **Engine pattern** - External contracts for complex logic (RuleEngine, SnapshotEngine, DocumentEngine, DebtEngine)
-3. **ERC-7201 storage** - Namespaced storage for safe upgrades
-4. **Role-based access control** - Granular permissions (not single owner)
-5. **10+ standard compliance** - ERC-20, ERC-3643, ERC-7551, ERC-2771, ERC-7802, etc.
-
----
-
-## Contract Inheritance Hierarchy
-
-```
-CMTATBaseCore (0) - Basic ERC20 + Mint + Burn + Validation + Access Control
- ↓
-CMTATBaseAccessControl (1) - RBAC roles management
- ↓
-CMTATBaseRuleEngine/Allowlist (2) - Transfer validation rules
- ↓
-CMTATBaseERC1404 (3) - ERC-1404 compliance (restrictedTransfer)
- ↓
-CMTATBaseERC20CrossChain (4) - CCIP & ERC-7802 support
- ↓
-CMTATBaseERC2771 (5) - Gasless meta-transactions
- ↓
-CMTATBaseERC1363/ERC7551 (6) - Additional standards
-```
-
----
-
-## Key Roles (Access Control)
-
-- `DEFAULT_ADMIN_ROLE` - Admin access (can grant/revoke roles)
-- `MINTER_ROLE` - Can mint tokens
-- `BURNER_ROLE` - Can burn tokens
-- `PAUSER_ROLE` - Can pause/unpause contract
-- `ENFORCER_ROLE` - Can freeze/unfreeze addresses
-
----
-
-## Real-World Usage
-
-Used by UBS (digital bonds), Daura (equity), Taurus, and others for tokenizing securities, stablecoins, and structured products.
-
----
-
-## Testing & Security
-
-- **Framework:** Hardhat + Chai
-- **Coverage:** ~99.43%
-- **Audits:** ABDK, Halborn
-- **Static analysis:** Aderyn, Slither
-
----
-
-## Useful Commands
-
-```bash
-npm run test # Run all tests
-npm run test:integration # Full integration tests
-npm run coverage # Generate coverage report
-npm run hardhat:compile # Compile contracts
-```
-
----
-
-## Key Files to Understand
-
-- `contracts/modules/0_CMTATBaseCore.sol` - Core base contract
-- `contracts/deployment/CMTAT_*.sol` - Pre-composed deployment variants
-- `contracts/interfaces/` - All supported interfaces and standards
-- `hardhat.config.js` - Build configuration
-- `package.json` - Dependencies and scripts
diff --git a/.claude/skills/erc1404-restricted/SKILL.md b/.claude/skills/erc1404-restricted/SKILL.md
deleted file mode 100644
index 6e479d35..00000000
--- a/.claude/skills/erc1404-restricted/SKILL.md
+++ /dev/null
@@ -1,81 +0,0 @@
-| eip | title | authors | status | discussions-to | type | category | created |
-| ---- | -------------------------------- | ------------------------------------------------------------ | ------ | ------------------------------------------------------------ | --------- | -------- | ---------- |
-| 1404 | Simple Restricted Token Standard | Ron Gierlach <[@rongierlach](https://github.com/rongierlach)>, James Poole <[@pooleja](https://github.com/pooleja)>, Mason Borda <[@masonicGIT](https://github.com/masonicGIT)>, Lawson Baker <[@lwsnbaker](https://github.com/lwsnbaker)> | Draft | https://github.com/simple-restricted-token/simple-restricted-token/issues | Standards | ERC | 2018-07-27 |
-
-# Simple Restricted Token Standard
-
-## Simple Summary
-
-A simple and interoperable standard for issuing tokens with transfer restrictions. The following draws on input from top issuers, law firms, relevant US regulatory bodies, and exchanges.
-
-## Abstract
-
-Current ERC token standards have provided the community with a platform on which to develop a decentralized economy that is focused on building Ethereum applications for the real world. As these applications mature and face consumer adoption, they begin to interface with corporate governance requirements as well as regulations. They must not only be able to meet corporate and regulatory requirements but must also be able to integrate with technology platforms underpinning their associated businesses. What follows is a simple and extendable standard that seeks to ease the burden of integration for wallets, exchanges, and issuers.
-
-## Motivation
-
-Token issuers need a way to restrict transfers of ERC-20 tokens to be compliant with securities laws and other contractual obligations. Current implementations do not address these requirements.
-
-A few emergent examples:
-
-- Enforcing Token Lock-Up Periods
-- Enforcing Passed AML/KYC Checks
-- Private Real-Estate Investment Trusts
-- Delaware General Corporations Law Shares
-
-Furthermore, standards adoption amongst token issuers has the potential to evolve into a dynamic and interoperable landscape of automated compliance.
-
-The following design gives greater freedom / upgradability to token issuers and simultaneously decreases the burden of integration for developers and exchanges.
-
-Additionally, we see fit to provide a pattern by which human-readable messages may be returned when token transfers are reverted. Transparency as to *why* a token's transfer was reverted is of equal importance to the successful enforcement of the transfer restriction itself.
-
-A widely adopted standard for detecting restrictions and messaging errors within token transfers will highly convenience the exchanges, wallets, and issuers of the future.
-
-## Specification
-
-The ERC-20 token provides the following basic features:
-
-```
-contract ERC20 {
- function totalSupply() public view returns (uint256);
- function balanceOf(address who) public view returns (uint256);
- function transfer(address to, uint256 value) public returns (bool);
- function allowance(address owner, address spender) public view returns (uint256);
- function transferFrom(address from, address to, uint256 value) public returns (bool);
- function approve(address spender, uint256 value) public returns (bool);
- event Approval(address indexed owner, address indexed spender, uint256 value);
- event Transfer(address indexed from, address indexed to, uint256 value);
-}
-```
-
-
-
-The ERC-1404 standard builds on ERC-20's interface, adding two functions:
-
-```
-contract ERC1404 is ERC20 {
- function detectTransferRestriction (address from, address to, uint256 value) public view returns (uint8);
- function messageForTransferRestriction (uint8 restrictionCode) public view returns (string);
-}
-```
-
-
-
-The logic of `detectTransferRestriction` and `messageForTransferRestriction` are left up to the issuer.
-
-The only requirement is that `detectTransferRestriction` must be evaluated inside a token's `transfer` and `transferFrom` methods.
-
-If, inside these transfer methods, `detectTransferRestriction` returns a value other than `0`, the transaction should be reverted.
-
-## Rationale
-
-The standard proposes two functions on top of the ERC-20 standard. Let's discuss the rationale for each.
-
-1. `detectTransferRestriction` - This function is where an issuer enforces the restriction logic of their token transfers. Some examples of this might include, checking if the token recipient is whitelisted, checking if a sender's tokens are frozen in a lock-up period, etc. Because implementation is up to the issuer, this function serves solely to standardize *where* execution of such logic should be initiated. Additionally, 3rd parties may publicly call this function to check the expected outcome of a transfer. Because this function returns a `uint8` code rather than a boolean or just reverting, it allows the function caller to know the reason why a transfer might fail and report this to relevant counterparties.
-2. `messageForTransferRestriction` - This function is effectively an accessor for the "message", a human-readable explanation as to *why* a transaction is restricted. By standardizing message look-ups, we empower user interface builders to effectively report errors to users.
-
-## Backwards Compatibility
-
-By design ERC-1404 is fully backwards compatible with ERC-20.
-Some examples of how it may be integrated with common types of restricted tokens may be found [here](https://github.com/simple-restricted-token/simple-restricted-token-standard#readme).
-
diff --git a/.claude/skills/erc7943-urwa/SKILL.md b/.claude/skills/erc7943-urwa/SKILL.md
deleted file mode 100644
index c10c08dc..00000000
--- a/.claude/skills/erc7943-urwa/SKILL.md
+++ /dev/null
@@ -1,462 +0,0 @@
-# ERC-7943: uRWA - Universal Real World Asset Interface
-
-> Source: https://eips.ethereum.org/EIPS/eip-7943
-
-
-
-### Interfaces for common base tokens defining compliance checks, transfer controls, and enforcement actions for Real World Assets (RWAs).
-
-
-| Authors | Dario Lo Buglio ([@xaler5](https://github.com/xaler5)), Tino Martinez Molina ([@tinom9](https://github.com/tinom9)), Mihai Colceriu ([@mihaic195](https://github.com/mihaic195)) |
-| --- | --- |
-| Created | 2025-06-10 |
-| Last Call Deadline | 2026-01-30 |
-| Requires | [EIP-165](https://eips.ethereum.org/EIPS/eip-165) |
-
- [This EIP is in the process of being peer-reviewed. If you are interested in this EIP, please participate using this discussion link.](https://ethereum-magicians.org/t/erc-universal-rwa-interface/23972)
-
-
-
-
-
-## Table of Contents
-
-
-- [Abstract](#abstract)
-- [Motivation](#motivation)
-- [Specification](#specification)
-
- - [canTransact, canTransfer and getFrozenTokens](#cantransact-cantransfer-and-getfrozentokens)
- - [forcedTransfer](#forcedtransfer)
- - [setFrozenTokens](#setfrozentokens)
- - [Additional Specifications](#additional-specifications)
-- [Rationale](#rationale)
-
- - [Extensibility](#extensibility)
- - [Notes on naming](#notes-on-naming)
-- [Backwards Compatibility](#backwards-compatibility)
-- [Reference Implementation](#reference-implementation)
-- [Security Considerations](#security-considerations)
-- [Copyright](#copyright)
-
-
-
-
-## [](#abstract) Abstract
-
-This EIP proposes the Universal RWA (uRWA) standard, a set of interfaces for tokenized Real World Assets (RWAs) such as securities, real estate, commodities, or other physical/financial assets on the blockchain.
-
-Real World Assets often require regulatory compliance features not found in standard tokens, including the ability to freeze assets, perform enforcement transfers for legal compliance, and restrict transfers to authorized users. The uRWA standard extends common token standards like [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-721](https://eips.ethereum.org/EIPS/eip-721) or [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) by introducing essential compliance functions while remaining minimal and not opinionated about specific implementation details.
-
-This enables DeFi protocols and applications to interact with tokenized real-world assets in a standardized way, knowing they can check transfer permissions, whether users are allowed to interact, handle frozen assets appropriately, and integrate with compliant RWA tokens regardless of the underlying asset type or internal compliance logic. It also adopts [ERC-165](https://eips.ethereum.org/EIPS/eip-165) for introspection.
-
-
-
-## [](#motivation) Motivation
-
-Real World Assets (RWAs) represent a significant opportunity to bridge traditional finance and decentralized finance (DeFi). By tokenizing assets like real estate, corporate bonds, commodities, art, or securities, we can unlock benefits such as fractional ownership, programmable compliance, enhanced liquidity through secondary markets for traditionally illiquid assets and integration with decentralized protocols.
-
-However, tokenizing real world assets introduces regulatory requirements often absent in purely digital assets, such as allowlists for users, transfer restrictions, asset freezing, or law enforcement rules. Existing token standards like [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) lack the inherent structure to address these compliance needs directly within the standard itself.
-
-Attempts at defining universal RWA standards historically imposed unnecessary complexity and gas overhead for simpler use cases that do not require the full spectrum of features like granular role-based access control, mandatory on-chain whitelisting, specific on-chain identity solutions, or metadata handling solutions mandated by the standard.
-
-Additionally, the broad spectrum of RWA classes inherently suggests the need to move away from a one-size-fits-all solution. This means a minimalistic approach, unopinionated features list, and maximally compatible design have been kept in mind as design goals.
-
-The uRWA standard seeks a more refined balance by defining an essential interface, establishing a common ground for interaction regarding compliance and control, without dictating the underlying implementation mechanisms. This allows core token implementations to remain lean while providing standard functions for RWA-specific interactions.
-
-The final goal is to build composable DeFi around RWAs, providing the same interface when dealing with compliance and regulation.
-
-
-
-## [](#specification) Specification
-
-The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHOULD”, and “MAY” in this document are to be interpreted as described in RFC 2119 and RFC 8174.
-
-The following defines the standard interfaces for an [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) token contract, which MUST extend from one base token interface such as [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-721](https://eips.ethereum.org/EIPS/eip-721) or [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155):
-
-```
-/// @notice Interface for ERC-20 based implementations.
-interface IERC7943Fungible is IERC165 {
- /// @notice Emitted when tokens are taken from one address and transferred to another.
- /// @param from The address from which tokens were taken.
- /// @param to The address to which seized tokens were transferred.
- /// @param amount The amount seized.
- event ForcedTransfer(address indexed from, address indexed to, uint256 amount);
-
- /// @notice Emitted when `setFrozenTokens` is called, changing the frozen `amount` of tokens for `account`.
- /// @param account The address of the account whose tokens are being frozen.
- /// @param amount The amount of tokens frozen after the change.
- event Frozen(address indexed account, uint256 amount);
-
- /// @notice Error reverted when an account is not allowed to transact.
- /// @param account The address of the account which is not allowed for transfers.
- error ERC7943CannotTransact(address account);
-
- /// @notice Error reverted when a transfer is not allowed according to internal rules.
- /// @param from The address from which tokens are being sent.
- /// @param to The address to which tokens are being sent.
- /// @param amount The amount sent.
- error ERC7943CannotTransfer(address from, address to, uint256 amount);
-
- /// @notice Error reverted when a transfer is attempted from `account` with an `amount` less than or equal to its balance, but greater than its unfrozen balance.
- /// @param account The address holding the tokens.
- /// @param amount The amount being transferred.
- /// @param unfrozen The amount of tokens that are unfrozen and available to transfer.
- error ERC7943InsufficientUnfrozenBalance(address account, uint256 amount, uint256 unfrozen);
-
- /// @notice Takes tokens from one address and transfers them to another.
- /// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
- /// @param from The address from which `amount` is taken.
- /// @param to The address that receives `amount`.
- /// @param amount The amount to force transfer.
- /// @return result True if the transfer executed correctly. Reverts on failure.
- function forcedTransfer(address from, address to, uint256 amount) external returns(bool result);
-
- /// @notice Changes the frozen status of `amount` tokens belonging to `account`.
- /// This overwrites the current value, similar to an `approve` function.
- /// @dev Requires specific authorization. Frozen tokens cannot be transferred by the account.
- /// @param account The address of the account whose tokens are to be frozen.
- /// @param amount The amount of tokens to freeze. It can be greater than account balance.
- /// @return result True if the freezing executed correctly. Reverts on failure.
- function setFrozenTokens(address account, uint256 amount) external returns(bool result);
-
- /// @notice Checks if a specific account is allowed to transact according to token rules.
- /// @dev This is often used for allowlist/KYC/KYB/AML checks.
- /// @param account The address to check.
- /// @return allowed True if the account is allowed, false otherwise.
- function canTransact(address account) external view returns (bool allowed);
-
- /// @notice Checks the frozen status/amount.
- /// @param account The address of the account.
- /// @dev It could return an amount higher than the account's balance.
- /// @return amount The amount of tokens currently frozen for `account`.
- function getFrozenTokens(address account) external view returns (uint256 amount);
-
- /// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
- /// @dev This can involve checks like allowlists, blocklists, transfer limits and other policy-defined restrictions.
- /// @param from The address sending tokens.
- /// @param to The address receiving tokens.
- /// @param amount The amount being transferred.
- /// @return allowed True if the transfer is allowed, false otherwise.
- function canTransfer(address from, address to, uint256 amount) external view returns (bool allowed);
-}
-
-/// @notice Interface for ERC-721 based implementations.
-interface IERC7943NonFungible is IERC165 {
- /// @notice Emitted when `tokenId` is taken from one address and transferred to another.
- /// @param from The address from which `tokenId` is taken.
- /// @param to The address to which seized `tokenId` is transferred.
- /// @param tokenId The ID of the token being transferred.
- event ForcedTransfer(address indexed from, address indexed to, uint256 indexed tokenId);
-
- /// @notice Emitted when `setFrozenTokens` is called, changing the frozen status of `tokenId` for `account`.
- /// @param account The address of the account whose `tokenId` is subjected to freeze/unfreeze.
- /// @param tokenId The ID of the token subjected to freeze/unfreeze.
- /// @param frozenStatus Whether `tokenId` has been frozen or unfrozen.
- event Frozen(address indexed account, uint256 indexed tokenId, bool indexed frozenStatus);
-
- /// @notice Error reverted when an account is not allowed to transact.
- /// @param account The address of the account which is not allowed for transfers.
- error ERC7943CannotTransact(address account);
-
- /// @notice Error reverted when a transfer is not allowed according to internal rules.
- /// @param from The address from which tokens are being sent.
- /// @param to The address to which tokens are being sent.
- /// @param tokenId The id of the token being sent.
- error ERC7943CannotTransfer(address from, address to, uint256 tokenId);
-
- /// @notice Error reverted when a transfer is attempted from `account` with a `tokenId` which has been previously frozen.
- /// @param account The address holding the token with `tokenId`.
- /// @param tokenId The ID of the token being frozen and unavailable to be transferred.
- error ERC7943InsufficientUnfrozenBalance(address account, uint256 tokenId);
-
- /// @notice Takes `tokenId` from one address and transfers it to another.
- /// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
- /// @param from The address from which `tokenId` is taken.
- /// @param to The address that receives `tokenId`.
- /// @param tokenId The ID of the token being transferred.
- /// @return result True if the transfer executed correctly. Reverts on failure.
- function forcedTransfer(address from, address to, uint256 tokenId) external returns(bool result);
-
- /// @notice Changes the frozen status of `tokenId` belonging to an `account`.
- /// This overwrites the current value, similar to an `approve` function.
- /// @dev Requires specific authorization. Frozen tokens cannot be transferred by the account.
- /// @param account The address of the account whose tokens are to be frozen.
- /// @param tokenId The ID of the token to freeze.
- /// @param frozenStatus Whether `tokenId` is being frozen or not.
- /// @return result True if the freezing executed correctly. Reverts on failure.
- function setFrozenTokens(address account, uint256 tokenId, bool frozenStatus) external returns(bool result);
-
- /// @notice Checks if a specific account is allowed to transact according to token rules.
- /// @dev This is often used for allowlist/KYC/KYB/AML checks.
- /// @param account The address to check.
- /// @return allowed True if the account is allowed, false otherwise.
- function canTransact(address account) external view returns (bool allowed);
-
- /// @notice Checks the frozen status of a specific `tokenId`.
- /// @dev It could return true even if account does not hold the token.
- /// @param account The address of the account.
- /// @param tokenId The ID of the token.
- /// @return frozenStatus Whether `tokenId` is currently frozen for `account`.
- function getFrozenTokens(address account, uint256 tokenId) external view returns (bool frozenStatus);
-
- /// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
- /// @dev This can involve checks like allowlists, blocklists, transfer limits and other policy-defined restrictions.
- /// @param from The address sending tokens.
- /// @param to The address receiving tokens.
- /// @param tokenId The ID of the token being transferred.
- /// @return allowed True if the transfer is allowed, false otherwise.
- function canTransfer(address from, address to, uint256 tokenId) external view returns (bool allowed);
-}
-
-/// @notice Interface for ERC-1155 based implementations.
-interface IERC7943MultiToken is IERC165 {
- /// @notice Emitted when tokens are taken from one address and transferred to another.
- /// @param from The address from which tokens were taken.
- /// @param to The address to which seized tokens were transferred.
- /// @param tokenId The ID of the token being transferred.
- /// @param amount The amount seized.
- event ForcedTransfer(address indexed from, address indexed to, uint256 indexed tokenId, uint256 amount);
-
- /// @notice Emitted when `setFrozenTokens` is called, changing the frozen `amount` of `tokenId` tokens for `account`.
- /// @param account The address of the account whose tokens are being frozen.
- /// @param tokenId The ID of the token being frozen.
- /// @param amount The amount of tokens frozen after the change.
- event Frozen(address indexed account, uint256 indexed tokenId, uint256 amount);
-
- /// @notice Error reverted when an account is not allowed to transact.
- /// @param account The address of the account which is not allowed for transfers.
- error ERC7943CannotTransact(address account);
-
- /// @notice Error reverted when a transfer is not allowed according to internal rules.
- /// @param from The address from which tokens are being sent.
- /// @param to The address to which tokens are being sent.
- /// @param tokenId The id of the token being sent.
- /// @param amount The amount sent.
- error ERC7943CannotTransfer(address from, address to, uint256 tokenId, uint256 amount);
-
- /// @notice Error reverted when a transfer is attempted from `account` with an `amount` of `tokenId` less than or equal to its balance, but greater than its unfrozen balance.
- /// @param account The address holding the `amount` of `tokenId` tokens.
- /// @param tokenId The ID of the token being transferred.
- /// @param amount The amount of `tokenId` tokens being transferred.
- /// @param unfrozen The amount of tokens that are unfrozen and available to transfer.
- error ERC7943InsufficientUnfrozenBalance(address account, uint256 tokenId, uint256 amount, uint256 unfrozen);
-
- /// @notice Takes tokens from one address and transfers them to another.
- /// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
- /// @param from The address from which `amount` is taken.
- /// @param to The address that receives `amount`.
- /// @param tokenId The ID of the token being transferred.
- /// @param amount The amount to force transfer.
- /// @return result True if the transfer executed correctly. Reverts on failure.
- function forcedTransfer(address from, address to, uint256 tokenId, uint256 amount) external returns(bool result);
-
- /// @notice Changes the frozen status of `amount` of `tokenId` tokens belonging to an `account`.
- /// This overwrites the current value, similar to an `approve` function.
- /// @dev Requires specific authorization. Frozen tokens cannot be transferred by the account.
- /// @param account The address of the account whose tokens are to be frozen.
- /// @param tokenId The ID of the token to freeze.
- /// @param amount The amount of tokens to freeze. It can be greater than account balance.
- /// @return result True if the freezing executed correctly. Reverts on failure.
- function setFrozenTokens(address account, uint256 tokenId, uint256 amount) external returns(bool result);
-
- /// @notice Checks if a specific account is allowed to transact according to token rules.
- /// @dev This is often used for allowlist/KYC/KYB/AML checks.
- /// @param account The address to check.
- /// @return allowed True if the account is allowed, false otherwise.
- function canTransact(address account) external view returns (bool allowed);
-
- /// @notice Checks the frozen status/amount of a specific `tokenId`.
- /// @dev It could return an amount higher than the account's balance.
- /// @param account The address of the account.
- /// @param tokenId The ID of the token.
- /// @return amount The amount of `tokenId` tokens currently frozen for `account`.
- function getFrozenTokens(address account, uint256 tokenId) external view returns (uint256 amount);
-
- /// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
- /// @dev This can involve checks like allowlists, blocklists, transfer limits and other policy-defined restrictions.
- /// @param from The address sending tokens.
- /// @param to The address receiving tokens.
- /// @param tokenId The ID of the token being transferred.
- /// @param amount The amount being transferred.
- /// @return allowed True if the transfer is allowed, false otherwise.
- function canTransfer(address from, address to, uint256 tokenId, uint256 amount) external view returns (bool allowed);
-}
-```
-
-
-
-### [](#cantransact-cantransfer-and-getfrozentokens) `canTransact`, `canTransfer` and `getFrozenTokens`
-
-These provide views into the implementing contract’s compliance, transfer policy logic and freezing status. These functions:
-
-- MUST NOT revert.
-- MUST NOT change the storage of the contract.
-- MAY depend on context (e.g., current timestamp, block number or `msg.sender`).
-- The `canTransfer`
-
- - MUST validate that the `amount` being transferred doesn’t exceed the unfrozen amount (which is the difference between the current balance and the frozen balance).
- - MUST perform a `canTransact` check on the `from` and `to` parameters. An important documentation note is that [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) doesn’t perform a `canTransact` check within `canTransfer` as required.
- - MUST return false in general, if any permissioned rule would prevent a given transfer from succeeding. A transfer refers to any operation that emits the token’s canonical transfer event. A permissioned check can be a pausing mechanism, a call to `canTransact` or anything else that requires privileged actors.
-- `getFrozenTokens` will return the absolute frozen amount, which MAY exceed the account’s current balance. In [ERC-721](https://eips.ethereum.org/EIPS/eip-721) tokens, it MAY return true even if the account does not hold the token.
-
-
-
-### [](#forcedtransfer) `forcedTransfer`
-
-This function provides a standard mechanism for forcing a transfer from a `from` to a `to` address. The function:
-
-- MUST directly manipulate balances or ownership to transfer the asset from `from` to `to` either by transferring or burning from `from` and minting to `to`.
-- MUST be restricted in access.
-- MUST perform necessary validation checks (e.g., sufficient balance/ownership of a specific token).
-- MUST emit both the standard transfer event (from the base standard) and the `ForcedTransfer` event.
-- In single-party permissioned contexts:
-
- - It MAY bypass the `canTransfer` checks. If this happens, and the transfer involves tokens that are currently counted as frozen, it MUST unfreeze the assets first and emit a `Frozen` event before the underlying base token transfer event reflecting the change. Having the unfrozen amount changed before the actual transfer is critical for tokens that might be susceptible to reentrancy attacks doing external checks on recipients as it is the case for [ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) tokens.
- - It SHOULD at least perform a `canTransact` check on the `to` parameter to ensure compliance.
-- In multi-party permissioned contexts:
-
- - It SHOULD perform the `canTransfer` checks and SHOULD NOT bypass the frozen constraints.
-- MUST revert in cases where validations and/or `canTransact` checks return false or fail.
-
-
-
-### [](#setfrozentokens) `setFrozenTokens`
-
-It provides a way to freeze or unfreeze assets held by a specific account. This is useful for temporary lock mechanisms. This function:
-
-- MUST emit the `Frozen` event.
-- MUST be restricted in access.
-- MUST allow freezing more assets than those held. This allows for future balances withholding.
-- MUST revert in cases of logical issues or validation checks failure.
-
-
-
-### [](#additional-specifications) Additional Specifications
-
-The contract MUST implement the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) `supportsInterface` function and MUST return true for the `bytes4` value (representing the `interfaceId`):
-
-- `0x29388973` for the fungible interface.
-- `0xa8fdc849` for the non-fungible interface.
-- `0x5627c61a` for the multi token interface.
-
-Implementations of these interfaces MUST implement the necessary functions of their chosen base standard (e.g., [ERC-20](https://eips.ethereum.org/EIPS/eip-20) for the fungible interface, [ERC-721](https://eips.ethereum.org/EIPS/eip-721) for the non-fungible interface and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) for the multi token interface) and MUST also restrict access to sensitive functions like `forcedTransfer` and `setFrozenTokens` using an appropriate access control mechanism (e.g., `onlyOwner`, Role-Based Access Control). The specific mechanism is NOT mandated by this interface standard.
-
-Implementations MUST ensure their transfer methods exhibit the following behavior:
-
-- **Public transfers** (`transfer`, `transferFrom`, `safeTransferFrom`, etc.) MUST NOT succeed in cases in which `canTransfer` or `canTransact` would return `false` for either one or both `from` and `to` addresses.
-- **Minting** in permissionless contexts (e.g., public `mint` functions) MUST NOT succeed for accounts where `canTransact` on the recipient would return `false`. In permissioned contexts (e.g., authorized minting by privileged roles), minting SHOULD respect `canTransact` checks on the recipient, though implementations MAY bypass these checks when necessary for operational or compliance reasons.
-- **Burning** in permissionless contexts (e.g., public `burn` functions) MUST respect `canTransfer` check, MUST respect the `canTransact` check on the token holder and MUST NOT allow burning more assets than the unfrozen amount. In permissioned contexts (e.g., authorized burning by privileged roles), burning MAY succeed for accounts where `canTransact` on the token holder would return `false`, and MAY burn more assets than the unfrozen amount, in which case the contract MUST update the frozen status accordingly and emit a `Frozen` event before the underlying base token transfer event.
-
-The `ERC7943CannotTransact`/`ERC7943CannotTransfer` errors MAY be used as a general revert mechanism whenever internal calls to `canTransact`/`canTransfer` return false. They MAY be replaced by more specific errors depending on the custom checks performed inside those calls, or simply not used.
-
-In general, the standard prioritizes error specificity, meaning that specific errors such as `ERC7943InsufficientUnfrozenBalance` SHOULD be thrown when applicable. The `ERC7943InsufficientUnfrozenBalance` error SHOULD be triggered when a transfer is attempted from `account` with an `amount` less than or equal to its balance, but greater than its unfrozen balance or with a `tokenId` which is currently frozen. If the `amount` is greater than the whole balance or the `tokenId` is not owned by the `account`, unrelated from the frozen amount, more specific errors from the base standard SHOULD be used instead.
-
-
-
-## [](#rationale) Rationale
-
-- **Minimalism:** Defines only the essential functions (`forcedTransfer`, `setFrozenTokens`, `canTransact`, `canTransfer`, `getFrozenTokens`) and associated events/errors needed for common RWA compliance and control patterns, avoiding mandated complexity or opinionated features. The reason to introduce specific errors (`ERC7943CannotTransact`, `ERC7943CannotTransfer` and `ERC7943InsufficientUnfrozenBalance`) is to provide completeness with the introduced functionalities (`canTransact`, `canTransfer` and `getFrozenTokens`). As dictated in the specifications, error specificity is prioritized, leaving space for implementations to accommodate more explicit errors. Regarding the events `Frozen` and `ForcedTransfer`, the reason for their existence is to signal *uncommon* transfers (like in `forcedTransfer`) but also to help off-chain indexers to correctly keep track and account for asset seizures and freezing. As mentioned in the specifications, the order in which these events are emitted in relation to the base token contract events is important in practice and merits special attention.
-- **Flexible compliance:** Provides standard view functions (`canTransact`, `canTransfer`, `getFrozenTokens`) for compliance checks without dictating *how* those checks are implemented internally by the token contract. This allows diverse compliance strategies.
-- **Compatibility:** Designed as an interface layer compatible with existing base standards like [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155). Implementations extend from [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) alongside their base standard interface. Additionally, with the adopted naming conventions, automatic backward compatibility is achieved with already existing standards like [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) and [ERC-7518](https://eips.ethereum.org/EIPS/eip-7518).
-- **Essential enforcement rules:** Includes `forcedTransfer` and `setFrozenTokens` as standard functions, acknowledging their importance for regulatory enforcement in the RWA space, distinct from standard transfers. Mandates access control for this sensitive function. To maintain a lean EIP, a single `setFrozenTokens` function (which overwrites the frozen asset quantity) and one `Frozen` event were favored over distinct `freeze`/`unfreeze` functions and events.
-- **[ERC-165](https://eips.ethereum.org/EIPS/eip-165):** Ensures implementing contracts can signal support for this interface.
-
-As an example, an AMM pool or a lending protocol can integrate with [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) based [ERC-20](https://eips.ethereum.org/EIPS/eip-20) tokens by calling `canTransact` or `canTransfer` to handle these assets in a compliant manner. Enforcement actions like `forcedTransfer` and `setFrozenTokens` can either be called by third party entities or be integrated by external protocols to allow for automated and programmable compliance. Users can then expand these tokens with additional features to fit the specific needs of individual asset types, either with on-chain identity systems, historical balances tracking for dividend distributions, semi-fungibility with token metadata, and other custom functionalities.
-
-
-
-### [](#extensibility) Extensibility
-
-While this ERC provides the necessary primitives for regulated assets, any additional feature can be added through extensions. Few examples:
-
-1) If for any administrative function like `setFrozenTokens` it is necessary to attach a proof to the call, the contract can have a function that batches operations like:
-
-```
-contract TokenWithLegalProofs is IERC7943MultiToken {
- ...
-
- function setFrozenTokensWithProof(address account, uint256 tokenId, uint256 amount, bytes calldata legalProof) external onlyOwner returns(bool result) {
- /// do anything with `legalProof`
- return setFrozenTokens(account, tokenId, amount);
- }
-}
-```
-
-2) Since the `setFrozenTokens` function overwrites the absolute frozen amount and given the fact that the standard allows for multiple privileged accounts, some race-conditions might happen. If that’s the case, one can build an extension function that works with expected values of amounts frozen, like:
-
-```
-function setFrozenTokensIf(address account, uint256 expectedPrev, uint256 newAmount) external onlyOwner returns(bool result) {
- require(frozenTokens[account] == expectedPrev, ERC7943ExpectedValueMismatch(expectedPrev, frozenTokens[account]));
- return setFrozenTokens(account,newAmount);
-}
-```
-
-Alternatively, another solution can be using delta amounts:
-
-```
-function setFrozenTokensDelta(address account, int256 deltaAmount) external onlyOwner returns(bool result) {
- uint256 actualValue = frozenTokens[account];
- if(deltaAmount >= 0) actualValue += uint256(deltaAmount);
- else {
- uint256 sub = uint256(-deltaAmount);
- require(sub <= actualValue, ERC7943ExpectedValueMismatch(sub, actualValue));
- actualValue -= sub;
- }
- return setFrozenTokens(account, actualValue);
-}
-```
-
-*Note* These helpers reduce accidental overwrites and expand in functionalities but do not prevent same-block conflicting updates or mempool ordering races by different privileged actors.
-
-3) Developers can also perform several operations through the use of `multicall` patterns similar to the one defined in [ERC-6357](https://eips.ethereum.org/EIPS/eip-6357) so that a mix of the given primitives with additional features can be batched in one transaction:
-
-```
-contract ERC7943Fungible is IERC7943Fungible, Multicall {
- // Now any combination of `setFrozenTokens`/`forcedTransfer`
- // coupled with other functionalities like the ones to blacklist/whitelist users
- // can be submitted in one transaction through the use of `multicall` function
-}
-```
-
-4) Functionalities like pausability can be added on top, either through the use of modifiers or directly within functions implementations:
-
-```
-function canTransfer(address from, address to, uint256 amount) external view returns (bool allowed) {
- if(paused()) return allowed;
- // ... other checks
- };
-}
-```
-
-
-
-### [](#notes-on-naming) Notes on naming
-
-The naming conventions in this ERC were carefully chosen to establish clarity and semantic consistency within the broader RWA ecosystem while maintaining neutrality and broad applicability.
-
-- **`forcedTransfer`**: This term was selected for its neutrality. While names like *confiscation*, *revocation*, or *recovery* describe specific motivations, `forcedTransfer` purely denotes the direct action of transferring assets, irrespective of the underlying reason. `forcedTransfer` was preferred over `forceTransfer` to maintain backward compatibility with [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643).
-- **`canTransfer`**: This name was preferred over `isTransferAllowed` for consistency with established RWA standards including [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) and [ERC-7518](https://eips.ethereum.org/EIPS/eip-7518). This alignment promotes interoperability and reduces cognitive overhead when working across different RWA tokens.
-- **`setFrozenTokens` / `getFrozenTokens`**: These names were chosen for managing transfer restrictions and align with [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) naming patterns. *Frozen* was also selected for its general applicability to both fungible (amount-based) and non-fungible (status-based) assets, as terms like *amount* or *asset(s)* might not be universally fitting.
-- **`ERC7943InsufficientUnfrozenBalance`**: Discussions around *insufficient* being similar to *unavailable* arose, where *unavailable* might have better suggested a temporal condition like a freezing status. However, the term *available*/*unavailable* was also overlapping with *frozen*/*unfrozen* creating more confusion and duality. Finally, coupling *insufficient* with the specified *unfrozen balance* better represents the domain, prefix and subject of the error, according to [ERC-6093](https://eips.ethereum.org/EIPS/eip-6093) guidelines.
-
-
-
-## [](#backwards-compatibility) Backwards Compatibility
-
-This EIP defines a new interface standard and does not alter existing ones like [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155). Standard wallets and explorers can interact with the base token functionality of implementing contracts, subject to the rules enforced by that contract’s implementation of `canTransact`, `canTransfer` and `getFrozenTokens` functions. Full support for the [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) functions requires explicit integration.
-
-
-
-## [](#reference-implementation) Reference Implementation
-
-Reference implementations of uRWA for [ERC-20](https://eips.ethereum.org/assets/eip-7943/contracts/uRWA20.sol), [ERC-721](https://eips.ethereum.org/assets/eip-7943/contracts/uRWA721.sol) and [ERC-1155](https://eips.ethereum.org/assets/eip-7943/contracts/uRWA1155.sol) token implementations is provided in assets folder. They use the OpenZeppelin library and include an account whitelist and enumerable role-based access control. These examples are provided for educational purposes only and are not audited.
-
-
-
-## [](#security-considerations) Security Considerations
-
-- **Access Control for `forcedTransfer` and `setFrozenTokens`:** The security of the mechanism chosen by the implementer to restrict access to these functions is paramount. Unauthorized access could lead to asset theft. Secure patterns (multisig, timelocks) are highly recommended.
-- **Front-run of the `setFrozenTokens` function:** The `setFrozenTokens` function might be susceptible to front-running, similar to the `approve` function of the [ERC-20](https://eips.ethereum.org/EIPS/eip-20). If the suggestion of allowing freezing more than what an account owns is not followed, a front-run might be an incentive to an account to avoid any attempt of freezing its balance. Additional features to gradually increment or decrement the frozen status MAY be considered for implementation.
-- **Implementation Logic:** The correctness of the *implementation* behind all interface functions is critical. Flaws in this logic could bypass intended transfer restrictions or incorrectly block valid transfers.
-- **Standard Contract Security:** Implementations MUST adhere to general smart contract security best practices (reentrancy guards where applicable, checks-effects-interactions, etc.). Specifically in the checks-effects-interactions consideration, implementations need to be aware of tokens having hooks, especially on recipients like in [ERC-721](https://eips.ethereum.org/EIPS/eip-721) or [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155). In such circumstances it might be convenient to adopt reentrancy guards to prevent unwanted executions.
diff --git a/.claude/tree/contracts_tree.txt b/.claude/tree/contracts_tree.txt
index a272e087..c6e4a899 100644
--- a/.claude/tree/contracts_tree.txt
+++ b/.claude/tree/contracts_tree.txt
@@ -18,6 +18,12 @@ contracts
│ ├── ERC7551
│ │ ├── CMTATStandaloneERC7551.sol
│ │ └── CMTATUpgradeableERC7551.sol
+│ ├── permit
+│ │ ├── CMTATStandalonePermit.sol
+│ │ └── CMTATUpgradeablePermit.sol
+│ ├── snapshot
+│ │ ├── CMTATStandaloneSnapshot.sol
+│ │ └── CMTATUpgradeableSnapshot.sol
│ └── light
│ ├── CMTATStandaloneLight.sol
│ └── CMTATUpgradeableLight.sol
@@ -86,16 +92,21 @@ contracts
│ ├── 0_CMTATBaseCommon.sol
│ ├── 0_CMTATBaseCore.sol
│ ├── 0_CMTATBaseGeneric.sol
-│ ├── 1_CMTATBaseAccessControl.sol
-│ ├── 2_CMTATBaseAllowlist.sol
-│ ├── 2_CMTATBaseRuleEngine.sol
-│ ├── 3_CMTATBaseDebt.sol
-│ ├── 3_CMTATBaseERC1404.sol
+│ ├── 0_CMTATBaseSnapshot.sol
+│ ├── 2_CMTATBaseAccessControl.sol
+│ ├── 3_CMTATBaseAllowlist.sol
+│ ├── 3_CMTATBaseRuleEngine.sol
+│ ├── 1_CMTATBaseDocument.sol
+│ ├── 4_CMTATBaseDebt.sol
+│ ├── 4_CMTATBaseERC1404.sol
│ ├── 4_CMTATBaseERC20CrossChain.sol
+│ ├── 4_CMTATBaseERC2612.sol
│ ├── 5_CMTATBaseDebtEngine.sol
│ ├── 5_CMTATBaseERC2771.sol
-│ ├── 6_CMTATBaseERC1363.sol
-│ ├── 6_CMTATBaseERC7551.sol
+│ ├── 6_CMTATBaseERC2771Snapshot.sol
+│ ├── 6_CMTATBaseERC7551Enforcement.sol
+│ ├── 7_CMTATBaseERC1363.sol
+│ ├── 7_CMTATBaseERC7551.sol
│ ├── internal
│ │ ├── AllowlistModuleInternal.sol
│ │ ├── common
@@ -123,6 +134,7 @@ contracts
│ │ ├── ExtraInformationModule.sol
│ │ ├── SnapshotEngineModule.sol
│ │ └── ValidationModule
+│ │ ├── ValidationModuleAllowance.sol
│ │ ├── ValidationModuleERC1404.sol
│ │ └── ValidationModuleRuleEngine.sol
│ ├── options
@@ -131,8 +143,9 @@ contracts
│ │ ├── DebtEngineModule.sol
│ │ ├── DebtModule.sol
│ │ ├── ERC20CrossChainModule.sol
+│ │ ├── ERC20EnforcementERC7551Module.sol
│ │ ├── ERC2771Module.sol
│ │ └── ERC7551Module.sol
│ └── security
│ └── AccessControlModule.sol
-32 directories, 105 files
+32 directories, 106 files
diff --git a/.claude/tree/test_tree.txt b/.claude/tree/test_tree.txt
index 670e093f..833ae347 100644
--- a/.claude/tree/test_tree.txt
+++ b/.claude/tree/test_tree.txt
@@ -20,8 +20,10 @@ test
│ ├── ERC20MintModuleCommon.js
│ ├── ERC7551ModuleCommon.js
│ ├── ExtraInfoModuleCommon.js
+│ ├── MulticallModuleCommon.js
│ ├── MetaTxModuleCommon.js
│ ├── PauseModuleCommon.js
+│ ├── PermitModuleCommon.js
│ ├── SnapshotModuleCommon
│ │ ├── global
│ │ │ ├── SnapshotModuleMultiplePlannedTest.js
@@ -68,6 +70,9 @@ test
│ ├── erc7551
│ │ ├── deploymentERC7551Standalone.test.js
│ │ └── deploymentERC7551Upgradeable.test.js
+│ ├── permit
+│ │ ├── deploymentPermitStandalone.test.js
+│ │ └── deploymentPermitUpgradeable.test.js
│ └── light
│ ├── deploymentStandaloneLight.test.js
│ └── deploymentUpgradeableLight.test.js
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4ca2dde7..72ea202b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -11,10 +11,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- - name: Setup NodeJS 20.5.0
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #v4.4.0
+ - name: Setup NodeJS 24.12.0
+ uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e #v6.4.0
with:
node-version: 20.5.0
diff --git a/.gitignore b/.gitignore
index fae9545a..f1d4abcc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,3 +26,9 @@ mcore_*
#Claude
PLAN.md
INSTRUCTION.md
+ERCDRAFT
+./history
+.~lock.coverpage_CMTA.odg#
+#codex
+.codex
+history
diff --git a/.gitmodules b/.gitmodules
index b2149193..72e58d9d 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
-[submodule "openzeppelin-contracts-upgradeable"]
- path = openzeppelin-contracts-upgradeable
+[submodule "lib/openzeppelin-contracts-upgradeable"]
+ path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
+[submodule "lib/forge-std"]
+ path = lib/forge-std
+ url = https://github.com/foundry-rs/forge-std
diff --git a/.nvmrc b/.nvmrc
index b55acecd..821e3957 100644
--- a/.nvmrc
+++ b/.nvmrc
@@ -1 +1 @@
-v20.5.0
\ No newline at end of file
+v24.12.0
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 00000000..47248563
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,100 @@
+# CMTAT Codebase Summary
+
+**CMTAT** (CMTA Token) is a **security token framework** for tokenizing real-world financial assets on EVM-compatible blockchains. It's developed by the Capital Markets and Technology Association (CMTA).
+
+AGENTS.md and CLAUDE.md files must always be identical
+Module numbering must strictly match dependency order (a lower-level module must not depend on a higher-level module).
+
+**Solidity** | **Hardhat**
+
+---
+
+## Directory Structure
+
+If you create/move/remove a file/directory from this project, update the different file trees path corresponding.
+
+Only run listing command such as `ls/tree` if you don't manage to use the tree structure here to find the directory and corresponding files.
+
+**Directory structure**
+
+```
+contracts/
+├── modules/ # Core smart contract logic
+│ ├── internal/ # Internal implementations
+│ └── wrapper/ # Public-facing modules
+│ ├── core/ # ERC20, Pause, Enforcement, Validation
+│ ├── extensions/ # Documents, Snapshots
+│ ├── options/ # Debt, ERC2771, Cross-chain
+│ └── security/ # Access control
+├── deployment/ # Pre-composed contract variants
+├── interfaces/ # ERC standards & custom interfaces
+└── mocks/ # Test helpers
+test/ # 5,630 tests (~99% coverage)
+doc/ # Specs & audit reports
+```
+
+**Contracts tree**
+
+See `./claude/tree/contracts_tree.txt`
+
+**Test tree**
+
+See `./claude/tree/test_tree.txt`
+
+**openzeppelin/contracts-upgradeable**
+
+See `./claude/tree/contracts-upgradeables_tree.txt`
+
+## Key Modules
+
+See `./doc/SUMMARY.md`
+
+## Deployment Variants
+
+See `./doc/SUMMARY.md`
+
+---
+
+## Architecture Highlights
+
+See `./doc/SUMMARY.md`
+
+---
+
+## Contract Inheritance Hierarchy
+
+See `./doc/SUMMARY.md`
+
+---
+
+## Key Roles (Access Control)
+
+See `./doc/SUMMARY.md`
+
+---
+
+## Useful Commands
+
+```bash
+npm run test # Run all tests
+npm run coverage # Generate coverage report
+npm run hardhat:compile # Compile contracts
+```
+
+## Test Troubleshooting
+
+If tests fail with gas reporter / Mocha reporter errors (for example `ERR_MOCHA_INVALID_REPORTER` with `eth-gas-reporter`), run tests with gas reporting disabled:
+
+```bash
+DeactivateReportGas=true npx hardhat test
+```
+
+---
+
+## Key Files to Understand
+
+- `contracts/modules/0_CMTATBaseCore.sol` - Core base contract
+- `contracts/deployment/CMTAT_*.sol` - Pre-composed deployment variants
+- `contracts/interfaces/` - All supported interfaces and standards
+- `hardhat.config.js` - Build configuration (EVM & Solidity version)
+- `package.json` - Dependencies and scripts
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 71ec4b27..c7657d4d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -25,6 +25,8 @@ See [https://semver.org](https://semver.org)
Reference: [keepachangelog.com/en/1.1.0/](https://keepachangelog.com/en/1.1.0/)
+Custom changelog tag: `Dependencies`, `Documentation`, `Testing`
+
## Checklist
> Before a new release, perform the following tasks
@@ -36,17 +38,258 @@ Reference: [keepachangelog.com/en/1.1.0/](https://keepachangelog.com/en/1.1.0/)
- Documentation
- Perform a code coverage and update the files in the corresponding directory [./doc/general/test/coverage](./doc/general/test/coverage)
- - Perform an audit with several audit tools (Aderyn and Slither), update the report in the corresponding directory [./doc/audits/tools](./doc/audits/tools)
+ - Perform an audit with several audit tools (Aderyn and Slither), update the report in the corresponding directory [./doc/security/tools](./doc/security/tools)
- Update surya doc by running the 3 scripts in [./doc/script](./doc/script)
- Update changelog
+## 3.3.0 - rc1
+
+> **Note:** This version has not been audited.
+
+### Smart contract
+
+#### Added
+
+- New base contract **`CMTATBaseDocument`**:
+ - Introduced as `contracts/modules/1_CMTATBaseDocument.sol`.
+ - Isolates document-management authorization (`_authorizeDocumentManagement`) from `CMTATBaseAccessControl`.
+ - Composes `DocumentERC1643Module` on top of the rule-engine base path.
+- **Stateful RuleEngine transfer hook support (testing/mocks):**
+ - Added `IRuleTransferHook` (`contracts/mocks/RuleEngine/interfaces/IRuleTransferHook.sol`) to allow rules to update rule-local state on transfer callbacks.
+ - Added `RuleTokenHolderTracker` (`contracts/mocks/RuleEngine/RuleTokenHolderTracker.sol`) to track holder balances/list in rule storage.
+ - `RuleEngineMock` now wires the holder-tracker rule and executes transfer hooks in `transferred(...)` paths.
+
+#### Changed
+
+- **ERC-1643 document identifier format aligned to `bytes32`** (breaking API change for document functions):
+ - Previous CMTAT variant (e.g. `v3.2.0`) used `string` for document names in `IERC1643` (`getDocument(string)`, `getAllDocuments() -> string[]`).
+ - Current implementation uses `bytes32` document names (`getDocument(bytes32)`, `getAllDocuments() -> bytes32[]`) and exposes `setDocument(bytes32,string,bytes32)` / `removeDocument(bytes32)` with associated events.
+ - **CMTAT terms remain on the modified CMTAT structure**: `IERC1643CMTAT.DocumentInfo` still uses `string name` for tokenization terms metadata (`setTerms` path).
+- **Base hierarchy refactor (strict dependency-order levels):**
+ - `CMTATBaseDocument` at **level 1** (`contracts/modules/1_CMTATBaseDocument.sol`).
+ - `CMTATBaseAccessControl` at **level 2** (`contracts/modules/2_CMTATBaseAccessControl.sol`) and now inherits `CMTATBaseDocument`.
+ - `CMTATBaseAllowlist` and `CMTATBaseRuleEngine` at **level 3**.
+ - `CMTATBaseDebt` and `CMTATBaseERC1404` at **level 4**.
+ - `CMTATBaseERC20CrossChain` at **level 5**.
+ - `CMTATBaseERC2612`, `CMTATBaseERC2771`, `CMTATBaseDebtEngine` at **level 6**.
+ - `CMTATBaseERC2771Snapshot`, `CMTATBaseERC7551Enforcement` at **level 7**.
+ - `CMTATBaseERC1363`, `CMTATBaseERC7551` at **level 8**.
+- **`CMTATBaseCommon`** no longer inherits `DocumentERC1643Module`.
+- **`CMTATBaseAccessControl`** now defines `_authorizeDocumentManagement` and enforces `DOCUMENT_ROLE`.
+- Updated impacted imports and deployment references to match the new module numbering/layout.
+- **ERC20CrossChain burn-path cleanup (no external API change):**
+ - Removed redundant `crosschainBurn` override from `CMTATBaseERC20CrossChain`; level-5 now uses `ERC20CrossChainModule.crosschainBurn` directly.
+ - Removed redundant sender-aware burn override from `CMTATBaseERC20CrossChain`; burn/burnFrom sender-aware flow now relies on the module implementation.
+ - In `ERC20CrossChainModule`, simplified internal self-burn routing and renamed helper `_burnWithSender` to `_burnFromOperator` for clearer intent.
+- **Meta-tx `_msgData` ERC1363 test path adjusted to avoid bytecode-size deployment failures:**
+ - Slimmed `CMTATUpgradeableERC1363MsgDataMock.getMsgData()` by removing event emission and using a `view` return path.
+ - Reworked `test/standard/modules/MetaTxMsgDataERC1363.test.js` to validate trusted-forwarder calldata shape directly instead of relying on event parsing.
+
+#### Fixed
+
+- Fixed compile-path inconsistencies caused by stale numbered imports after base-level refactor.
+- Restored full compilation after engine/mock alignment:
+ - `CMTATEngineInitializerMock` no longer calls unavailable document-engine initializer on snapshot path.
+ - `DocumentEngineMock` now implements IERC1643-compatible `setDocument(bytes32,string,bytes32)`.
+
+### Documentation
+
+#### Changed
+
+- Updated base-module hierarchy and file references in `doc/README.md` to reflect:
+ - `1_CMTATBaseDocument.sol`
+ - `2_CMTATBaseAccessControl.sol`
+ - `3_CMTATBaseAllowlist.sol`
+ - `3_CMTATBaseRuleEngine.sol`
+ - `4_CMTATBaseDebt.sol`
+ - `4_CMTATBaseERC1404.sol`
+ - `5_CMTATBaseERC20CrossChain.sol`
+ - `6_CMTATBaseERC2612.sol`
+ - `6_CMTATBaseERC2771.sol`
+ - `6_CMTATBaseDebtEngine.sol`
+ - `7_CMTATBaseERC2771Snapshot.sol`
+ - `7_CMTATBaseERC7551Enforcement.sol`
+ - `8_CMTATBaseERC1363.sol`
+ - `8_CMTATBaseERC7551.sol`
+- Updated `doc/README.md` ERC-1643 section to use current `bytes32` API signatures (`getDocument(bytes32)`, `getAllDocuments() returns (bytes32[])`) with compatibility note for `IERC1643CMTAT.DocumentInfo.name` (`string`).
+- Updated contracts tree file `.claude/tree/contracts_tree.txt`.
+- Added technical clarification for freeze-event semantics across standards:
+ - `doc/technical/erc-7943-uRWA-integration.md` now explicitly documents that base `Frozen(account, amount)` is a normalized frozen-state update event (including unfreeze updates), while direction should be derived from ERC-3643/7551 directional events.
+ - `doc/technical/erc-3643-implementation.md` now documents the event-layering model (`Frozen` base state update + `TokensFrozen`/`TokensUnfrozen` directional wrappers).
+
+### Testing
+
+#### Added
+
+- Added dedicated stateful RuleEngine rule test coverage in `test/standard/modules/RuleEngineMockStatefulRule.test.js`:
+ - verifies holder-balance tracking and holder-list transitions through transfer hook callbacks.
+- Added initializer edge-case tests for `DocumentEngineModule` and `SnapshotEngineModule`:
+ - `test/common/DocumentModule/DocumentModuleSetDocumentEngineCommon.js`: covers zero-engine assignment and re-initialization revert paths.
+ - `test/common/SnapshotModuleCommon/SnapshotModuleSetSnapshotEngineCommon.js`: covers zero-engine assignment and re-initialization revert paths.
+- Added standard initializer branch tests in `test/deployment/deployment.test.js`:
+ - manual initialization path, initialization with rule engine, and double-initialize revert.
+- Added interface and initializer coverage across deployment test suites:
+ - `test/common/CMTATIntegrationCommon.js`: extended integration paths.
+ - `test/deployment/erc721mock.test.js`: ERC-721 generic initializer and interface paths.
+ - Light/core, standard, permit, ERC-1363, snapshot, and document deployment suites.
+- Added edge-case coverage for core transfer and approve paths:
+ - `test/common/ERC20BaseModuleCommon.js`: zero-value transfers and explicit approve coverage.
+ - `test/common/AllowlistModuleCommon.js`: explicit `canSend`/`canReceive` matrix including zero-value transfers.
+- Extended `test/common/AllowlistModuleCommon.js`, `test/common/DocumentModule/DocumentModuleCommon.js`, and `test/common/ERC20EnforcementModuleCommon.js` with additional edge-case tests.
+
+#### Fixed
+
+- Removed hardcoded `gasLimit: 30_000_000` override from `deployCMTATERC1363Standalone` in `test/deploymentUtils.js`. The explicit override exceeded the Prague/Fusaka per-transaction gas cap (`FUSAKA_TRANSACTION_GAS_LIMIT = 16,777,216`) enforced by Hardhat ≥ 2.28, causing a `ProviderError` on every ERC-1363 standalone test run. Auto-estimated gas is well within the cap for this contract.
+
+### Documentation
+
+#### Changed
+
+- Updated test count references in `README.md` and `doc/README.md`: 3,078 → 5,630 automated tests.
+- `README.md`: added hyperlinks to all ERC standard references in the features table; expanded the Supported Financial Instruments table (added Snapshot, DebtEngine, ERC-1363, and UUPS variants; clarified Allowlist entry); added Contract Sizes section with deployed/initcode sizes for all deployment variants; corrected UUPS standalone note.
+- `SECURITY.md`: expanded responsible disclosure policy.
+- `doc/README.md` and `doc/SUMMARY.md`: updated module-level documentation and surya reports to reflect current hierarchy and coverage results.
+- Updated code coverage reports in `doc/test/coverage/` after full test run.
+
+## 3.3.0 - rc0
+
+> **Note:** This version has not been audited.
+
+Commit: `49544f4de1993008acfc9e848d0bf03bd31d8579`
+
+### Smart contract
+
+#### Added
+
+- New base contract **`CMTATBaseERC2612`** (`contracts/modules/4_CMTATBaseERC2612.sol`) combining:
+ - [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612): gasless approvals via EIP-712 signature (`permit`), gated by CMTAT pause and freeze validation.
+ - [ERC-6357 Multicall](https://eips.ethereum.org/EIPS/eip-6357): batch multiple contract calls into a single transaction (`multicall`).
+- New deployment variants: **`CMTATStandalonePermit`** and **`CMTATUpgradeablePermit`** (`contracts/deployment/permit/`), based on `CMTATBaseERC2612`.
+- New module **`ERC20EnforcementERC7551Module`** (`contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol`):
+ - Splits ERC-7551 specific enforcement out of `ERC20EnforcementModule` (see *Changed*).
+ - Provides `bytes data` overloads for `forcedTransfer`, `freezePartialTokens`, `unfreezePartialTokens` (as required by `IERC7551ERC20Enforcement`).
+ - Provides `getActiveBalanceOf` and overrides `getFrozenTokens` to satisfy both `IERC7551ERC20Enforcement` and `IERC3643ERC20Enforcement`.
+- New validation contract **`ValidationModuleAllowance`** (`contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol`):
+ - Validates allowance authorization (`approve` and `permit`): reverts if the contract is paused or if `owner`/`spender` is frozen.
+ - Used in `CMTATBaseERC2612.permit` to enforce CMTAT compliance checks before setting the allowance.
+- New mixin **`CMTATBaseSnapshot`** (`contracts/modules/0_CMTATBaseSnapshot.sol`):
+ - Pure ERC-20 + `SnapshotEngineModule` mixin providing the `_update` hook for historical balance tracking.
+ - Designed to be composed into deployment variants that require snapshot support.
+- New base contract **`CMTATBaseERC2771Snapshot`** (`contracts/modules/6_CMTATBaseERC2771Snapshot.sol`):
+ - Combines `CMTATBaseERC2771` with `CMTATBaseSnapshot`, resolving all ERC-20 / snapshot disambiguation overrides.
+ - Used as the foundation for snapshot-enabled standard deployment variants.
+- New base contract **`CMTATBaseERC7551Enforcement`** (`contracts/modules/6_CMTATBaseERC7551Enforcement.sol`):
+ - Combines `CMTATBaseERC2771` with `ERC20EnforcementERC7551Module`.
+ - Exposes ERC-7551 enforcement functions (`forcedTransfer/freezePartialTokens/unfreezePartialTokens` with `bytes`) and `getActiveBalanceOf` in Standard deployments.
+- New deployment variants **`CMTATStandaloneSnapshot`** and **`CMTATUpgradeableSnapshot`** (`contracts/deployment/snapshot/`):
+ - Standard CMTAT feature set plus SnapshotEngine support for historical balance queries.
+
+#### Changed
+
+- **`ERC20EnforcementModule`**: Removed `IERC7551ERC20Enforcement` interface inheritance and the ERC-7551 specific functions (`getActiveBalanceOf`, `forcedTransfer(address,address,uint256,bytes)`, `freezePartialTokens(address,uint256,bytes)`, `unfreezePartialTokens(address,uint256,bytes)`). These are now in `ERC20EnforcementERC7551Module`. The module now implements only `IERC3643ERC20Enforcement` and `IERC7943FungibleEnforcementSpecific`.
+- **ERC-7551 event model alignment**:
+ - `IERC7551ERC20EnforcementEvent` now exposes `ForcedTransfer(address operator, address from, address to, uint256 value, bytes data)` (replacing the legacy `Enforcement(...)` event shape).
+ - ERC-7551 event emission was removed from `ERC20EnforcementModuleInternal` and is now emitted in ERC-7551 specific paths (`ERC20EnforcementERC7551Module`, and `CMTATBaseCore.forcedBurn`).
+- **`CMTATBaseERC7551`**: Updated to inherit from `ERC20EnforcementERC7551Module` (instead of relying on `ERC20EnforcementModule` alone) to expose ERC-7551 bytes-data enforcement functions and `getActiveBalanceOf`. Added explicit diamond-inheritance disambiguation overrides for `_msgSender`, `_msgData`, `_contextSuffixLength`, `_update`, `transfer`, `transferFrom`, `approve`, `name`, `symbol`, `decimals`, and `getFrozenTokens`.
+- **`CMTATBaseERC7551`**: Promoted to level 7 (`contracts/modules/7_CMTATBaseERC7551.sol`) and now inherits from `CMTATBaseERC7551Enforcement`.
+- **`CMTATBaseERC1363`**: Promoted to level 7 (`contracts/modules/7_CMTATBaseERC1363.sol`) and now inherits from `CMTATBaseERC7551Enforcement` so ERC-1363 deployments keep the standard ERC-7551 enforcement path.
+- **`CMTATStandardStandalone`** and **`CMTATStandardUpgradeable`** now inherit from `CMTATBaseERC7551Enforcement`, so Standard deployments expose ERC-7551 enforcement functions.
+- **`CMTATUpgradeableUUPS`** inheritance remains unchanged (no `CMTATBaseERC7551Enforcement`).
+- **`CMTATBaseAllowlist`**: Now composes `ERC20EnforcementERC7551Module`, so Allowlist deployments also expose ERC-7551 enforcement functions (`forcedTransfer/freezePartialTokens/unfreezePartialTokens` with `bytes`) and `getActiveBalanceOf`.
+- **`EnforcementModuleInternal`**: Hardened freeze-list writes by rejecting `address(0)` in `_addAddressToTheList` (new `CMTAT_Enforcement_ZeroAddressNotAllowed` custom error), preventing misuse of `setAddressFrozen` / `batchSetAddressFrozen` on the zero address.
+- **`ERC20EnforcementModuleInternal`**: Hardened partial freeze paths by rejecting `address(0)` in `_freezePartialTokens` and `_unfreezePartialTokens` (new `CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed` custom error).
+- **`CMTATBaseDebtEngine`**: Now inherits from both `CMTATBaseERC20CrossChain` and `CMTATBaseSnapshot`, adding SnapshotEngine support to the Debt variant. Adds `_authorizeSnapshots` and disambiguation overrides for `_update`, `transfer`, `transferFrom`, `approve`, `name`, `symbol`, `decimals`.
+- **`CMTATBaseDebt`**: Restored SnapshotEngine support by inheriting `CMTATBaseSnapshot` and adding the required disambiguation/authorization overrides (`approve`, `transfer`, `transferFrom`, `decimals`, `name`, `symbol`, `_update`, `_authorizeSnapshots`) so Debt deployments expose `snapshotEngine` / `setSnapshotEngine` again.
+- **RuleEngine operator propagation for cross-chain burn flows**:
+ - `burn` now preserves and propagates `_msgSender()` through the transfer-compliance hook so spender-aware RuleEngine checks are enforced for operator-initiated burns.
+ - `burnFrom` now preserves and propagates `_msgSender()` through the transfer-compliance hook so spender-aware RuleEngine checks are enforced for allowance-based delegated burns.
+ - `crosschainBurn` now follows the same operator propagation model for consistency with `burnFrom`.
+ - `mint` and `crosschainMint` now also propagate `_msgSender()` so spender-aware RuleEngine checks apply consistently to operator-initiated mint flows.
+- **ERC-7943 interface update** — breaking changes aligned with the updated ERC-7943 specification:
+ - `canTransact(address)` removed; replaced by `canSend(address)` and `canReceive(address)` in `ValidationModule`, implementing the new `IERC7943FungibleSendReceiveCheck` interface. Both currently delegate to the same underlying eligibility check (frozen status + allowlist), but allow future asymmetric access policies.
+ - `ERC7943CannotTransact` error removed; replaced by directional errors `ERC7943CannotSend` (emitted when a sender, spender, or burn source is blocked) and `ERC7943CannotReceive` (emitted when a recipient or mint target is blocked), defined in `IERC7943FungibleSendReceiveError`.
+ - Internal `_canTransact` split into `_canSend` and `_canReceive` (both virtual, overridden in `ValidationModuleAllowlist`).
+ - `_canMintBurnByModuleAndRevert` split into `_canMintByModuleAndRevert` (reverts with `ERC7943CannotReceive`) and `_canBurnByModuleAndRevert` (reverts with `ERC7943CannotSend`).
+ - Interface names: `IERC7943TransactError` → `IERC7943FungibleSendReceiveError`; `IERC7943TransactCheck` → `IERC7943FungibleSendReceiveCheck`.
+ - ERC-7943 ERC-165 interface ID updated: `0x29388973` → `0x3edbb4c4`.
+
+### Testing
+
+#### Added
+
+- New test files for the Permit deployment variants: `test/deployment/permit/deploymentPermitStandalone.test.js`, `test/deployment/permit/deploymentPermitUpgradeable.test.js`.
+- New common test modules: `test/common/PermitModuleCommon.js`, `test/common/MulticallModuleCommon.js`.
+
+#### Changed
+
+- `test/common/AllowlistModuleCommon.js`: updated to cover new allowance validation behavior and ERC-7943 directional errors.
+- `test/common/ERC20BaseModuleCommon.js`: updated to cover updated `approve` validation and ERC-7943 directional errors.
+- `test/common/EnforcementModuleCommon.js`, `test/common/PermitModuleCommon.js`, `test/common/ERC20BurnModuleCommon.js`, `test/common/ERC20MintModuleCommon.js`, `test/common/ERC20CrossChainModuleCommon.js`: replaced `canTransact` calls with `canSend`; replaced `ERC7943CannotTransact` revert expectations with the appropriate directional error (`ERC7943CannotSend` or `ERC7943CannotReceive`).
+- `test/utils.js`: updated `IERC7943_INTERFACEID` to `0x3edbb4c4`.
+- `test/deployment/erc721mock.test.js`: updated to `ERC7943CannotReceive`.
+- Deployment test wiring updated after snapshot-module extraction:
+ - Removed snapshot common test calls from non-snapshot deployment suites where `snapshotEngine()` is not exposed (ERC-7551 and ERC-1363 proxy deployment suites).
+ - Added dedicated ERC-7551 enforcement common tests (`test/common/ERC20EnforcementERC7551ModuleCommon.js`) and wired them to ERC-7551 deployment suites.
+ - Added zero-address rejection coverage for enforcement freeze entry points in `test/common/EnforcementModuleCommon.js` (`setAddressFrozen` overloads and `batchSetAddressFrozen`).
+ - Added zero-address rejection coverage for partial freeze entry points in `test/common/ERC20EnforcementModuleCommon.js` (`freezePartialTokens` / `unfreezePartialTokens`, with and without reason).
+ - Added RuleEngine spender-propagation coverage for `burn` and `batchBurn` (`test/common/ERC20BurnModuleCommon.js`) to validate operator-aware checks.
+ - Added `batchBurn` exact-balance edge-case coverage (`testCanBatchBurnWithExactBalances`) in `test/common/ERC20BurnModuleCommon.js`.
+- `package.json`:
+ - `test:snapshot` script path list fixed to remove stale/non-existent targets.
+ - Added `test:snapshot:module` to keep module-level snapshot suite invocation separate.
+
+### Documentation
+
+#### Added
+
+- ERC specification: `doc/ERCSpecification/erc-2612.md` (ERC-2612 Permit).
+- ERC specification: `doc/ERCSpecification/erc-6357-multicall.md` (ERC-6357 Multicall).
+- Module documentation: `doc/modules/options/erc2612/erc2612.md` (`CMTATBaseERC2612` API reference).
+- `ERC20EnforcementERC7551Module` section in `doc/modules/options/erc7551/erc7551.md`.
+- Old ERC-7943 specification archived as `doc/ERCSpecification/erc-7943-uRWA-old.md` for reference.
+
+#### Changed
+
+- `doc/SUMMARY.md`: added **Permit** and **Snapshot** deployment variants; updated inheritance hierarchy to show `CMTATBaseERC2612` and `CMTATBaseERC2771Snapshot` branches.
+- `doc/README.md`: updated ERC-7943 interface table, implementation mapping, transfer flow diagram, and pre-check functions table to reflect `canSend`/`canReceive` split and new error names.
+- `doc/README.md` and `doc/modules/options/erc7551/erc7551.md`: updated ERC-7551 event references from legacy `Enforcement(...)` to `ForcedTransfer(operator,from,to,value,data)` and clarified that ERC-7551 event emission occurs in `ERC20EnforcementERC7551Module`.
+- `doc/modules/extensions/ERC20Enforcement/erc20enforcement.md`: added note about ERC-7551 enforcement functions moved to `ERC20EnforcementERC7551Module`.
+- `doc/modules/options/erc7551/erc7551.md`: added overview table distinguishing `ERC7551Module` from `ERC20EnforcementERC7551Module`.
+- Updated ERC specifications: `erc-1404-restricted.md`, `erc-3643.md`, `erc-7551-ewpg.md`, `erc-7943-uRWA.md`.
+- `doc/README.md`:
+ - Fixed broken local links in audit references.
+ - Corrected deployment-functionality summary tables for snapshot/MetaTx coverage.
+ - Added a dedicated `CMTAT Snapshot` column in the functionality matrix to avoid ambiguity.
+ - Updated security documentation paths from `doc/audits/...` to `doc/security/...` after directory rename.
+ - Added Sequent pre-review references in both audit/pre-review and tooling sections.
+- `README.md` and `doc/README.md`:
+ - Clarified that **Hardhat** is the main development toolchain for CMTAT/repository.
+ - Added note that **Forge/Foundry** is installed for compilation, while Foundry-specific scripts/tests are maintained in [CMTAT-Foundry](https://github.com/CMTA/CMTAT-Foundry).
+ - Updated Hardhat links to `https://v2.hardhat.org` and Foundry link to `https://www.getfoundry.sh`.
+- `doc/USAGE.md`:
+ - Updated OpenZeppelin dependency references to `v5.6.1`.
+ - Updated OpenZeppelin upgradeable submodule location to `lib/openzeppelin-contracts-upgradeable` and clarified its use for Hardhat test helpers.
+ - Updated Node.js reference to `v24.12.0`.
+
+### Dependencies
+
+#### Changed
+
+- Upgraded OpenZeppelin npm packages to `v5.6.1`:
+ - `@openzeppelin/contracts`
+ - `@openzeppelin/contracts-upgradeable`
+- Moved OpenZeppelin upgradeable git submodule from `openzeppelin-contracts-upgradeable` to `lib/openzeppelin-contracts-upgradeable`, and updated test helper imports accordingly.
+- Updated `.nvmrc` to `v24.12.0`.
+
## 3.2.0
> **Note:** This version has not been audited.
+Commit: `49544f4de1993008acfc9e848d0bf03bd31d8579`
+
### Smart contract
#### Added
diff --git a/CLAUDE.md b/CLAUDE.md
index abc48175..47248563 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2,6 +2,9 @@
**CMTAT** (CMTA Token) is a **security token framework** for tokenizing real-world financial assets on EVM-compatible blockchains. It's developed by the Capital Markets and Technology Association (CMTA).
+AGENTS.md and CLAUDE.md files must always be identical
+Module numbering must strictly match dependency order (a lower-level module must not depend on a higher-level module).
+
**Solidity** | **Hardhat**
---
@@ -26,7 +29,7 @@ contracts/
├── deployment/ # Pre-composed contract variants
├── interfaces/ # ERC standards & custom interfaces
└── mocks/ # Test helpers
-test/ # 3,078 tests (~99% coverage)
+test/ # 5,630 tests (~99% coverage)
doc/ # Specs & audit reports
```
@@ -44,29 +47,29 @@ See `./claude/tree/contracts-upgradeables_tree.txt`
## Key Modules
-See `./doc/summary.md`
+See `./doc/SUMMARY.md`
## Deployment Variants
-See `./doc/summary.md`
+See `./doc/SUMMARY.md`
---
## Architecture Highlights
-See `./doc/summary.md`
+See `./doc/SUMMARY.md`
---
## Contract Inheritance Hierarchy
-See `./doc/summary.md`
+See `./doc/SUMMARY.md`
---
## Key Roles (Access Control)
-See `./doc/summary.md`
+See `./doc/SUMMARY.md`
---
@@ -78,6 +81,14 @@ npm run coverage # Generate coverage report
npm run hardhat:compile # Compile contracts
```
+## Test Troubleshooting
+
+If tests fail with gas reporter / Mocha reporter errors (for example `ERR_MOCHA_INVALID_REPORTER` with `eth-gas-reporter`), run tests with gas reporting disabled:
+
+```bash
+DeactivateReportGas=true npx hardhat test
+```
+
---
## Key Files to Understand
diff --git a/README.md b/README.md
index f990eb49..cfd7c4ee 100644
--- a/README.md
+++ b/README.md
@@ -1,3100 +1,192 @@
-# CMTA Token
+# CMTA Token (CMTAT)
-> To use the CMTAT, we recommend the latest audited version, from the [Releases](https://github.com/CMTA/CMTAT/releases) page. Currently, it is the version [v3.0.0](https://github.com/CMTA/CMTAT/releases/tag/v3.0.0).
+> Latest audited release: [v3.0.0](https://github.com/CMTA/CMTAT/releases/tag/v3.0.0)
>
-> PDF files of README are available here: [CMTATSpecificationV3.0.0.pdf](./doc/specification/CMTATSpecificationV3.0.0.pdf), [CMTATSpecificationV3.1.0.pdf](./doc/specification/CMTATSpecificationV3.1.0.pdf)
+> Latest release: [v3.2.0](https://github.com/CMTA/CMTAT/releases/tag/v3.2.0)
+
+CMTAT is a blockchain-agnostic open-source **security token framework**. This repository provides the Solidity reference implementation for EVM-compatible blockchains such as Ethereum, Optimism, Arbitrum, and Polygon PoS. It is developed and maintained by the [Capital Markets and Technology Association](https://www.cmta.ch/) (CMTA).
+It provides a modular implementation focused on regulated issuance and lifecycle management (transfer restrictions, enforcement, pause/deactivation, supply controls, documentation, and optional cross-chain features), with multiple deployment variants (standalone and upgradeable) to fit different product and jurisdiction requirements.
+
+## What is CMTAT?
+
+CMTAT extends the standard [ERC-20](https://eips.ethereum.org/EIPS/eip-20) token with compliance features required for regulated financial instruments:
+
+| Feature | Purpose | Standards | Module Scope |
+|---|---|---|---|
+| **Pause** | Freeze all transfers globally (e.g., during corporate actions) | [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477) (eWpG profile) | Core |
+| **Deactivate** | Permanently disable token operations when required by lifecycle/governance decisions | CMTAT-specific | Core |
+| **Account Freeze** | Block specific addresses from transferring | [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) enforcement model, [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) send/receive checks | Core |
+| **Mint / Burn** | Controlled issuance and redemption of tokens | [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477) (eWpG profile) | Core |
+| **Batch Mint / Batch Burn** | Process multiple mint or burn operations in a single transaction | [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) | Core |
+| **Configurable Decimals** | Define token decimals at deployment time | [ERC-20](https://eips.ethereum.org/EIPS/eip-20)-compatible behavior | Core |
+| **Forced Transfer** | Admins can move tokens from frozen accounts | [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477) (eWpG profile), [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) | Core/Extension |
+| **Set Name / Symbol** | Update token name and symbol after deployment (supported deployment versions) | [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) | Core |
+| **Freeze Partial Tokens** | Freeze a specific amount of tokens on an address | [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477) (eWpG profile), [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) equivalent (`setFrozenTokens`/`getFrozenTokens`) | Extension |
+| **Transfer Validation** | Plug-in rule engine to restrict transfers by origin, receiver, or amount | [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477), [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) | Extension/Option |
+| **Snapshots** | Record balances at a specific point in time (e.g., for dividends) | CMTAT SnapshotEngine integration | Extension/Option |
+| **Documents** | Attach legal documents to the token on-chain | [ERC-1643](https://github.com/ethereum/EIPs/issues/1643)-compatible document model | Extension/Option |
+| **Cross-Chain Mint/Burn** | Cross-chain bridge-oriented mint/burn interface | [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) | Extension |
+| **Permit** | Signature-based approvals without on-chain approve transaction | [ERC-2612](https://eips.ethereum.org/EIPS/eip-2612) | Deployment-version specific |
+| **Multicall** | Execute multiple calls in one transaction | [ERC-6357](https://eips.ethereum.org/EIPS/eip-6357) | Deployment-version specific |
+| **UUPS Upgradeability** | Upgradeable proxy pattern support | [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822) | Deployment-version specific |
+| **Debt Features** | Debt lifecycle and credit-event related capabilities | CMTAT Debt modules | Deployment-version specific |
+| **ERC-1363 Payable Token Hooks** | Token callbacks (`transferAndCall` / `approveAndCall`) | [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) | Deployment-version specific |
+
+Document model note:
+- ERC-1643 document identifiers in CMTAT use `bytes32` names.
+- CMTAT tokenization terms keep the modified CMTAT document structure (`IERC1643CMTAT.DocumentInfo`) with `string name`.
+
+## Who uses CMTAT?
+
+CMTAT is used in production by major financial institutions including **UBS**, **Taurus SA**, **Zand Trust**, **Daura**, **Obligate**, and **Syz Group** to tokenize equities, artwork, bonds, structured products, money market funds, and stablecoins.
+
+### Example Per Use Case
+
+- **Equities**: [Magic Tomato SA (2022)](https://www.taurushq.com/blog/magictomato-1st-foodtech-to-tokenise-its-shares-and-raise-equity/), [Qoqa Brew (2022)](https://www.taurushq.com/blog/qoqa-brew-brasserie-du-futur-tokenisation-et-financement-by-taurus/), [Cité Gestion SA (2023)](https://cmta.ch/news-articles/cite-gestion-becomes-cmta-certified-issuer-of-tokenized-shares), [CODE41 (2023)](https://www.taurushq.com/blog/code41-tokenises-its-shares-for-a-capital-increase-amongst-its-community-through-taurus-technology/).
+- **Debt / Bonds**: [UBS Project Guardian digital bond (2024)](https://www.linkedin.com/posts/cmta-ch_shareubs-activity-7137735139438002177-oDUL), [SCCF tokenized trade-finance notes (2023)](https://www.taurushq.com/blog/sccf-and-horizon-capital-leverage-taurus-technology-to-execute-landmark-tokenized-trade-finance-debt-transaction/), [Obligate](https://www.obligate.com)
+- **Structured Products**: [UBS tokenized warrant on Ethereum (2024)](https://www.ubs.com/global/en/media/display-page-ndp/en-20240207-tokenized-warrant.html)
+- **Stablecoins**: Zand Trust (2025) issued an AED stablecoin using CMTAT v3.0.0 via Taurus infrastructure; [Zand Trust](https://zandtrust.com/).
+- **Tokenized Market Funds**: [UBS uMINT (2024)](https://www.ubs.com/global/en/media/display-page-ndp/en-20241101-first-tokenized-investment-fund.html)
+- **Tokenized Artwork**: [Syz Art tokenization](https://www.syzgroup.com/en/tokenization-syzart).
+
+## Supported Financial Instruments
+
+| Product | Deployment Version |
+|---|---|
+| Equities | CMTAT Standard |
+| Equities / Bonds with balance snapshots (dividends, corporate actions) | CMTAT Snapshot, CMTAT Debt, CMTAT DebtEngine |
+| Equities (Germany / eWpG) | CMTAT ERC-7551 |
+| Debt / Bonds | CMTAT Debt |
+| Debt / Bonds (external debt engine) | CMTAT DebtEngine |
+| Stablecoins | CMTAT Light |
+| Allowlist / Whitelist | CMTAT Allowlist or CMTAT Standard with RuleEngine |
+| Permit + Multicall | CMTAT Permit |
+| Payable token / DeFi callbacks | CMTAT ERC-1363 |
+| Any (UUPS upgradeable proxy) | CMTAT UUPS |
+
+Most products come in a **standalone** (immutable) or **upgradeable** (proxy) variant. The UUPS variant (`CMTATUpgradeableUUPS`) is upgradeable only — no standalone counterpart exists.
+
+## Contract Sizes
+
+Measured with `solc 0.8.34`, optimizer enabled (200 runs). EVM deployed bytecode limit: **24.576 KiB**.
+
+| Deployment Version | Deployed (KiB) | Initcode standalone (KiB) | Initcode upgradeable (KiB) |
+|---|---|---|---|
+| CMTAT Standard | 22.243 | 25.635 | 22.569 |
+| CMTAT Snapshot | 22.067 | 25.459 | 22.394 |
+| CMTAT Light | 11.298 | 13.048 | 11.507 |
+| CMTAT Allowlist | 19.879 | 23.056 | 20.205 |
+| CMTAT Debt | 23.187 | 26.301 | 23.396 |
+| CMTAT DebtEngine | 23.791 | 26.905 | 24.000 |
+| CMTAT ERC-7551 | 22.807 | 26.198 | 23.133 |
+| CMTAT ERC-1363 | 23.805 | 27.238 | 24.131 |
+| CMTAT Permit | 23.268 | 26.557 | 23.477 |
+| CMTAT UUPS | 23.544 | — | 23.896 |
+
+All variants are within the deployed bytecode limit. The deployed size is identical between standalone and upgradeable for the same variant; the initcode is larger for standalone contracts since it includes the full constructor logic rather than an initializer.
+
+## Key Standards
+
+CMTAT implements a wide set of Ethereum standards:
+
+- **[ERC-20](https://eips.ethereum.org/EIPS/eip-20)** — fungible token
+- **[ERC-3643](https://eips.ethereum.org/EIPS/eip-3643)** — security token (without on-chain identity)
+- **[ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477)** — crypto security token interface (Germany eWpG profile)
+- **[ERC-7943 (uRWA)](https://eips.ethereum.org/EIPS/eip-7943)** — universal RWA interface
+- **[ERC-1404](https://github.com/ethereum/EIPs/issues/1404)** — restricted token
+- **[ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612)** — gasless approvals (specific deployment versions only)
+- **[ERC-1363](https://eips.ethereum.org/EIPS/eip-1363)** — payable token hooks (specific deployment versions only)
+- **[ERC-6357 Multicall](https://eips.ethereum.org/EIPS/eip-6357)** — batched calls in one transaction (specific deployment versions only)
+- **[ERC-2771](https://eips.ethereum.org/EIPS/eip-2771)** — meta-transactions (gas sponsorship / gasless)
+- **[ERC-7802](https://eips.ethereum.org/EIPS/eip-7802)** — cross-chain transfers
+- **[ERC-7201](https://eips.ethereum.org/EIPS/eip-7201)** — storage namespaces for upgradeability
+- **[UUPS Proxy (ERC-1822 pattern)](https://eips.ethereum.org/EIPS/eip-1822)** — upgradeability pattern (specific deployment versions only)
+
+## Cross-Chain Compatibility
+
+CMTAT provides cross-chain compatibility through `ERC20CrossChain` and related deployment options:
+
+- **ERC-7802**: native `crosschainMint` / `crosschainBurn` support for bridge-style interoperability.
+- **Chainlink CCIP (CCT)**: compatible burn/mint token flow, including `getCCIPAdmin()` support through the `CCIPModule`.
+- **LayerZero**: supported through external OFT adapters (ERC-3643 and ERC-7802 variants) in [CMTAT-LayerZero](https://github.com/CMTA/CMTAT-LayerZero).
+
+For full architecture, permissions, and operational notes, see:
+- [Cross-chain bridge integration](./doc/technical/cross-chain-bridge-integration.md)
+- [Main documentation](./doc/README.md)
+
+## Other Blockchain Implementations
+
+CMTAT is blockchain-agnostic and also has implementations/adaptations beyond this Solidity EVM repository:
+
+- **Solana**: [CMTAT-Solana](https://github.com/CMTA/CMTAT-Solana)
+- **Tezos**:
+ - Official SmartPy implementation: [CMTAT-Tezos-FA2](https://github.com/CMTA/CMTAT-Tezos-FA2)
+ - LIGO implementation: [CMTAT-Ligo](https://github.com/CMTA/CMTAT-Ligo)
+- **Aztec (privacy-focused variant)**: [private-CMTAT-aztec](https://github.com/CMTA/private-CMTAT-aztec)
+- **Zama Confidential variant**: [CMTAT-Confidential](https://github.com/CMTA/CMTAT-Confidential)
+ - A confidential security token implementation combining CMTAT compliance features with the Zama Confidential Blockchain Protocol for private balances.
-## Introduction
-
-The CMTA token (CMTAT) is a security token framework that includes various compliance features such as conditional transfer, account freeze, and token pause, as well as several technical features such as [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) for cross-chain transfer and [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) for upgradeadibility.
-
-This repository provides CMTA's reference Solidity implementation of CMTAT, suitable for EVM chains such as Ethereum.
-
-[TOC]
-
-### History
-
-The CMTA token (CMTAT) is a security token framework that includes various compliance features such as conditional transfer, account freeze, and token pause. CMTAT was initially optimized for the Swiss law framework, however, these numerous features and extensions make it suitable for other jurisdictions too.
-
-The CMTAT is an open standard from the [Capital Markets and Technology Association](https://www.cmta.ch/) (CMTA), which gathers organizations from the financial, legal and technology sectors.
-The CMTAT was first developed by a working group of CMTA's [members](https://cmta.ch/members) and its development is now overseen by the [Technical Committee of CMTA's Advisory Board](https://cmta.ch/advisory-board).
-
-### Goal
-
-CMTAT has been built with five main goals:
-
-1. Suitable for various regulatory financial assets and instruments (Equities, Structured products, Debt and Stablecoin) and adapted to any jurisdiction (international)
-
-2. Easy to modify and adapt for specific use-case (customization) through its modular architecture
-3. Interoperability with the Ethereum ecosystem by implementing recognized standards:
- - Tokenization: [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) (without on-chain identity), [ERC-7943 (uRWA)](https://eips.ethereum.org/EIPS/eip-7943), [ERC-1404](https://github.com/ethereum/EIPs/issues/1404), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477), [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363),...
- - Technicals: [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (MetaTx/Gasless), [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201), [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802),...
-
-4. Security by undergoing audits from trusted firms like [ADBK](https://abdk.consulting) and [Halborn](https://www.halborn.com), and by implementing a range of industry best practices.
- - Strong code statements coverage(~99.43%) with 3078 automated tests executed
- - Run static analyzer ([Aderyn](https://github.com/Cyfrin/aderyn), [Slither](https://github.com/crytic/slither/tree/master)), as well as AI Auditing tools ([Nethermind Audit Agent](https://auditagent.nethermind.io), [Wake Arena](https://ackee.xyz)), before and after the audits
- - RBAC Access Control to clearly separates the different roles and permissions
-
-5. Freedom of use through an open-source weak copyleft license ([MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/FAQ/))
-
-
-
-By taking these five main goals, here a comparison with others known implementations to deploy financial instruments on-chain.
-
-| | CMTAT | ERC-3643 (Tokeny implementation) | ERC-1400 (UniversalToken) | TokenF | ERC-20 Smart Coin (Cast framework) |
-| ----------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Version/Commit | v3.0.0 (09/2025) | [4.2.0-beta2](https://github.com/TokenySolutions/T-REX/releases/tag/4.2.0-beta2) (01/2025) | [54320c6](https://github.com/Consensys/UniversalToken/commit/54320c6f7a8ee1fd7fcb19073e9c122e1e8f96f9) (01/2024) | [0c1c2ac](https://github.com/dl-tokenf/contracts/commit/0c1c2ac0aa8c95423928a9ed09ab14bce64054f5) (04/2025) | [dd8bf5e](https://github.com/castframework/smartcoin/commit/dd8bf5e1ba24d2379b102db74bfc8326fb649b65) (01/2025) |
-| Company / Association behind | [CMTA](https://cmta.ch/) | [Tokeny](https://tokeny.com/), [ERC3643 Association](https://www.erc3643.org/) | [Consensys](https://consensys.io/) | [Distributed Lab](https://distributedlab.com/) | [SOCIÉTÉ GÉNÉRALE FORGE](https://www.sgforge.com) |
-| 1 (suitable for various financial instruments) | ✔ | Partial | ✔ | Partial | Partial |
-| Details | - | Lack of support for Debt product
On-chain identity management can potentially make it too complex for stablecoins Also lacks support for adding information related to on-chain terms (hash, uri) | - | Lacks support for adding information related to on-chain terms (hash, uri) as well as Debt product but contracts could be extended. | Lacks support for adding information related to on-chain terms (hash, uri) as well as Debt product |
-| 2 (customizable) | ✔ | ✘ | ✘ | ✔ | ✔ |
-| Details | Modular architecture | Code difficult to modify because functionalities are not clearly separated and onchain identity management is required | Code difficult to modify because functionalities are not clearly separated | Customizable but uses the [Diamant proxy](https://eips.ethereum.org/EIPS/eip-2535) pattern structure which makes it more complex to implement | Contracts are minimalist and easy to modify |
-| 3 (interoperability) | ✔ | ✔ | Partial | ✔ | ✔ |
-| Details | Tokenization: [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) (without on-chain identity), [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) (uRWA), [ERC-1404](https://github.com/ethereum/EIPs/issues/1404), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477), [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363),... Technicals: [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771), [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201), [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802),... | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) and [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) | While ERC-1400 is an [ERC-20](https://eips.ethereum.org/EIPS/eip-20), the standard ERC-1400 is not itself an official standard It has also a dependence with [ERC-1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract, which is not always available/deployed on some layer2. | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) and [ERC-2535](https://eips.ethereum.org/EIPS/eip-2535) | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) |
-| 4 (Security) | ✔ | ✔ | ✘ | ✘ | ✘ |
-| | - 1.0 and 2.3.0: audited by [ABDK](https://abdk.consulting) 3.0.0 audited by [Halborn](https://www.halborn.com) - RBAC Access Control | - Past version audited by [Hacken](https://hacken.io). - Lack of granularity in term of Access Control (only two roles: Agent and Owner) | No official public audit for the last commits, last audit was done in 2020 | No official audit available | No official audit available |
-| 5 (License - Open source & Allow Commercial use) | ✔ | Partial (only ERC-3643 core) | ✔ | ✔ | |
-| | [MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) (weak copyleft) | - ERC-3643 core: GPL 3.0 (strong copyleft) - Compliance module: CC-BY-NC-4.0(forbid commercial use) | Apache 2.0 (permissive) | MIT (permissive) | [Apache-2.0 license](https://github.com/castframework/smartcoin/tree/main#Apache-2.0-1-ov-file) (permissive) |
-
-
-
-### Who uses CMTAT and for what?
-
-CMTAT is suitable for the digitalization of various financial assets. Below is a selection of public case studies
-
-More details are available here: [cmta.ch/faqs](https://cmta.ch/faqs#what-cases-has-cmtat-already-been-used-in)
-
-#### Digitalization of equity securities
-
-The CMTAT was initially designed for the digitalization of company shares. For SMEs, digitalization provides an opportunity to access new financing and investment models by selling digital shares through online exchanges. Some companies that have digitalized shares using the CMTAT include:
-
-- [Daura](https://thetokenizer.io/2022/12/13/daura-counts-on-smart-contract-standard-cmtat-for-the-tokenization-of-swiss-shares/) uses the CMTAT through their own fork to digitalize the shares of companies using its [platform](https://www.daura.ch), deployed on [zkSync](https://zksync.io/).
-- [Taurus SA](https://www.taurushq.com) (partial list): [Magic Tomato SA (2022)](https://www.taurushq.com/blog/magictomato-1st-foodtech-to-tokenise-its-shares-and-raise-equity/) - an online grocery platform opened its governance and capital to its community, by issuing digital non-voting shares (bons de participation), [Qoqa Brew (2022)](https://www.taurushq.com/blog/qoqa-brew-brasserie-du-futur-tokenisation-et-financement-by-taurus/) - an online retailer opened the capital of its on-site brewery Q-Brew to its community by issuing digital non-voting shares, [Cité Gestion SA (2023)](https://cmta.ch/news-articles/cite-gestion-becomes-cmta-certified-issuer-of-tokenized-shares) - a Swiss bank and wealth manager, issued digitalized shares in 2022, using the CMTAT, [CODE41 (2023)](https://www.taurushq.com/blog/code41-tokenises-its-shares-for-a-capital-increase-amongst-its-community-through-taurus-technology/) - a Swiss watchmaking company tokenized its shares for a capital increase using CMTAT.
-
-#### Digitalization of debt securities
-
-- [Project Guardian - UBS (2024)](https://www.linkedin.com/posts/cmta-ch_shareubs-activity-7137735139438002177-oDUL): CMTAT was used to issue a digital bond by UBS, as part of the first live repo transaction with a natively-issued digital bond on a public blockchain as part of the Monetary Authority of Singapore’s (MAS) Project Guardian.
-- The Obligate platform [Enote Protocol](https://docs.obligate.com/obligate/enote-protocol) enables BulletBond issuances using smart contracts, deployed on Polygon PoS. For this purpose, they use a fork of CMTAT with the `SnapshotModule`(replaced in CMTAT v3.0.0 by the SnapshotEngine) and the DebtModule.
-- [SCCF (2023)](https://www.taurushq.com/blog/sccf-and-horizon-capital-leverage-taurus-technology-to-execute-landmark-tokenized-trade-finance-debt-transaction/): trade finance firm SCCF issued short term tokenized notes to refinance a loan to a commodity trading firm active in biofuels through [Taurus SA](https://www.taurushq.com). See also [SCCF and Taurus Announce Successful Tokenization of End-to-End Trade Finance Transaction on TDX Marketplace (2024)](https://www.taurushq.com/blog/sccf-and-taurus-announce-successful-tokenization-of-end-to-end-trade-finance-transaction-on-tdx-marketplace/)
-
-#### Digitalization of structured products
-
-- In early 2024, [UBS](https://www.ubs.com/global/en/investment-bank/tokenize.html) executed a pilot transaction with OSL, a licensed professional investor in Hong Kong, to issue a tokenized warrant on Ethereum using the CMTAT smart contract framework. The tokenization arrangement for this warrant utilizes the CMTAT codebase to represent the warrant smart contract, which forms part of the tokenized register of holders. See [ubs.com - UBS expands its digital asset capabilities by launching Hong Kong’s first-ever tokenized warrant on the Ethereum network [ubs.com]](https://www.ubs.com/global/en/media/display-page-ndp/en-20240207-tokenized-warrant.html).
-- [Credit Suisse, Pictet and Vontobel (2022)](https://cmta.ch/news-articles/trading-and-settlement-in-digital-securities) issued tokenized investment products that were traded on [BX Swiss](https://www.bxswiss.com/news/20221213-BX-Swiss-legt-das-technische-Fundament-fuer-die-Zukunft-des-regulierten-Handels-mit-tokenisierten-Wertpapieren) as part of a proof-of-concept leveraging the CMTAT.
-
-#### Digitalization of artwork
-
-- [Syz Group](https://www.syzgroup.com/en), a Swiss private bank, has successfully digitized two pieces of art using CMTAT in 2023 and 2024. See [Syz Art Tokenisation](https://www.syzgroup.com/en/tokenization-syzart)
-
-#### Tokenized market funds
-
-- In 2024, [UBS](https://www.ubs.com/global/en/investment-bank/tokenize.html) launched UBS USD Money Market Investment Fund Token (uMINT), a Money Market investment built on Ethereum distributed ledger technology. The tokenization arrangement for this fund utilizes CMTAT codebase to represent the fund smart contract, which forms part of the fund’s tokenized register of members. See [ubs.com - UBS Asset Management launches its first tokenized investment fund [ubs.com]](https://www.ubs.com/global/en/media/display-page-ndp/en-20241101-first-tokenized-investment-fund.html)
-
-#### Tokenization platform
-
-- Fireblocks integrates CMTAT into their [tokenization platform](https://www.fireblocks.com/platforms/tokenization/). See also [Fireblocks - Fireblocks joins CMTA to define the standards for tokenization in traditional capital markets](https://www.fireblocks.com/blog/fireblocks-joins-cmta-to-define-the-standards-for-tokenization-in-traditional-capital-markets/)
-- Taurus SA integrates CMTAT (Solidity and [Tezos version](https://www.taurushq.com/blog/taurus-supports-tokenisation-of-equity-on-the-tezos-blockchain/)) into their tokenization platform called [Taurus-CAPITAL](https://www.taurushq.com/capital/)
-
-#### Wrapped Tokens
-
-- 21.co (the original parent company of [21Shares](https://www.21shares.com/) acquired by FalconX) used CMTAT through their own [fork](https://github.com/amun/CMTAT) to create Wrapped Tokens on Ethereum. See for example Wrapped Bitcoin(21BTC) on [Etherscan](https://etherscan.io/token/0x3f67093dffd4f0af4f2918703c92b60acb7ad78b) and [their announcement](https://www.globenewswire.com/news-release/2024/09/03/2939399/0/en/21-co-Expands-its-Wrapped-Tokens-Lineup-with-the-Launch-of-Wrapped-Bitcoin-21BTC-on-Ethereum.html)
-
-#### Private DvP settlement
-
-- In 2026, [Seturion](https://group.boerse-stuttgart.com/en/seturion/) successfully achieved private DvP settlement of tokenized assets on a public blockchain stack while keeping all sensitive data confidential using the implementation of [CMTAT on Aztec](https://github.com/taurushq-io/private-CMTAT-aztec), an Ethereum Layer-2 network that employs zero-knowledge cryptography on protocol level to ensure fully programmable privacy. Read more [here](https://www.linkedin.com/posts/seturion_achieving-private-dvp-settlement-on-public-activity-7424387919538450433-OItI/).
-
-### Where CMTAT is mentioned?
-
-CMTAT is referenced in several reports. Although these reports do not reflect the most recent version, they already provide a good indication of potential use cases. The insights from these reports have also contributed to numerous improvements in CMTAT.
-
-- [University of Toronto - Blockchain Meets Securities: A Scalable Tokenization Framework](https://dl.acm.org/doi/10.1145/3777461) / [pdf](https://www.eecg.utoronto.ca/~veneris/DLTACM25.pdf) (2025), page 22
-- [Forum - Asset Tokenization in Financial Markets: The Next Generation of Value Exchange (2025)](https://reports.weforum.org/docs/WEF_Asset_Tokenization_in_Financial_Markets_2025.pdf), page 38
-- [King's Business School/Rhys Bidder - What Is The Future Of Stablecoins, And How Do We Get There? (2025)](https://www.kcl.ac.uk/business/assets/PDF/qcgbf-working-papers/taking-the-next-step-v5.pdf), page 33
-- [Nethermind - Tokenization Standards: The Missing Link for Institutional Adoption (2025)](https://www.nethermind.io/blog/tokenization-standards-the-missing-link-for-institutional-adoption): page 2, 16, 19, 33-36 & 39
-- [Nethermind & PwC Germany - Tokenization Standards: Taming the Regulatory Menagerie](https://gftn.co/hubfs/Tokenization_Standards_Nethermind_PwC_GFTN.pdf)
-- [Project Guardian - Fixed Income Framework (2024)](https://www.mas.gov.sg/-/media/mas-media-library/development/fintech/guardian/guardian-fixed-income-framework.pdf): page 13, 39, 59 & 65
-- [ICMA contribution to MAS Guardian Fixed Income Framework (GFIF) publication (2024)](https://www.icmagroup.org/assets/Summary-of-third-party-proposals-for-integrating-ICMAs-Bond-Data-Taxonomy-in-token-frameworks-and-DLT-platforms-complementing-section-6-Data-Model-of-GFIF.pdf)
-
-### What Makes CMTAT Different from a Regular ERC-20 Token?
-
-Standard ERC-20 tokens allow anyone to transfer freely.
-CMTAT adds **compliance features** required for real-world financial assets such as:
-
-| Feature | Purpose |
-| -------------------------------------- | ------------------------------------------------------------ |
-| **Pause** | Freeze all transfers globally (e.g., during corporate actions) |
-| **Account Freeze** | Block specific addresses from transferring |
-| **Transfer Validation - Custom rules** | Custom rules (`RuleEngine`) allowing to restrict transfers based on the origin, the receiver or the amount transferred |
-| **Forced Transfer** | Admins can move tokens from frozen accounts |
-| **Snapshots** | Record balances at specific times (for dividends) |
-| **Documents** | Attach legal documents to the token |
-
-### Use case
-
-#### Financial instruments
-
-This reference implementation allows the issuance and management of tokens representing equity securities, and other forms of financial instruments such as debt securities and structured products. It can also be used for stablecoins.
-
-#### Jurisdiction
-
-CMTAT was initially optimized for the Swiss law framework, it then took a more **international** path with the version v3.0.0. Subsequently, its numerous compliance features, as well as the numerous configuration possibilities during deployment, make it also suitable for other jurisdictions.
-
-Its modular structure allows it to be easily modified to suit specific cases. For example, a deployment version has been made for Germany (ERC-7551 / eWpG).
-
-You may modify the token code by adding, removing, or modifying features. However, the core modules must remain in place for compliance with the CMTA specification.
-
-#### Specific deployment version tailored to use case
-
-##### Product use case (equities, stablecoins)
-
-CMTAT comes with several different deployment versions to meet specific use cases.
-
-| Product | Deployment version | Note |
-| -------------------------- | ------------------ | ------------------------------------------------------------ |
-| Equities | CMTAT Standard | All features, without those directly to Debt |
-| Equities in Germany | CMTAT ERC-7551 | The standard version with a few supplementary functions to meet the standard [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477), tailored for the Germany and eWpg. |
-| Debt/bond | CMTAT Debt | CMTAT Standard is also suitable but this version adds the possibility to put several on-chain information related to debt and bond product |
-| Stablecoin (e.g USDC/USDT) | CMTAT Light | The core features (i.e., minting, burning,address freeze / blacklisting, pause) without additional functions required by equities and debt instruments (e.g., document management, snapshot, partial freeze of balances). |
-
-##### Technical use case (whitelist, upgradeable/proxy)
-
-| Features | Deployment version supported |
-| ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Restrict transfer to inside a whitelist / Allowlist | CMTAT Allowlist Or all other deployment (except Light) version with a `RuleEngine` configured |
-| On-chain snapshot (useful for on-chain dividend distribution) | All deployment version (except Light) with a `SnapshotEngine`configured |
-| Deployment through proxy (Upgradeable) Deployment immutable (standalone / without proxy) | Each deployment version comes with a standalone (immutable) or upgradeable mode. A specific deployment version exists for UUPS Proxy |
-| MetaTx/Gasless with ERC-2771 | All deployment version, except Debt & Light version |
-
-#### CMTAT for stablecoins
-
-Here is a comparison between the features present in major custodian stablecoin and the library CMTAT.
-
-| | | **Monerium** | **USDC** | **USDT** | **CMTAT 3.0.0 Light** | CMTAT 3.0.0 Standard |
-| :----------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | ------------------------------------------------------------ |
-| Source | | [ec59a36](https://github.com/monerium/smart-contracts/commit/ec59a3677a17a06610d7e4788211c19da561241b) | [Ethereum USDC implementation contract](https://etherscan.io/address/0x43506849d7c04f9138d1a2050bbf3a0c054402dd#code) | [Ethereum USDT address](https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7) | | |
-| Currency | | $, euros, pound sterling, Icelandic króna | $ | $ | - | - |
-| Company behind | | [Monerium](https://monerium.com) | [Circle](https://www.circle.com) | [Tether](https://tether.to/en/) | [CMTA](https://cmta.ch/) | [CMTA](https://cmta.ch/) |
-| **Standard** | | | | | | |
-| | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) | ✔ | ✔ | ✔ | Same as standard version | ✔ |
-| | [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) | ✔ ([GitHub)](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/Token.sol#L152) | ✔ | ✘ | Same as standard version | ✘ |
-| | [ERC-3009](https://eips.ethereum.org/EIPS/eip-3009) (Transfer With Authorization) | ✘ | ✔ | ✘ | Same as standard version | ✘ |
-| | [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (MetaTX) | ✘ | ✘ | ✘ | ✘ | ✔ (ERC2771Module / CMTATBaseERC2771) |
-| ERC-20 extends functionalities | | | | | | |
-| | Mint/issue | ✘ (see mint with allowance) | ✘ (see mint with allowance) | ✔ | Same as standard version | ✔ |
-| | Mint with dedicated allowance ("mintFrom") | ✔ ([Github](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/MintAllowanceUpgradeable.sol#L3)) | ✔ | ✘ | Same as standard version | ✘ |
-| | Batch Mint version | ✘ | ✘ | ✘ | Same as standard version | ✔ |
-| | burn / redeem | ✔ ([Github](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/Token.sol#L74)) | ✔ | ✔ (`redeem`/ `destroyBlackFunds` | Same as standard version | ✔ |
-| | Set name after deployment | ✘ | ✘ | ✘ | Same as standard version | ✔ (ERC20BaseModule) |
-| | Set symbol after deployment | ✘ | ✘ | ✘ | Same as standard version | ✔ (ERC20BaseModule) |
-| Regulatory | | | | | | |
-| | Integrated blacklist (inside token smart contract) | ✘ | ✔ | ✔ | Same as standard version | ✔ |
-| | External blacklist (can be shared with several different tokens) | ✔ [GitHub](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/BlacklistValidatorUpgradeable.sol#L102) | ✘ | ✘ | ✘ | ✔ (through a dedicated smart contract RuleEngine) |
-| | | **Monerium** | **USDC** | **USDT** | **CMTAT 3.0.0 Light** | **CMTAT 3.0 Standard** |
-| Access Control | | | | | | |
-| | [Ownership](https://docs.openzeppelin.com/contracts/5.x/api/access#Ownable) | ✔ [(Github](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/SystemRoleUpgradeable.sol#L8)) | ✔ | ✔ | Same as standard version | ✘ (use Access Control instead, but ownership could be added) |
-| | [RBAC Access control](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl) | ✔ [GitHub](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/SystemRoleUpgradeable.sol#L7) | ✔ (Minter & Blacklister) | ✘ | Same as standard version | ✔ |
-| Upgradeability | | | | | | |
-| | Upgradable (transparent/Beacon) | ✘ | ✔ | ✘ | Same as standard version | ✔ |
-| | Upgradeable UUPS | ✔ ([GitHub](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/Token.sol#L23)) | ✘ | ✘ | ✘ | ✔ (through a dedicated deployment version) |
-| | Migrate function integrated | ✘ | ✘ | ✔ (because USDT was made before the apparition of proxy architecture) | Same as standard version | ✘ |
-| Standalone (immutable) | | ✘ | ✘ | ✔ | Same as standard version | ✔ (through a dedicated deployment version) |
-| Pause transfers | | Partial Could use the `validator` contract to pause all transfers ([GitHub](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/Token.sol#L122C13-L122C22)) | ✔ | ✔ | Same as standard version | ✔ (PauseModule) |
-| Fee on transfer | | ✘ | ✘ | ✔ (currently set at 0) | Same as standard version | ✘ |
-
-
-
-#### CMTAT for tokenized market funds
-
-Here is a comparison between the features present in known tokenized market funds and the library CMTAT.
-
-| | | Spiko (EUTBL and USTBL) | Franklin Templeton (FOBXX / Benji) | Blackrock (BUIDL) | CMTAT 3.0.0 Standard | CMTAT 3.00 ERC-1363 |
-| :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Reference | | | [Franklin OnChain U.S. Government Money Fund (FOBXX)](https://www.franklintempleton.com/investments/options/money-market-funds/products/29386/SINGLCLASS/franklin-on-chain-u-s-government-money-fund/FOBXX) [Avalanche - Franklin Templeton Launches Tokenized Money Market Fund BENJI On The Avalanche Network](https://www.avax.network/about/blog/franklin-templeton-launches-tokenized-money-market-fund-benji-avalanche) | Securitize contracts [Proxy](https://etherscan.io/address/0x7712c34205737192402172409a8f7ccef8aa2aec) [Implementation](https://etherscan.io/address/0x603bb6909be14f83282e03632280d91be7fb83b2#code) | - | - |
-| Source | | [9ef58f3](https://github.com/spiko-tech/contracts/commit/9ef58f31bc8dc9cb562dfcbae6091866b3da5121) | [Franklin Templeton Digital Assets - contracts](https://digitalassets.franklintempleton.com/benji/benji-contracts/) [Contract proxy](https://snowtrace.io/token/0xE08b4c1005603427420e64252a8b120cacE4D122?chainid=43114) [Contract implementation](https://snowtrace.io/address/0x5c118e6A0bD2de0AF66655806E3001727C13d105/contract/43114/code) | | - | - |
-| Company behind | | [Spiko](https://www.spiko.io/) | [Franklin Templeton](https://digitalassets.franklintempleton.com) | [Blackrock](https://www.blackrock.com/) through [Securitize](https://securitize.io) | [CMTA](https://cmta.ch/) | [CMTA](https://cmta.ch/) |
-| **Standard** | | | | | | |
-| | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) | ✔ | ✔ | ✔ | ✔ | Same as standard version |
-| | [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) | ✔ | ✘ | ✘ | ✘ | ✔ |
-| | [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) | ✔ ([GitHub)](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L26) | ✘ | ✘ | ✘ (Could be extended to support it) | Same as standard version |
-| | [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (MetaTX) | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L22)) | ✘ | ✘ | ✔ | Same as standard version |
-| ERC-20 extends functionalities | | | | | | |
-| | Mint/issue | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L59)) | ✔ | ✔ | ✔ | Same as standard version |
-| | Mint with dedicated allowance ("mintFrom") | ✘ | ✘ | ✘ | ✘ | Same as standard version |
-| | Batch Mint version | ✘ | ✘ | ✘ | ✔ | Same as standard version |
-| | burn / redeem | ✔ ([Github](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L63)) | ✔ | ✔ (burn & omnibusBurn) | ✔ | Same as standard version |
-| Regulatory | | | | | | |
-| | Whitelist / Allowlist | ✔ | ✔ (through external contract `moduleRegistry`) | ✔ (through external contract `ComplianceServiceWhitelisted`) | ✔ (through *RuleEngine*) | Same as standard version |
-| | On-chain country investor restriction /banned | ✘ | ✘ | ✔ (though an on-chain list of investor and the library `ComplianceServiceLibrary` ) | | |
-| | Integrated blacklist (inside token smart contract) | ✘ (Could be implemented, but use a whitelist system currently) | ✘ | ✘ | ✔ (EnforcementModule) | Same as standard version |
-| | External blacklist (can be shared with several different tokens) | ✔ [GitHub](https://github.com/monerium/smart-contracts/blob/d2a633e8d2d028dcc6f251a394273a9cac1b1e43/src/BlacklistValidatorUpgradeable.sol#L102) | ✔ (through external contract `moduleRegistry`) | ✘ | ✔ (RuleEngine) | Same as standard version |
-| | Forced Transfer | ✘ | ✔ (called `instantTransfer`) | ✔ (called *size*) | ✔ | Same as standard version |
-| | Restriction on `transferFrom` | ✘ | ✔ (through `disableERC20ThirdPartyTransfer` & `enableERC20ThirdPartyTransfer`) | ✘ | Partial (transfer revert if spender is frozen) | Same as standard version |
-| | | **Spiko** | **Franklin Templeton (FOBXX / Benji)** | **Blackrock (BUILD)** | **CMTAT 3.0.0 Standard** | **CMTAT 3.00 ERC-1363** |
-| Access Control | | | | | | |
-| | [Ownership](https://docs.openzeppelin.com/contracts/5.x/api/access#Ownable) | ✔ [(Github](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L23)) | ✘ (only `ModuleRegistry` is ownable) | ✔ | ✘ (easily adaptable to support this) | Same as standard version |
-| | [RBAC Access control](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl) | ✔ [GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/permissions/PermissionManager.sol) | ✔ | ✔ (several roles: Exchange, Issuer, transfer agent and master) | ✔ | Same as standard version |
-| | [Access Control Manager](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessManaged) | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/permissions/PermissionManager.sol#L14C5-L14C15)) | ✘ | ✘ | ✘ (Could be extended to support it) | Same as standard version |
-| Upgradeability | | | | | | |
-| | Upgradable (transparent/Beacon) | ✔ | ✔ | ✔ | ✔ | Same as standard version |
-| | Upgradeable UUPS | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L29)) | ✔ | ✘ | ✘ (Could be extended to support it) | Same as standard version |
-| Pause transfers | | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L67)) | ✔ (trough `enableERC20Transfer` and `disableERC20Transfer`) | ✔ | ✔ | Same as standard version |
-| Lock tokens | | ✘ | ✘ | ✔ | ✘ | Same as standard version |
-| Specific functions for omnibus wallet | | ✘ | ✘ | ✔ | ✘ (see specific deployment version) | Same as standard version |
-| Dedicated function to fetch the list of token holders and their balance | | ✘ | ✔ (`getAccountsBalances`) | ✔ (`checkWalletsForList` & `balanceOfInvestor`) | ✘ | Same as standard version |
-| Price indicated on-chain | | ✘ | ✔ (`lastKnownPrice`) | ✘ | ✘ | Same as standard version |
-
-**Note**
-
-- *Fasanara Capital Ltd* has also tokenized a money market fund. Since they have worked with [Tokeny](https://tokeny.com) and use therefore the ERC-3643 standard, a comparison with this standard is provided in other sections of this document. See also [Tokeny - How Tokeny Powers Fasanara’s Tokenized Money Market Funds](https://tokeny.com/customer-story-fasanaras-tokenized-mmf/)
-- Upgradeability: a specific CMTAT deployment version allows to use UUPS proxy
-
-### Comparison of CMTAT and other tokenization frameworks
-
-Here is a comparison between the features present in known tokenization framework and the library CMTAT.
-
-| Label | CMTAT Solidity code | **E**RC-1400 | ERC-3643 | Cast Framework |
-| :----------------------------------------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Version/implementation compared | [CMTAT v3.1.0](https://github.com/CMTA/CMTAT/releases/tag/v3.1.0) | [UniversalToken (Consensys)](https://github.com/Consensys/UniversalToken/tree/54320c6f7a8ee1fd7fcb19073e9c122e1e8f96f9) | [Tokeny's T-Rex](https://github.com/TokenySolutions/T-REX)
[3fcf44d](https://github.com/TokenySolutions/T-REX/tree/3fcf44d4fc102fb891aaad27ee58e8936d885542) (06/02/2025) | Smart Coin (ERC-20 version) [dd8bf5e](https://github.com/castframework/smartcoin/tree/dd8bf5e1ba24d2379b102db74bfc8326fb649b65) |
-| Company / Association behind | [CMTA](https://cmta.ch/) | [Consensys](https://consensys.io/) | [Tokeny](https://tokeny.com/), [ERC3643 Association](https://www.erc3643.org/) | [SOCIÉTÉ GÉNÉRALE FORGE](https://www.sgforge.com) |
-| | | | | |
-| ERC-20 | ✔ | ✔ | ✔ | ✔ |
-| **Regulatory features** | | | | |
-| Transfer restriction (blacklist / address freeze) | ✔ | ✔ | ✔ | ✔ |
-| Transfer restriction on the spender address (*transferFrom*) | ✔ | **✘** | **✘** | ✔ [(GitHub)](https://github.com/castframework/smartcoin/blob/dd8bf5e1ba24d2379b102db74bfc8326fb649b65/contracts/smartCoin/SmartCoin.sol#L342) |
-| On-chain identity management | **✘** (could be added with a `RuleEngine`) | **✘** | ✔ | **✘** |
-| Document management | ✔ ([ERC-1643](https://github.com/ethereum/eips/issues/1643)) | ✔ ([ERC-1643](https://github.com/ethereum/eips/issues/1643)) | **✘** | **✘** |
-| Whitelist management | ✔ (deployment version or RuleEngine) | ✔ | ✔ (on-chain id) | **✘** |
-| Token contract pause | ✔ | ✔ | ✔ | ✔ |
-| Conditional Transfer for specific addresses | **✘** | **✘** | **✘** | ✔ (integrated into the token contract) |
-| Conditional Transfer for all addresses | ✔ (through RuleEngine) | **✘** | ✔ (through compliance contract) | **✘** |
-| **Technical features** | | | | |
-| Configurable ERC-20 decimals | ✔ | **✘** Set at 18 ([Github](https://github.com/Consensys/UniversalToken/blob/master/contracts/ERC1400.sol#L680)) | ✔ | **✘** (18 by default) |
-| Role-based access control | ✔ | ✔ | Partial (only one role Agent) | ✔ |
-| Adaptable access control (code can be easily adapted to other type of access control) | ✔ | **✘** | **✘** | Partial |
-| Mint & burn to any address | ✔ | ✔ | ✔ | ✔ |
-| Forced transfer function | ✔ | ✔ | ✔ | Partial Only force burn is available ([GitHub](https://github.com/castframework/smartcoin/blob/dd8bf5e1ba24d2379b102db74bfc8326fb649b65/contracts/smartCoin/SmartCoin.sol#L97)) |
-| Partially fungible token support | **✘** | ✔ | **✘** | **✘** |
-| Contract version on-chain | ✔ | ✔ | ✔ | ✔ ([GitHub](https://github.com/castframework/smartcoin/blob/dd8bf5e1ba24d2379b102db74bfc8326fb649b65/contracts/smartCoin/SmartCoin.sol#L228)) |
-| Deployable on Layer2 and other EVM blockchains | ✔ (require PUSH0) | Partial Requires [ERC-1820](https://eips.ethereum.org/EIPS/eip-1820) Registry contract | ✔ (require PUSH0) | ✔ |
-| **Other** | | | | |
-| License | MPL 2.0 (weak copyleft) | Apache 2.0 (permissive) | GPL 3.0 (strong copyleft) | Apache 2.0 (permissive) |
-| Third-party security audit | ✔ ([ABDK](https://abdk.consulting) & [Halborn](https://www.halborn.com)) | **✘** | ✔ [Hacken](https://hacken.io)) | **✘** |
-| **CMTAT unique features** | | | | |
-| *Regulatory features* | | | | |
-| Security identifiers | ✔ | **✘** | **✘** | **✘** |
-| Explicit support of debt instruments | ✔ | **✘** | **✘** | **✘** |
-| *Technical* | | | | |
-| MetaTx ("Gasless") support ([ERC-2771](https://eips.ethereum.org/EIPS/eip-2771)) | ✔ | **✘** | **✘** | **✘** |
-| Customizable modular design | ✔ | **✘** | **✘** | **✘** |
-| ERC-20 custom errors ([ERC-6093](https://eips.ethereum.org/EIPS/eip-6093)) | ✔ (use OpenZeppelin v5) | **✘** | **✘** (use OpenZeppelin v4) | **✘** (use OpenZeppelin v4) |
-| [ERC-5679: Token minting and Burning](https://eips.ethereum.org/EIPS/eip-5679) | ✔ | **✘** | **✘** | **✘** |
-| Upgradibility with [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) | ✔ | **✘** | **✘** | **✘** |
-| Snapshots/checkpoints | ✔ (external contract or by extending CMTAT) | **✘** | **✘** | **✘** |
-| **Cross-chain bridge** | | | | |
-| [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) Cross-chain transfer | ✔ | **✘** | **✘** | **✘** |
-| [Chainlink CCT](https://docs.chain.link/ccip/concepts/cross-chain-token) support | ✔ | **✘** (Lack burn/burnFrom/mint) | Partial (Lack burn/burnFrom) | **✘** (Lack owner/getCCIPAdmin/burnFrom) |
-
-**Note**
-
-- At the time of our analysis (July 2025), the next version of T-REX/ERC-3643 had not yet been merged into the main branch and officially released. However, we assumed that it would be merged soon and that it would also be audited.
-- Access control: CMTAT Access control is easily adaptable because it is implemented in high level contracts (base modules) instead of low level modules (wrapper).
-
-### Technical
-
-#### Security and contribution
-
-The design and security of the CMTAT was supported by [ABDK](https://abdk.consulting) (CMTAT v1.0 and v2.3.0) and [Halborn](https://www.halborn.com) (CMTAT v3.0.0), two leading audit companies in smart contract security.
-
-- The preferred way to receive comments is through the GitHub issue tracker.
-- Private comments and questions can be sent to the CMTA secretariat at admin@cmta.ch.
-- For security matters, please see [SECURITY.md](./SECURITY.md).
-
-#### Overview
-
-> Core means that they are the main features to build CMTAT
-
-##### Core features
-
-The CMTAT supports the following core features:
-
-* ERC-20:
- * Mint, burn, and transfer operations
- * Configure `name`, `symbol`and `decimals`at deployment, as well as [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) functions to update `name`and `symbol`once deployed
-
-* Pause of the contract and mechanism to deactivate it
-* Freeze of specific accounts through ERC-3643 functions.
-
-##### Extended features
-
-> Extended features are nice-to-have features. They are generally included in the majority of deployment version.
-
-The CMTAT supports the following extended features:
-
-- Add information related to several documents ([ERC-1643](https://github.com/ethereum/EIPs/issues/1643)) though an external contract (`DocumentEngine`)
-
-- Perform snapshot on-chain through an external contract (`SnapshotEngine`)
-- Conditional transfers, via an external contract (`RuleEngine`)
-- Put several information on-chain such as `tokenId` (ISIN or other identifier), `terms` (reference to any legally required documentation) and additional information (`information`)
-
-##### Optional features
-
-> Optional means that they are generally specific to deployment version
-
-The CMTAT supports the following optional features:
-
-- Transfer restriction through allowlisting/whitelisting (can be also done with a `RuleEngine`)
- - Deployment: CMTAT Standalone Allowlist / CMTAT Upgradeable Allowlist
- - Module: AllowlistModule
-
-- Put Debt information and Credit Events on-chain
- - Deployment: CMTAT Standalone Debt / CMTAT Upgradeable Debt
- - Module: DebtModule & DebtEngineModule
-
-- Cross-chain functionalities with [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802)
- - Define directly in a CMTAT Base contract (not a module)
-
-- "Gasless" (MetaTx) transactions with [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771)
- - Module: ERC2771Module
-
-
-Furthermore, the present implementation uses standard mechanisms in
-order to support `upgradeability`, via deployment of the token with a proxy by implementing [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201)
-
-## Standard ERC
-
-Here the list of ERC used by CMTAT v3.0.0
-
-### Schema
-
-
-
-
-
-### CMTAT version support
-
-Here the list of ERC supported between different version:
-
-| | Associated contracts/modules | ERC status | CMTAT v1.0.0 | CMTAT v2.3.0 | CMTAT v3.0.0 | CMTAT v3.2.0 | | | | | |
-| ------------------------------------------------------------ | -------------------------------------------- | ------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Deployment version | | | | | (Standalone & Proxy) | | Light | UUPS | ERC1363 | Allowlist (whitelist) | Debt |
-| **Fungible tokens** | | | | | | | | | | | |
-| [ERC-20](https://eips.ethereum.org/EIPS/eip-20) | ERC20BaseModule | Standard Track (final) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) | CMTATBaseERC1363 | Standard Track (final) | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ | ✘ |
-| **Tokenization** | | | | | | | | | | | |
-| [ERC-7943 (uRWA)](https://eips.ethereum.org/EIPS/eip-7943) | ValidationModuleCore, ERC20EnforcementModule | Review | ✘ | ✘ | ✘ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ |
-| [ERC-1404](https://github.com/ethereum/eips/issues/1404) (Simple Restricted Token Standard) | ValidationModuleERC1404 (Exensions) | Draft | ✔ | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ | ✘ | ✘ |
-| [ERC-1643](https://github.com/ethereum/eips/issues/1643) (Document Management Standard) (Standard from [ERC-1400](https://github.com/ethereum/EIPs/issues/1411)) (Slightly improved) | DocumentModule (Exensions) | Draft | ✘ | ✘ | ✔ (through DocumentEngine with small improvement) | ✔ (through DocumentEngine with small improvement) | ✘ | ✔ | ✔ | ✔ | ✔ |
-| [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643)
(Without on-chain identity) | Core + ERC20EnforcementModule (extensions) | Standard Track (final) | ✘ | ✘ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ |
-| [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477) | Core + ERC20EnforcementModule (extensions) | Draft | ✘ | ✘ | ✔ | ✔ | Partially | ✔ | ✔ | ✔ | ✔ |
-| **Proxy support related** | | | | | | | | | | | |
-| Deployment with a UUPS proxy ([ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)) | - | Stagnant (but used) | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ | ✘ | ✘ |
-| [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) (Storage namespaces for proxy contract) | All | Standard Track (final) | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| **Technical** | | | | | | | | | | | |
-| [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (Meta Tx / gasless) | ERC2771Module (options) | Standard Track (final) | ✔ | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✘ |
-| [ERC-6093](https://eips.ethereum.org/EIPS/eip-6093) (Custom errors for ERC-20 tokens) | - | Standard Track (final) | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) (cross-chain token/transfers) | ERC20CrossChainModule (options) | Draft | ✘ | ✘ | ✔ | ✔ | ✘ | ✔ | ✔ | ✘ | ✘ |
-| [ERC-5679](https://eips.ethereum.org/EIPS/eip-5679) (Token minting and burning with data) | ERC20MintModule ERC20BurnModule | Standard Track (final) | ✘ | ✘ | Partial (without ERC-165 support) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-
-### Details
-
-#### ERC-3643
-
-> [ERC specification](https://eips.ethereum.org/EIPS/eip-3643)
-> Status: Standards Track
-
-The [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) is an official Ethereum standard, unlike ERC-1400 and ERC-1404. This standard, also built on top of ERC-20, offers a way to manage and perform compliant transfers of security tokens.
-
-ERC-3643 enforces identity management as a core component of the standards by using a decentralized identity system called [onchainid](https://www.onchainid.com/).
-
-While CMTAT does not include directly the identity management system, it shares with ERC-3643 many of the same functions. The interface is available in [IERC3643Partial.sol](./contracts/interfaces/tokenization/IERC3643Partial.sol)
-
-If you want to use CMTAT to create a version implementing all functions from ERC-3643, you can create it through a dedicated deployment version (like what has been done for UUPS and ERC-1363).
-
-The implemented interface is available in [IERC3643Partial](./contracts/interfaces/tokenization/IERC3643Partial.sol).
-
-The main reason the argument names change is because CMTAT relies on OpenZeppelin to name the arguments.
-
-Required modules:
-
-- Core: PauseModule, ERC20BaseModule, ERC20MintModule, VersionModule, EnforcementModule, ValidationModuleCore
-- Extensions: ERC20EnforcementModule
-
-##### All functions
-
-```solidity
-// interface IERC3643Pause
-// PauseModule
-function paused() external view returns (bool)
-function pause() external
-function unpause() external
-
-// interface IERC3643ERC20Base
-// ERC20BaseModule
-function setName(string calldata name) external
-function setSymbol(string calldata symbol) external
-
-// IERC3643BatchTransfer
-// ERC20MintModule
-function batchTransfer(address[] calldata tos,uint256[] calldata values) external returns (bool)
-
-// IERC3643Version
-// VersionModule
-function version() external view returns (string memory)
-
-// IERC3643Enforcement
-// EnforcementModule
-function isFrozen(address account) external view returns (bool)
-function setAddressFrozen(address account, bool freeze) external
-function batchSetAddressFrozen(address[] calldata accounts, bool[] calldata freeze) external;
-
-// IERC3643ERC20Enforcement
-// ERC20EnforcementModule
-function getFrozenTokens(address account) external view returns (uint256);
-function freezePartialTokens(address account, uint256 value) external;
-function unfreezePartialTokens(address account, uint256 value) external;
-function forcedTransfer(address from, address to, uint256 value) external returns (bool);
-
-
-// IERC3643Mint
-// ERC20MintModule
-function mint(address account, uint256 value) external;
-function batchMint( address[] calldata accounts,uint256[] calldata values) external;
-
-// IERC3643Burn
-// ERC20BurnModule
-function burn(address account, uint256 value) external;
-function batchBurn(address[] calldata accounts,uint256[] calldata values) external;
-
-// IERC3643ComplianceRead
-// ValidationModuleCore
-function canTransfer(
- address from,
- address to,
- uint256 value
- ) external view returns (bool isValid);
-}
-```
-
-
-
-##### Functions not implemented
-
-All functions related to on-chain identity are **not** implemented inside CMTAT:
-
-- ` setOnchainID`
-- `setIdentityRegistry`
-- `recoveryAddress` because this function takes the ` investorOnchainID` as an argument
-
-These following functions to reduce contract code size:
-
-- `batchForcedTransfer`to reduce contract code size
-- `batchFreezePartialTokens` and `batchUnfreezePartialTokens`
-
-All functions related to the interface `IAgentRole`because CMTAT uses a RBAC Access Control to offer more granularity in terms of access control.
-
-And finally `setCompliance` because CMTAT uses a different architecture for its `ruleEngine`.
-
-##### Version
-
-Module: VersionModule
-
-| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
-| :--------------------------------------------------------- | :--------------- | ------------------ |
-| `version() external view returns (string memory version_)` | Same | All |
-
-##### Pause
-
-Module: PauseModule
-
-| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
-| :--------------------------------------- | :-------------------------------- | ------------------ |
-| `pause() external` | Same | All |
-| `unpause() external` | Same | All |
-| `paused() external view returns (bool);` | Same | All |
-| `event Paused(address _userAddress);` | `event Paused(address account)` | All |
-| `event Unpaused(address _userAddress);` | `event Unpaused(address account)` | All |
-
-##### ERC20Base
-
-| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
-| :-------------------------------------------- | :----------------------------------- | ------------------ |
-| `setName(string calldata _name) external;` | `setName(string calldata name_)` | All |
-| `setSymbol(string calldata _symbol) external` | `setSymbol(string calldata symbol_)` | All |
-
-##### Supply Management (burn/mint)
-
-| **ERC-3643** | **CMTAT v3.0.0 Modules** | **CMTAT v3.0.0 Functions** | Deployment version |
-| :----------------------------------------------------------- | :----------------------- | :----------------------------------------------------------- | ------------------ |
-| `batchMint(address[] calldata _toList, uint256[] calldata _amounts) external;` | ERC20MintModule | `mint(address account, uint256 value)` | All |
-| `batchMint(address[] calldata _toList, uint256[] calldata _amounts) external;` | ERC20MintModule | `batchMint(address[] calldata accounts,uint256[] calldata values) ` | All |
-| `batchTransfer(address[] calldata _toList, uint256[] calldata _amounts) external;` | ERC20MintModule | `batchTransfer(address[] calldata tos,uint256[] calldata values)` | All |
-| `burn(address _userAddress, uint256 _amount) external` | ERC20BurnModule | `function burn(address account,uint256 value)` | All |
-| `batchBurn(address[] calldata _userAddresses, uint256[] calldata _amounts) external` | ERC20BurnModule | `batchBurn(address[] calldata accounts,uint256[] calldata values)` | All |
-
-Warning: `batchTransfer` is restricted to the MINTER_ROLE to avoid the possibility to use non-standard function to move tokens.
-
-##### ERC20Enforcement
-
-| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
-| :----------------------------------------------------------- | :----------------------------------------------------------- | --------------------------------------------------- |
-| `isFrozen(address _userAddress)` | `isFrozen(address account)` | All |
-| `forcedTransfer(address _from, address _to, uint256 _amount) external returns (bool)` | `forcedTransfer(address from, address to, uint256 value) external returns (bool)` | All except Light version (replaced by `forcedBurn`) |
-| `batchForcedTransfer(address[] calldata _fromList, address[] calldata _toList, uint256[] calldata _amounts) external` | Not implemented | - |
-
-##### ValidationModuleCore
-
-Note: `canTransfer` is defined for the compliance contract in ERC-3643.
-
-| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
-| :----------------------------------------------------------- | :----------------------------------------------------- | ------------------ |
-| `canTransfer(address _from, address _to, uint256 _amount) external view returns (bool)` | `canTransfer(address from, address to, uint256 value)` | All |
-
-#### ERC-7943 (uRWA)
-
-> [ERC specification](https://eips.ethereum.org/EIPS/eip-7943) / [Ethereum magician](https://ethereum-magicians.org/t/erc-7943-universal-rwa-interface-urwa/23972)
->
-> Status: review
-
-#### ERC-7943 Implementation in CMTAT
-
-ERC-7943 is a standard defining a set of interfaces for tokenized Real World Assets (RWAs) such as securities, real estate, commodities, or other physical/financial assets on the blockchain. The uRWA standard extends common token standards like [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-721](https://eips.ethereum.org/EIPS/eip-721) or [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) by introducing essential compliance functions while remaining minimal and not opinionated about specific implementation details.
-
-CMTAT implements it by splitting functionality into interfaces and modules.
-
-##### Interface Breakdown
-
-All related interfaces are defined in the interface file [draft-IERC7943.sol](./contracts/interfaces/tokenization/draft-IERC7943.sol).
-
-| Interface | Purpose |
-| ------------------------------------------ | ------------------------------------------------------------ |
-| `IERC7943FungibleEnforcement` | `forcedTransfer`, `getFrozenTokens` |
-| `IERC7943FungibleEnforcementSpecific` | `setFrozenTokens` |
-| `IERC7943FungibleEnforcementEventAndError` | `Frozen`, `ForcedTransfer` events `ERC7943InsufficientUnfrozenBalance` |
-| `IERC7943TransactError` | `ERC7943CannotTransact` error |
-| `IERC7943FungibleTransferError` | `ERC7943CannotTransfer` error |
-| `IERC7943TransactCheck` | `canTransact` |
-
-##### Implementation Mapping
-
-| ERC-7943 Requirement | CMTAT Implementation |
-| ------------------------------------ | ------------------------------------------------------------ |
-| **Functions** | |
-| `forcedTransfer(from, to, amount)` | `ERC20EnforcementModule.sol` |
-| `setFrozenTokens(account, amount)` | `ERC20EnforcementModule.sol` |
-| `getFrozenTokens(account)` | `ERC20EnforcementModule.sol` |
-| `canTransact(account)` | `ValidationModule.sol` |
-| `canTransfer(from, to, amount)` | `ValidationModuleCore.sol` |
-| **Error** | |
-| `ERC7943CannotTransact` | `ValidationModule.sol` |
-| `ERC7943CannotTransfer` | `CMTATBaseCore.sol`, `CMTATBaseAllowlist`, `CMTATBaseRuleEngine` |
-| `ERC7943InsufficientUnfrozenBalance` | [ERC20EnforcementModuleInternal.sol](./contracts/modules/internal/ERC20EnforcementModuleInternal.sol) |
-| **Event** | [ERC20EnforcementModuleInternal.sol](./contracts/modules/internal/ERC20EnforcementModuleInternal.sol) |
-| `Frozen` | |
-| `ForcedTransfer` | [ERC20EnforcementModuleInternal.sol](./contracts/modules/internal/ERC20EnforcementModuleInternal.sol) |
-
-
-
-##### Transfer Flow Diagram
-
-When a transfer is attempted with the standard CMTAT version:
-
-```
-transfer(to, 100)
-│
-├─ Is contract paused? ──────────────→ revert EnforcedPause()
-│
-├─ Is sender/receiver frozen? ───────→ revert ERC7943CannotTransact(account)
-│
-├─ RuleEngine says no? ─────────────→ RuleEngine reverts with its own errors
-├─ Other check (transferred) says no? ─────────────→ revert ERC7943CannotTransfer(...)
-│
-├─ Not enough active balance? ───────→ revert ERC7943InsufficientUnfrozenBalance(...)
-│
-└─ Transfer executes
-```
-
-There are three ERC-7943 errors used in this workflow: `ERC7943CannotTransact`, `ERC7943CannotTransfer` and `ERC7943InsufficientUnfrozenBalance`
-
-
-
-#### ERC-7551 (eWPG)
-
-> [ERC specification](https://github.com/ethereum/ERCs/blob/60a282eb3c867af2dbed8eff12e7549b548cf1bf/ERCS/erc-7551.md) / [Ethereum magician](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477)
->
-> Status: draft
-
-ERC-7551 ([eWpG](https://www.gesetze-im-internet.de/ewpg/)) is a proposal by the German Federal Association of Crypto Registrars for a smart contract interface tailored to *crypto securities* in Germany (eWpG). It aims to provide a flexible, minimal foundational layer so that tokens can meet legal/compliance requirements while leaving the door open on how to restrict the use of the token (on-chain id like ERC-3643).
-
-The implemented interface is available in [IERC7551](./contracts/interfaces/tokenization/draft-IERC7551.sol).
-
-Only the specific deployment version dedicated (CMTATERC7551) implements the full interface.
-
-Required modules:
-
-- Core: EnforcementModule, PauseModule, ERC20MintModule, ERC20BurnModule, ValidationModuleCore
-- Extension: ExtraInformationModule
-- Option: ERC7751Module
-
-##### Link to off-chain document
-
-Contrary to the ERC-7551 specification, CMTAT does not enforce a non-zero value for the `termsHash`.
-
-`unpause`will not revert if `termsHash == 0x0`.
-
-##### Summary tab
-
-The following table compares the functionalities and details how the relevant functionalities are implemented in CMTAT's reference Solidity implementation:
-
-| **N°** | **Functionalities** | **ERC-7551 Functions** | **CMTAT v3.0.0 standard** | CMTAT v3.0.0 ERC7551 | Implementations details | Modules |
-| :--------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| 1 | Freeze and unfreeze a specific amount of tokens | `freezePartialTokens(address account, uint256 amount, bytes calldata data)` `unfreezePartialTokens(address account, uint256 amount, bytes calldata data)` | ✔ | ✔ | - | EnforcementModule (core) ERC20EnforcementModule (extensions) |
-| 2 | Pausing transfers The operator can pause and unpause transfers | `pause()/unpause()` | ✔ | ✔ | - | PauseModule (core) |
-| 3 | Link to off-chain document Add the hash of a document | `setTerms(bytes32 _hash, string calldata _uri)` | ✘ | ✔ | The hash is put in the field ` Terms` Terms is represented as a Document (name, uri, hash, last on-chain modification date) based on [ERC-1643](https://github.com/ethereum/eips/issues/1643). | ERC7751Module (options) |
-| | Equivalent functionality | | ✔ | ✔ | `setTerms(IERC1643CMTAT.DocumentInfo calldata terms_)` | ExtraInformationModule (extensions) |
-| 4 | Metadata JSON file | `setMetaData(string calldata _metadata) ` | ✘ (can be put in the field `information`) | ✔ | - | ERC7751Module (options) |
-| 5 | Forced transfers Transfer `amount` tokens to `to` without requiring the consent of `from` | `forcedTransfer(address account, address to, uint256 value, bytes calldata data) ` | ✔ | ✔ | - | ERC20EnforcementModule |
-| 6 | Token supply management Reduce the balance of `tokenHolder` by `amount` without increasing the amount of tokens of any other holder | `burn(address tokenHolder, uint256 amount, bytes calldata data) ` | ✔ | ✔ | - | ERC20BurnModule (core) |
-| 7 | Token supply management Increase the balance of `to` by `amount` without decreasing the amount of tokens from any other holder. | `mint(address to, uint256 amount, bytes calldata data)` | ✔ | ✔ | - | ERC20MintModule (core) |
-| **View/read-only functions** | | | | | | |
-| 8 | Transfer compliance Check if a transfer is valid | `canTransfer(address from, address to, uint256 value) ` `canTransferFrom()` | ✔ | ✔ | - | ValidationModuleCore |
-| 9 | Transfer compliance Check if a transfer with a spender is valid | `canTransferFrom(address spender, address from, address to, uint256 value) ` | ✔ | ✔ | - | ValidationModuleCore |
-| 10 | Active/Frozen Balance | `getActiveBalanceOf(address tokenHolder)` `getFrozenTokens(address tokenHolder)` | ✔ | ✔ | - | ERC20EnforcementModule |
-
-##### Full functions
-
-```solidity
-// IERC7551Mint
-// ERC20MintModule
-event Mint(address indexed minter, address indexed account, uint256 value, bytes data);
-function mint(address account, uint256 value, bytes calldata data) external;
-
-// IERC7551Burn
-// ERC20BurnModule
-event Burn(address indexed burner, address indexed account, uint256 value, bytes data);
-function burn(address account, uint256 amount, bytes calldata data) external;
-
-// IERC7551Pause
-// PauseModule
-function paused() external view returns (bool);
-function pause() external;
-function unpause() external;
-
-// IERC7551ERC20Enforcement
-// ERC20EnforcementModule
-function getActiveBalanceOf(address account) external view returns (uint256);
-function getFrozenTokens(address account) external view returns (uint256);
-function freezePartialTokens(address account, uint256 amount, bytes memory data) external;
-function unfreezePartialTokens(address account, uint256 amount, bytes memory data) external;
-function forcedTransfer(address account, address to, uint256 value, bytes calldata data) external returns (bool);
-
-
-// IERC7551Compliance is IERC3643ComplianceRead
-// ValidationModuleCore
-function canTransferFrom(
- address spender,
- address from,
- address to,
- uint256 value
- ) external view returns (bool);
-// From IERC3643ComplianceRead
-function canTransfer(address from, address to, uint256 value) external view returns (bool);
-
-
-// IERC7551Document
-// IERC7551Module
-event Terms(bytes32 hash_, string uri_);
-event MetaData(string newMetaData);
-function termsHash() external view returns (bytes32);
-function setTerms(bytes32 _hash, string calldata _uri) external;
-function metaData() external view returns (string memory);
-function setMetaData(string calldata metaData_) external;
-```
-
-
-
-#### ERC-7802 (Crosschain transfers)
-
-> [ERC specification](https://eips.ethereum.org/EIPS/eip-7802)
-> Status: draft
-
-This standard introduces a minimal and extendable interface, `IERC7802`, for tokens to enable standardized crosschain communication.
-
-CMTAT implements this standard in the option module `ERC20CrossChain`
-
-This standard is notably used by Optimism to provide cross-chain bridge between Optimism chain, see [docs.optimism.io/interop/superchain-erc20](https://docs.optimism.io/interop/superchain-erc20)
-
-More information available in the cross chain section.
-
-Deployment version: since it is an option module, it is not currently used in the deployment version `debt`, `light` & `allowlist`.
-
-```solidity
-interface IERC7802 is IERC165 {
- /// @notice Emitted when a crosschain transfer mints tokens.
- event CrosschainMint(address indexed to, uint256 value, address indexed sender);
-
- /// @notice Emitted when a crosschain transfer burns tokens.
- event CrosschainBurn(address indexed from, uint256 value, address indexed sender);
-
- /// @notice Mint tokens through a crosschain transfer.
- function crosschainMint(address to, uint256 value) external;
-
- /// @notice Burn tokens through a crosschain transfer.
- function crosschainBurn(address from, uint256 value) external;
-}
-```
-
-
-
------
-
-## Architecture
-
-CMTAT architecture is divided in two main components: modules and engines.
-
-### Overview
-
-#### Schema
-
-Here is an overview on how CMTAT is built:
-
-
-
-#### Tree file structure
-
-Here is the GitHub file structure for CMTAT repository.
-
-```
-contracts/
- ├── deployment/ # Ready-to-deploy token contracts
- ├── modules/
- │ ├── internal/ # Core logic (low-level)
- │ └── wrapper/ # Public interfaces using internal modules or OpenZeppelin library
- │ ├── core/ # ERC20, mint, burn, pause
- │ ├── controllers/ # Transfer validation
- │ ├── extensions/ # Snapshots, documents
- │ └── options/ # Optional features (debt, allowlist)
- └── interfaces/ # Contract interfaces
-```
-
-### Base contract
-
-The base contracts are abstract contracts, so not directly deployable, which inherit from several different modules.
-
-Base contracts are used by the different deployable contracts (CMTATStandalone, CMTATUpgradeable,...) to inherit from the different modules
-
-| Name | Level | Description | Associated contracts deployments |
-| ------------------------------------------------------------ | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| [CMTATBaseCommon](./contracts/modules/0_CMTATBaseCommon.sol) | 0 | Inherits from all core and extension modules, except ValidationModule | No deployment contract directly inherits from this base contract (see next level) |
-| [CMTATBaseCore](./contracts/modules/0_CMTATBaseCore.sol) | 0 | Inherits from all core modules | CMTAT Light (Upgradeable & Standalone |
-| [CMTATBaseGeneric](./contracts/modules/0_CMTATBaseGeneric.sol) | 0 | Inherits from non-ERC20 related modules | - (Only mock available) |
-| [CMTATBaseAccessControl](./contracts/modules/1_CMTATBaseAccessControl.sol) | 1 | Inherits from CMTATBaseCommon and OpenZeppelin Access Control | - |
-| [CMTATBaseAllowlist](./contracts/modules/2_CMTATBaseAllowlist.sol) | 2 | Inherits from CMTATBaseAccessControl, but also from ValidationModuleAllowlist | CMTAT Allowlist (upgradeable & Standalone) |
-| [CMTATBaseRuleEngine](./contracts/modules/2_CMTATBaseRuleEngine.sol) | 2 | Add RuleEngine support by inheriting from ValidationModuleRuleEngine | No deployment contract directly inherits from this base contract (see next level) |
-| [CMTATBaseDebt](./contracts/modules/3_CMTATBaseDebt.sol) | 3 | Add debt support by inheriting from Debt module | CMTAT Debt (Standalone & Upgradeable) |
-| [CMTATBaseERC1404](./contracts/modules/3_CMTATBaseERC1404.sol) | 3 | Add [ERC-1404](https://github.com/ethereum/EIPs/issues/1404) support | CMTAT Standalone / Upgradeable |
-| [CMTATBaseERC20CrossChain](./contracts/modules/4_CMTATBaseERC20CrossChain.sol) | 4 | Add cross-chain support, notably [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) | No deployment contract directly inherits from this base contract (see next level) |
-| [CMTATBaseERC2771](./contracts/modules/5_CMTATBaseERC2771.sol) | 5 | Add [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) support by inheriting from ERC2771Module | CMTAT Standalone / Upgradeable CMTAT Upgradeable UUPS |
-| [CMTATBaseDebtEngine](./contracts/modules/5_CMTATBaseDebtEngine.sol) | 5 | Add DebtEngine support by inheriting from DebtEngine module | CMTAT Standalone DebtEngine / Upgradeable |
-| [CMTATBaseERC1363](./contracts/modules/6_CMTATBaseERC1363.sol) | 6 | Add [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) support by inheriting directly from OpenZeppelin contract | CMTAT ERC1363 (Upgradeable & Standalone) |
-| [CMTATBaseERC7551](./contracts/modules/6_CMTATBaseERC7551.sol) | 6 | Add ERC-7551 support by inheriting from ERC7551 Module | CMTAT ERC7551 (Upgradeable & Standalone) |
-
-#### Level 0 (main modules)
-
-#### CMTAT Base Common
-
-
-
-
-
-CMTAT Base adds several functions:
-
-- `burnAndMint`to burn and mint atomically in the same function.
-
-##### CMTAT Base Core
-
-CMTAT Base Core adds several functions:
-
-- `burnAndMint`to burn and mint atomically in the same function.
-- `forcedBurn`to allow the admin to burn tokens from a frozen address (defined in EnforcementModule)
-
- - This function is not required in CMTATBase because the function `forcedTransfer` (ERC20EnforcementModule) can be used instead.
-
- 
-
-
-
-##### CMTAT Base Generic
-
-
-
-
-
-
-
-#### Level 1 (ERC-20 Transfer restriction)
-
-##### CMTAT Base RuleEngine
-
-
-
-##### CMTAT Base Allowlist
-
-
-
-
-
-#### Level 2 (add heavy modules)
-
-##### CMTATBaseDebt
-
-
-
-##### CMTATBaseERC1404
-
-
-
-
-
-#### Level 3 (cross-chain transfer)
-
-
-
-#### Level 4 (metaTx)
-
-##### CMTAT Base ERC2771
-
-
-
-#### Level 5 (use case)
-
-##### CMTAT Base ERC1363 (payable token)
-
-
-
-
-
-
-
-
-
-
-
-##### CMTAT Base ERC7551
-
-
-
-
-
-
-
-
-
-
-
-
-
-### Module
-
-#### Description
-
-Modules describe a **logical** code separation inside CMTAT. They are defined as abstract contracts.
-Their code and functionalities are part of the CMTAT and therefore are also included in the calculation of the contract size and the maximum size limit of 24 kB.
-
-It is always possible to delete a module, but this requires modifying the code and compiling it again, which would require a security audit to be performed on these modifications.
-
-Modules are also separated in different categories.
-
-- **Internal** modules: implementation for a module when OpenZeppelin does not provide a library to use. For example, this is the case for the `EnforcementModule`.
-- **Wrapper** modules: abstract contract around OpenZeppelin contracts or internal module.
- For example, the wrapper `PauseModule` provides public functions to call the internal functions from OpenZeppelin.
- - **Core** (Wrapper sub-category): Contains the modules required to be CMTA compliant
- - **Security**: module related to access control
- - **Extension** (Wrapper sub-category): not required to be CMTA compliant, "bonus features" (snapshotModule, debtModule)
- - **Options**: also bonus features to meet specific use cases through specific deployment version.
-
-
-
-
-#### List
-
-Here is the list of modules supported between different versions and the differences.
-
-For simplicity, the module names and function locations are those of version 3.0.0
-
-- "fn" means function
-- Changes made in a release are considered maintained in the following release unless explicitly stated otherwise
-
-##### Controllers
-
-| Modules | Type | Description | File | CMTAT 1.0 | CMTAT 2.30 | CMTAT >= 3.0.0 | | | |
-| ---------------------------------- | ----------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Deployment version | | | | | | Standalone, Upgradeable, UUPS, Debt, ERC1363, ERC7551 | CMTAT Debt | CMTAT Allowlist | CMTAT Light |
-| ValidationModule | Controllers | Check transfer validity by calling the Pause and Enforcement modules | [ValidationModule.sol](./contracts/modules/wrapper/controllers/ValidationModule.sol) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| ValidationModuleAllowlist | Controllers | Check transfer validity by calling Allowlist module | [ValidationModuleAllowlist.sol](./contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol) | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ |
-| ValidationModuleRuleEngineInternal | Internal | Configure a `RuleEngine` | [ValidationModuleRuleEngineInternal.sol](./contracts/modules/internal/ValidationModuleRuleEngineInternal.sol) | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ |
-| ValidationModuleCore | Core | Implements`canTransfer`and `canTransferFrom` The core module does not implement ERC-1404 and the RuleEngine | [ValidationModuleCore.sol](./contracts/modules/wrapper/core/ValidationModuleCore.sol) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
-| ValidationModuleRuleEngine | Extensions | Set and call the ruleEngine to check transfer. | [ValidationModuleRuleEngine.sol](./contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol) | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ |
-| ValidationModuleERC1404 | Extensions | Implements ERC-1404 | [ValidationModuleERC1404.sol](./contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol) | ✔ | ✔ | ✔ | ✘ | ✘ | ✘ |
-
-
-
-**Controllers**
-
-- ValidationModule
-
-
-
-- ValidationModuleAllowlist
-
-
-
-**Internal**
-
-- ValidationModuleRuleEngineInternal
-
-
-
-
-
-**Core**
-
-- ValidationModuleCore
-
-
-
-
-
-**Extensions**
-
-- ValidationModuleRuleEngine
-
-
-
-- ValidationModuleERC1404
-
-
-
-
-
-##### Core modules
-
-Generally, these modules are required to be compliant with the CMTA specification.
-
-| Modules | Description | File | CMTAT 1.0 | CMTAT 2.30 | CMTAT >= 3.0.0 |
-| ------------------------------------------------------------ | ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| [VersionModule](./doc/modules/core/Version/version.md) | Contract version | [VersionModule.sol](./contracts/modules/wrapper/core/VersionModule.sol) | ✔ | ✔ (Add two fields: flag and information) | ✔ Remove field flag (not used) Keep only the field VERSION and move the rest (tokenId, information,..) to an extension module `ExtraInformation` CMTAT 3.0.1: update name baseModule -> VersionModule |
-| [ERC20 Burn](./doc/modules/core/ERC20Burn/ERC20Burn.md) (Prev. BurnModule) | Burn functions | [ERC20BurnModule.sol](./contracts/modules/wrapper/core/ERC20BurnModule.sol) | ✔ | ✔ Replace fn `burnFrom` by fn `forcedBurn` | Add fn `burnBatch` Rename `forceBurn` in `burn` `burnFrom` is moved to the option module `ERC20CrossChain`(v3.1.0) |
-| [Enforcement](./doc/modules/core/Enforcement/enforcement.md) | Freeze/unfreeze address | [EnforcementModule.sol](./contracts/modules/wrapper/core/EnforcementModule.sol) | ✔ | ✔ | ✔ |
-| [ERC20Base](./doc/modules/core/ERC20Base/ERC20base.md) | decimals, set name & symbol | [ERC20BaseModule.sol](./contracts/modules/wrapper/core/ERC20BaseModule.sol) | ✔ | ✔ Remove fn `forceTransfer` (replaced by `burn`and `mint`) | Add fn `balanceInfo` (useful to distribute dividends) Add fn `forcedTransfer` Add fn `setName`and `setSymbol` Remove custom fn `approve`(keep only ERC-20 approve) |
-| [ERC20 Mint](./doc/modules/core/ERC20Mint/ERC20Mint.md) | Mint functions + BatchTransfer | [ERC20MintModule.sol](./contracts/modules/wrapper/core/ERC20MintModule.sol) | ✔ | ✔ | Add fn `mintBatch` Add fn `transferBatch` |
-| [Pause Module](./doc/modules/core/Pause/pause.md) | Pause and deactivate contract | [PauseModule.sol](./contracts/modules/wrapper/core/PauseModule.sol) | ✔ | ✔ | Replace fn `kill` by fn `deactivateContract` |
-
-
-
-
-
-##### Extension modules
-
-Generally, these modules are not required to be compliant with the CMTA specification.
-
-| Modules | Description | File | CMTAT 1.0 | CMTAT 2.30 | CMTAT >= 3.0.0 |
-| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| [ExtraInformation](./doc/modules/extensions/ExtraInformation/extraInformation.md) | Set extra information (tokenId, terms, metadata) | [ExtraInformationModule.sol](./contracts/modules/wrapper/extensions/ExtraInformationModule.sol) | ✔ (BaseModule) | ✔ (BaseModule) | ✔ |
-| [SnapshotEngineModule](./doc/modules/extensions/snapshotEngine/Snapshot.md) (Prev. SnapshotModule) | Set snapshotEngine | [SnapshotEngineModule.sol](./contracts/modules/wrapper/extensions/SnapshotEngineModule.sol) | ✔ | Partial (Not included by default because unaudited) | ✔ (require an external SnapshotEngine) |
-| [DocumentEngineModule](./doc/modules/extensions/documentEngine/document.md) | Set additional document (ERC1643) through a DocumentEngine | [DocumentEngineModule.sol](./contracts/modules/wrapper/extensions/DocumentEngineModule.sol) | ✘ | ✘ | ✔ |
-| [ERC20EnforcementModule](./doc/modules/extensions/ERC20Enforcement/erc20enforcement.md) | The admin (or a third party appointed by it) can partially freeze a part of the balance of a token holder. | [ERC20EnforcementModule.sol](./contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol) | ✘ | ✘ | ✔ |
-
-##### Option modules
-
-| Modules | Description | File | CMTAT 1.0 | CMTAT 2.3.0 | CMTAT >= 3.2.0 | | | |
-| ------------------------------------------------------------ | ---------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Deployment version | | | | | Standalone & Upgradeable | Allowlist | Debt | ERC7551 |
-| [DebtModule](doc/modules/options/debt/debt.md) | Set Debt and CreditEvent Info | [DebtModule.sol](./contracts/modules/wrapper/options/DebtModule.sol) | ✘ | ✔ | ✘ | ✘ | ✔ | ✘ |
-| [DebtEngineModule](doc/modules/options/debtEngine/debtEngine.md) | Add a DebtEngine module | [DebtEngineModule.sol](./contracts/modules/wrapper/options/DebtEngineModule.sol) | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ |
-| [ERC2771Module](doc/modules/options/erc2771/erc2771.md) | ERC-2771 support | [ERC2771Module.sol](./contracts/modules/wrapper/options/ERC2771Module.sol) | ✔ | ✔ (forwarder immutable) | ✔ | ✔ | ✘ | ✔ |
-| [Allowlist](doc/modules/options/allowlist/allowlist.md) | Add integrated allowlist support | [AllowlistModule.sol](./contracts/modules/wrapper/options/AllowlistModule.sol) | ✘ | ✘ | ✘ | ✔ | ✘ | ✘ |
-| [ERC7551Module](doc/modules/options/debt/erc7551.md) | Add specific ERC-7551 functions | [ERC7551Module.sol](./contracts/modules/wrapper/options/ERC7551Module.sol) | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ |
-| [ERC20CrossChainModule](doc/modules/options/erc20crosschain/ERC20CrossChain.md) | Add cross-chain functionalities (ERC-7802, burn, burnFrom) | [ERC20CrossChainModule.sol](./contracts/modules/wrapper/options/ERC20CrossChainModule.sol) | ✘ | ✘ | ✔ | ✘ | ✘ | ✔ |
-| [CCIPModule](doc/modules/options/ccip/ccip.md) | Add CCIP specific function | [CCIPModule.sol](./contracts/modules/wrapper/options/CCIPModule.sol) | ✘ | ✘ | ✔ | ✘ | ✘ | ✔ |
-
-
-
-##### Security
-
-| | Description | File | CMTAT 1.0 | CMTAT 2.30 | CMTAT >= 3.0.0 |
-| ----------------------------------------------------- | -------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| [AccessControlModule](doc/modules/security/access.md) | Access Control | [AccessControlModule.sol](./contracts/modules/wrapper/security/AccessControlModule.sol) | ✔ | ✔ (Admin has all the roles by default) | ✔ |
-
-
-
-### Access Control (RBAC)
-
-CMTAT access control is also modular and flexible.
-
-**Wrapper modules**
-
-Firstly, wrapper modules will separately:
-
-- define the roles useful to restrict its own functions
-- define virtual functions `authorize` which require to be overridden in CMTAT base module to add access control check.
-
-To allow flexibility and customisation, wrapper modules do not implement the access control themselves. Access control is defined in CMTAT base modules. Therefore, it is possible to create a new base module to use a different access control.
-
-**CMTAT base module**
-
-Current CMTAT base module use the standard RBAC access control by using the contract `AccessControl`from OpenZeppelin.
-
-This is defined in the CMTAT base contract `CMTATBaseAccessControl`(level 1)
-
-The `AccessControlModule` which is used by the different CMTAT base module and deployment contracts override the OpenZeppelin function `hasRole` to give by default all the roles to the `admin`.
-
-See also [docs.openzeppelin.com - AccessControl](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl)
-
-#### Key management
-
-As with any token contract, access to the admin key must be adequately restricted.
-
-Likewise, access to the proxy contract must be restricted and segregated from the token contract.
-
-##### UUPS Proxy
-
-For the deployment version for **UUPS proxies**, unfortunately there is no segregation between contract rights (admin) and the proxy. A possible improvement would be to add an owner who would only have the rights to update the proxy.
-
-Any compromise to the DEFAULT_ADMIN_ROLE account may allow a hacker to take advantage of this authority and change the implementation contract which is pointed by proxy and therefore execute potential malicious functionality in the implementation contract.
-
-#### Role list
-
-Here is the list of roles and their 32 bytes identifier.
-
-| | Defined in | 32 bytes identifier |
-| ---------------------- | --------------------------------------------------------- | ------------------------------------------------------------ |
-| DEFAULT_ADMIN_ROLE | OpenZeppelin AccessControl | 0x0000000000000000000000000000000000000000000000000000000000000000 |
-| **Core Modules** | | |
-| BURNER_ROLE | BurnModule | 0x3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848 |
-| MINTER_ROLE | MintModule | 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6 |
-| ENFORCER_ROLE | EnforcementModule | 0x973ef39d76cc2c6090feab1c030bec6ab5db557f64df047a4c4f9b5953cf1df3 |
-| PAUSER_ROLE | PauseModule | 0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a |
-| **Extension Modules** | | |
-| SNAPSHOOTER_ROLE | SnashotModule | 0x809a0fc49fc0600540f1d39e23454e1f6f215bc7505fa22b17c154616570ddef |
-| DOCUMENT_ROLE | DocumentModule | 0xdd7c9aafbb91d54fb2041db1d5b172ea665309b32f5fffdbddf452802a1e3b20 |
-| EXTRA_INFORMATION_ROLE | ExtraInformationModule (Also used by ERC7551 module) | 0x921df7a58eb4ea112afa962b8186161404ecda2e8fe97f8246026d02ad1a74b7 |
-| ERC20ENFORCER_ROLE | ERC20EnforcementModule | 0xd62f75bf68b069bc8e2abd495a949fafec67a4e5a5b7cb36aedf0dd51eec7e72 |
-| **Option Modules** | | |
-| ALLOWLIST_ROLE | AllowlistModule | 0x26a560d834a19637eccba4611bbc09fb32970bb627da0a70f14f83fdc9822cbc |
-| DEBT_ROLE | DebtModule | 0xc6f3350ab30f55ce45863160fc345c1663d4633fe7cacfd3b9bbb6420a9147f8 |
-| DEBT_ENGINE_ROLE | DebtEngineModule | 0x516b2a17ebe2d0badac282ee8b39b7f1c94deb40fe902ce0db99741f01cae093 |
-| CROSS_CHAIN_ROLE | ERC20CrossChainModule | 0x620d362b92b6ef580d4e86c5675d679fe08d31dff47b72f281959a4eecdd036a |
-| BURNER_FROM_ROLE | ERC20CrossChainModule | 0x5bfe08abba057c54e6a28bce27ce8c53eb21d7a94376a70d475b5dee60b6c4e2 |
-| BURNER_SELF_ROLE | ERC20CrossChainModule | 0x13d9f3ea33477b975af6cd01437366c28412d5bd9b872fa0fc25bd3a160683af |
-
-
-
-#### Role by modules
-
-Here is a summary tab for each restricted functions defined in a module
-For function signatures, struct arguments are represented with their corresponding native type.
-
-Roles are defined in their specific modules but enforced in CMTAT Base module.
-
-Thus, you are free to use a module, for example `PauseModule` and apply a different access control to restrict the function.
-
-| | Function signature | Visibility [public/external] | Input variables (Function arguments) | Output variables (return value) | Role Required |
-| --------------------------------------------- | ------------------------------------------------------------ | ---------------------------- | ------------------------------------------------------------ | ------------------------------------ | ------------------------------------------------------------ |
-| **Core Modules** | | | | | |
-| ERC20BaseModule | | | | | |
-| | `setName(string name_)` | public | `string name_` | - | DEFAULT_ADMIN_ROLE |
-| | `setSymbol(string symbol_)` | public | `string symbol_` | - | DEFAULT_ADMIN_ROLE |
-| ERC20BurnModule | | | | | |
-| | `burn(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | BURNER_ROLE |
-| | `burn(address account, uint256 value)` | public | `address account, uint256 value` | - | BURNER_ROLE |
-| | `batchBurn(address[] accounts, uint256[] values, bytes data)` | public | `address[] accounts, uint256[] values, bytes data` | - | BURNER_ROLE |
-| | `batchBurn(address[] accounts, uint256[] values)` | public | `address[] accounts, uint256[] values` | - | BURNER_ROLE |
-| ERC20MintModule | | | | | |
-| | `mint(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | MINTER_ROLE |
-| | `mint(address account, uint256 value)` | public | `address account, uint256 value` | - | MINTER_ROLE |
-| | `batchMint(address[] accounts, uint256[] values)` | public | `address[] accounts, uint256[] values` | - | MINTER_ROLE |
-| | `batchTransfer( address[] tos, uint256[] values)` | public | `address[] tos, uint256[] values` | bool | MINTER_ROLE |
-| EnforcementModule | | | | | |
-| | `setAddressFrozen(address account, bool freeze)` | public | `address account, bool freeze` | - | ENFORCER_ROLE |
-| | `setAddressFrozen(address account, bool freeze, bytes data)` | public | `address account, bool freeze, bytes data` | - | ENFORCER_ROLE |
-| | `batchSetAddressFrozen( address[] accounts, bool[] freezes)` | public | `address[] accounts, bool[] freezes` | - | ENFORCER_ROLE |
-| PauseModule | | | | | |
-| | `pause()` | public | - | - | PAUSER_ROLE |
-| | `unpause()` | public | - | - | PAUSER_ROLE |
-| | `deactivateContract()` | public | - | - | DEFAULT_ADMIN_ROLE |
-| **Extension Modules** | | | | | |
-| DocumentEngineModule | | | | | |
-| | `setDocumentEngine(address documentEngine_ )` | public | `IERC1643 documentEngine_` | - | DOCUMENT_ROLE |
-| ERC20EnforcementModule | | | | | |
-| | `forcedTransfer(address from, address to, uint256 value, bytes data)` | public | `address from, address to, uint256 value, bytes data` | bool | DEFAULT_ADMIN_ROLE |
-| | `forcedTransfer(address from, address to, uint256 value)` | public | `address from, address to, uint256 value` | bool | DEFAULT_ADMIN_ROLE |
-| | `freezePartialTokens(address account, uint256 value)` | public | `address account, uint256 value` | - | ERC20ENFORCER_ROLE |
-| | `unfreezePartialTokens(address account, uint256 value)` | public | `address account, uint256 value` | - | ERC20ENFORCER_ROLE |
-| | `freezePartialTokens(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | ERC20ENFORCER_ROLE |
-| | `unfreezePartialTokens(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | ERC20ENFORCER_ROLE |
-| ExtraInformationModule | | | | | |
-| | `setTokenId(string tokenId_ )` | public | | | EXTRA_INFORMATION_ROLE |
-| | `setTerms((string,string,bytes32) terms_)` | public | `IERC1643CMTAT.DocumentInfo terms_` | | |
-| | `setInformation(string information_)` | public | `string information_` | | |
-| SnapshotEngineModule | | | | | ERC20ENFORCER_ROLE |
-| | `setSnapshotEngine(address snapshotEngine_)` | public | `ISnapshotEngine snapshotEngine_` | | SNAPSHOOTER_ROLE |
-| **Option Modules** | | | | | |
-| AllowlistModule | | | | | |
-| | `setAddressAllowlist(address account, bool status)` | public | `address account, bool status` | - | ALLOWLIST_ROLE |
-| | `setAddressAllowlist(address account, bool status, bytes data)` | public | `address account, bool status, bytes data` | - | ALLOWLIST_ROLE |
-| | `batchSetAddressAllowlist(address[] accounts, bool[] status)` | public | `address[] accounts, bool[] status` | - | ALLOWLIST_ROLE |
-| DebtEngineModule | | | | | BURNER_FROM_ROLE |
-| | `setDebtEngine(address debtEngine_)` | public | `IDebtEngine debtEngine_` | - | DEBT_ENGINE_ROLE |
-| DebtModule | | | | | |
-| | `setCreditEvents( (bool,bool,string) creditEvents_)` | public | `CreditEvents creditEvents_` | - | DEBT_ROLE |
-| | `setDebt((string,string,string,string),(uint256,uint256,uint256,string,string,string,string,string,string,string,string,address) debt_)` | public | `ICMTATDebt.DebtInformation debt_` | - | DEBT_ROLE |
-| ERC7551Module | | | | | |
-| | `setMetaData(string metadata_)` | public | `string metadata_` | - | EXTRA_INFORMATION_ROLE |
-| | `setTerms(bytes32 hash, string uri)` | public | `bytes32 hash, string uri` | - | EXTRA_INFORMATION_ROLE |
-| ERC20CrossChain | | | | | |
-| | `crosschainMint(address to, uint256 value)` | public | `address to, uint256 value` | - | CROSS_CHAIN_ROLE |
-| | `crosschainBurn(address from, uint256 value)` | public | `address from, uint256 value` | - | CROSS_CHAIN_ROLE |
-| | `burnFrom(address account, uint256 value)` | public | `address account, uint256 value` | - | BURNER_FROM_ROLE |
-| | `burn(uint256 value)` | public | `uint256 value` | - | BURNER_SELF_ROLE |
-| CCIPModule | | | | | |
-| | `setCCIPAdmin(address newAdmin)` | public | `address newAdmin` | - | DEFAULT_ADMIN_ROLE |
-| **Base contract** | | | | | |
-| BaseCommon | | | | | |
-| | `burnAndMint(address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes data)` | public | `address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes data` | - | Same role requirement as `burn`and `mint`, so BURNER_ROLE and MINTER_ROLE |
-| CMTATBaseCore (only CMTAT light version) | | | | | |
-| | `burnAndMint(address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes data)` | public | `address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes data` | - | Same role requirement as `burn`and `mint`, so BURNER_ROLE and MINTER_ROLE |
-| | `forcedBurn(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | DEFAULT_ADMIN_ROLE |
-
-
-
-
-
-#### Schema
-
-This schema contains the different roles and their restricted functions.
-
-
-
-
-
-The OpenZepplin functions `grantRole`and `revokeRole` can be used by the admin to grant and revoke role to an address.
-
-#### Transfer adminship
-
-To transfer the adminship to a new admin, the current admin must call two functions:
-
-1) `grantRole()` by specifying the DEFAULT_ADMIN_ROLE identifier and the new admin address
-2) `renounceRole()` to revoke the DEFAULT_ADMIN_ROLE from its own account.
-
-The new admin can also revoke a role from the current/old admin by calling `revokeRole`.
-
-It is also possible to have several different admins.
-
-### Engines
-
-Engines are external smart contracts called by CMTAT modules.
-
-These engines are **optional** and their addresses can be left to zero.
-
-#### Schema
-
-Here is a schema with the different modules and the associated engines.
-
-
-
-#### RuleEngine (IERC-1404)
-
-The `RuleEngine` is an external contract used to apply transfer restrictions to the CMTAT through whitelisting, blacklisting,...
-
-This contract is defined in the module `ValidationModuleRuleEngine` with the following interface `IRuleEngine`.
-
-##### Requirement
-
-Since the version v3.2.0, the requirements to use a RuleEngine are the following:
-
-> To be used with a deployment version including the module `ValidationModuleRuleEngine`:
->
-> The `RuleEngine` must import and implement the interface `IRuleEngine` which declares the ERC-3643 functions `transferred`(read-write) and `canTransfer`(ready-only) with several other functions related to [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg/16416) and [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643).
->
-> To be used with a deployment version including the module `ValidationModuleERC1404`:
->
-> The `RuleEngine` must import and implement the interface `IRuleEngineERC1404` which extends the interface `IRuleEngine`and defines functions related to [ERC-1404](https://github.com/ethereum/eips/issues/1404).
->
-> Currently, all deployed version supporting a RuleEngine used the ERC-1404 version `ValidationModuleERC1404`
-
-The two interfaces (`IRuleEngine`and `IRuleEngineERC1404`) can be found in [IRuleEngine.sol](./contracts/interfaces/engine/IRuleEngine.sol).
-
-Warning:
-
-- The `RuleEngine` has to restrict the access of the function `transferred` to only the `CMTAT token contract`.
-- To stay flexible, the `ValidationModule` stores the RuleEngine with the the following engine: `IRuleEngine`. If you want to implement the standard ERC-1404, you have to use an engine implementing the interface `IRuleEngineERC1404`.
-
-##### How it works
-
-Before each transfer (standard transfer/mint/burn), the CMTAT calls the ERC-3643 function `transferred` which is the entrypoint for the RuleEngine.
-
-```solidity
-function transferred(address from, address to, uint256 value) external;
-```
-
-CMTAT defines the interaction with the RuleEngine inside a specific module, [ValidationModuleRuleEngine](./contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol) and [CMTATBaseRuleEngine](./contracts/modules/2_CMTATBaseRuleEngine.sol).
-
-- ValidationModuleRuleEngine
-
-
-
-- CMTATBaseRuleEngine
-
-
-
-This function `_transferred` is called before each transfer/burn/mint through the internal function `_checkTransferred` defined in [CMTAT_BASE](https://github.com/CMTA/CMTAT/blob/23a1e59f913d079d0c09d32fafbd95ab2d426093/contracts/modules/CMTAT_BASE.sol#L198).
-
-Here is a schema to show how it works:
-
-
-
-1. The token holders initiate a transfer transaction on CMTAT contract.
-2. The validation module inside the CMTAT calls the ERC-3643 function `transferred` from the RuleEngine if set with the following parameters inside: `from, to, value`.
-3. The Rule Engine performs the restriction check and revert if the transfer is not authorised.
-
-###### TransferFrom - Spender restriction
-
-The `RuleEngine`is also called with the function `transferFrom`.
-
-In this case, the `transferred`function called contains an additional `spender`argument:
-
-```solidity
-function transferred(address spender, address from, address to, uint256 value) external;
-```
-
-This allows the `RuleEngine`to also apply restriction on the spender.
-
-##### Interface
-
-###### IRuleEngine
-
-Here the list of functions defined by the RuleEngine interface through inheritance
-
-```solidity
-// IRuleEngine
-function transferred(address spender, address from, address to, uint256 value)
-external;
-
-// IERC3643IComplianceContract
-function transferred(address from, address to, uint256 value)
-external;
-
-// IERC7551Compliance
-function canTransferFrom(address spender,address from,address to,uint256 value)
-external view returns (bool);
-
-
-// IER3643ComplianceRead
-function canTransfer(address from,address to,uint256 value)
-external view returns (bool isValid);
-
-// ERC-165
-// Should not be used to compute the IRuleEngine ERC-165 interface ID
- function supportsInterface(bytes4 interfaceId)
- public view override returns (bool)
-```
-
-The ERC-165 interface id for the `IRuleEngine` interface is `0x20c49ce7`
-
-###### IRuleEngineERC1404
-
-Here the list of functions defined by the RuleEngineERC1404 interface through the supplementary ERC-1404 inheritance `IERC1404Extend`
-
-```solidity
-// IERC-1404
-function detectTransferRestriction(address from,address to,uint256 value)
-external view returns (uint8);
-
-function messageForTransferRestriction(uint8 restrictionCode)
-external view returns (string memory);
-
-// IERC-1404Extend
-enum REJECTED_CODE_BASE {
- TRANSFER_OK,
- TRANSFER_REJECTED_DEACTIVATED,
- TRANSFER_REJECTED_PAUSED,
- TRANSFER_REJECTED_FROM_FROZEN,
- TRANSFER_REJECTED_TO_FROZEN,
- TRANSFER_REJECTED_SPENDER_FROZEN,
- TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE
-}
-
-function detectTransferRestrictionFrom(address spender,address from,address to,uint256 value)
-external view returns (uint8);
-```
-
-The ERC-165 interface id for the `IERC1404Extend` interface is `0x78a8de7d`
-
-##### Interface details
-
-###### IRuleEngine
-
-`IRuleEngine` is the main interface which inherits from all other interfaces: `IERC1404Extend`, `IERC7551Compliance` and `IERC3643IComplianceContract`.
-
-```solidity
-interface IRuleEngine is IERC1404Extend, IERC7551Compliance, IERC3643IComplianceContract {
- /**
- * @notice
- * Function called whenever tokens are transferred from one wallet to another
- * @dev
- * Must revert if the transfer is invalid
- * Same name as ERC-3643 but with one supplementary argument `spender`
- * This function can be used to update state variables of the RuleEngine contract
- * This function can be called ONLY by the token contract bound to the RuleEngine
- * @param spender spender address (sender)
- * @param from token holder address
- * @param to receiver address
- * @param value value of tokens involved in the transfer
- */
- function transferred(address spender, address from, address to, uint256 value) external;
-}
-```
-
-###### IERC7551 & ERC-3643 Compliance
-
-A RuleEngine must implement the ERC-7551 function `canTransferFrom`& ERC-3643 compliance function `canTransfer`.
-
-```solidity
-interface IERC7551Compliance is IERC3643ComplianceRead {
- /*
- * @notice This function return true if the message sender is able to transfer amount tokens to to respecting all compliance.
- * @dev Don't check the balance and the user's right (access control)
- */
- function canTransferFrom(
- address spender,
- address from,
- address to,
- uint256 value
- ) external view returns (bool);
-}
-interface IERC3643ComplianceRead {
- /**
- * @notice Returns true if the transfer is valid, and false otherwise.
- * @dev Don't check the balance and the user's right (access control)
- */
- function canTransfer(
- address from,
- address to,
- uint256 value
- ) external view returns (bool isValid);
-}
-```
-
-
-
-###### ERC-1404 & ERC1404Extend
-
-A RuleEngine must implement the `ERC1404Extend` interface which inherits from `IERC1404`
-
-- IERC1404
-
-```solidity
-interface IERC1404 {
-
- /**
- * @notice Returns a uint8 code to indicate if a transfer is restricted or not
- * @dev
- * See {ERC-1404}
- * This function is where an issuer enforces the restriction logic of their token transfers.
- * Some examples of this might include:
- * - checking if the token recipient is whitelisted,
- * - checking if a sender's tokens are frozen in a lock-up period, etc.
- * @return uint8 restricted code, 0 means the transfer is authorized
- *
- */
- function detectTransferRestriction(
- address from,
- address to,
- uint256 value
- ) external view returns (uint8);
-
-
- /**
- * @dev See {ERC-1404}
- * This function is effectively an accessor for the "message",
- * a human-readable explanation as to why a transaction is restricted.
- *
- */
- function messageForTransferRestriction(
- uint8 restrictionCode
- ) external view returns (string memory);
-}
-```
-
-
-
-- IERC1404Extend
-
-```solidity
-/**
-* @title IERC1404 with custom related extensions
-*/
-interface IERC1404Extend is IERC1404{
- /*
- * @dev leave the code 6-9 free/unused for further CMTAT additions in your ruleEngine implementation
- */
- enum REJECTED_CODE_BASE {
- TRANSFER_OK,
- TRANSFER_REJECTED_PAUSED,
- TRANSFER_REJECTED_FROM_FROZEN,
- TRANSFER_REJECTED_TO_FROZEN,
- TRANSFER_REJECTED_SPENDER_FROZEN,
- TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE
- }
-
- /**
- * @notice Returns a uint8 code to indicate if a transfer is restricted or not
- * @dev
- * See {ERC-1404}
- * Add an additionnal argument `spender`
- * This function is where an issuer enforces the restriction logic of their token transfers.
- * Some examples of this might include:
- * - checking if the token recipient is whitelisted,
- * - checking if a sender's tokens are frozen in a lock-up period, etc.
- * @return uint8 restricted code, 0 means the transfer is authorized
- *
- */
- function detectTransferRestrictionFrom(
- address spender,
- address from,
- address to,
- uint256 value
- ) external view returns (uint8);
-}
-```
-
-##### RuleEngine CMTA implementation
-
-CMTA provides an implementation of a [RuleEngine](https://github.com/CMTA/RuleEngine) compatible with CMTAT. This RuleEngine is also compatible with ERC-3643 tokens.
-
-In this implementation, the token holder calls the ERC-20 function `transfer` which triggers a call to the `RuleEngine` (ERC-3643 `transferred`) and the different rules associated.
-
-The different rules are not included in the RuleEngine interface and you are free to build a different RuleEngine.
-
-###### Schema
-
-
-
-###### Version
-
-Here is the list of the different versions available for each CMTAT version.
-
-| CMTAT version | RuleEngine |
-| ----------------------- | ------------------------------------------------------------ |
-| CMTAT v3.0.0 | [RuleEngine v3.0.0-rc0](https://github.com/CMTA/RuleEngine/releases/tag/v3.0.0-rc0) (unaudited) |
-| CMTAT 2.5.0 (unaudited) | RuleEngine >= [v2.0.3](https://github.com/CMTA/RuleEngine/releases/tag/v2.0.3) (unaudited) |
-| CMTAT 2.4.0 (unaudited) | RuleEngine >=v2.0.0 Last version: [v2.0.2](https://github.com/CMTA/RuleEngine/releases/tag/v2.0.2)(unaudited) |
-| CMTAT 2.3.0 | [RuleEngine v1.0.2](https://github.com/CMTA/RuleEngine/releases/tag/v1.0.2) |
-| CMTAT 2.0 (unaudited) | [RuleEngine 1.0](https://github.com/CMTA/RuleEngine/releases/tag/1.0) (unaudited) |
-| CMTAT 1.0 | No ruleEngine available |
-
-This contract acts as a controller and can call different contract rules to apply rules on each transfer.
-
-###### Rules
-
-Rules have their own dedicated repository: [github.com/CMTA/Rules](https://github.com/CMTA/Rules) and they can be used through a RuleEngine or directly with CMTAT.
-
-Here are the list of rules in development:
-
-| Rule | Type [ready-only / read-write] | Security Audit planned in the roadmap | Description |
-| ---------------------------- | ------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| RuleWhitelist | Ready-only | ☑ | This rule can be used to restrict transfers from/to only addresses inside a whitelist. |
-| RuleWhitelistWrapper | Ready-only | ☑ | This rule can be used to restrict transfers from/to only addresses inside a group of whitelist rules managed by different operators. |
-| RuleBlacklist | Ready-only | ☑ | This rule can be used to forbid transfer from/to addresses in the blacklist |
-| RuleSanctionList | Ready-only | ☑ | The purpose of this contract is to use the oracle contract from Chainalysis to forbid transfer from/to an address included in a sanctions designation (US, EU, or UN). |
-| RuleConditionalTransferLight | Ready-Write | In development | This rule requires that transfers have to be approved before being executed by the token |
-| RuleConditionalTransfer | Ready-Write | ✘ (experimental rule) | Same principle as the light version (see above) but with more options such as a time limit for approving a request as well as for carrying out the transfer |
-
-#### SnapshotEngine
-
-This Engine allows to perform snapshot on-chain.
-
-- This engine is defined in the module `SnapshotModule`.
-- CMTAT implements only one function defined in the interface [ISnapshotEngine](./contracts/interfaces/engine/ISnapshotEngine.sol)
-
-**Before** each transfer, the CMTAT calls the function `operateOnTransfer` which is the entrypoint for the SnapshotEngine.
-
-```solidity
-/*
-* @dev minimum interface to define a SnapshotEngine
-*/
-interface ISnapshotEngine {
- /**
- * @notice Records balance and total supply snapshots before any token transfer occurs.
- * @dev This function should be called inside the {_update} hook so that
- * snapshots are updated prior to any state changes from {_mint}, {_burn}, or {_transfer}.
- * It ensures historical balances and total supply remain accurate for snapshot queries.
- *
- * @param from The address tokens are being transferred from (zero address if minting).
- * @param to The address tokens are being transferred to (zero address if burning).
- * @param balanceFrom The current balance of `from` before the transfer (used to update snapshot).
- * @param balanceTo The current balance of `to` before the transfer (used to update snapshot).
- * @param totalSupply The current total supply before the transfer (used to update snapshot).
- */
- function operateOnTransfer(address from, address to, uint256 balanceFrom, uint256 balanceTo, uint256 totalSupply) external;
-}
-```
-
-##### SnapshotEngine CMTA implementation
-
-CMTA provides an implementation of a [SnapshotEngine](https://github.com/CMTA/SnapshotEngine) compatible with CMTAT.
-
-| CMTAT | SnapshotEngine |
-| -------------------------------- | ------------------------------------------------------------ |
-| CMTAT v3.0.0 | [v0.3.0](https://github.com/CMTA/SnapshotEngine/releases/tag/v0.3.0) (unaudited) |
-| CMTAT v2.3.0 | SnapshotEngine v0.1.0 (unaudited) |
-| CMTAT v2.4.0, v2.5.0 (unaudited) | Include inside SnapshotModule (unaudited) |
-| CMTAT v2.3.0 | Include inside SnapshotModule (unaudited) |
-| CMTAT v1.0.0 | Include inside SnapshotModule, but not gas efficient (audited) |
-
-##### CMTAT Snapshot - Deployment version
-
-Instead of an external contract, it is also possible to extend CMTAT to include the logic to perform snapshots.
-
-The [SnapshotEngine](https://github.com/CMTA/SnapshotEngine) repository provides also a specific deployment version which extends CMTAT to include a part of the SnapshotEngine codebase to perform snapshot on-chain.
-
-#### DebtEngine
-
-This engine can be used to configure Debt and Credits Events information
-
-- It is defined in the `DebtEngineModule` (option module)
-- It allows to set Credit Events and Debt info through an external contract called `DebtEngine`.
-
-This module only implements two functions, available in the interface [IDebtEngine](./contracts/interfaces/engine/IDebtEngine.sol) to get information from the `DebtEngine`.
-
-```solidity
-interface IDebtEngine is ICMTATDebt, ICMTATCreditEvents {
- // nothing more
-}
-interface ICMTATDebt {
- /**
- * @notice Returns debt information
- */
- function debt() external view returns(DebtInformation memory);
-}
-interface ICMTATCreditEvents {
- /**
- * @notice Returns credit events
- */
- function creditEvents() external view returns(CreditEvents memory);
-}
-```
-
-Using an external contract provides two advantages:
-
-- Reduces code size of CMTAT, which is near of the maximal size limit
-- Allow to manage this information for several different tokens (CMTAT or not).
-
-Here is the list of the different version available for each CMTAT version.
-
-| CMTAT version | DebtEngine |
-| ------------------------ | ------------------------------------------------------------ |
-| CMTAT v3.0.0 | Under development |
-| CMTAT v2.5.0 (unaudited) | [DebtEngine v0.2.0](https://github.com/CMTA/DebtEngine/releases/tag/v0.2.0) (unaudited) |
-
-#### DocumentEngine (IERC-1643)
-
-The `DocumentEngine` is an external contract to support [*ERC-1643*](https://github.com/ethereum/EIPs/issues/1643) inside CMTAT, a standard proposition to manage documents on-chain. This standard is notably used by [ERC-1400](https://github.com/ethereum/eips/issues/1411) from Polymath.
-
-This engine is defined in the module `DocumentModule`
-
-This EIP defines a document with three attributes:
-
-- A short name (represented as a `bytes32`)
- - In CMTAT, since this EIP is not official, we decided to use the type `string` instead of `bytes32`to allow `name` with more than 32 characters as suggested in this [comment](https://github.com/ethereum/EIPs/issues/1643#issuecomment-453970278).
-
-- A generic URI (represented as a `string`) that could point to a website or other document portal.
-- The hash of the document contents associated with it on-chain.
-
-CMTAT only implements two functions from this standard, available in the interface [IERC1643](./contracts/interfaces/tokenization/draft-IERC1643.sol) to get the documents from the documentEngine.
-
-```solidity
-interface IERC1643 {
- struct Document {
- string uri;
- bytes32 documentHash;
- uint256 lastModified;
- }
- /**
- * @notice return a document identified by its name
- */
- function getDocument(string memory name) external view returns (Document memory doc);
- /**
- * @notice return all documents
- */
- function getAllDocuments() external view returns (string[] memory);
-}
-```
-
-The `DocumentEngine` has to import and implement this interface. To manage the documents, the engine is completely free on how to do it.
-
-Using an external contract provides two advantages:
-
-- Reduce code size of CMTAT, which is near the maximal size limit
-- Allow documents management for several different tokens (CMTAT or not).
-
-Here is the list of the different versions available for each CMTAT version.
-
-| CMTAT version | DocumentEngine |
-| ------------------------ | ------------------------------------------------------------ |
-| CMTAT v3.0.0 | Under development |
-| CMTAT v2.5.0 (unaudited) | [DocumentEngine v0.3.0](https://github.com/CMTA/DocumentEngine/releases/tag/v0.3.0) (unaudited) |
-
-#### AuthorizationEngine (Deprecated)
-
-> Warning: this engine has been removed since CMTAT v3.0.0
-
-The `AuthorizationEngine` was an external contract to add supplementary checks on AccessControl (functions `grantRole` and `revokeRole`) from the CMTAT. Since delegating access rights to an external contract is complicated and it is better to manage access control directly in CMTAT, we removed it in version 3.0.0.
-
-There was only one prototype available: [CMTA/AuthorizationEngine](https://github.com/CMTA/AuthorizationEngine)
-
-| CMTAT version | AuthorizationEngine |
-| -------------------------------------- | -------------------------------------- |
-| CMTAT v3.0.0 | Removed |
-| CMTAT v2.4.0, 2.5.0, 2.5.1 (unaudited) | AuthorizationEngine v1.0.0 (unaudited) |
-| CMTAT 2.3.0 (audited) | Not available |
-| CMTAT 1.0 (audited) | Not available |
-
-----
-
-## Enforcement / Transfer restriction
-
-There are several ways to restrict transfers as well as burn/mint operations
-
-### Pre-Check
-
-CMTAT provides **pre-check functions** to verify if a transfer will succeed before executing it.
-These functions are useful to avoid failed transactions due to compliance rules.
-
-| Function | ERC | Purpose | Module |
-| ------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------- | -------------------- |
-| `canTransfer(from, to, value)` | [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943), [ERC-7551](https://github.com/ethereum/ERCs/blob/60a282eb3c867af2dbed8eff12e7549b548cf1bf/ERCS/erc-7551.md) | Check if a direct transfer is allowed | ValidationModuleCore |
-| `canTransferFrom(spender, from, to, value)` | [ERC-7551](https://github.com/ethereum/ERCs/blob/60a282eb3c867af2dbed8eff12e7549b548cf1bf/ERCS/erc-7551.md) | Check if a delegated transfer is allowed | ValidationModuleCore |
-| `canTransact(account)` | [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) | Check if an account can transact (ERC-7943) | ValidationModule |
-
-### Enforcement Module
-
-Specific addresses can be frozen with the following ERC-3643 functions `setAddressFrozen`and `batchSetAddressFrozen`
-
-```solidity
-interface IERC3643Enforcement {
- function isFrozen(address account) external view returns (bool);
- function setAddressFrozen(address account, bool freeze) external;
- function batchSetAddressFrozen(address[] calldata accounts, bool[] calldata freeze) external;
-}
-```
-
-Additionally, a `data`parameter can be also used, which will be emitted inside the smart contract
-
-```solidity
-function setAddressFrozen(address account, bool freeze, bytes calldata data)
-```
-
-Due to a limited contract size, there is no batch version with a data parameter available.
-
-When an address is frozen, it is not possible to mint tokens to this address or burn its tokens. To move tokens from a frozen address, the issuer must use the function `forcedTransfer`.
-
-### ERC20EnforcementModule
-
-- A part of the balance of a specific address can be frozen with the following ERC3643 function `freezePartialTokens` and `unfreezePartialTokens`
-- Transfer/burn can be forced by the admin (ERC20EnforcementModule) with the following ERC3643 function `forcedTransfer`.
- - In this case, if a part of the balance is frozen, the tokens are unfrozen before being burnt or transferred.
-
-```solidity
-interface IERC3643ERC20Enforcement {
- /**
- * @notice Returns the amount of tokens that are partially frozen on a wallet
- */
- function getFrozenTokens(address account) external view returns (uint256);
-
- /**
- * @notice freezes token amount specified for given address.
- */
- function freezePartialTokens(address account, uint256 value) external;
- /**
- * @notice unfreezes token amount specified for given address
- */
- function unfreezePartialTokens(address account, uint256 value) external;
- /**
- *
- * @notice Triggers a forced transfer.
- */
- function forcedTransfer(address from, address to, uint256 value) external returns (bool);
-}
-```
-
-### Pause & Deactivate contract (PauseModule)
-
-#### Pause
-
-- Standard transfers can be put in pause with the following ERC3643 function `pause`and `unpause`
-
-- From ERC-3643
-
-```solidity
-interface IERC3643Pause {
- /**
- * @notice Returns true if the contract is paused, and false otherwise.
- */
- function paused() external view returns (bool);
- /**
- * @notice pauses the token contract,
- * @dev When contract is paused token holders cannot transfer tokens anymore
- *
- */
- function pause() external;
-
- /**
- * @notice unpauses the token contract,
- * @dev When contract is unpaused token holders can transfer tokens
- *
- */
- function unpause() external;
-}
-```
-
-#### Note
-
-The pause function does not affect burn and mint operations implemented in the contracts `ERC20MintModule` and `ERC20BurnModule`.
-
-By separating burn/mint from standard transfer, the admin can re-adjust the supply while the standard transfers are paused. The alternative in this case to block mint and burn operations is to remove the MINTER and BURNER roles from the addresses concerned.
-
-On the other hand, specific function for cross-chain bridge (`3_CMTATBaseERC20CrossChain.sol`) will revert if contract is paused because they are not intended to be used by the issuer to manage the supply.
-
-#### Future possible improvement
-
-An alternative solution would be to provide an additional function `pauseAllTransfers` which would pause standard transfers, as well as all burn and mint operations.
-However, due to the architecture of current contracts, it is not possible to add this functionality without exceeding the maximum contract size on Ethereum.
-Consideration will be given to how this can be achieved in a future release.
-
-#### Deactivate contracts
-
-```solidity
-interface ICMTATDeactivate {
- event Deactivated(address account);
- /**
- * @notice deactivate the contract
- * Warning: the operation is irreversible, be careful
- */
- function deactivateContract() external;
-
- /**
- * @notice Returns true if the contract is deactivated, and false otherwise.
- */
- function deactivated() external view returns (bool) ;
-}
-```
-
-Since the version v2.3.1, a function `deactivateContract` is implemented in the PauseModule to deactivate the contract.
-
-If a contract is deactivated, it is no longer possible to perform transfer and burn/mint operations.
-
-##### Kill (previous version)
-
-CMTAT initially supported a `kill()` function relying on the SELFDESTRUCT opcode (which effectively destroyed the contract's storage and code).
-However, Ethereum's [Cancun upgrade](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md) (rolled out in Q1 of 2024) has removed support for SELFDESTRUCT (see [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780)).
-
-From then on, the `kill` function no longer worked as expected, and we have replaced it by the function `deactivateContract` .
-
-##### How it works
-
-Firstly, the contract must be in `pause`state, by calling the function `pause`, otherwise the function reverts.
-
-This function sets a boolean state variable `isDeactivated` to true.
-The function `unpause `is updated to revert if the previous variable is set to true, thus the contract is in the pause state "forever".
-
-The consequences are the following:
-
-- In standalone deployment, this operation is irreversible, it is not possible to rollback.
-- In upgradeable deployment (with a proxy), it is still possible to rollback by deploying a new implementation which sets the variable `isDeactivated`to false.
-
-### Supply management (burn & mint)
-
- Minting and burning follow a simpler path:
- 1. Check if contract is deactivated (permanent pause)
- 2. Check if target address is frozen
-
-These behaviour are enforced in the different `ValidationModule`
-
-Frozen accounts can only have tokens removed via `forcedBurn()` or `forcedTransfer()` by admins.
-
-#### Summary tab
-
-This tab summarises the different behaviour of burn/mint functions if:
-
-- The target address is frozen (EnforcementModule)
-- The target address does not have enough active balance (ERC20EnforcementModule)
-- If a `ruleEngine` is configured (ValidationModuleInternal)
-- If the contract is in pause state
-- If the contract is deactivated
-
-| | burn | batchBurn | burnFrom | burnAndMint | mint | batchMint | batchTransfer | crosschain burn | Crosschain mint | forcedTransfer |
-| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Module | ERC20Burn | ERC20Burn | CMTATBaseERC20CrossChain | CMTATBaseCommon | ERC20Mint | ERC20Mint | ERC20Mint | CMTATBaseERC20CrossChain | CMTATBaseERC20CrossChain | ERC20Enforcement |
-| Module type | Core | Core | Options | Base module | Core | Core | Core | Options | Options | Extensions |
-| Allow operation on a frozen address | ✘ | ✘ | ✘ | Same as burn & mint | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ |
-| Unfreeze missing funds if active balance is not enough (`ERC20EnforcementModule`) | ✘ | ✘ | ✘ | Same as burn & mint | - | - | ✘ | ✘ | - | ✔ |
-| Call the `RuleEngine` | ✔ | ✔ | ✔ | Same as burn & mint | ✔ | ✔ | ✔ | ✔ | ✔ | ✘ |
-| Authorised if contract is in pause state | ✔ | ✔ | ✘ | Same as burn & mint | ✔ | ✔ | ✘ | ✘ | ✘ | ✔ |
-| Authorised if the contract is deactivated | ✘ | ✘ | ✘ | Same as burn & mint | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ |
-
-
-
-##### Note
-
-Contrary to a `mint`operation, the function `batchTransfer` will perform the compliance check on the `from` address, which will be an address with the minter role. Another difference is the function will revert if the contract is in pause state.
-
-
-
-### Allowlist (whitelist) module
-
-With the `Allowlist` module and the associated `ValidationModuleAllowlist`, a supplementary check will be performed on the relevant address to determine if they are in the allowlist.
-
-#### Interface
-
-```solidity
-interface IAllowlistModule {
- /* ============ Events ============ */
- /**
- * @notice Emitted when an address is added to or removed from the allowlist
- */
- event AddressAddedToAllowlist(address indexed account, bool indexed status, address indexed enforcer, bytes data);
- /**
- * @notice Emitted when the allowlist is enabled or disabled
- */
- event AllowlistEnableStatus(address indexed operator, bool status);
- /* ============ Functions ============ */
- /**
- * @notice Checks if an account is allowlisted
- */
- function isAllowlisted(address account) external view returns (bool);
- /**
- * @notice Adds or removes an address from the allowlist
- */
- function setAddressAllowlist(address account, bool status) external;
-
- /**
- * @notice Adds or removes an address from the allowlist with additional data
- */
- function setAddressAllowlist(address account, bool status, bytes calldata data) external;
- /**
- * @notice Batch version of {setAddressAllowlist}
- */
- function batchSetAddressAllowlist(address[] calldata accounts, bool[] calldata status) external;
- /**
- * @notice Enables or disables the allowlist
- */
- function enableAllowlist(bool status) external;
-
- /**
- * @notice Returns whether the allowlist is currently enabled
- */
- function isAllowlistEnabled() external view returns (bool);
-}
-
-```
-
-#### Schema
-
-
-
-
-
-### Schema
-
-Here is a schema describing the different check performed during:
-
-- `transfer`, `transferFrom` and `batchTransfer`
-- `burn` / `mint` (supply management)
-- `burn` / `mint` for crosschain transfers
-
-
-
-### ERC-20 approve
-
-The ERC-20 `approve` function reverts when the contract is paused, except in the Light version.
-
-This behaviour is enforced in CMTAT base module.
-
-To avoid exceeding the maximum contract code size and to reduce gas costs at runtime, enforcement checks (such as whether the sender or spender is frozen, or whether they are allowlisted for the allowlist deployment version) are not performed.
-
-With the same objective, the `Light` deployment version does not perform any checks in the `approve` function, including checks on the pause state. This is acceptable because tokens can only be transferred via the `transferFrom` function, which enforces all the required checks.
-
-
-
-## Functionality details
-
-### ERC-20 properties
-
-All ERC-20 properties (`name`, `symbol`and `decimals`) can be set at deployment or initialization if a proxy is used.
-
-Once the contract is deployed, the core module `ERC20BaseModule` offers two ERC-3643 functions which allow to update the name and the symbol (but not the decimals).
-
-```solidity
-interface IERC3643ERC20Base {
- /**
- * @notice sets the token name
- */
- function setName(string calldata name) external;
- /**
- * @notice sets the token symbol
- */
- function setSymbol(string calldata symbol) external;
-}
-```
-
-
-
-### MetaTx/Gasless support (ERC-2771 module)
-
-The CMTAT supports client-side gasless transactions using the standard [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771).
-
-The contract uses the OpenZeppelin contract `ERC2771ContextUpgradeable`, which allows a contract to get the original client with `_msgSender()` instead of the feepayer given by `msg.sender`.
-
-At deployment, the parameter `forwarder` inside the CMTAT contract constructor has to be set with the defined address of the forwarder.
-
-After deployment:
-
-- In standalone deployment, the forwarder is immutable and can not be changed after deployment.
-
-- In upgradeable deployment (with a proxy), it is possible to change the forwarder by deploying a new implementation. This is possible because the forwarder is stored inside the implementation contract bytecode instead of the proxy's storage.
-
-References:
-
-- [OpenZeppelin Meta Transactions](https://docs.openzeppelin.com/contracts/5.x/api/metatx)
-
-- OpenGSN has deployed several forwarders, see their [documentation](https://docs.opengsn.org/contracts/#receiving-a-relayed-call) to see some examples.
-
-### Supply management (mint/burn)
-
-#### Event
-
-Here is the list of events emitted by functions, which modify the total supply.
-
-If you want to track all operations which burn or mint tokens, you can track the ERC-20 standard Transfer event with the address zero as the origin address (from) for a mint and the same address zero as the receiver address for a burn.
-
-##### Summary tab
-
-| Name | Defined | Standard | Concerned functions |
-| ------------------------------------------------------------ | ----------------------------- | --------------------- | ------------------------------------------------------------ |
-| `Transfer(address indexed from, address indexed to, uint256 value)` | IERC20 (OpenZeppelin) | ERC-20 | All functions which impact the supply because a burn/mint is a transfer |
-| `Mint(address indexed account, uint256 value, bytes data)` | IERC7551Mint | ERC-7551 (draft) | `mint` (ERC20MintModule) |
-| `BatchMint( address indexed minter, address[] accounts, uint256[] values` | | - | `batchMint` (ERC20MintModule) |
-| `Burn(address indexed account, uint256 value, bytes data)` | IERC7551Burn | ERC-7551 (draft) | `burn` (ERC20BurnModule) |
-| `BatchBurn(address indexed burner, address[] accounts, uint256[] values)` | | - | `batchMint` (ERC20BurnModule) |
-| `BurnFrom(address indexed burner, address indexed account, address indexed spender, uint256 value)` | IBurnERC20 | - | `burnFrom(address account, uint256 value)`
`burn(uint256 value)` (ERC20CrossChain) |
-| `CrosschainMint(address indexed to, uint256 value, address indexed sender)` | IERC7551 | ERC-7802 | `crosschainMint` (ERC20CrossChain) |
-| `CrosschainBurn(address indexed from, uint256 value, address indexed sender)` | IERC7551 | ERC-7802 | `crosschainMint` (ERC20CrossChain) |
-| `Enforcement (address indexed enforcer, address indexed account, uint256 amount, bytes data)` (Enforcement ) | IERC7551ERC20EnforcementEvent | ERC-7551 (draft) | `forcedTransfer` (ERC20EnforcementModule) `forcedBurn` (CMTATBaseCore) |
-| `Spend(address indexed account, address indexed spender, uint256 value)` | IERC20Allowance | - | `transferFrom` (ERC20BaseModule) `transferFrom`don't change the supply `burnFrom(address account, uint256 value)` |
-
-
-
-#### Burn (ERC20BurnModule)
-
-Core modue
-
-##### ERC-3643
-
-```solidity
-interface IERC3643Burn{
- /**
- * @notice Burns tokens from a given address, by transferring them to address(0)
- */
- function burn(address account,uint256 value) external;
- /**
- * @notice Batch version of {burn}
- */
- function batchBurn(address[] calldata accounts,uint256[] calldata values) external;
-}
-```
-
-##### ERC-7551
-
-```solidity
-interface IERC7551Burn {
- /**
- * @notice Emitted when the specified `value` amount of tokens owned by `owner`are destroyed with the given `data`
- */
- event Burn(address indexed burner, address indexed account, uint256 value, bytes data);
- /**
- * @notice Burns tokens from a given address, by transferring them to address(0)
- */
- function burn(address account, uint256 amount, bytes calldata data) external;
-}
-```
-
-
-
-#### Mint (ERC20MintModule)
-
-Core module
-
-##### ERC-3643
-
-```solidity
-interface IERC3643Mint{
- /**
- * @notice Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0)
- */
- function mint(address account, uint256 value) external;
- /**
- * @notice batch version of {mint}
- */
- function batchMint( address[] calldata accounts,uint256[] calldata values) external;
-}
-```
-
-##### ERC7551
-
-```solidity
-interface IERC7551Mint {
- /**
- * @notice Emitted when the specified `value` amount of new tokens are created and
- * allocated to the specified `account`.
- */
- event Mint(address indexed minter, address indexed account, uint256 value, bytes data);
- /**
- * @notice Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0)
- */
- function mint(address account, uint256 value, bytes calldata data) external;
-}
-```
-
-
-
-#### Cross-chain (ERC20Crosschain)
-
-This part is implemented in the option module `ERC20CrossChain`
-
-##### BurnFrom / burn
-
-```solidity
-/**
- * @notice Standard interface for token burning operations with allowance.
- */
-interface IBurnFromERC20 {
- /** ============ Events ============ **/
- /**
- * @notice Emitted when a spender burns tokens on behalf of an account, reducing the spender's allowance.
- */
- event BurnFrom(address indexed burner, address indexed account, address indexed spender, uint256 value);
-
- /** ============ Functions ============ **/
- /**
- * @notice Burns a specified amount of tokens from a given account, deducting from the caller's allowance.
- */
- function burnFrom(address account, uint256 value) external;
-
- /**
- * @notice Burns a specified amount of tokens from the caller's own balance.
- * @param value The number of tokens to burn.
- * @dev This function is restricted to authorized roles.
- */
- function burn(uint256 value) external;
-}
-```
-
-##### ERC-7802
-
-See the dedicated section (at the beginning of this document)
-
-##### Access control
-
-in the different `CMTATBase`modules, the function responsible to manage the access control are overridden to forbid `self burn`.
-
-It means that a token holder can not burn its own tokens.
-
-Example (ERC20CrossChainModule):
-
-```solidity
-function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{}
-```
-
-**Reason**
-
-It's deliberate that only the issuer (and not the tokenholder) can cancel a token, and that this corresponds to a legal requirement in several countries.
-
-Indeed, once issued, a security can only be cancelled by its issuer, not by its holder. Since the token serves as a vehicle for the security, the same must apply to the token itself. An investor wishing to "get rid of" a token must transfer it to the issuer, who can then cancel it when the law allows.
-
-**Alternative**
-
-You can still allow `self burn` by creating a new function or by overriding the corresponding functions.
-
-### Manage on-chain document
-
-#### Terms
-
-Tokenization terms are defined by the extension module `ExtraInformationModule `
-
-The term is made of:
-
-- A name (string)
-- An `IERC1643.Document`document, which means:
- - A string uri (optional)
- - The document hash (optional)
- - The last on-chain modification date (set by the smart contract)
-
-```solidity
-interface IERC1643 {
- struct Document {
- string uri;
- bytes32 documentHash;
- uint256 lastModified;
- }
- // rest of the interface
-}
-interface ICMTATBase {
- /*
- * @dev A reference to (e.g. in the form of an Internet address) or a hash of the tokenization terms
- */
- struct Terms {
- string name;
- IERC1643.Document doc;
- }
- event Term(Terms newTerm);
- /*
- * @notice returns tokenization terms
- */
- function terms() external view returns (Terms memory);
- /*
- * @notice set tokenization terms
- */
- function setTerms(IERC1643CMTAT.DocumentInfo calldata terms_) external;
-}
-```
-
-#### Additional documents through ERC1643 and DocumentEngine
-
-Additional documents can be added through the `DocumentEngine`
-
-For more information, see the section dedicated to the `DocumentEngine`
-
-### Cross-chain transfers (ERC-7802, CCIP-CCT, LayerZero)
-
-#### Chainlink CCIP - CCT
-
-CMTAT implements the required function of the [Cross-Chain Token Standard](https://docs.chain.link/ccip/concepts/cross-chain-token) (CCT) which means:
-
-- CMTAT CCIP admin can enable the token in CCIP, without the need of requesting assistance to [Chainlink](https://chain.link).
-- Chainlink CCIP pool can perform the relevant mint and burn operations on CMTAT tokens.
-
-See also [docs.chain.link - Cross Chain Token (EVM)](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#overview)
-
-##### [Registration functions](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#registration-functions)
-
-CMTAT implements the following function `getCCIPAdmin()` to return the address authorized to register the token in CCIP.
-
-The alternative function proposed by CCIP, `owner`, is not implemented by CMTAT but this could be done easily. Note that `getCCIPAdmin` is the recommended function to use in the CCIP documentation.
-
-##### [Transfer functions](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#transfer-functions)
-
-Here is the list of functions required to implement CCT and be compatible with CCIP.
-
-| | | Implemented | CCIP Pool [BurnMint Requirements](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#burnmint-requirements) | CCIP Pool [Lock-Release requirements](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#lockrelease-requirements) | Pausable | CMTAT Module | Role |
-| -------------------------- | ------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---------------------------------- | ---------------- |
-| Register CCIP token | | | | | | | |
-| | `owner()` | ✘ | - | - | | - | |
-| | `getCCIPAdmin()` | ✔ | - | - | | CCIPModule | - |
-| Burn and Mint Requirements | | | | | | | |
-| | `mint(address account, uint256 amount)` | ✔ | ✔ | ✘ | ✘ | MintModule (Core module) | MINTER_ROLE |
-| | `burn(uint256 amount)` | ✔ | ✔ | ✘ | ✘ | ERC20CrossChain | BURNER_FROM_ROLE |
-| | ERC-20 `decimals()` | ✔ | ✔ | ✔ | - | ERC20BaseModule (Core module) | |
-| | ERC-20 `balanceOf(address account)` | ✔ | ✔ | ✔ | - | OpenZeppelin inheritance | |
-| | `burnFrom(address account, uint256 amount)` | ✔ | ✔ | ✘ | ✔ | ERC20CrossChain | BURNER_FROM_ROLE |
-
-Note:
-
-- `Lock and Mint` and `Burn and Unlock` models are also compatible with CMTAT through the implementation of `Burn and Mint`requirements.
-- `Lock and Unlock`model does not need specific requirement from the token contract.
-- The admin must grant the required permissions to mint/burn to the CCIP token pool.
-- Pausing the contract through the PauseModule will not affect the mint and burn functions of the MintModule and BurnModule. The alternative solution in this case is to revoke the MINTER_ROLE and BURNER_ROLE from the relevant addresses to prevent minting and burning.
-
-##### CMTAT implementation
-
-Here is the list of implemented functions and their respective modules.
-
-```solidity
-// ERC20BaseModule
-function decimals() public view virtual override(ERC20Upgradeable) returns (uint8)
-// OpenZeppelin ERC20Upgrdeable
-function balanceOf(address account) public view virtual returns (uint256)
-// CCIPModule
-function setCCIPAdmin(address newAdmin) public virtual onlyCCIPSetAdmin
-function getCCIPAdmin() public view virtual returns (address)
-// MintModule
-function mint(address account, uint256 value) public virtual override(IERC5679Mint) onlyMinter
-// ERC20CrossChain
-function burnFrom(address account, uint256 value) public virtual override(IBurnFromERC20) onlyBurnerFrom
-function burn(uint256 value) public virtual onlyBurnerFrom
-```
-
-##### Example
-
-[CMTAT-CCIP](https://github.com/CMTA/CMTAT-CCIP) repository contains a collection of Foundry scripts designed to simplify and show deployment of a CMTAT token (v3.1.0) with CCIP contracts.
-
-It was built by [Nox Labs](https://github.com/Nox-Labs) in collaboration with CMTA and [Taurus](https://www.taurushq.com).
-
-#### Optimism superchain ERC-20 (ERC-7802)
-
-> CMTAT implements ERC-7802 in the option module `ERC20CrossChain`
-
-The [`SuperchainTokenBridge`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol) uses [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) to enable asset interoperability within the Superchain.
-
-- Asset interoperability allows tokens to move across the Superchain by burning tokens on the source chain and minting an equivalent amount on the destination chain.
-- Instead of wrapping assets, this mechanism effectively "teleports" tokens between chains in the Superchain.
-
-Reference: [docs.optimism.io/interop/superchain-erc20](https://docs.optimism.io/interop/superchain-erc20)
-
-##### Initiating message (source chain)
-
-> Example of use
-
-1. The user (or a contract) calls [`SuperchainTokenBridge.sendERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol#L52-L78).
-2. The token bridge calls the function [`CMTAT.crosschainBurn`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainERC20.sol#L37-L46) to burn those tokens on the source chain.
-3. The source token bridge calls [`SuperchainTokenBridge.relayERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol#L80-L97) on the destination token bridge. This call is relayed using [`L2ToL2CrossDomainMessenger`](https://docs.optimism.io/interop/message-passing). The call is *initiated* here, by emitting an initiating message. It will be executed later, after the destination chain receives an executing message to [`L2ToL2CrossDomainMessenger`](https://docs.optimism.io/interop/message-passing).
-
-##### Executing message (destination chain)
-
-1. The autorelayer (or the user, or any offchain entity) sends an executing message to [`L2ToL2CrossDomainMessenger`](https://docs.optimism.io/interop/message-passing) to relay the message.
-2. The destination token bridge calls [`CMTAT.crosschainMint`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainERC20.sol#L26-L35) to mint tokens for the user/contract that called `SuperchainTokenBridge.sendERC20` originally.
-
-##### Requirement
-
-- You must allow the `SuperchainTokenBridge` to call `crosschainMint` and `crosschainBurn`. No additional permission or role setup is required.
-
-- Deploy the `CMTAT` at the same address on every chain in the Superchain where you want your token to be available. If you do not deploy the contract to a specific destination chain, users will be unable to successfully move their tokens to that chain.
-
-#### LayerZero
-
-Two OFT adapters (ERC-3643/ERC-7802) working with CMTAT are available here: [CMTAT-LayerZero](https://github.com/CMTA/CMTAT-LayerZero).
-
-It was built by [Nox Labs](https://github.com/Nox-Labs) in collaboration with CMTA and [Taurus](https://www.taurushq.com).
-
-CMTAT provides two main methods to burn and mint tokens.
-
-- Standard burn/mint with the same interface as ERC-3643
-- Cross-chain burn/mint through ERC-7802
-
-To bridge tokens through LayerZero, you can use an adapter which implements one of these two methods.
-
-## Deployment model
-
-Contracts for deployment are available in the directory [contracts/deployment](./contracts/deployment)
-
-### Summary tab
-
-| CMTAT Model | Description | Standalone/Proxy | Contract | Note |
-| -------------------- | ------------------------------------------------------------ | ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| CMTAT Standard | Deployment without proxy (immutable) | Standalone | [CMTATStandalone](./contracts/deployment/CMTATStandalone.sol) | Core & extension module without Debt, Allowlist, ERC-3643 and UUPS Include also the option module `ERC2771`, as well as `ERC20CrossChain`support |
-| | Deployment with a standard proxy (Transparent or Beacon Proxy) | Upgradeable | [CMTATUpgradeable](./contracts/deployment/CMTATUpgradeable.sol) | - |
-| Upgradeable UUPS | Deployment with a UUPS proxy | Only upgradeable | [CMTATUpgradeableUUPS](./contracts/deployment/CMTATUpgradeableUUPS.sol) | Same as standard version, but adds also the UUPS proxy support |
-| ERC-1363 | Implements [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) | Standalone | [CMTATStandaloneERC1363](./contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol) | Same as standard version, but adds also the support of `ERC-1363` |
-| | - | Upgradeable | [CMTATUpgradeableERC1363](./contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol) | - |
-| Light | Only core modules | Standalone | [CMTATStandaloneLight](./contracts/deployment/light/CMTATStandaloneLight.sol) | The core features (i.e., minting, burning,address freeze / blacklisting, pause) without additional functions required by equities and debt instruments (e.g., document management, snapshot, partial freeze of balances). |
-| | | Upgradeable | [CMTATUpgradeableLight](./contracts/deployment/light/CMTATUpgradeableLight.sol) | - |
-| Debt | Set Debt information and Credit Events | Standalone | [CMTATStandaloneDebt](./contracts/deployment/debt/CMTATStandaloneDebt.sol) | Add the debt support. Contrary to the standard version, it does not include the module `ERC2771Module` and the support of `ERC20CrossChain` |
-| | | Upgradeable | [CMTATUpgradeableDebt](./contracts/deployment/debt/CMTATUpgradeableDebt.sol) | - |
-| DebtEngine | Set Debt information and Credit Events through an external contract `DebtEngine` | Standalone | [CMTATStandaloneDebtEngine](./contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol) | Add the debt engine support. Contrary to the standard version, it does not include the module `ERC2771Module`. Contrary to the Debt version, it includes `ERC20CrossChain` module and ERC-1404 functionality. |
-| | | Upgradeable | [CMTATUpgradeableDebtEngine](./contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol) | - |
-| Allowlist | Restrict transfer to an allowlist (whitelist) | Standalone | [CMTATStandaloneAllowlist](./contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol) | Contrary to the standard version, it does not include the `RuleEng`ERC-1404` support (ValidationModuleERC1404) & ERC20Crosschain |
-| | | Upgradeable | [CMTATUpgradeableAllowlist](./contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol) | - |
-| ERC7551 | Deployment specific for ERC-7551 | Standalone | [CMTATStandaloneERC7551](./contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol) | Add support of `ERC7551Module` |
-| | | Upgradeable | [CMTATUpgradeableERC7551](./contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol) | - |
-| CMTAT with snapshots | Deployment version that performs time-based snapshots directly on-chain and without relying on the external contract `SnapshotEngine` | Upgradeable | [CMTA - SnapshotEngine](https://github.com/CMTA/SnapshotEngine) (external repository) | - |
-
-### Standard Standalone
-
-To deploy CMTAT without a proxy, in standalone mode, you need to use the contract version `CMTATStandalone`.
-
-Here is the surya inheritance schema:
-
-
-
-### Upgradeable (with a proxy)
-
-The CMTAT supports deployment via a proxy contract. Furthermore, using a proxy permits to upgrade the contract, using a standard proxy upgrade pattern.
-
-- The implementation contract to use with a TransparentProxy is the `CMTATUpgradeable`.
-- The implementation contract to use with a UUPSProxy is the `CMTATUpgradeableUUPS`.
-
-Please see the OpenZeppelin [upgradeable contracts documentation](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable) for more information about the proxy requirements applied to the contract.
-
-See the OpenZeppelin [Upgrades plugins](https://docs.openzeppelin.com/upgrades-plugins/1.x/) for more information about plugin upgrades in general.
-
-#### Inheritance
-
-- UUPS
-
-
-
-- Proxy standard
-
-
-
-
-
-#### Implementation details
-
-##### Storage
-
-CMTAT also implements the standard [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) to manage the storage location. See [this article](https://www.rareskills.io/post/erc-7201) by RareSkills for more information.
-
-| Modules | Variable | bytes32 Value |
-| ------------------------------ | ----------------------------------------- | ------------------------------------------------------------ |
-| **Internal** | | |
-| AllowlistModuleInternal | AllowlistModuleInternalStorageLocation | 0x53076eaf2d1e2f915f2e0487c9f92cca686c37fd47bf11f95f0da313b2809800 |
-| EnforcementModuleInternal | EnforcementModuleInternalStorageLocatio | 0x0c7bc8a17be064111d299d7669f49519cb26c58611b72d9f6ccc40a1e1184e00 |
-| ERC20EnforcementModuleInternal | ERC20EnforcementModuleStorageLocation | 0x9d8059a24cb596f1948a937c2c163cf14465c2a24abfd3cd009eec4ac4c39800 |
-| | ValidationModuleRuleEngineStorageLocation | 0x77c8cc897d160e7bf5b10921804e357da17ae27460d4a6b5d9b27ffddf159d00 |
-| **Core** | | |
-| ERC20BaseModule | ERC20BaseModuleStorageLocation | 0x9bd8d607565c0370ae5f91651ca67fd26d4438022bf72037316600e29e6a3a00 |
-| PauseModule | | 0xab1527b6135145d8da1edcbd6b7b270624e17f2b41c74a8c746ff388ad454700 |
-| **Extension** | | |
-| DocumentEngineModule | DocumentEngineModuleStorageLocation | 0xbd0905600c85d707dc53eba2e146c1c2527cd32ac3ff6b86846155151b3e2700 |
-| ExtraInformationModule | ExtraInformationModuleStorageLocation | 0xd2d5d34c4a4dea00599692d3257c0aebc5e0359176118cd2364ab9b008c2d100 |
-| SnapshotEngineModule | SnapshotEngineModuleStorageLocation | 0x1387b97dfab601d3023cb57858a6be29329babb05c85597ddbe4926c1193a900 |
-| **Options** | | |
-| CCIPModule | CCIPModuleStorageLocation | 0x364fbfd89c0eee55bbc8dd10b1a9bf3e04fba9f3ee606f4c79a82f9941ad7a00 |
-| DebtModule | DebtModuleStorageLocation | 0xf8a315cc5f2213f6481729acd86e55db7ccc930120ccf9fb78b53dcce75f7c00 |
-| ERC7551Module | ERC7551ModuleStorageLocation | 0x2727314c926b592b6f70e7d6d2e4677ebcac070f293306927f71fe77858eec00 |
-
-
-
-##### Initialize functions
-
-Inside the public initializer function to initialize your proxy, you have to call the different functions `__{ContractName}_init_unchained`.
-
-Do not forget to call the functions `init_unchained` from the parent initializer if you create your own contract from the different modules.
-
-For wrapper modules, we have removed the public function `{ContractName}_init` when they are not useful to reduce the size of the contracts.
-
-As indicated in the [OpenZeppelin documentation](https://docs.openzeppelin.com/contracts/5.x/upgradeable#multiple-inheritance):
-
-> Initializer functions are not linearized by the compiler like constructors. Because of this, each `__{ContractName}_init` function embeds the linearized calls to all parent initializers. As a consequence, calling two of these `init` functions can potentially initialize the same contract twice.
->
-> The function `__{ContractName}_init_unchained` found in every contract is the initializer function minus the calls to parent initializers, and can be used to avoid the double initialization problem, but doing this manually is not recommended. We hope to be able to implement safety checks for this in future versions of the Upgrades Plugins.
-
-### ERC-1363
-
-[ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) is an extension interface for ERC-20 tokens that supports executing code on a recipient contract after transfers, or code on a spender contract after approvals, in a single transaction.
-
-Two dedicated versions (proxy and standalone) implementing this standard are available.
-
-More information on this standard here: [erc1363.org](https://erc1363.org), [RareSkills - ERC-1363](https://www.rareskills.io/post/erc-1363)
-
-#### Inheritance
-
-- CMTAT ERC-1363 Base
-
-
-
-
-
-
-
-
-
-- CMTAT Upgradeable ERC-1363
-
-
-
-
-
-- CMTAT Standalone ERC-1363
-
-
-
-### Light version
-
-The light version only includes core modules.
-
-It also includes a function `forceBurn`to allow the admin to burn a token from a frozen address. This function is not required for deployment versions which include the extension module `ERC20EnforcementModule` because this module contains a function `forcedTransfer`which can be used instead.
-
-If the address is not frozen, it is also possible to perform a burn-and-mint atomically through the function `burnAndMint` like the deployment standard versions
-
-- CMTAT Upgradeable Light
-
-
-
-- CMTAT Standalone Light
-
-
-
-- CMTATBaseCore
-
-
-
-### Debt version
-
-Two deployment version are available to represent Debt and Credit Events information on-chain: `Debt` and `DebtEngine`
-
-The first one `Debt` includes the `DebtModule` and allows to set these information directly in the main token contract.
-
-The second `DebtEngine` includes the `DebtEngineModule` to set these information through an external contract called by the CMTAT token contract.
-
-See also [CMTAT - Standard for the tokenization of debt instruments using distributed ledger technology](https://cmta.ch/standards/standard-for-the-tokenization-of-debt-instruments-using-distributed-ledger-technology)
-
-#### Struct
-
-The debt information are defined by the struct `ICMTATDebt` in [ICMTAT.sol](./contracts/interfaces/tokenization/ICMTAT.sol)
-
-```solidity
-interface ICMTATDebt {
- struct DebtInformation {
- DebtIdentifier debtIdentifier;
- DebtInstrument debtInstrument;
- }
- struct DebtIdentifier {
- string issuerName;
- string issuerDescription;
- string guarantor;
- string debtHolder;
- }
- struct DebtInstrument {
- // uint256
- uint256 interestRate;
- uint256 parValue;
- uint256 minimumDenomination;
- // string
- string issuanceDate;
- string maturityDate;
- string couponPaymentFrequency;
- string interestScheduleFormat;
- string interestPaymentDate;
- string dayCountConvention;
- string businessDayConvention;
- string currency;
- // address
- address currencyContract;
- }
- function debt() external view returns(DebtInformation memory);
-}
-```
-
-
-
-##### Debt Identifier
-
-Information on the issuer and other persons involved.
-
-Defined by the struct `DebtIdentifier` in [ICMTAT.sol](./contracts/interfaces/tokenization/ICMTAT.sol)
-
-| Field name | Type | Description |
-| ----------------- | ------ | ------------------------------------------------------------ |
-| issuerName | string | Issuer identifier (legal entity identifier [LEI] or, if unavailable, Swiss entity identification number [UID] or equivalent) |
-| issuerDescription | string | - |
-| guarantor | string | Guarantor identifier (legal entity identifier [LEI] or, if unavailable, Swiss entity identification number [UID] or equivalent), if applicable |
-| debtHolder | string | Debtholders representative identifier (legal entity identifier [LEI] or, if unavailable, Swiss entity identification number [UID] or equivalent), if applicable |
-
-##### Debt Instrument
-
-Information on the Instruments.
-
-Defined by the struct `DebtInstrument` in [ICMTAT.sol](./contracts/interfaces/tokenization/ICMTAT.sol)
-
-| Field name | Type | Description |
-| ---------------------- | ------- | ------------------------------------------------------------ |
-| interestRate | uint256 | - |
-| parValue | uint256 | - |
-| minimumDenomination | uint256 | - |
-| issuanceDate | string | - |
-| maturityDate | string | - |
-| couponPaymentFrequency | string | - |
-| interestScheduleFormat | string | The purpose of the interest schedule is to set, within the parameters of the smart contract, the dates on which the interest payments accrue. Format A: start date/end date/period Format B: start date/end date/day of period (e.g., quarter or year) Format C: date 1/date 2/date 3/…. |
-| interestPaymentDate | string | Interest payment date (if different from the date on which the interest payment accrues): Format A: period (indicating the period between the accrual date for the interest payment and the date on which the payment is scheduled to be made) Format B: specific date |
-| dayCountConvention | string | - |
-| businessDayConvention | string | - |
-| currency | string | - |
-| currencyContract | address | - |
-
-##### Credit Events
-
-Defined by the struct `CreditEvents`in [ICMTAT.sol](./contracts/interfaces/tokenization/ICMTAT.sol).
-
-Similar to the debt information, Credit Events can be set directly inside the smart contract (`DebtModule`) or through the external contract `DebtEngine`(`DebtEngineModule`).
-
-```solidity
-interface ICMTATCreditEvents {
- function creditEvents() external view returns(CreditEvents memory);
- struct CreditEvents {
- bool flagDefault;
- bool flagRedeemed;
- string rating;
- }
-}
-```
-
-
-
-| Field name | Type |
-| ------------ | ------ |
-| flagDefault | bool |
-| flagRedeemed | bool |
-| rating | string |
-
-#### Specification
-
-Here are the different fields and functions to read and store the related debt information and Credit Events.
-
-| | Module | Function | Type [Read/Write] | Internal field |
-| --------------- | -------------------------------- | ---------------------------------------- | ---------------------- | --------------- |
-| Debt Identifier | | | | |
-| | DebtModule DebtEngineModule | debt() | Read | `_debt` |
-| | DebtModule | setDebt(...) | Write | `_debt` |
-| Debt Instrument | | | | |
-| | DebtModule DebtEngineModule | debt() | Read | `_debt` |
-| | DebtModule | setDebt(...) setDebtInstrument(...) | Write | `_debt` |
-| Credit Events | DebtEngineModule | creditEvents() | Read | `_creditEvents` |
-| | DebtModule | setCreditEvents(...) | Write | `_creditEvents` |
-
-#### Schema
-
-##### Debt
-
-- CMTAT Standalone Debt
-
-
-
-- CMTAT Upgradeable Debt
-
-
-
-- CMTAT Base Debt
-
-
-
-
-
-##### DebtEngine
-
-- CMTAT Standalone DebtEngine
-
-
-
-- CMTAT Upgradeable DebtEngine
-
-
-
-- CMTAT Base DebtEngine
-
-
-
-
-
-
-
-### Allowlist
-
-The Allowlist deployment version allows to restrict transfer to token holders present inside an allowlist (whitelist) maintained inside the smart contract.
-
-For this purpose, a specific Validation controller is used called `ValidationModuleAllowlist`as well as a specific option module `AllowlistModule`.
-
-As a result, with this deployment version, it is not possible to set a `RuleEngine` and the contract does not implement the standard `ERC-1404`.
-
-More information regarding the Ethereum API available in the [Allowlist module documentation ](doc/modules/options/allowlist/allowlist.md)
-
-#### How to use it ?
-
-1) Select the deployment version you want: `CMTATStandaloneAllowlist` or `CMTATUpgradeableAllowlist`
-2) Once the contract is deployed, with an authorized user (default admin or an address with the `ALLOWLIST_ROLE`) enables the `allowlist`by calling the function `enableAllowlist` with true as status.
- - Once this is done, all transfers (including `mint` and `burn`) will be rejected if the origin or target address is not in the `allowlist`
- - For a mint operation, the contract authorized the origin address zero by default.
- - For a burn operation, the operation will be rejected if the target account is not in the `allowlist`. In this case, the issuer must use the function `forcedTransfer`to burn the tokens.
- - It is possible to disable the use of the allowlist by calling the same function `enableAllowlist` with false as status.
-3) Add the different addresses in the `allowlist` by calling the functions `setAddressAllowlist` and `batchSetAddressAllowlist`. It is possible to call theses functions even if the `allowlist` is not enabled.
-
-
-
-#### Inheritance
-
-- CMTAT Standalone Allowlist
-
-
-
-- CMTAT Upgradeable Allowlist
-
-
-
-- CMAT base Allowlist
-
-
-
-
-
-### Factory
-
-Factory contracts are available to deploy the CMTAT with a beacon proxy, a transparent proxy or an UUPS proxy.
-
-These contracts have now their own GitHub project: [CMTAT Factory](https://github.com/CMTA/CMTATFactory)
-
-| CMTAT version | CMTAT Factory |
-| --------------------------------- | ------------------------------------------------------------ |
-| CMTAT v3.0.0 | CMTAT Factory [v0.2.0](https://github.com/CMTA/CMTATFactory/releases/tag/v0.2.0) (unaudited) |
-| CMTAT v2.5.0 / v2.5.1 (unaudited) | Available within CMTAT see contracts/deployment (unaudited) |
-| CMTAT 2.3.0 (audited) | Not available |
-| CMTAT 1.0 (audited) | Not available |
-
-Further reading: [Taurus - Making CMTAT Tokenization More Scalable and Cost-Effective with Proxy and Factory Contracts](https://www.taurushq.com/blog/cmtat-tokenization-deployment-with-proxy-and-factory/) (version used CMTAT v2.5.1)
-
-### Deployment for other types of tokens (ERC-721, ERC-1155, ...)
-
-Deployment version using another type of token than ERC-20 (e.g ERC-721) or with a different logic (e.g [ZamaFHE - EncryptedERC20](https://www.zama.ai/post/confidential-erc-20-tokens-using-homomorphic-encryption)) can be built by using the base contract `CMTATBaseGeneric`. This base contract inherits from several non-ERC-20 modules
-
-Currently, there is no available version but a mock contract which implements ERC-721 with `CMTATBaseGeneric`is available in the mock directory: [EC721MockUpgradeable.sol](./contracts/mocks/ERC721MockUpgradeable.sol)
-
-- ERC721MockUpgradeable
-
-
-
-- CMTATBaseGeneric
-
-
-
-
-
-----
-
-## Documentation
-
-The documentation is available in the directory `doc`
-
-Here a summary of the main documents
-
-| Document | Files |
-| ----------------------------------- | ------------------------------------------------------------ |
-| Documentation of the modules API. | [modules](./doc/modules) |
-| How to use the project + toolchains | [USAGE.md](./doc/USAGE.md) |
-| FAQ | [FAQ.md](./doc/general/FAQ.md) |
-| Crosschain transfers | [crosschain-bridge-support.md](./doc/general/crosschain-bridge-support.md) |
-
-CMTA provides further documentation describing the CMTAT framework in a platform-agnostic way, and covering legal aspects, see
-
-- [CMTA Token (CMTAT)](https://cmta.ch/standards/cmta-token-cmtat)
-- [Standard for the tokenization of shares of Swiss corporations using the distributed ledger technology](https://cmta.ch/standards/standard-for-the-tokenization-of-shares-of-swiss-corporations-using-the-distributed-ledger-technology)
-- [Standard for the tokenization of debt instruments using distributed ledger technology](https://cmta.ch/standards/standard-for-the-tokenization-of-debt-instruments-using-distributed-ledger-technology)
-
-### Further reading
-
-- CMTA official publication
- - [CMTA - A comparison of different security token standards](https://cmta.ch/news-articles/a-comparison-of-different-security-token-standards)
-
-- Solidity (EVM version)
- - [Taurus - Security Token Standards: A Closer Look at CMTAT](https://www.taurushq.com/blog/security-token-standards-a-closer-look-at-cmtat/)
- - [Taurus - Equity Tokenization: How to Pay Dividend On-Chain Using CMTAT](https://www.taurushq.com/blog/equity-tokenization-how-to-pay-dividend-on-chain-using-cmtat/) (CMTAT v2.4.0)
- - [Taurus - Token Transfer Management: How to Apply Restrictions with CMTAT and ERC-1404](https://www.taurushq.com/blog/token-transfer-management-how-to-apply-restrictions-with-cmtat-and-erc-1404/) (CMTAT v2.4.0)
- - [Taurus - Making CMTAT Tokenization More Scalable and Cost-Effective with Proxy and Factory Contracts](https://www.taurushq.com/blog/cmtat-tokenization-deployment-with-proxy-and-factory/) (CMTAT v2.5.1)
- - [Taurus - Conditional Transfers with CMTAT & Taurus-CAPITAL: A Step-by-Step Guide](https://www.taurushq.com/blog/tokenization-conditionaltransfer-with-cmtat/) (CMTAT v2.5.0)
-
-- Aztec
- - [Taurus - Addressing the Privacy and Compliance Challenge in Public Blockchain Token Transactions](https://www.taurushq.com/blog/enhancing-token-transaction-privacy-on-public-blockchains-while-ensuring-compliance/) (Aztec)
- - [Taurus Deploys the First Private Stablecoin Contract](https://www.taurushq.com/blog/taurus-deploys-the-first-private-stablecoin-contract/)
-- Tezos
- - [QuillAudits - TEZOS CMTAT](https://www.quillaudits.com/research/rwa-development/non-evm-standards/tozos-cmtat)
-
-
-
-------
## Security
-### Vulnerability disclosure
-
-Please see [SECURITY.md](./SECURITY.md).
-
-
-### Module
-
-Access control is managed thanks to the module `AccessControlModule`.
-
-See [AccessControlModule.sol](./contracts/modules/wrapper/security/AccessControlModule.sol)
-
-### Audit
-
-CMTAT is regularly audited by globally recognised firm specialised in smart contracts security.
-
-Only the audited version should be used in production.
-
-| Version | Security Audit Firm |
-| ------------------------------------------------------------ | ---------------------------------------------- |
-| [CMTAT v3.0.0](https://github.com/CMTA/CMTAT/releases/tag/v3.0.0) | [Halborn](https://www.halborn.com) |
-| CMTAT v2.3.0 | [ABDKConsulting](https://www.abdk.consulting/) |
-| CMTAT v1.0.0 | [ABDKConsulting](https://www.abdk.consulting/) |
-
+CMTAT has been audited by [ABDK](https://abdk.consulting) (v1.0, v2.3.0) and [Halborn](https://www.halborn.com) (v3.0.0), with ~99% test coverage across 5,630 automated tests.
+In addition to external audits and test coverage, CMTAT security reviews also include static analysis tools such as [Aderyn](https://github.com/Cyfrin/aderyn) and [Slither](https://github.com/crytic/slither), as well as AI-assisted auditing tools such as [Nethermind Audit Agent](https://auditagent.nethermind.io).
-#### Out of scope
+See [SECURITY.md](./SECURITY.md) for the responsible disclosure policy.
-Mocks contracts in the directory [contracts/mocks](./contracts/mocks) are not audited and are not intended for use in production.
+## License
-They are only used for testing.
+[MPL-2.0](./LICENSE.md) — weak copyleft, allows commercial use.
-#### First audit - September 2021 [ABDK]
+### License Comparison
-Fixed version: [1.0](https://github.com/CMTA/CMTAT/releases/tag/1.0)
+| Topic | MPL-2.0 | MIT | GNU GPL (v3) | Apache-2.0 |
+|---|---|---|---|---|
+| Open source | ✔ | ✔ | ✔ | ✔ |
+| Commercial use | ✔ | ✔ | ✔ | ✔ |
+| Copyleft level | Weak (file-level) | None (permissive) | Strong (project-level) | None (permissive) |
+| If you modify licensed code | Must publish modified MPL files | No obligation to publish | Must publish derivative source under GPL | No obligation to publish |
+| Proprietary code mixing | Allowed (keep MPL files under MPL) | Allowed | Restricted by GPL copyleft | Allowed |
+| Patent license | ✔ (explicit) | ✘ (not explicit) | ✔ (via GPLv3 terms) | ✔ (explicit) |
+| Notice / attribution | Required | Required | Required | Required (+ NOTICE handling) |
-Fixes of security issues discovered by the initial audit were reviewed by ABDK and confirmed to be effective, as certified by the [report released](doc/audits/ABDK-CMTAT-audit-20210910.pdf) on September 10, 2021, covering [version c3afd7b](https://github.com/CMTA/CMTAT/tree/c3afd7b4a2ade160c9b581adb7a44896bfc7aaea) of the contracts.
-Version [1.0](https://github.com/CMTA/CMTAT/releases/tag/1.0) includes additional fixes of minor issues, compared to the version retested.
+`Similarity`: all four licenses allow commercial use and redistribution.
+`Key difference`: MPL-2.0 is a middle ground between permissive licenses (MIT/Apache-2.0) and strong copyleft (GPL): only modified MPL-covered files must remain open.
-A summary of all fixes and decisions taken is available in the file [CMTAT-Audit-20210910-summary.pdf](./doc/audits/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.pdf)
+**What is the patent license?**
+A patent license in an open-source license means contributors grant users permission to use any patents that would otherwise be needed to use their contributed code. This reduces patent-risk for adopters. `Apache-2.0`, `MPL-2.0`, and `GPLv3` include explicit patent protections (with termination clauses if someone starts a patent lawsuit over the covered software), while `MIT` does not include an explicit patent grant.
-#### Second audit - March 2023 [ABDK]
+## Getting Started
-Fixed version: [v2.3.0](https://github.com/CMTA/CMTAT/releases/tag/v2.3.0)
-
-The second audit covered version [2.2](https://github.com/CMTA/CMTAT/releases/tag/2.2).
-
-Version v2.3.0 contains the different fixes and improvements related to this audit.
-
-The report is available in [ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf](./doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0/ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf).
-
-#### Third audit - July 2025 [Halborn]
-
-This audit has been made by [Halborn](https://www.halborn.com).
-
-Fixed version: [v3.0.0](https://github.com/CMTA/CMTAT/releases/tag/v3.0.0)
-
-The third audit covered version [v3.0.0-rc5](https://github.com/CMTA/CMTAT/tree/v3.0.0-rc5).
-
-Version v3.0.0 contains the different fixes and improvements related to this audit.
-
-The report is available in [Taurus_CMTAT_Smart_Contract_Security_Assessment_Report_Halborn.pdf](./doc/audits/Halborn-CMTATv3.0.0-2025/Taurus_CMTAT_Smart_Contract_Security_Assessment_Report_Halborn.pdf).
-
-> After the 1st audit phase, we made another fix to perform compliance check with all batch functions. See [commits - 198d0194a0eef526b0a33cb625f6227da07608d4](https://github.com/CMTA/CMTAT/pull/313/commits/198d0194a0eef526b0a33cb625f6227da07608d4). This fix was also reviewed by Halborn.
-
-### Tools
-
-> More details are available in the file [USAGE.md](./doc/USAGE.md)
-
-#### [Aderyn](https://github.com/Cyfrin/aderyn)
-
-Here are the reports produced by [Aderyn](https://github.com/Cyfrin/aderyn):
-
-| Version | File |
-| ------- | ------------------------------------------------------------ |
-| v3.2.0 | [v3.2.0-aderyn-report.md](./doc/audits/tools/aderyn/v3.2.0-aderyn-report.md) |
-| v3.1.0 | [v3.1.0-aderyn-report.md](./doc/audits/tools/aderyn/v3.1.0-aderyn-report.md) |
-| v3.0.0 | [v3.0.0-aderyn-report.md](./doc/audits/tools/aderyn/v3.0.0-aderyn-report.md) |
-
-#### [Slither](https://github.com/crytic/slither)
-
-Here are the reports produced by [Slither](https://github.com/crytic/slither):
-
-| Version | File |
-| ------- | ------------------------------------------------------------ |
-| v3.2.0 | [v3.2.0-slither-report.md](./doc/audits/tools/slither/v3.2.0-slither-report.md) |
-| v3.1.0 | [v3.1.0-slither-report.md](./doc/audits/tools/slither/v3.1.0-slither-report.md) |
-| v3.0.0 | [v3.0.0-slither-report.md](./doc/audits/tools/slither/v3.0.0-slither-report.md) |
-| v2.5.0 | [v2.5.0-slither-report.md](./doc/audits/tools/slither/v2.5.0-slither-report.md) |
-| v2.3.0 | [v2.3.0-slither-report.md](./doc/audits/tools/slither/v2.3.0-slither-report.md) |
-
-#### [Mythril](https://github.com/Consensys/mythril)
-
-Here are the reports produced by Mythril
-
-| Version | File |
-| ------- | ------------------------------------------------------------ |
-| v3.0.0 | Mythril currently generates a fatal error, impossible to run the tool |
-| v2.5.0 | [mythril-report-standalone.md](./doc/audits/tools/mythril/v2.5.0/myth_standalone_report.md) [mythril-report-proxy.md](./doc/audits/tools/mythril/v2.5.0/myth_proxy_report.md) |
-
-#### [Nethermind Audit Agent](https://auditagent.nethermind.io)
-
-Here are the reports produced by [Nethermind Audit Agent](https://auditagent.nethermind.io):
-
-| Version | File |
-| ---------- | ------------------------------------------------------------ |
-| v3.1.0 | [nethermind-audit-agent/v3.1.0](./doc/audits/tools/nethermind-audit-agent/v3.1.0) |
-| v3.0.0-rc5 | [nethermind-audit-agent/v3.0.0-rc5](./doc/audits/tools/nethermind-audit-agent/v3.0.0-rc5) |
-
-The v3.1.0 report identified **14 findings** (2 high, 2 medium, 10 low). All findings were reviewed by CMTA maintainers; 7 were assessed as invalid and 7 were acknowledged as design choices. No finding required a code fix.
-
-| N° | Title | Severity | Validity |
-|----|-------|----------|----------|
-| 1 | Partial-freeze not enforced on transfer path | High | Invalid |
-| 2 | Unprotected `initialize()` allows front-running of proxy initialization | High | Invalid |
-| 3 | Missing spender validation in transfer check function | Medium | Design choice |
-| 4 | Missing contract validation for RuleEngine address | Medium | Design choice |
-| 5 | Transfers ignore pause/deactivation in `CMTATBaseCommon` | Low | Design choice |
-| 6 | Transfers to frozen recipients possible in `CMTATBaseCommon.transfer()` | Low | Design choice |
-| 7 | Reentrancy window between unfreeze and balance update | Low | Invalid |
-| 8 | `canTransfer`/`canTransferFrom` can return `true` when transfer would revert | Low | Design choice |
-| 9 | SnapshotEngine hook bypassed in `_update` | Low | Design choice |
-| 10 | RuleEngine spender hardcoded to `address(0)` for minter-initiated transfers | Low | Invalid |
-| 11 | Forced transfers still enforced by standard validation | Low | Invalid |
-| 12 | Inconsistent deactivation handling between `canTransfer()` and `detectTransferRestriction()` | Low | Invalid |
-| 13 | `approve` not protected by pause modifier | Low | Design choice |
-| 14 | ERC2771 forwarder set via constructor in upgradeable deployments | Low | Invalid |
-
-A detailed response to each finding is available in [CMTAT_AuditAgent_Report_Comment_v3.1.0.md](./doc/audits/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.md).
-
-#### [Wake Arena](https://ackee.xyz) (Ackee Blockchain Security)
-
-Here are the reports produced by [Wake Arena](https://ackee.xyz), an automated AI vulnerability analysis tool developed by Ackee Blockchain Security:
-
-| Version | File |
-| ------------ | ------------------------------------------------------------ |
-| v3.2.0-rc2 | [Wake Arena Report - CMTA: CMTAT-v3.2.0-rc2](./doc/audits/tools/ackee-wake-arena/Wake%20Arena%20Report%20-%20CMTA_%20CMTAT-v3.2.0-rc2.pdf) |
-
-> Ackee Blockchain Security, Wake Arena AI Report \| CMTA: CMTAT, February 10, 2026 12:24 UTC.
-
-The report (v3.2.0-rc2, February 10, 2026) identified **6 findings** (0 critical, 0 high, 3 medium, 2 low, 1 info):
-
-| ID | Title | Impact | Status |
-|----|-------|--------|--------|
-| M1 | Double invocation of compliance hook in `_minterTransferOverride` | Medium | Fixed |
-| M2 | Double invocation of compliance hook in `_burnOverride` | Medium | Fixed |
-| M3 | Double invocation of compliance hook in `_mintOverride` | Medium | Fixed |
-| L1 | Misleading `Spend` event emitted on `transferFrom` when allowance is infinite | Low | Acknowledged (comment added) |
-| L2 | Unmitigated ERC20 `approve` allowance change race condition | Low | Acknowledged – won't fix |
-| I1 | Documentation mismatch: `_authorizeSelfBurn` comment referenced wrong role | Info | Fixed |
-
-A detailed feedback and response to each finding is available in [CMTAT-wake-arena-feedback.md](./doc/audits/tools/ackee-wake-arena/CMTAT-wake-arena-feedback.md).
-
-### Test
-
-A code coverage is available in [index.html](./doc/test/coverage/index.html).
-
-
-
-## Usage
-
-More details are available in the file [USAGE.md](./doc/USAGE.md)
-
-### **Use CMTAT in Your Project**
-
-f you want to use CMTAT, we recommend including it as a library via a [GitHub submodule](https://www.atlassian.com/git/tutorials/git-submodule) rather than creating a fork.
-
-This approach keeps your changes separate from the upstream CMTAT codebase and makes it easier to upgrade to newer versions. Updating a submodule is generally cleaner and more straightforward than maintaining a fork.
-
-### Solidity style guideline
-
-CMTAT follows the solidity style guideline present here: [docs.soliditylang.org/en/latest/style-guide.html](https://docs.soliditylang.org/en/latest/style-guide.html)
-
-- Orders of Functions
-
-Functions are grouped according to their visibility and ordered:
-
-```
-1. constructor
-
-2. receive function (if exists)
-
-3. fallback function (if exists)
-
-4. external
-
-5. public
-
-6. internal
-
-7. private
-```
-
-Within a grouping, place the `view` and `pure` functions last
-
-- Function declaration
-
-```
-1. Visibility
-2. Mutability
-3. Virtual
-4. Override
-5. Custom modifiers
-```
-
-Inside each contract, library or interface, use the following order:
-
-```
-1. Type declarations
-2. State variables
-3. Events
-4. Errors
-5. Modifiers
-6. Functions
-```
-
-
-
-### Configuration & toolchain
-
-#### Details
-
-The project is built with [Hardhat](https://hardhat.org) and uses [OpenZeppelin](https://www.openzeppelin.com/solidity-contracts)
-
-- hardhat.config.js
- - Solidity [v0.8.34](https://docs.soliditylang.org/en/v0.8.34/)
- - EVM version: Prague (Pectra upgrade)
- - Optimizer: true, 200 runs
-
-- Package.json
- - OpenZeppelin Contracts (Node.js module): [v5.5.0](https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v5.5.0)
- - OpenZeppelin Contracts Upgradeable (Node.js module): [v5.5.0](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.3.0)
-
-#### Installation & Compilation
-
-- Clone the repository
-
-Clone the git repository, with the option `--recurse-submodules` to fetch the submodules:
-
-`git clone git@github.com:CMTA/CMTAT.git --recurse-submodules`
-
-- Install node modules
-
-`npm install`
-
-- Run test
-
-`npx hardhat test`
-
-### Hardhat
-
-> Since the [sunset of Truffle](https://consensys.io/blog/consensys-announces-the-sunset-of-truffle-and-ganache-and-new-hardhat) by Consensys, [Hardhat](https://hardhat.org) is our main development environment.
-
-To use Hardhat, the recommended way is to use the version installed as
-part of the node modules, via the `npx` command:
-
-`npx hardhat`
-
-Alternatively, you can install Hardhat [globally](https://hardhat.org/hardhat-runner/docs/getting-started):
-
-`npm install -g hardhat`
-
-### Contract size
+[Hardhat](https://v2.hardhat.org) is the main development toolchain for this repository and for CMTAT.
+[Forge (Foundry)](https://www.getfoundry.sh) is also installed and can compile the contracts, but Foundry-specific deployment scripts and Foundry-native test suites are maintained in a dedicated repository: [CMTAT-Foundry](https://github.com/CMTA/CMTAT-Foundry).
```bash
-npm run-script size
-```
-
-
-
-
----
-
-## CMTAT Implementations
-
-This section provides an overview of CMTAT-related projects, both official implementations managed by CMTA and community-driven projects. Some community projects may have received feedback from CMTA.
-
-### Official / CMTA-Managed Implementations
-
-#### Solana
-
-Specifications to deploy CMTAT-compliant tokens on Solana are available in the repository [CMTAT-Solana](https://github.com/CMTA/CMTAT-Solana), developed by [Taurus](https://www.taurushq.com) as an internal CMTA project in collaboration with the Solana Foundation.
-
-#### Tezos
+# Install dependencies
+npm install
-[CMTAT FA2](https://github.com/CMTA/CMTAT-Tezos-FA2): Official version written in SmartPy, developed by [AirGap](https://airgap.it) in collaboration with CMTA.
+# Compile contracts
+npm run hardhat:compile
-A second unofficial version is available in the community section.
+# Run all tests
+npm run test
-### Unofficial Implementations
-
-#### Aztec (Noir)
-
-A specific version is available for [Aztec](https://aztec.network/): [Aztec Private CMTAT](https://github.com/taurushq-io/private-CMTAT-aztec), developed by [Taurus](https://www.taurushq.com) in collaboration with CMTA.
-
-- This version is **not officially approved** by CMTA.
-- See also [Taurus - Addressing the Privacy and Compliance Challenge](https://www.taurushq.com/blog/enhancing-token-transaction-privacy-on-public-blockchains-while-ensuring-compliance/)
-
-#### Starknet (Cairo)
-
-A version for [Starknet](https://www.starknet.io/) written in Cairo is under development by [Sereel](https://www.sereel.com/) in collaboration with CMTA: [0xsereel/cairo-cmtat](https://github.com/0xsereel/cairo-cmtat)
-
-#### Tezos (Ligo)
-
-- [@ligo/cmtat](https://github.com/CMTA/CMTAT-Ligo): Unofficial version written in Ligo by Frank Hillard.
- - See also [Tokenization of securities on Tezos by Frank Hillard](https://medium.com/@frank.hillard_62931/tokenization-of-securities-on-tezos-2e3c3e90fc5a)
-
-### Community projects
-
-- [swapnilraj - fix-engine](https://github.com/swapnilraj/CMTAT/tree/swp/fix-engine)
-
-Add FIX Asset Descriptors to CMTAT. See also [ERC-FIX](https://www.erc-fix.com/spec)
-
-- [siva-sub - cmtat-icma-tokenized-bonds](https://github.com/siva-sub/cmtat-icma-tokenized-bonds)
-
- Integration of CMTATv3.0 framework with ICMA Bond Data Taxonomy v1.2
-
-### Guideline
-
-If you create a version for another blockchain, feel free to use this summary tab to build a correspondence table between CMTAT framework, CMTAT Solidity version and your implementation.
-
-#### CMTAT framework
-
-In the below table, the CMTAT framework required features are mapped to Solidity features.
-
-| **CMTAT framework mandatory functionalities** | **CMTAT Solidity corresponding features** |
-| --------------------------------------------- | ------------------------------------------------------------ |
-| Know total supply | ERC20 `totalSupply` |
-| Know balance | ERC20 `balanceOf` |
-| Transfer tokens | ERC20 `transfer` |
-| Create tokens (mint) | `Mint/batchMint` |
-| Cancel tokens (force burn) | `burn/batchBurn` *(Nb. we recommend to have a dedicated function to burn tokens without the token holder consent or from a frozen address*) |
-| Pause tokens | Pause (*Nb. With CMTAT Solidity it is still possible to burn and mint while transfers are paused.)* |
-| Unpause tokens | `unpause` |
-| Deactivate contract | `deactivateContract` |
-| Freeze | `setAddressFrozen` (previously `freeze`) |
-| Unfreeze | `setAddressFrozen` (previously `unfreeze`) |
-| Name attribute | ERC20 `name` attribute |
-| Ticker symbol attribute | ERC20 `symbol` attribute |
-| Token ID attribute | `tokenId` |
-| Reference to legally required documentation | `terms` (document name, hash and uri with at least the uri) |
-
-**Freeze**
-
-To be compatible with [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), the freeze functionality is implemented with only one function: `setAddressFrozen` which takes the target address and the frozen status (true/false).
-
-However, for non-EVM blockchains, it could be clearer and make more sense to separate the freeze and unfreeze (or `thaw`) functionality with two separate and distinct functions, such as:
-
-```solidity
-freeze(address targetAddress)
-unfreeze(address targetAddress)
+# Generate coverage report
+npm run coverage
```
-#### CMTAT extended
-
-In the below table, the CMTAT framework extendedfeatures are mapped to Solidity features.
-
-| CMTAT Functionalities | **CMTAT Solidity corresponding features** | CMTAT Allowlist | CMTAT Light | CMTAT Debt | CMTAT Standard |
-| ------------------------------------ | ---------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| On-chain snapshot | `snapshotModule & snapshotEngine` | ✔ | ✘ | ✔ | ✔ |
-| Forced Transfer | `forcedTransfer` | ✔ | ✘ | ✔ | ✔ |
-| Forced burn | `forcedBurn` | ✘ | ✔ | ✘ | ✘ |
-| Freeze partial token | `freezePartialTokens`/ `unfreezePartialTokens` | ✔ | ✘ | ✔ | ✔ |
-| Integrated whitelisting/allowlisting | CMTAT Allowlist | ✔ | ✘ | ✘ | ✘ |
-| External Whitelisting/allowlisting | CMTAT with rule whitelist | ✘ | ✘ | ✔ | ✔ |
-| RuleEngine / transfer hook | CMTAT with RuleEngine | ✘ | ✘ | ✔ | ✔ |
-| Upgradibility | CMTAT Upgradeable version | ✔ | ✔ | ✔ | ✔ |
-| Feepayer/gasless | CMTAT with ERC-2771 module | ✔ | ✘ | ✘ | ✔ |
-
-**ForcedBurn/forcedTransfer:**
-
-In the standard burn function, it is not possible to burn token from a frozen wallet. CMTAT offers a dedicated function `forcedTransfer`which allows to force a transfer or a burn. If the `forcedTransfer` function is not available, the alternative is to implement only the function `forcedBurn`.
-
-This is what is done for the CMTAT light version which does not include `forcedTransfer`. You can also decide to implement both. In this case, we suggest that only `forcedBurn`can burn tokens and not `forcedTransfer`. With the CMTAT Solidity version, when `forcedTransfer` is available, we do not implement `forcedBurn` to reduce smart contract code size, but this limitation is not necessarily present with other blockchains.
-
-#### Implementation details
-
-| Functionalities | **CMTAT Solidity** | Note |
-| ---------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
-| Mint while pause | ✔ | Dedicated crosschain mint (e.g. `crosschainMint`) cannot be performed while the contract is in the pause state. |
-| Burn while pause | ✔ | Dedicated crosschain burn (e.g.`crosschainBurn`) cannot be performed while the contract is in the pause state. |
-| Self Burn | ✘ | Token holder can not burn their own tokens. Only authorised addresses are allowed to burn tokens. |
-| Standard burn on a frozen address | ✘ | Required to use `forcedTransfer` or `forcedBurn` |
-| Burn tokens with the function `forcedTransfer` | ✔ | See note above |
-
-**Self burn**
-
-It's deliberate that only the issuer (and not the tokenholder) can burn a token, and that this corresponds to a legal requirement in several countries.
-
-Indeed, once issued, a security can only be cancelled by its issuer, not by its holder. Since the token serves as a vehicle for the security, the same must apply to the token itself. An investor wishing to "get rid of" a token must transfer it to the issuer, who can then cancel it when the law allows.
+## Documentation
-However, feel free to add it in your CMTAT version if this makes sense for you from a legal or business perspective.
+Full specification, architecture details, module descriptions, and ERC compatibility tables are in **[doc/README.md](./doc/README.md)**.
-## Intellectual property
+Additional resources:
-The code is copyright (c) Capital Market and Technology Association, 2018-2026, and is released under [Mozilla Public License 2.0](./LICENSE.md).
+- [Usage Guide](./doc/USAGE.md)
+- Specification
+ - [Specification PDF (v3.0.0)](./doc/specification/CMTATSpecificationV3.0.0.pdf)
+ - [Specification PDF (v3.1.0)](./doc/specification/CMTATSpecificationV3.1.0.pdf)
+ - [Specification PDF (v3.2.0)](./doc/specification/CMTATSpecificationV3.2.0.pdf)
+- [Security Reports](./doc/security/)
+- [CMTA Website](https://cmta.ch/)
+- [GitHub Releases](https://github.com/CMTA/CMTAT/releases)
diff --git a/SECURITY.md b/SECURITY.md
index a45d44dc..748bddf2 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,27 +2,87 @@
## Reporting a Vulnerability
-To report a security vulnerability in this project, please contact security@taurusgroup.ch.
+To report a security vulnerability in this project, please contact `security@taurushq.com`.
You may encrypt your message using the following PGP key:
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
-mDMEX3G3ARYJKwYBBAHaRw8BAQdA7sQCSqSkAmGylsLRJepXuAZKkcWA+EWRPeGa
-22cIXYC0KVRhdXJ1cyBTZWN1cml0eSA8c2VjdXJpdHlAdGF1cnVzZ3JvdXAuY2g+
-iJAEExYIADgFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQQ0q1qzH0uLrdBgWQWf
-aUpuIE2KEAUCYOVKQwIbIwAKCRCfaUpuIE2KEEerAP9RiGFo932uc/dFhPmVU5Qm
-hhHbAWLt3CxeHWAztOVAgAEAw68wXxpa5NURAzZ2Qx9m8POwQjKNp7E2dA1cRRPA
-wQ2YMwRg5V8AFgkrBgEEAdpHDwEBB0CGZgfupQUEjQmiY/aCYEdeKqh8U6uLdxt+
-t+xf5cNeJ7QpVGF1cnVzIFNlY3VyaXR5IDxzZWN1cml0eUB0YXVydXNncm91cC5j
-aD6IkAQTFggAOBYhBPhEpYINIeMoGsBzFGodmG7oyiNkBQJg5V8AAhsDBQsJCAcC
-BhUKCQgLAgQWAgMBAh4BAheAAAoJEGodmG7oyiNkyDkA/iLFlVbP008qIz3tqkUn
-ExG1zc9YbJVu9oQdLmixNkWkAPwKpwXSkYiMXds9NoO8lMt6dbVtkjhhVp8fnbyY
-i9bCDrg4BGDlXwASCisGAQQBl1UBBQEBB0AjHYntohFgtCX+B2O37enowSn6DCjc
-Ni3JfkpLp19nKQMBCAeIeAQYFggAIBYhBPhEpYINIeMoGsBzFGodmG7oyiNkBQJg
-5V8AAhsMAAoJEGodmG7oyiNkJ/EA/iAKT8FOeNdXmx3LhOcw9stV4AZYyQgUqFgZ
-kOCSrfYUAQDOt/xVpVawvcAbVTAk7C3QuV9+i4aJFMDFBR2xXxVBDA==
-=Wytk
+mQGNBGWo3bMBDACoe4Fm7DS7iW5WodUTqCDYYfhfir4vrwWgUcR4KSwa+UynK3zm
+fS0mdOw9I/eiKKn8O/9ajXAUTlSwogCPnj9srHd9FhZp3dTVUdNni/BPUTOW9upU
+53hvHLjlKDl/gasz09pDBN+x5fNucP8rbqz4AiZJRuTwCMc6l9tFW7vK/ev6u/zZ
+S0EooOSIUs6PFSUaQpL7cSPMSnCbZxG28i96W1nQrfpmLsJcWC+TRfgxTcro2wFk
+99YVCUQkVqRcVfCENs8smdUeSrpdVuCNC9c18830ZwPX1lHyn+oradh7bFspugd+
+MOIKzpTZycXYRMby456p8Xi4x8tFWU/nkVPCj2Dxt97c6Intg1cbSYUU4z5JtHwm
+jnDyIRHXUKvroigK4EBkpnoaUEKNKVS86P9SBrt1f9CnLX2tmQTlJ0b57GU+Mr+W
+XV23n8ZUfg5oo3aP7jjZSVPctLeroT7BaHNOn2mCKSMdC+njHiaqrh5wg2Vz/9uR
+3JcuBPl6RPRxWMsAEQEAAbQnVGF1cnVzIFNlY3VyaXR5IDxzZWN1cml0eUB0YXVy
+dXNocS5jb20+iQHUBBMBCgA+FiEEgwhcYhAkO6sudVNT8ClED0lW4vkFAmWo3bMC
+GwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ8ClED0lW4vmelQv/
+fRhv0MoHDs36TOynO8Y8GkyoLwAfgDb14aiwGSU92DMZEf5At5VmsrpZy6IMcgla
+tJCL3IwSl7Moyr9VrTvpJZlz67mWAXVkSURLZEiVvLYltIbIzRzOsYHpuTW/+NBW
+dI8L+ivXg1GpGJxCrorjKC3Hg0vvkzOl3EBKt6PS4tkx9uZmhzzXwWi/NTX3ymcp
+Y+mtMUeKDuMVVaZUwI0w8o8TkUOf1z3TjnxOkBOQ4tT7bItPohnUOSi+lbwQdEFw
+CKxaACFvVPlQU2EE7JiXDmnaIxf692fs7wi1xXZz7hfx9RlJZLxxwEAIlws8reYT
+uxXYVbrXJykGODQd5vaYJwmMpZ56GuNUSIlffaoQUBzg5IsBExHBRH9qCjbO5P5u
+oPIk5c5nVgIyUI877t45EwTuNuVWQmJQWKcGf1UK+/HG2FpQK+SD9AKHeyQx4n6N
+vmuOz2vG28+lZ9lRKjTXrQg26zRcOxg358r73wCeXbnw7qk3QUT9g3SK/jR9QLmY
+uQGNBGWo3bMBDADLOgqv3W+r0JauiR2PIk5psJEwn3MdRmdEWxDuWXkATkYQPLmv
+heaaFpTLBJC6tR091BTGUddwnFmrXNjs26nzEDwpgQS8ey3XNzIOV+FxO8OvOWMU
+oXompFPU1LyD1WUcVARmBEGs2JocvzNz5MrYt5aUQZNnCBMJpx5aQ0LEMYB0/T/5
+zg9NBKrLRkKhk/1rUJo6zd3wH+qbvHNefAM6tnfXhYwmO9nqGZ7OKz9xH3Z43kDH
+wSH7FntEju2/jPU0WhzxtjC7rNbjXt2LzFvfQTvYvT5l0l91f4PUNozlZtpF4eYW
+137wlaSQXYLbccVAVi24kG773IB3DPaFSxX2P0rmZS+FkWutMlwn7RE6zBR/sj/o
+8dspPZjj+y+baWL99JKntR1bns0MiIyzicdYeFkYnNer1xuMJsXaDtiQPS63W9q0
+h+Xm281F44pJNGflAhaJsYcYyB6aZnJm1dY67g2tCAsBW87FwDisumjPNPJz6+Rs
+q2VivZT4Q+kib5cAEQEAAYkBvAQYAQoAJhYhBIMIXGIQJDurLnVTU/ApRA9JVuL5
+BQJlqN2zAhsMBQkDwmcAAAoJEPApRA9JVuL5sqoL/R2yXF+LauzTq360H/lrF/vD
+P6000vf7Um6tGbkjkCChRoimCVsBfhZEY/7tCw77GsWGkSTh+YF3pXoIVuP8t6uw
+OcqIFdKpriuto5Z1DGeqRFEqQCNAYYOxnfuQ0ft+nL+qwMxp0FaeIq5rgtWuDkhn
+eSC3LDha3CzFLOf/VNX4p9UEFuWWEL76gXl27nU5PIeaOneECnIEwrESB7qqE+Zp
+DqYZQKg2+ZJHOpcia1DlZQJ7J8qGehJ4aQ8sPUnrOZ5LHPKHqP/4J36gRmPvCiul
+vzjcK/sdLaWNgoKs0CRbSPXW+lu9KflpNYFpXEBiDQimI4rYSXq/AAEoQzPcd+QL
+lnQfVHHV1uaxkeV7AKNwe8SWrUmRD3i0QFRFpTmBKY9g/W1nLUwIqo3tp1kqNO2d
+zt4S/4OJz/DZB/HWgt1Y+L6Jo4MkTwWmzv8o6gpNanPUzgO6E98z1rw3Kw2bQNHR
+bVFACHnJPzOjTOiRviCKSTYkIax0+qeH642ERMG7KZkBjQRlqN5FAQwAn/fj+S88
+4cMFjBvlwfmiDIyBl7Lg//mzg1GwFc5vCEW7XgpjrL52lr0W0dB7Na1z87rip47M
+nkdLGP9jPAEVlxHBPeSmCV9xEmQUOF5ZRGZAIqG3MJS5f58Ei8YmJUogFGSTTPra
+xdEoUd1mizEcL+sBP3TTGZPvh/y2Kgdsflat8PLOP8WHb2B29DU3FgAFbD+z0YUW
+vRHdD6gdSvowItXfCVvGuMbcXXLob42HG/uzY6Vdw1VNCGcs4Z+1KZBTQ4Ir8WZv
+9g9+cZ9fUSE+5xpQBFcLTVZLSHlhJFHqE6Ara3/BVAMIzH65ue+ojAMw3HFwuIBq
+/mjAEQDsFzDU61L5mmtTwRD7a+5ViKG07jJnAyC4XueKG+IeEmlu1+KhR4MF0ZDT
+Q2hqJkwSp2Zar49O7svJ6WjWgTaTzOHbuMuFe7sN9mtTWMfOy0xGtYcQuR0KDGb+
+7gxHJro9bEhz+dPCacsD05jotW3W22jsJRyI5G2J7lh0Wn0/LyvUwzDVABEBAAG0
+J1RhdXJ1cyBTZWN1cml0eSA8c2VjdXJpdHlAdGF1cnVzaHEuY29tPokB1AQTAQoA
+PhYhBIMGQcRaqSSE19gNW5YTeP4Rego5BQJlqN5FAhsDBQkDwmcABQsJCAcCBhUK
+CQgLAgQWAgMBAh4BAheAAAoJEJYTeP4Rego5mUEMAJypadV3otB2471P1UWd1XhW
+hulcdMX3nEs2ueKEzPgDgrYhvhazu0gemIrWGFcVavskWxIjPN2FYLI33qu8Tcnf
+MnaZdU7lDvTTjV9hNrrzwlQuvgZWtV2P8AhfeFyvO4n5+rqG5z6WMey9mrlQFcJQ
+5SX/3f6lAY9wMQ3vbGtkw0nhN5VbEJk+cgvYZ1ZdJ3bpg+mEjoo6R/VtzaO1q4ND
+9w7IPsnMOdtIjJZOhen2dyJFW3/NRv1oLvEUJhRoAkiGrYfMlbTAg53K4OuqfHBV
+X5xqfO/2Ui8XBby+3lpV0KzD+/0TA7f7nHD4FueouSN0XwDBJ59lfpMEQURwS5SZ
+WkN7QfGiHtE9KDj0DZvUgtXYdhRnLMifc+TQOQjHiddB22b2whqAOMCn232yItwd
+4S4Ukepo1KLIu9x5kWvfGFQpWr5jq5ICDf7bAB7EJndvX9L6seeLUSDOmk5pdNg3
+Yuwi45aYZMNPD6bz7Uwgm0GONCAd9EP3JiE4eyA6WrkBjQRlqN5FAQwAwE9cUShA
+9riDNRnRT0zvanXRiH3LQxvvt2TT1MNiU0BC5pNl9oClECwJ8ewWWQ45EBNUQN3z
+FRJqLmyMan7fAO5rEUyMl4IHiYVTN/oT6/YKgmq3LIHnNip3d4rfRhKxvs0Dv+iO
+iv6qLlwW39hoZnGXUUj6eq7s1ZxJzzR9HEdHO1mVHWcxNqdfL+6IAA6lp3EfiJy3
++zd0c7gmJaWF8egpU4GXZ/+ZE3qWuxFw/I5mVwDXxg5x7L3Sne2WmNIbURPtb5gw
+Iz5VpgFpFCwyXBFVQTtSLhmJ9xLYVswEGp5/XWhztEJKtV4lbmHHhl5hkH7C/O8L
+uXuJFOoRyiDcG+OqRC1b0//wcV3FioGCjqHsq5abtGwZzqAuZwsMhBlhP4mmWa8J
+1EZtA0FELD70qdm+SfdhxHbG92l9KDGqDfGoRCOn5Hq6INLh/9lLbwHlYFIGfwMu
+kvLwZX3rJD4ztVzyksyL/CNFRM10i0eYH/trSP13eOh/KyZ9PtNTtzLvABEBAAGJ
+AbwEGAEKACYWIQSDBkHEWqkkhNfYDVuWE3j+EXoKOQUCZajeRQIbDAUJA8JnAAAK
+CRCWE3j+EXoKOaiBC/9ufzvIF28jMYMx3FymLKFRMgaBEDqsElFFZpk0rkbvRwFj
+sRNscI/Y4B9KsitZ/s6beXmofms0PLgOAqqA8RWJtE4fwj5qgIaHNoGEzUc/yFb+
+GhyIg7O5G0cRs7hfoOx9CUC4vyqpNi1Suna2wTb6pHCRsb+LFj9ekC95WvO64oTh
+j49dvlTDHWChCwS/bd2fDD2LgvH4UHwYHI9LPjN4z4aHwJV45rU8SlsGBD6i9Q6Q
+sdxhEVmx4KpWbjiA0xmLX8G0i69HGLgBFNYfxpBD/IuHthJc97uTFvcbYgDX9h4g
+BA1fQnLO+5qV7WqU7P41NELd56TBGtbnc+uWyvSHaVImQoMgnRvhr7AtNDV9kED3
+lbkdFIAd4kQkDCj0yLqNVOqp4Ho3oS5sKDK0fmI5rf/S4EXQ5Czplp1rRBlvocOo
++bg4YggPEeQ3r9cmnrvrh2ofkgDDHaJ/TwX3RKLzvdQMEJ+qnKxer+8BEkZ7q3Bt
+Pm/6M0sgjs8OpWPIMuE=
+=n8Eb
-----END PGP PUBLIC KEY BLOCK-----
```
diff --git a/contracts/deployment/CMTATStandalone.sol b/contracts/deployment/CMTATStandardStandalone.sol
similarity index 82%
rename from contracts/deployment/CMTATStandalone.sol
rename to contracts/deployment/CMTATStandardStandalone.sol
index 9894afaf..1aff14bb 100644
--- a/contracts/deployment/CMTATStandalone.sol
+++ b/contracts/deployment/CMTATStandardStandalone.sol
@@ -2,15 +2,15 @@
pragma solidity ^0.8.20;
-import {CMTATBaseERC2771} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
/**
-* @title CMTAT version for a standalone deployment (without proxy)
+* @title CMTAT standard version for a standalone deployment (without proxy) — no snapshot engine
*/
-contract CMTATStandalone is CMTATBaseERC2771 {
+contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement {
/**
* @notice Contract version for standalone deployment
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
diff --git a/contracts/deployment/CMTATUpgradeable.sol b/contracts/deployment/CMTATStandardUpgradeable.sol
similarity index 68%
rename from contracts/deployment/CMTATUpgradeable.sol
rename to contracts/deployment/CMTATStandardUpgradeable.sol
index 100fdade..7c4a4a5f 100644
--- a/contracts/deployment/CMTATUpgradeable.sol
+++ b/contracts/deployment/CMTATStandardUpgradeable.sol
@@ -2,14 +2,14 @@
pragma solidity ^0.8.20;
-import {CMTATBaseERC2771} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
/**
-* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
+* @title CMTAT standard version for a proxy deployment (Transparent or Beacon proxy) — no snapshot engine
*/
-contract CMTATUpgradeable is CMTATBaseERC2771 {
+contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement {
/**
* @notice Contract version for the deployment with a proxy
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
diff --git a/contracts/deployment/CMTATUpgradeableUUPS.sol b/contracts/deployment/CMTATUpgradeableUUPS.sol
index edf5f88f..72a6eae8 100644
--- a/contracts/deployment/CMTATUpgradeableUUPS.sol
+++ b/contracts/deployment/CMTATUpgradeableUUPS.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.20;
import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
-import {CMTATBaseERC2771} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseERC2771} from "../modules/6_CMTATBaseERC2771.sol";
import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
/**
diff --git a/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol b/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol
index 69d41ff2..dded7613 100644
--- a/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol
+++ b/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol
@@ -2,8 +2,8 @@
pragma solidity ^0.8.20;
-import {CMTATBaseERC1363} from "../../modules/6_CMTATBaseERC1363.sol";
-import {ERC2771Module, ERC2771ContextUpgradeable} from "../../modules/wrapper/options/ERC2771Module.sol";
+import {CMTATBaseERC1363} from "../../modules/8_CMTATBaseERC1363.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
diff --git a/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol b/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol
index ea6b5f75..3d76e8a0 100644
--- a/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol
+++ b/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol
@@ -2,8 +2,8 @@
pragma solidity ^0.8.20;
-import {CMTATBaseERC1363} from "../../modules/6_CMTATBaseERC1363.sol";
-import {ERC2771Module, ERC2771ContextUpgradeable} from "../../modules/wrapper/options/ERC2771Module.sol";
+import {CMTATBaseERC1363} from "../../modules/8_CMTATBaseERC1363.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
/**
diff --git a/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol b/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol
index 6c6665fd..dc44b8d2 100644
--- a/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol
+++ b/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseERC7551} from "../../modules/6_CMTATBaseERC7551.sol";
+import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol";
import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
diff --git a/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol b/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol
index 5cc994dc..4e3250a1 100644
--- a/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol
+++ b/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol
@@ -3,7 +3,7 @@
pragma solidity ^0.8.20;
import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
-import {CMTATBaseERC7551} from "../../modules/6_CMTATBaseERC7551.sol";
+import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol";
/**
* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
diff --git a/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol b/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol
index 8fd57088..5f39698b 100644
--- a/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol
+++ b/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol
@@ -2,8 +2,8 @@
pragma solidity ^0.8.20;
-import {CMTATBaseAllowlist} from "../../modules/2_CMTATBaseAllowlist.sol";
-import {ERC2771Module, ERC2771ContextUpgradeable} from "../../modules/wrapper/options/ERC2771Module.sol";
+import {CMTATBaseAllowlist} from "../../modules/3_CMTATBaseAllowlist.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
/**
diff --git a/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol b/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol
index 01cc1116..082af72c 100644
--- a/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol
+++ b/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol
@@ -2,8 +2,8 @@
pragma solidity ^0.8.20;
-import {CMTATBaseAllowlist} from "../../modules/2_CMTATBaseAllowlist.sol";
-import {ERC2771Module, ERC2771ContextUpgradeable} from "../../modules/wrapper/options/ERC2771Module.sol";
+import {CMTATBaseAllowlist} from "../../modules/3_CMTATBaseAllowlist.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
/**
diff --git a/contracts/deployment/debt/CMTATStandaloneDebt.sol b/contracts/deployment/debt/CMTATStandaloneDebt.sol
index 5341edd5..490c1f04 100644
--- a/contracts/deployment/debt/CMTATStandaloneDebt.sol
+++ b/contracts/deployment/debt/CMTATStandaloneDebt.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseDebt} from "../../modules/3_CMTATBaseDebt.sol";
+import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT version for a standalone deployment (without proxy)
diff --git a/contracts/deployment/debt/CMTATUpgradeableDebt.sol b/contracts/deployment/debt/CMTATUpgradeableDebt.sol
index 516499b7..bdf6786a 100644
--- a/contracts/deployment/debt/CMTATUpgradeableDebt.sol
+++ b/contracts/deployment/debt/CMTATUpgradeableDebt.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseDebt} from "../../modules/3_CMTATBaseDebt.sol";
+import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol";
/**
* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
*/
diff --git a/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol b/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol
index 28b07d48..4161ba60 100644
--- a/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol
+++ b/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseDebtEngine} from "../../modules/5_CMTATBaseDebtEngine.sol";
+import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT version for a standalone deployment (without proxy)
diff --git a/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol b/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol
index c13fcff6..89e22b73 100644
--- a/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol
+++ b/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseDebtEngine} from "../../modules/5_CMTATBaseDebtEngine.sol";
+import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol";
/**
* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
*/
diff --git a/contracts/deployment/permit/CMTATStandalonePermit.sol b/contracts/deployment/permit/CMTATStandalonePermit.sol
new file mode 100644
index 00000000..5a013fad
--- /dev/null
+++ b/contracts/deployment/permit/CMTATStandalonePermit.sol
@@ -0,0 +1,34 @@
+//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol";
+import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
+
+/**
+* @title CMTAT version for a standalone deployment (without proxy) with Permit and Multicall
+*/
+contract CMTATStandalonePermit is CMTATBaseERC2612 {
+ /**
+ * @notice Contract version for standalone deployment
+ * @param admin address of the admin of contract (Access Control)
+ * @param ERC20Attributes_ ERC20 name, symbol and decimals
+ * @param extraInformationAttributes_ tokenId, terms, information
+ * @param engines_ external contract
+ */
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor(
+ address admin,
+ ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+ ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+ ICMTATConstructor.Engine memory engines_
+ ) {
+ // Initialize the contract to avoid front-running
+ initialize(
+ admin,
+ ERC20Attributes_,
+ extraInformationAttributes_,
+ engines_
+ );
+ }
+}
diff --git a/contracts/deployment/permit/CMTATUpgradeablePermit.sol b/contracts/deployment/permit/CMTATUpgradeablePermit.sol
new file mode 100644
index 00000000..9eac96e9
--- /dev/null
+++ b/contracts/deployment/permit/CMTATUpgradeablePermit.sol
@@ -0,0 +1,19 @@
+//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol";
+
+/**
+* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy) with Permit and Multicall
+*/
+contract CMTATUpgradeablePermit is CMTATBaseERC2612 {
+ /**
+ * @notice Contract version for the deployment with a proxy
+ */
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor() {
+ // Disable the possibility to initialize the implementation
+ _disableInitializers();
+ }
+}
diff --git a/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol b/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol
new file mode 100644
index 00000000..3fc248c0
--- /dev/null
+++ b/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol
@@ -0,0 +1,38 @@
+//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {CMTATBaseERC2771Snapshot} from "../../modules/7_CMTATBaseERC2771Snapshot.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
+import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
+
+
+/**
+* @title CMTAT with snapshot engine — standalone deployment (without proxy)
+*/
+contract CMTATStandaloneSnapshot is CMTATBaseERC2771Snapshot {
+ /**
+ * @notice Contract version for standalone deployment with snapshot engine
+ * @param forwarderIrrevocable address of the forwarder, required for the gasless support
+ * @param admin address of the admin of contract (Access Control)
+ * @param ERC20Attributes_ ERC20 name, symbol and decimals
+ * @param extraInformationAttributes_ tokenId, terms, information
+ * @param engines_ external contract
+ */
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor(
+ address forwarderIrrevocable,
+ address admin,
+ ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+ ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+ ICMTATConstructor.Engine memory engines_
+ ) ERC2771Module(forwarderIrrevocable) {
+ // Initialize the contract to avoid front-running
+ initialize(
+ admin,
+ ERC20Attributes_,
+ extraInformationAttributes_,
+ engines_
+ );
+ }
+}
diff --git a/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol b/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol
new file mode 100644
index 00000000..b7bd0b7c
--- /dev/null
+++ b/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol
@@ -0,0 +1,24 @@
+//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {CMTATBaseERC2771Snapshot} from "../../modules/7_CMTATBaseERC2771Snapshot.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
+
+
+/**
+* @title CMTAT with snapshot engine — proxy deployment (Transparent or Beacon proxy)
+*/
+contract CMTATUpgradeableSnapshot is CMTATBaseERC2771Snapshot {
+ /**
+ * @notice Contract version for the deployment with a proxy, with snapshot engine
+ * @param forwarderIrrevocable address of the forwarder, required for the gasless support
+ */
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor(
+ address forwarderIrrevocable
+ ) ERC2771Module(forwarderIrrevocable) {
+ // Disable the possibility to initialize the implementation
+ _disableInitializers();
+ }
+}
diff --git a/contracts/interfaces/technical/IMintBurnToken.sol b/contracts/interfaces/technical/IMintBurnToken.sol
index db300192..190741b0 100644
--- a/contracts/interfaces/technical/IMintBurnToken.sol
+++ b/contracts/interfaces/technical/IMintBurnToken.sol
@@ -78,7 +78,8 @@ interface IBurnBatchERC20 {
* Batch version of {burn}.
* - For each burn, emits a `Transfer` event to the zero address.
* - Emits a `burnBatch` event
- * - The `data` parameter applies uniformly to all burn operations in this batch.
+ * - The `data` parameter is batch-level metadata for the `BatchBurn` event.
+ * - It is not forwarded to each individual burn item.
* - Requirements:
* - `accounts.length` must equal `values.length`.
* @param accounts The list of addresses whose tokens will be burned.
@@ -126,4 +127,4 @@ interface IBurnFromERC20 {
* @dev This function is restricted to authorized roles.
*/
function burn(uint256 value) external;
-}
\ No newline at end of file
+}
diff --git a/contracts/interfaces/tokenization/ICMTAT.sol b/contracts/interfaces/tokenization/ICMTAT.sol
index 48f50f31..ef4336ad 100644
--- a/contracts/interfaces/tokenization/ICMTAT.sol
+++ b/contracts/interfaces/tokenization/ICMTAT.sol
@@ -2,7 +2,8 @@
pragma solidity ^0.8.20;
-import {IERC1643CMTAT, IERC1643} from "./draft-IERC1643CMTAT.sol";
+import {IERC1643CMTAT} from "./draft-IERC1643CMTAT.sol";
+import {IERC1643} from "./draft-IERC1643.sol";
/**
* The issuer must be able to “deactivate” the smart contract, to prevent execution of transactions on
@@ -28,7 +29,12 @@ interface ICMTATDeactivate {
* @notice Emitted when the contract is permanently deactivated.
* @param account The address that performed the deactivation.
*/
- event Deactivated(address account);
+ event Deactivated(address indexed account);
+
+ /**
+ * @notice Error raised when deactivation is attempted after deactivation is already final.
+ */
+ error AlreadyDeactivated();
/*
* @notice Permanently deactivates the contract.
@@ -193,5 +199,3 @@ interface ICMTATDebt {
*/
function debt() external view returns(DebtInformation memory debtInformation_);
}
-
-
diff --git a/contracts/interfaces/tokenization/IERC3643Partial.sol b/contracts/interfaces/tokenization/IERC3643Partial.sol
index ea7f80ce..e349eece 100644
--- a/contracts/interfaces/tokenization/IERC3643Partial.sol
+++ b/contracts/interfaces/tokenization/IERC3643Partial.sol
@@ -169,6 +169,21 @@ interface IERC3643Enforcement {
* @dev For event definitions, see {IERC7551ERC20Enforcement}.
*/
interface IERC3643ERC20Enforcement is IERC7943FungibleEnforcement {
+ /**
+ * @dev Emitted when a certain amount of tokens is frozen on a wallet.
+ * This event is emitted by `freezePartialTokens` and `batchFreezePartialTokens`.
+ * @param account The wallet address impacted by the freezing status.
+ * @param value The amount of tokens that is frozen.
+ */
+ event TokensFrozen(address indexed account, uint256 value);
+
+ /**
+ * @dev Emitted when a certain amount of tokens is unfrozen on a wallet.
+ * This event is emitted by `unfreezePartialTokens` and `batchUnfreezePartialTokens`.
+ * @param account The wallet address impacted by the freezing status.
+ * @param value The amount of tokens that is unfrozen.
+ */
+ event TokensUnfrozen(address indexed account, uint256 value);
/* ============ State Functions ============ */
/**
* @notice Freezes a specific amount of tokens for a given account.
@@ -283,4 +298,3 @@ interface IERC3643IComplianceContract {
*/
function transferred(address from, address to, uint256 value) external;
}
-
diff --git a/contracts/interfaces/tokenization/draft-IERC1643.sol b/contracts/interfaces/tokenization/draft-IERC1643.sol
index 1cfc4583..ef375282 100644
--- a/contracts/interfaces/tokenization/draft-IERC1643.sol
+++ b/contracts/interfaces/tokenization/draft-IERC1643.sol
@@ -24,10 +24,18 @@ interface IERC1643 {
* @param name The unique name used to identify the document.
* @return document The associated document's metadata (URI, hash, timestamp).
*/
- function getDocument(string memory name) external view returns (Document memory document);
+ function getDocument(bytes32 name) external view returns (Document memory document);
/**
* @notice Returns the list of all document names registered in the contract.
* @return documentNames_ An array of strings representing all document identifiers.
*/
- function getAllDocuments() external view returns (string[] memory documentNames_);
-}
\ No newline at end of file
+ function getAllDocuments() external view returns (bytes32[] memory documentNames_);
+
+ function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external;
+
+ function removeDocument(bytes32 name) external;
+
+ event DocumentUpdated(bytes32 indexed name, string uri, bytes32 documentHash);
+
+ event DocumentRemoved(bytes32 indexed name, string uri, bytes32 documentHash);
+}
diff --git a/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol b/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol
index 5f0a3869..86c4f529 100644
--- a/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol
+++ b/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol
@@ -1,9 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;
-import {IERC1643} from "./draft-IERC1643.sol";
-
-
interface IERC1643CMTAT {
struct DocumentInfo {
string name;
@@ -11,4 +8,4 @@ interface IERC1643CMTAT {
bytes32 documentHash;
}
}
-
\ No newline at end of file
+
diff --git a/contracts/interfaces/tokenization/draft-IERC7551.sol b/contracts/interfaces/tokenization/draft-IERC7551.sol
index b89d3e74..d32676b3 100644
--- a/contracts/interfaces/tokenization/draft-IERC7551.sol
+++ b/contracts/interfaces/tokenization/draft-IERC7551.sol
@@ -57,13 +57,14 @@ interface IERC7551Pause {
}
interface IERC7551ERC20EnforcementEvent {
/**
- * @notice Emitted when a forced transfer or burn occurs.
- * @param enforcer The address that initiated the enforcement.
- * @param account The address affected by the enforcement.
- * @param amount The number of tokens involved.
- * @param data Additional data related to the enforcement.
- */
- event Enforcement (address indexed enforcer, address indexed account, uint256 amount, bytes data);
+ * @notice Emitted when a forced transfer is executed.
+ * @param operator The address that initiated the forced transfer.
+ * @param from The address from which tokens are debited.
+ * @param to The address to which tokens are credited.
+ * @param value The amount of tokens transferred.
+ * @param data Optional metadata associated with the action.
+ */
+ event ForcedTransfer(address indexed operator, address indexed from, address indexed to, uint256 value, bytes data);
}
interface IERC7551ERC20EnforcementTokenFrozenEvent {
@@ -197,4 +198,4 @@ interface IERC7551Document {
* @param metaData_ The new metadata value.
*/
function setMetaData(string calldata metaData_) external;
-}
\ No newline at end of file
+}
diff --git a/contracts/interfaces/tokenization/draft-IERC7943.sol b/contracts/interfaces/tokenization/draft-IERC7943.sol
index e0c20e40..74355cbe 100644
--- a/contracts/interfaces/tokenization/draft-IERC7943.sol
+++ b/contracts/interfaces/tokenization/draft-IERC7943.sol
@@ -85,24 +85,30 @@ interface IERC7943FungibleEnforcementEventAndError{
}
/**
-* @notice Transfer Error Interface for ERC-20, ERC-721 and ERC-1155 based implementations.
-*
+* @notice Send/Receive Error Interface for ERC-20 based implementations.
+*
*/
-interface IERC7943TransactError{
+interface IERC7943FungibleSendReceiveError {
+ /**
+ * @notice Error reverted when an account is not allowed to send tokens.
+ * @param account The address of the account which is not allowed to send.
+ */
+ error ERC7943CannotSend(address account);
+
/**
- * @notice Error reverted when an account is not allowed to transact.
- * @param account The address of the account which is not allowed for transfers.
- */
- error ERC7943CannotTransact(address account);
+ * @notice Error reverted when an account is not allowed to receive tokens.
+ * @param account The address of the account which is not allowed to receive.
+ */
+ error ERC7943CannotReceive(address account);
}
/**
* @notice Transfer Error Interface for ERC-20 based implementations.
-*
+*
*/
interface IERC7943FungibleTransferError {
- /**
- * @notice Error reverted when a transfer is not allowed according to internal rules.
+ /**
+ * @notice Error reverted when a transfer is not allowed according to internal rules.
* @param from The address from which tokens are being sent.
* @param to The address to which tokens are being sent.
* @param amount The amount sent.
@@ -110,12 +116,18 @@ interface IERC7943FungibleTransferError {
error ERC7943CannotTransfer(address from, address to, uint256 amount);
}
-interface IERC7943TransactCheck{
- /// @notice Checks if a specific account is allowed to transact according to token rules.
+interface IERC7943FungibleSendReceiveCheck {
+ /// @notice Checks if a specific account is allowed to send tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to send, false otherwise.
+ function canSend(address account) external view returns (bool allowed);
+
+ /// @notice Checks if a specific account is allowed to receive tokens according to token rules.
/// @dev This is often used for allowlist/KYC/KYB/AML checks.
/// @param account The address to check.
- /// @return allowed True if the account is allowed, false otherwise.
- function canTransact(address account) external view returns (bool allowed);
+ /// @return allowed True if the account is allowed to receive, false otherwise.
+ function canReceive(address account) external view returns (bool allowed);
}
diff --git a/contracts/library/ERC1404ExtendInterfaceId.sol b/contracts/library/ERC1404ExtendInterfaceId.sol
index 47268f01..6f620836 100644
--- a/contracts/library/ERC1404ExtendInterfaceId.sol
+++ b/contracts/library/ERC1404ExtendInterfaceId.sol
@@ -2,5 +2,15 @@
pragma solidity ^0.8.20;
library ERC1404ExtendInterfaceId {
+ /**
+ * @dev ERC-165 interface id of IERC1404Extend.
+ * Includes inherited IERC1404 functions:
+ * - detectTransferRestriction(address,address,uint256)
+ * - messageForTransferRestriction(uint8)
+ * Plus IERC1404Extend function:
+ * - detectTransferRestrictionFrom(address,address,address,uint256)
+ *
+ * Computed value: 0x78a8de7d
+ */
bytes4 public constant ERC1404EXTEND_INTERFACE_ID = 0x78a8de7d;
-}
\ No newline at end of file
+}
diff --git a/contracts/mocks/CMTATMsgDataMock.sol b/contracts/mocks/CMTATMsgDataMock.sol
index c8b4ec09..b5335cdf 100644
--- a/contracts/mocks/CMTATMsgDataMock.sol
+++ b/contracts/mocks/CMTATMsgDataMock.sol
@@ -2,15 +2,17 @@
pragma solidity ^0.8.20;
-import {CMTATStandalone} from "../deployment/CMTATStandalone.sol";
+import {CMTATStandardStandalone} from "../deployment/CMTATStandardStandalone.sol";
import {CMTATStandaloneAllowlist} from "../deployment/allowlist/CMTATStandaloneAllowlist.sol";
import {CMTATStandaloneERC1363} from "../deployment/ERC1363/CMTATStandaloneERC1363.sol";
+import {CMTATUpgradeableERC1363} from "../deployment/ERC1363/CMTATUpgradeableERC1363.sol";
+import {CMTATStandaloneSnapshot} from "../deployment/snapshot/CMTATStandaloneSnapshot.sol";
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
/*
* @title Mock contracts to test _msgData() coverage
*/
-contract CMTATStandaloneMsgDataMock is CMTATStandalone {
+contract CMTATStandaloneMsgDataMock is CMTATStandardStandalone {
event MsgDataReturned(bytes data);
/// @custom:oz-upgrades-unsafe-allow constructor
@@ -20,7 +22,7 @@ contract CMTATStandaloneMsgDataMock is CMTATStandalone {
ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
ICMTATConstructor.Engine memory engines_
- ) CMTATStandalone(forwarderIrrevocable, admin, ERC20Attributes_, extraInformationAttributes_, engines_) {}
+ ) CMTATStandardStandalone(forwarderIrrevocable, admin, ERC20Attributes_, extraInformationAttributes_, engines_) {}
function getMsgData() external returns (bytes memory) {
bytes memory data = _msgData();
@@ -65,3 +67,31 @@ contract CMTATStandaloneERC1363MsgDataMock is CMTATStandaloneERC1363 {
return data;
}
}
+
+contract CMTATUpgradeableERC1363MsgDataMock is CMTATUpgradeableERC1363 {
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor(address forwarderIrrevocable) CMTATUpgradeableERC1363(forwarderIrrevocable) {}
+
+ function getMsgData() external view returns (bytes memory) {
+ return _msgData();
+ }
+}
+
+contract CMTATStandaloneSnapshotMsgDataMock is CMTATStandaloneSnapshot {
+ event MsgDataReturned(bytes data);
+
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor(
+ address forwarderIrrevocable,
+ address admin,
+ ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+ ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+ ICMTATConstructor.Engine memory engines_
+ ) CMTATStandaloneSnapshot(forwarderIrrevocable, admin, ERC20Attributes_, extraInformationAttributes_, engines_) {}
+
+ function getMsgData() external returns (bytes memory) {
+ bytes memory data = _msgData();
+ emit MsgDataReturned(data);
+ return data;
+ }
+}
diff --git a/contracts/mocks/DocumentEngineMock.sol b/contracts/mocks/DocumentEngineMock.sol
index f3953dce..163b6bdf 100644
--- a/contracts/mocks/DocumentEngineMock.sol
+++ b/contracts/mocks/DocumentEngineMock.sol
@@ -11,33 +11,33 @@ interface IERC1643Whole is IDocumentEngine{
* lastModified The timestamp of the last modification
*/
struct DocumentInfo {
- string name;
+ bytes32 name;
string uri;
bytes32 documentHash;
}
// Document Management
function setDocument(DocumentInfo calldata doc) external;
- function removeDocument(string memory name) external;
+ function removeDocument(bytes32 name) external;
// Document Events
- event DocumentRemoved(string indexed name, Document doc);
- event DocumentUpdated(string indexed name, Document doc);
+ event DocumentRemoved(bytes32 indexed name, Document doc);
+ event DocumentUpdated(bytes32 indexed name, Document doc);
}
/*
* @title a DocumentEngine mock for testing, not suitable for production
*/
contract DocumentEngineMock is IERC1643Whole {
- mapping(string => Document) private documents;
- mapping(string => uint256) private documentKey;
- string[] private documentNames;
+ mapping(bytes32 => Document) private documents;
+ mapping(bytes32 => uint256) private documentKey;
+ bytes32[] private documentNames;
/// @dev Error thrown when a document does not exist
error DocumentDoesNotExist();
/// @notice Retrieves the document details by name
/// @param name The name of the document
- function getDocument(string memory name)
+ function getDocument(bytes32 name)
external
view
override
@@ -62,9 +62,28 @@ contract DocumentEngineMock is IERC1643Whole {
emit DocumentUpdated(doc_.name, doc);
}
+ /// @notice IERC1643-compatible setter
+ function setDocument(
+ bytes32 name,
+ string calldata uri,
+ bytes32 documentHash
+ ) external override {
+ Document storage doc = documents[name];
+ doc.uri = uri;
+ doc.documentHash = documentHash;
+ doc.lastModified = block.timestamp;
+ if (documentKey[name] == 0) {
+ // To avoid key == 0
+ uint256 key = documentNames.length + 1;
+ documentKey[name] = key;
+ documentNames.push(name);
+ }
+ emit DocumentUpdated(name, doc);
+ }
+
/// @notice Removes a document
/// @param name The name of the document
- function removeDocument(string calldata name) external override {
+ function removeDocument(bytes32 name) external override {
if (documentKey[name] == 0) {
revert DocumentDoesNotExist();
}
@@ -78,7 +97,7 @@ contract DocumentEngineMock is IERC1643Whole {
/// @notice Retrieves all document names
/// @return An array of document names
- function getAllDocuments() external view override returns (string[] memory) {
+ function getAllDocuments() external view override returns (bytes32[] memory) {
return documentNames;
}
-}
\ No newline at end of file
+}
diff --git a/contracts/mocks/ERC1363ReceiverMock.sol b/contracts/mocks/ERC1363ReceiverMock.sol
index 932c56a0..d51035f1 100644
--- a/contracts/mocks/ERC1363ReceiverMock.sol
+++ b/contracts/mocks/ERC1363ReceiverMock.sol
@@ -3,7 +3,6 @@
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/interfaces/IERC1363Receiver.sol";
-import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
contract ERC1363ReceiverMock is IERC1363Receiver {
@@ -13,4 +12,4 @@ contract ERC1363ReceiverMock is IERC1363Receiver {
emit TokensReceived(operator, from, value, data);
return IERC1363Receiver.onTransferReceived.selector;
}
-}
\ No newline at end of file
+}
diff --git a/contracts/mocks/ERC721MockUpgradeable.sol b/contracts/mocks/ERC721MockUpgradeable.sol
index abcb8603..999f34d4 100644
--- a/contracts/mocks/ERC721MockUpgradeable.sol
+++ b/contracts/mocks/ERC721MockUpgradeable.sol
@@ -29,14 +29,14 @@ contract ERC721MockUpgradeable is ERC721Upgradeable, CMTATBaseGeneric {
* @param tokenId NFT tokenId
*/
function mint(address to, uint256 tokenId) public {
- _canMintBurnByModuleAndRevert(to);
+ _canMintByModuleAndRevert(to);
ERC721Upgradeable._mint(to, tokenId);
}
function burn(uint256 tokenId) external {
address currentOwner = ownerOf(tokenId);
- _canMintBurnByModuleAndRevert(currentOwner);
- ERC721Upgradeable._burn( tokenId);
+ _canBurnByModuleAndRevert(currentOwner);
+ ERC721Upgradeable._burn(tokenId);
}
function safeTransferFrom(
diff --git a/contracts/mocks/RuleEngine/RuleEngineMock.sol b/contracts/mocks/RuleEngine/RuleEngineMock.sol
index 5f8f930f..39791267 100644
--- a/contracts/mocks/RuleEngine/RuleEngineMock.sol
+++ b/contracts/mocks/RuleEngine/RuleEngineMock.sol
@@ -6,21 +6,27 @@ import {IRule} from "./interfaces/IRule.sol";
import {IRuleEngineMock} from "./interfaces/IRuleEngineMock.sol";
import {RuleMock} from "./RuleMock.sol";
import {RuleMockMint} from "./RuleMockMint.sol";
+import {RuleSpenderAuthorized} from "./RuleSpenderAuthorized.sol";
+import {RuleTokenHolderTracker} from "./RuleTokenHolderTracker.sol";
+import {IRuleTransferHook} from "./interfaces/IRuleTransferHook.sol";
import {ERC165, IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
+import {RuleEngineInterfaceId} from "../../library/RuleEngineInterfaceId.sol";
+import {ERC1404ExtendInterfaceId} from "../../library/ERC1404ExtendInterfaceId.sol";
/*
* @title a RuleEngine mock for testing, not suitable for production
*/
contract RuleEngineMock is ERC165, IRuleEngineMock {
IRule[] internal _rules;
- address immutable authorizedSpender;
+ address private _holderTrackerRule;
error RuleEngine_InvalidTransfer(address from, address to, uint256 value);
- bytes4 private RULE_ENGINE_INTERFACE_ID = 0x20c49ce7;
- bytes4 private ERC1404EXTEND_INTERFACE_ID = 0x78a8de7d;
constructor(address spender) {
_rules.push(new RuleMock());
_rules.push(new RuleMockMint());
- authorizedSpender = spender;
+ _rules.push(new RuleSpenderAuthorized(spender));
+ RuleTokenHolderTracker holderTrackerRuleInstance = new RuleTokenHolderTracker();
+ _rules.push(holderTrackerRuleInstance);
+ _holderTrackerRule = address(holderTrackerRuleInstance);
}
/*
@@ -29,6 +35,16 @@ contract RuleEngineMock is ERC165, IRuleEngineMock {
*/
function setRules(IRule[] calldata rules_) external override {
_rules = rules_;
+ _holderTrackerRule = address(0);
+ uint256 rulesLength = _rules.length;
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ try IRuleTransferHook(address(_rules[i])).transferred(address(0), address(0), address(0), 0) {
+ _holderTrackerRule = address(_rules[i]);
+ break;
+ } catch {
+ continue;
+ }
+ }
}
function rulesCount() external view override returns (uint256) {
@@ -99,30 +115,32 @@ contract RuleEngineMock is ERC165, IRuleEngineMock {
address to,
uint256 value
) public view override returns (bool) {
- if(spender == address(0) || spender == authorizedSpender) {
- return detectTransferRestriction(from, to, value) == 0;
- } else {
- return false;
- }
+ return detectTransferRestrictionFrom(spender, from, to, value) == 0;
}
/*
* @dev
* Warning: if you want to use this mock, you have to restrict the access to this function through an an access control
*/
- function transferred(
+ function transferred(
address spender,
address from,
address to,
- uint256 value) view public override{
+ uint256 value) public override{
require(canTransferFrom(spender, from, to, value), RuleEngine_InvalidTransfer(from, to, value));
+ _callRuleHooks(spender, from, to, value);
}
- function transferred(
+ function transferred(
address from,
address to,
- uint256 value) view public override {
+ uint256 value) public override {
require(canTransfer(from, to, value), RuleEngine_InvalidTransfer(from, to, value));
+ _callRuleHooks(address(0), from, to, value);
+ }
+
+ function holderTrackerRule() external view returns (address) {
+ return _holderTrackerRule;
}
/**
@@ -146,10 +164,17 @@ contract RuleEngineMock is ERC165, IRuleEngineMock {
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
- return interfaceId == RULE_ENGINE_INTERFACE_ID || interfaceId == ERC1404EXTEND_INTERFACE_ID || super.supportsInterface(interfaceId);
+ return interfaceId == RuleEngineInterfaceId.RULE_ENGINE_INTERFACE_ID || interfaceId == ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID || super.supportsInterface(interfaceId);
}
- function returnInterfaceId() public view returns (bytes4) {
- return RULE_ENGINE_INTERFACE_ID;
+ function returnInterfaceId() public pure returns (bytes4) {
+ return RuleEngineInterfaceId.RULE_ENGINE_INTERFACE_ID;
+ }
+
+ function _callRuleHooks(address spender, address from, address to, uint256 value) internal {
+ uint256 ruleArrayLength = _rules.length;
+ for (uint256 i = 0; i < ruleArrayLength; ++i) {
+ try IRuleTransferHook(address(_rules[i])).transferred(spender, from, to, value) {} catch {}
+ }
}
}
diff --git a/contracts/mocks/RuleEngine/RuleSpenderAuthorized.sol b/contracts/mocks/RuleEngine/RuleSpenderAuthorized.sol
new file mode 100644
index 00000000..4020764c
--- /dev/null
+++ b/contracts/mocks/RuleEngine/RuleSpenderAuthorized.sol
@@ -0,0 +1,63 @@
+//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {IRule} from "./interfaces/IRule.sol";
+import {CodeList} from "./CodeList.sol";
+
+/*
+* @title a mock rule for spender authorization, not suitable for production
+*/
+contract RuleSpenderAuthorized is IRule, CodeList {
+ uint8 constant SPENDER_NOT_AUTHORIZED = 21;
+ string constant TEXT_SPENDER_NOT_AUTHORIZED = "Spender not authorized";
+
+ address immutable authorizedSpender;
+
+ constructor(address spender) {
+ authorizedSpender = spender;
+ }
+
+ function canTransfer(
+ address /*_from*/,
+ address /*_to*/,
+ uint256 /*_amount*/
+ ) public pure override returns (bool isValid) {
+ return true;
+ }
+
+ function detectTransferRestriction(
+ address /*_from*/,
+ address /*_to*/,
+ uint256 /*_amount*/
+ ) public pure override returns (uint8) {
+ return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+
+ function detectTransferRestrictionFrom(
+ address spender,
+ address /*_from*/,
+ address /*_to*/,
+ uint256 /*_amount*/
+ ) public view override returns (uint8) {
+ if (spender == address(0) || spender == authorizedSpender) {
+ return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+ return SPENDER_NOT_AUTHORIZED;
+ }
+
+ function canReturnTransferRestrictionCode(
+ uint8 _restrictionCode
+ ) public pure override returns (bool) {
+ return _restrictionCode == SPENDER_NOT_AUTHORIZED;
+ }
+
+ function messageForTransferRestriction(
+ uint8 _restrictionCode
+ ) external pure override returns (string memory) {
+ return
+ _restrictionCode == SPENDER_NOT_AUTHORIZED
+ ? TEXT_SPENDER_NOT_AUTHORIZED
+ : TEXT_CODE_NOT_FOUND;
+ }
+}
diff --git a/contracts/mocks/RuleEngine/RuleTokenHolderTracker.sol b/contracts/mocks/RuleEngine/RuleTokenHolderTracker.sol
new file mode 100644
index 00000000..3a66be9c
--- /dev/null
+++ b/contracts/mocks/RuleEngine/RuleTokenHolderTracker.sol
@@ -0,0 +1,78 @@
+//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {IRule} from "./interfaces/IRule.sol";
+import {IRuleTransferHook} from "./interfaces/IRuleTransferHook.sol";
+import {CodeList} from "./CodeList.sol";
+
+/**
+ * @title Mock stateful rule that tracks token holders through RuleEngine hooks.
+ * @dev This rule is permissive (always returns TRANSFER_OK) and only updates storage.
+ */
+contract RuleTokenHolderTracker is IRule, IRuleTransferHook, CodeList {
+ mapping(address => uint256) private _trackedBalance;
+ mapping(address => bool) private _isHolder;
+ address[] private _holders;
+ uint256 private _holdersCount;
+
+ function transferred(address, address from, address to, uint256 value) external override {
+ if (from != address(0)) {
+ _trackedBalance[from] -= value;
+ _updateHolderStatus(from);
+ }
+ if (to != address(0)) {
+ _trackedBalance[to] += value;
+ _updateHolderStatus(to);
+ }
+ }
+
+ function trackedBalance(address account) external view returns (uint256) {
+ return _trackedBalance[account];
+ }
+
+ function isHolder(address account) external view returns (bool) {
+ return _isHolder[account];
+ }
+
+ function holdersCount() external view returns (uint256) {
+ return _holdersCount;
+ }
+
+ function holderAt(uint256 index) external view returns (address) {
+ return _holders[index];
+ }
+
+ function canTransfer(address, address, uint256) external pure override returns (bool) {
+ return true;
+ }
+
+ function detectTransferRestriction(address, address, uint256) public pure override returns (uint8) {
+ return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+
+ function detectTransferRestrictionFrom(address, address, address, uint256) public pure override returns (uint8) {
+ return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+
+ function canReturnTransferRestrictionCode(uint8) external pure override returns (bool) {
+ return false;
+ }
+
+ function messageForTransferRestriction(uint8) external pure override returns (string memory) {
+ return TEXT_CODE_NOT_FOUND;
+ }
+
+ function _updateHolderStatus(address account) private {
+ bool shouldBeHolder = _trackedBalance[account] > 0;
+ bool current = _isHolder[account];
+ if (shouldBeHolder && !current) {
+ _isHolder[account] = true;
+ _holders.push(account);
+ _holdersCount += 1;
+ } else if (!shouldBeHolder && current) {
+ _isHolder[account] = false;
+ _holdersCount -= 1;
+ }
+ }
+}
diff --git a/contracts/mocks/RuleEngine/interfaces/IRuleTransferHook.sol b/contracts/mocks/RuleEngine/interfaces/IRuleTransferHook.sol
new file mode 100644
index 00000000..b794d0e5
--- /dev/null
+++ b/contracts/mocks/RuleEngine/interfaces/IRuleTransferHook.sol
@@ -0,0 +1,12 @@
+//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+/**
+ * @dev Optional hook interface for rules that need to update their own state
+ * on token transfer/mint/burn intents.
+ */
+interface IRuleTransferHook {
+ function transferred(address spender, address from, address to, uint256 value) external;
+}
+
diff --git a/contracts/mocks/engine/CMTATDocumentEngineModuleMock.sol b/contracts/mocks/engine/CMTATDocumentEngineModuleMock.sol
new file mode 100644
index 00000000..f44dad97
--- /dev/null
+++ b/contracts/mocks/engine/CMTATDocumentEngineModuleMock.sol
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {CMTATBaseCore} from "../../modules/0_CMTATBaseCore.sol";
+import {DocumentEngineModule} from "../../modules/wrapper/options/DocumentEngineModule.sol";
+import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
+import {IERC1643} from "../../interfaces/engine/IDocumentEngine.sol";
+
+/**
+ * @title CMTAT document engine module mock
+ * @dev Test-only contract that wires DocumentEngineModule on top of CMTAT core.
+ */
+contract CMTATDocumentEngineModuleMock is CMTATBaseCore, DocumentEngineModule {
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor() {
+ _disableInitializers();
+ }
+
+ function initialize(
+ address admin,
+ ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+ IERC1643 documentEngine_
+ ) public initializer {
+ __CMTAT_init(admin, ERC20Attributes_);
+ __DocumentEngineModule_init_unchained(documentEngine_);
+ }
+
+ function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) onlyRole(DOCUMENT_ENGINE_ROLE) {}
+}
diff --git a/contracts/mocks/engine/CMTATEngineInitializerMock.sol b/contracts/mocks/engine/CMTATEngineInitializerMock.sol
index 1398de2e..a8c234b5 100644
--- a/contracts/mocks/engine/CMTATEngineInitializerMock.sol
+++ b/contracts/mocks/engine/CMTATEngineInitializerMock.sol
@@ -2,9 +2,9 @@
pragma solidity ^0.8.20;
-import {CMTATUpgradeable} from "../../deployment/CMTATUpgradeable.sol";
-import {IERC1643} from "../../interfaces/engine/IDocumentEngine.sol";
+import {CMTATUpgradeableSnapshot} from "../../deployment/snapshot/CMTATUpgradeableSnapshot.sol";
import {ISnapshotEngine} from "../../interfaces/engine/ISnapshotEngine.sol";
+import {IERC1643} from "../../interfaces/engine/IDocumentEngine.sol";
/**
* @title CMTATEngineInitializerMock
@@ -13,9 +13,8 @@ import {ISnapshotEngine} from "../../interfaces/engine/ISnapshotEngine.sol";
*
* This contract exposes:
* - __SnapshotEngineModule_init_unchained() - sets SnapshotEngine during initialization
- * - __DocumentEngineModule_init_unchained() - sets DocumentEngine during initialization
*/
-contract CMTATEngineInitializerMock is CMTATUpgradeable {
+contract CMTATEngineInitializerMock is CMTATUpgradeableSnapshot {
/**
* @notice Contract version for the deployment with a proxy
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -23,7 +22,7 @@ contract CMTATEngineInitializerMock is CMTATUpgradeable {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(
address forwarderIrrevocable
- ) CMTATUpgradeable(forwarderIrrevocable) {
+ ) CMTATUpgradeableSnapshot(forwarderIrrevocable) {
// Nothing to do
}
@@ -32,15 +31,13 @@ contract CMTATEngineInitializerMock is CMTATUpgradeable {
* This allows testing the uncovered initializer branches.
* Uses reinitializer(2) to allow calling after initial initialize().
* @param snapshotEngine_ The snapshot engine address (can be zero)
- * @param documentEngine_ The document engine address (can be zero)
*/
function initializeWithEngines(
ISnapshotEngine snapshotEngine_,
- IERC1643 documentEngine_
+ IERC1643 /* documentEngine_ */
) public reinitializer(2) {
// Call the uncovered initializers
// These functions check for non-zero address internally
__SnapshotEngineModule_init_unchained(snapshotEngine_);
- __DocumentEngineModule_init_unchained(documentEngine_);
}
}
diff --git a/contracts/mocks/test/proxy/CMTAT_PROXY_TEST.sol b/contracts/mocks/test/proxy/CMTAT_PROXY_TEST.sol
index 70f66430..359f6c24 100644
--- a/contracts/mocks/test/proxy/CMTAT_PROXY_TEST.sol
+++ b/contracts/mocks/test/proxy/CMTAT_PROXY_TEST.sol
@@ -2,13 +2,13 @@
pragma solidity ^0.8.20;
-import {CMTATUpgradeable} from "../../../deployment/CMTATUpgradeable.sol";
+import {CMTATStandardUpgradeable} from "../../../deployment/CMTATStandardUpgradeable.sol";
/**
* @title a contrat used to test the proxy upgrade functionality
*/
-contract CMTAT_PROXY_TEST is CMTATUpgradeable {
+contract CMTAT_PROXY_TEST is CMTATStandardUpgradeable {
/**
* @notice Contract version for the deployment with a proxy
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -16,7 +16,7 @@ contract CMTAT_PROXY_TEST is CMTATUpgradeable {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(
address forwarderIrrevocable
- ) CMTATUpgradeable(forwarderIrrevocable) {
+ ) CMTATStandardUpgradeable(forwarderIrrevocable) {
// Nothing to do
}
}
diff --git a/contracts/modules/0_CMTATBaseCommon.sol b/contracts/modules/0_CMTATBaseCommon.sol
index 64f78dd9..709a4f80 100644
--- a/contracts/modules/0_CMTATBaseCommon.sol
+++ b/contracts/modules/0_CMTATBaseCommon.sol
@@ -11,12 +11,9 @@ import {ERC20MintModule, ERC20MintModuleInternal} from "./wrapper/core/ERC20Mint
// Extensions
import {ExtraInformationModule} from "./wrapper/extensions/ExtraInformationModule.sol";
import {ERC20EnforcementModule, ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
-import {DocumentEngineModule, IERC1643} from "./wrapper/extensions/DocumentEngineModule.sol";
-import {SnapshotEngineModule} from "./wrapper/extensions/SnapshotEngineModule.sol";
// options
import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol";
/* ==== Interface and other library === */
-import {ISnapshotEngine} from "../interfaces/engine/ISnapshotEngine.sol";
import {IBurnMintERC20} from "../interfaces/technical/IMintBurnToken.sol";
import {IERC5679} from "../interfaces/technical/IERC5679.sol";
@@ -27,9 +24,7 @@ abstract contract CMTATBaseCommon is
ERC20BurnModule,
ERC20BaseModule,
// Extension
- SnapshotEngineModule,
ERC20EnforcementModule,
- DocumentEngineModule,
ExtraInformationModule,
// Interfaces
IBurnMintERC20,
@@ -79,7 +74,7 @@ abstract contract CMTATBaseCommon is
ERC20Upgradeable._transfer(from, to, value);
return true;
}
- /*
+ /**
* @inheritdoc ERC20BaseModule
*/
function transferFrom(
@@ -120,35 +115,6 @@ abstract contract CMTATBaseCommon is
function _checkTransferred(address /*spender*/, address from, address /* to */, uint256 value) internal virtual {
ERC20EnforcementModuleInternal._checkActiveBalanceAndRevert(from, value);
}
- /**
- * @dev we don't check the transfer validity here
- *
- *
- */
- function _update(
- address from,
- address to,
- uint256 amount
- ) internal virtual override(ERC20Upgradeable) {
- // We check here the address of the snapshotEngine here because we don't want to read balance/totalSupply if there is no Snapshot Engine
- ISnapshotEngine snapshotEngineLocal = snapshotEngine();
-
- if(address(snapshotEngineLocal) != address(0)){
- uint256 fromBalanceBefore = balanceOf(from);
- uint256 toBalanceBefore = balanceOf(to);
- uint256 totalSupplyBefore = totalSupply();
-
- // We perform the update here (CEI pattern)
- ERC20Upgradeable._update(from, to, amount);
-
- // Required to use the balance before the update
- snapshotEngineLocal.operateOnTransfer(from, to, fromBalanceBefore, toBalanceBefore, totalSupplyBefore);
- } else {
- // Update without snapshot call
- ERC20Upgradeable._update(from, to, amount);
- }
- }
-
/* ==== Mint and Burn Operations ==== */
/**
@@ -157,7 +123,7 @@ abstract contract CMTATBaseCommon is
* Check if the mint is valid
*/
function _mintOverride(address account, uint256 value) internal virtual override(ERC20MintModuleInternal) {
- _checkTransferred(address(0), address(0), account, value);
+ _checkTransferred(_msgSender(), address(0), account, value);
ERC20MintModuleInternal._mintOverride(account, value);
}
@@ -167,7 +133,7 @@ abstract contract CMTATBaseCommon is
* Check if the burn is valid
*/
function _burnOverride(address account, uint256 value) internal virtual override(ERC20BurnModuleInternal) {
- _checkTransferred(address(0), account, address(0), value);
+ _checkTransferred(_msgSender(), account, address(0), value);
ERC20BurnModuleInternal._burnOverride(account, value);
}
@@ -177,7 +143,7 @@ abstract contract CMTATBaseCommon is
* Check if a minter transfer is valid
*/
function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(ERC20MintModuleInternal) {
- _checkTransferred(address(0), from, to, value);
+ _checkTransferred(_msgSender(), from, to, value);
ERC20MintModuleInternal._minterTransferOverride(from, to, value);
}
}
diff --git a/contracts/modules/0_CMTATBaseCore.sol b/contracts/modules/0_CMTATBaseCore.sol
index bfb5d92a..69164a30 100644
--- a/contracts/modules/0_CMTATBaseCore.sol
+++ b/contracts/modules/0_CMTATBaseCore.sol
@@ -16,7 +16,8 @@ import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.
import {VersionModule} from "./wrapper/core/VersionModule.sol";
import {PauseModule} from "./wrapper/core/PauseModule.sol";
import {EnforcementModule} from "./wrapper/core/EnforcementModule.sol";
-import {ValidationModule, ValidationModuleCore} from "./wrapper/core/ValidationModuleCore.sol";
+import {ValidationModule} from "./wrapper/core/ValidationModuleCore.sol";
+import {ValidationModuleAllowance} from "./wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol";
// Security
import {AccessControlModule, AccessControlUpgradeable} from "./wrapper/security/AccessControlModule.sol";
@@ -40,7 +41,7 @@ abstract contract CMTATBaseCore is
// Core
ERC20MintModule,
ERC20BurnModule,
- ValidationModuleCore,
+ ValidationModuleAllowance,
ERC20BaseModule,
AccessControlModule,
IForcedBurnERC20,
@@ -144,14 +145,14 @@ abstract contract CMTATBaseCore is
}
- /*
+ /**
* @inheritdoc ERC20BaseModule
*/
function name() public virtual override(ERC20Upgradeable, ERC20BaseModule) view returns (string memory) {
return ERC20BaseModule.name();
}
- /*
+ /**
* @inheritdoc ERC20BaseModule
*/
function symbol() public virtual override(ERC20Upgradeable, ERC20BaseModule) view returns (string memory) {
@@ -163,10 +164,11 @@ abstract contract CMTATBaseCore is
* @dev
* We can not use type(IERC5679).interfaceId, we use instead of 0xd0017968
* because IERC5679 inherits from two interfaces (IERC5679Burn and Mint)
- * Core version does not implement in its integrality ERC-7943 (0x29388973)
+ * Core version does not implement in its integrality ERC-7943 (0x3edbb4c4)
+ * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) {
- return interfaceId == 0xd0017968 || AccessControlUpgradeable.supportsInterface(interfaceId);
+ return interfaceId == 0xd0017968 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId);
}
/* ============ State Functions ============ */
@@ -179,6 +181,14 @@ abstract contract CMTATBaseCore is
ERC20Upgradeable._transfer(from, to, value);
return true;
}
+
+ /*
+ * @inheritdoc ERC20Upgradeable
+ */
+ function approve(address spender, uint256 value) public virtual override returns (bool) {
+ _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender);
+ return ERC20Upgradeable.approve(spender, value);
+ }
/*
* @inheritdoc ERC20BaseModule
*/
@@ -227,7 +237,7 @@ abstract contract CMTATBaseCore is
require(EnforcementModule.isFrozen(account), CMTAT_BurnEnforcement_AddressIsNotFrozen());
// Skip ERC20BurnModule
ERC20Upgradeable._burn(account, value);
- emit Enforcement(_msgSender(), account, value, data);
+ emit ForcedTransfer(_msgSender(), account, address(0), value, data);
}
/*//////////////////////////////////////////////////////////////
@@ -236,13 +246,13 @@ abstract contract CMTATBaseCore is
/* ==== Mint and Burn Operations ==== */
function _mintOverride(address account, uint256 value) internal virtual override(ERC20MintModuleInternal) {
- ValidationModule._canMintBurnByModuleAndRevert(account);
+ ValidationModule._canMintByModuleAndRevert(account);
ERC20MintModuleInternal._mintOverride(account, value);
}
function _burnOverride(address account, uint256 value) internal virtual override(ERC20BurnModuleInternal) {
- ValidationModule._canMintBurnByModuleAndRevert(account);
+ ValidationModule._canBurnByModuleAndRevert(account);
ERC20BurnModuleInternal._burnOverride(account, value);
}
diff --git a/contracts/modules/0_CMTATBaseGeneric.sol b/contracts/modules/0_CMTATBaseGeneric.sol
index 7474a07c..8a517bb5 100644
--- a/contracts/modules/0_CMTATBaseGeneric.sol
+++ b/contracts/modules/0_CMTATBaseGeneric.sol
@@ -9,12 +9,12 @@ import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/Cont
import {ValidationModule} from "./wrapper/controllers/ValidationModule.sol";
/* ==== Wrapper === */
// Security
-import {AccessControlModule, AccessControlUpgradeable} from "./wrapper/security/AccessControlModule.sol";
+import {AccessControlModule} from "./wrapper/security/AccessControlModule.sol";
// Core
import {VersionModule} from "./wrapper/core/VersionModule.sol";
// Extensions
import {ExtraInformationModule} from "./wrapper/extensions/ExtraInformationModule.sol";
-import {DocumentEngineModule, IERC1643} from "./wrapper/extensions/DocumentEngineModule.sol";
+import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol";
/* ==== Interface and other library === */
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
@@ -30,7 +30,7 @@ abstract contract CMTATBaseGeneric is
// Core
VersionModule,
// Extension
- DocumentEngineModule,
+ DocumentERC1643Module,
ExtraInformationModule,
AccessControlModule
{
@@ -83,6 +83,6 @@ abstract contract CMTATBaseGeneric is
//////////////////////////////////////////////////////////////*/
/* ==== Access Control ==== */
- function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) onlyRole(DOCUMENT_ROLE){}
+ function _authorizeDocumentManagement() internal virtual override(DocumentERC1643Module) onlyRole(DOCUMENT_ROLE){}
function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) onlyRole(EXTRA_INFORMATION_ROLE){}
}
diff --git a/contracts/modules/0_CMTATBaseSnapshot.sol b/contracts/modules/0_CMTATBaseSnapshot.sol
new file mode 100644
index 00000000..343bb87d
--- /dev/null
+++ b/contracts/modules/0_CMTATBaseSnapshot.sol
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+/* ==== OpenZeppelin === */
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+/* ==== Wrapper === */
+import {SnapshotEngineModule} from "./wrapper/extensions/SnapshotEngineModule.sol";
+/* ==== Interface === */
+import {ISnapshotEngine} from "../interfaces/engine/ISnapshotEngine.sol";
+
+/**
+* @title Snapshot engine mixin
+* @dev Pure mixin: provides _update logic with snapshot engine integration.
+* Access control for setSnapshotEngine (_authorizeSnapshots) is left abstract
+* and must be implemented by the inheriting contract.
+*/
+abstract contract CMTATBaseSnapshot is ERC20Upgradeable, SnapshotEngineModule {
+ function _update(address from, address to, uint256 amount) internal virtual override(ERC20Upgradeable) {
+ ISnapshotEngine snapshotEngineLocal = snapshotEngine();
+ if (address(snapshotEngineLocal) != address(0)) {
+ uint256 fromBalanceBefore = balanceOf(from);
+ uint256 toBalanceBefore = balanceOf(to);
+ uint256 totalSupplyBefore = totalSupply();
+ ERC20Upgradeable._update(from, to, amount);
+ snapshotEngineLocal.operateOnTransfer(from, to, fromBalanceBefore, toBalanceBefore, totalSupplyBefore);
+ } else {
+ ERC20Upgradeable._update(from, to, amount);
+ }
+ }
+}
diff --git a/contracts/modules/1_CMTATBaseDocument.sol b/contracts/modules/1_CMTATBaseDocument.sol
new file mode 100644
index 00000000..f428819e
--- /dev/null
+++ b/contracts/modules/1_CMTATBaseDocument.sol
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol";
+
+/**
+ * @title Level-1 base with document management
+ */
+abstract contract CMTATBaseDocument is DocumentERC1643Module {}
diff --git a/contracts/modules/1_CMTATBaseAccessControl.sol b/contracts/modules/2_CMTATBaseAccessControl.sol
similarity index 83%
rename from contracts/modules/1_CMTATBaseAccessControl.sol
rename to contracts/modules/2_CMTATBaseAccessControl.sol
index fe4e4757..4d49e936 100644
--- a/contracts/modules/1_CMTATBaseAccessControl.sol
+++ b/contracts/modules/2_CMTATBaseAccessControl.sol
@@ -13,17 +13,19 @@ import {ERC20MintModule} from "./wrapper/core/ERC20MintModule.sol";
// Extensions
import {ExtraInformationModule} from "./wrapper/extensions/ExtraInformationModule.sol";
import {ERC20EnforcementModule} from "./wrapper/extensions/ERC20EnforcementModule.sol";
-import {DocumentEngineModule, IERC1643} from "./wrapper/extensions/DocumentEngineModule.sol";
-import {SnapshotEngineModule} from "./wrapper/extensions/SnapshotEngineModule.sol";
+import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol";
// options
-import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol";
+import {ERC20BaseModule} from "./wrapper/core/ERC20BaseModule.sol";
/* ==== Interface and other library === */
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
+import {CMTATBaseDocument} from "./1_CMTATBaseDocument.sol";
abstract contract CMTATBaseAccessControl is
AccessControlModule,
- CMTATBaseCommon
+ CMTATBaseCommon,
+ CMTATBaseDocument
{
+
/*//////////////////////////////////////////////////////////////
INITIALIZER FUNCTION
//////////////////////////////////////////////////////////////*/
@@ -44,10 +46,11 @@ abstract contract CMTATBaseAccessControl is
* @dev
* We can not use type(IERC5679).interfaceId instead of 0xd0017968
* because IERC5679 inherits from two interfaces (IERC5679Burn and Mint)
- * 0x29388973 is the interfaceId of ERC-7943
+ * 0x3edbb4c4 is the interfaceId of ERC-7943
+ * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) {
- return interfaceId == 0xd0017968 || interfaceId == 0x29388973 || AccessControlUpgradeable.supportsInterface(interfaceId);
+ return interfaceId == 0xd0017968 || interfaceId == 0x3edbb4c4 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId);
}
@@ -78,7 +81,7 @@ abstract contract CMTATBaseAccessControl is
* @custom:access-control
* - the caller must have the `DOCUMENT_ROLE`.
*/
- function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) onlyRole(DOCUMENT_ROLE){}
+ function _authorizeDocumentManagement() internal virtual override(DocumentERC1643Module) onlyRole(DOCUMENT_ROLE){}
/**
* @custom:access-control
@@ -98,9 +101,4 @@ abstract contract CMTATBaseAccessControl is
*/
function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) onlyRole(DEFAULT_ADMIN_ROLE){}
- /**
- * @custom:access-control
- * - the caller must have the `SNAPSHOOTER_ROLE`.
- */
- function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE){}
}
diff --git a/contracts/modules/2_CMTATBaseAllowlist.sol b/contracts/modules/3_CMTATBaseAllowlist.sol
similarity index 76%
rename from contracts/modules/2_CMTATBaseAllowlist.sol
rename to contracts/modules/3_CMTATBaseAllowlist.sol
index 061c0180..3cae7a8c 100644
--- a/contracts/modules/2_CMTATBaseAllowlist.sol
+++ b/contracts/modules/3_CMTATBaseAllowlist.sol
@@ -9,18 +9,20 @@ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/
/* ==== Wrapper === */
// Base
import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
-import {CMTATBaseAccessControl} from "./1_CMTATBaseAccessControl.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
// Core
import {PauseModule} from "./wrapper/core/PauseModule.sol";
import {EnforcementModule} from "./wrapper/core/EnforcementModule.sol";
// Extensions
import {ERC20EnforcementModule, ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
+import {ERC20EnforcementERC7551Module} from "./wrapper/options/ERC20EnforcementERC7551Module.sol";
// options
import {ERC2771Module, ERC2771ContextUpgradeable} from "./wrapper/options/ERC2771Module.sol";
import {AllowlistModule} from "./wrapper/options/AllowlistModule.sol";
// controller
import {ValidationModuleAllowlist} from "./wrapper/controllers/ValidationModuleAllowlist.sol";
import {ValidationModule, ValidationModuleCore} from "./wrapper/core/ValidationModuleCore.sol";
+import {ValidationModuleAllowance} from "./wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol";
/* ==== Interface and other library === */
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
import {IERC7943FungibleTransferError} from "../interfaces/tokenization/draft-IERC7943.sol";
@@ -31,8 +33,9 @@ abstract contract CMTATBaseAllowlist is
// Core
CMTATBaseAccessControl,
ValidationModuleAllowlist,
- ValidationModuleCore,
+ ValidationModuleAllowance,
ERC2771Module,
+ ERC20EnforcementERC7551Module,
IERC7943FungibleTransferError
{
/*//////////////////////////////////////////////////////////////
@@ -117,9 +120,58 @@ abstract contract CMTATBaseAllowlist is
* if strict control over the total amount a spender can consume is required.
*/
function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) {
+ _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender);
return ERC20Upgradeable.approve(spender, value);
}
+ function transfer(address to, uint256 value)
+ public
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (bool)
+ {
+ return CMTATBaseCommon.transfer(to, value);
+ }
+
+ function transferFrom(address from, address to, uint256 value)
+ public
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (bool)
+ {
+ return CMTATBaseCommon.transferFrom(from, to, value);
+ }
+
+ function decimals()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (uint8)
+ {
+ return CMTATBaseCommon.decimals();
+ }
+
+ function name()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (string memory)
+ {
+ return CMTATBaseCommon.name();
+ }
+
+ function symbol()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (string memory)
+ {
+ return CMTATBaseCommon.symbol();
+ }
+
/**
* @inheritdoc ValidationModuleCore
*/
@@ -165,6 +217,12 @@ abstract contract CMTATBaseAllowlist is
function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}
function _authorizeAllowlistManagement() internal virtual override(AllowlistModule) onlyRole(ALLOWLIST_ROLE) {}
+ function _authorizeERC20Enforcer() internal virtual override(CMTATBaseAccessControl, ERC20EnforcementModule) {
+ CMTATBaseAccessControl._authorizeERC20Enforcer();
+ }
+ function _authorizeForcedTransfer() internal virtual override(CMTATBaseAccessControl, ERC20EnforcementModule) {
+ CMTATBaseAccessControl._authorizeForcedTransfer();
+ }
/* ==== Transfer/mint/burn restriction ==== */
/**
@@ -176,15 +234,25 @@ abstract contract CMTATBaseAllowlist is
return ValidationModuleAllowlist._canMintBurnByModule(account);
}
- function _canMintBurnByModuleAndRevert(
- address account
+ function _canMintByModuleAndRevert(
+ address to
+ ) internal view virtual override(ValidationModuleAllowlist, ValidationModule) {
+ ValidationModuleAllowlist._canMintByModuleAndRevert(to);
+ }
+
+ function _canBurnByModuleAndRevert(
+ address from
) internal view virtual override(ValidationModuleAllowlist, ValidationModule) {
- ValidationModuleAllowlist._canMintBurnByModuleAndRevert(account);
+ ValidationModuleAllowlist._canBurnByModuleAndRevert(from);
+ }
+
+ function _canSend(address account) internal view virtual override(ValidationModuleAllowlist, ValidationModule) returns (bool allowed) {
+ return ValidationModuleAllowlist._canSend(account);
}
- function _canTransact(address account) internal view virtual override(ValidationModuleAllowlist, ValidationModule) returns (bool allowed) {
- return ValidationModuleAllowlist._canTransact(account);
- }
+ function _canReceive(address account) internal view virtual override(ValidationModuleAllowlist, ValidationModule) returns (bool allowed) {
+ return ValidationModuleAllowlist._canReceive(account);
+ }
function _canTransferStandardByModule(
address spender,
@@ -207,6 +275,16 @@ abstract contract CMTATBaseAllowlist is
ValidationModule._canTransferGenericByModuleAndRevert(spender, from, to);
}
+ function getFrozenTokens(address account)
+ public
+ view
+ virtual
+ override(ERC20EnforcementModule, ERC20EnforcementERC7551Module)
+ returns (uint256 frozenBalance_)
+ {
+ return ERC20EnforcementERC7551Module.getFrozenTokens(account);
+ }
+
/*//////////////////////////////////////////////////////////////
METAXTX MODULE
diff --git a/contracts/modules/3_CMTATBaseDebt.sol b/contracts/modules/3_CMTATBaseDebt.sol
deleted file mode 100644
index 24ae503c..00000000
--- a/contracts/modules/3_CMTATBaseDebt.sol
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: MPL-2.0
-
-pragma solidity ^0.8.20;
-/* ==== Module === */
-import {DebtModule} from "./wrapper/options/DebtModule.sol";
-import {CMTATBaseRuleEngine} from "./2_CMTATBaseRuleEngine.sol";
-/**
-* @title Extend CMTAT Base with option modules
-*/
-abstract contract CMTATBaseDebt is CMTATBaseRuleEngine, DebtModule {
- function _authorizeDebtManagement() internal virtual override(DebtModule) onlyRole(DEBT_ROLE){}
-}
diff --git a/contracts/modules/2_CMTATBaseRuleEngine.sol b/contracts/modules/3_CMTATBaseRuleEngine.sol
similarity index 96%
rename from contracts/modules/2_CMTATBaseRuleEngine.sol
rename to contracts/modules/3_CMTATBaseRuleEngine.sol
index 3957f313..b1220581 100644
--- a/contracts/modules/2_CMTATBaseRuleEngine.sol
+++ b/contracts/modules/3_CMTATBaseRuleEngine.sol
@@ -7,11 +7,11 @@ import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
/* ==== Wrapper === */
// Core
-import {CMTATBaseAccessControl} from "./1_CMTATBaseAccessControl.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
import {PauseModule} from "./wrapper/core/PauseModule.sol";
import {EnforcementModule} from "./wrapper/core/EnforcementModule.sol";
// Extensions
-import {ERC20EnforcementModule, ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
+import {ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
// Controllers
import {ValidationModuleRuleEngine} from "./wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
@@ -126,6 +126,7 @@ abstract contract CMTATBaseRuleEngine is
* @dev revert if the contract is in pause state
*/
function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) {
+ _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender);
return ERC20Upgradeable.approve(spender, value);
}
/**
diff --git a/contracts/modules/4_CMTATBaseDebt.sol b/contracts/modules/4_CMTATBaseDebt.sol
new file mode 100644
index 00000000..50c23149
--- /dev/null
+++ b/contracts/modules/4_CMTATBaseDebt.sol
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+/* ==== OpenZeppelin === */
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+/* ==== Module === */
+import {DebtModule} from "./wrapper/options/DebtModule.sol";
+import {CMTATBaseRuleEngine} from "./3_CMTATBaseRuleEngine.sol";
+import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
+import {CMTATBaseSnapshot} from "./0_CMTATBaseSnapshot.sol";
+import {SnapshotEngineModule} from "./wrapper/extensions/SnapshotEngineModule.sol";
+/**
+* @title Extend CMTAT Base with option modules
+*/
+abstract contract CMTATBaseDebt is CMTATBaseRuleEngine, DebtModule, CMTATBaseSnapshot {
+ function approve(address spender, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseRuleEngine) returns (bool)
+ {
+ return CMTATBaseRuleEngine.approve(spender, value);
+ }
+
+ function transfer(address to, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (bool)
+ {
+ return CMTATBaseCommon.transfer(to, value);
+ }
+
+ function transferFrom(address from, address to, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (bool)
+ {
+ return CMTATBaseCommon.transferFrom(from, to, value);
+ }
+
+ function decimals()
+ public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (uint8)
+ {
+ return CMTATBaseCommon.decimals();
+ }
+
+ function name()
+ public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory)
+ {
+ return CMTATBaseCommon.name();
+ }
+
+ function symbol()
+ public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory)
+ {
+ return CMTATBaseCommon.symbol();
+ }
+
+ function _update(address from, address to, uint256 amount)
+ internal virtual override(ERC20Upgradeable, CMTATBaseSnapshot)
+ {
+ CMTATBaseSnapshot._update(from, to, amount);
+ }
+
+ function _authorizeDebtManagement() internal virtual override(DebtModule) onlyRole(DEBT_ROLE){}
+
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+}
diff --git a/contracts/modules/3_CMTATBaseERC1404.sol b/contracts/modules/4_CMTATBaseERC1404.sol
similarity index 81%
rename from contracts/modules/3_CMTATBaseERC1404.sol
rename to contracts/modules/4_CMTATBaseERC1404.sol
index 3d27b834..e25c9a0f 100644
--- a/contracts/modules/3_CMTATBaseERC1404.sol
+++ b/contracts/modules/4_CMTATBaseERC1404.sol
@@ -2,14 +2,14 @@
pragma solidity ^0.8.20;
-import {CMTATBaseRuleEngine} from "./2_CMTATBaseRuleEngine.sol";
+import {CMTATBaseRuleEngine} from "./3_CMTATBaseRuleEngine.sol";
/* ==== Wrapper === */
// Use by detectTransferRestriction
-import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol";
+import {ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol";
// Extensions
-import {ERC20EnforcementModule, ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
+import {ERC20EnforcementModule} from "./wrapper/extensions/ERC20EnforcementModule.sol";
// Controllers
-import {ValidationModuleERC1404, IERC1404, IERC1404Extend} from "./wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol";
+import {ValidationModuleERC1404, IERC1404Extend} from "./wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol";
import {ValidationModuleRuleEngine} from "./wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
abstract contract CMTATBaseERC1404 is
@@ -72,7 +72,11 @@ abstract contract CMTATBaseERC1404 is
) internal virtual override( ValidationModuleERC1404) view returns (uint8 code) {
uint256 frozenTokensLocal = ERC20EnforcementModule.getFrozenTokens(from);
if(frozenTokensLocal > 0 ){
- uint256 activeBalance = ERC20Upgradeable.balanceOf(from) - frozenTokensLocal;
+ uint256 balance = ERC20Upgradeable.balanceOf(from);
+ if (frozenTokensLocal >= balance) {
+ return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE);
+ }
+ uint256 activeBalance = balance - frozenTokensLocal;
if(value > activeBalance) {
return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE);
}
diff --git a/contracts/modules/5_CMTATBaseDebtEngine.sol b/contracts/modules/5_CMTATBaseDebtEngine.sol
deleted file mode 100644
index 7b2c3208..00000000
--- a/contracts/modules/5_CMTATBaseDebtEngine.sol
+++ /dev/null
@@ -1,12 +0,0 @@
-// SPDX-License-Identifier: MPL-2.0
-
-pragma solidity ^0.8.20;
-/* ==== Module === */
-import {DebtEngineModule} from "./wrapper/options/DebtEngineModule.sol";
-import {CMTATBaseERC20CrossChain} from "./4_CMTATBaseERC20CrossChain.sol";
-/**
-* @title Extend CMTAT Base with option modules
-*/
-abstract contract CMTATBaseDebtEngine is DebtEngineModule, CMTATBaseERC20CrossChain {
- function _authorizeDebtEngineManagement() internal virtual override(DebtEngineModule) onlyRole(DEBT_ENGINE_ROLE){}
-}
\ No newline at end of file
diff --git a/contracts/modules/4_CMTATBaseERC20CrossChain.sol b/contracts/modules/5_CMTATBaseERC20CrossChain.sol
similarity index 90%
rename from contracts/modules/4_CMTATBaseERC20CrossChain.sol
rename to contracts/modules/5_CMTATBaseERC20CrossChain.sol
index 68e9ef5e..569cb8cd 100644
--- a/contracts/modules/4_CMTATBaseERC20CrossChain.sol
+++ b/contracts/modules/5_CMTATBaseERC20CrossChain.sol
@@ -4,11 +4,11 @@ pragma solidity ^0.8.20;
/* ==== OpenZeppelin === */
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
/* ==== Module === */
-import {CMTATBaseERC1404, CMTATBaseRuleEngine, ERC20Upgradeable} from "./3_CMTATBaseERC1404.sol";
-import {CMTATBaseAccessControl} from "./1_CMTATBaseAccessControl.sol";
+import {CMTATBaseERC1404, CMTATBaseRuleEngine, ERC20Upgradeable} from "./4_CMTATBaseERC1404.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
-import {ERC20BurnModule, ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol";
-import {ERC20MintModule, ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol";
+import {ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol";
+import {ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol";
import {ERC20CrossChainModule} from "./wrapper/options/ERC20CrossChainModule.sol";
import {CCIPModule} from "./wrapper/options/CCIPModule.sol";
@@ -139,12 +139,4 @@ abstract contract CMTATBaseERC20CrossChain is ERC20CrossChainModule, CCIPModule,
*/
function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{}
- /* ==== ERC-20 OpenZeppelin ==== */
- function _update(
- address from,
- address to,
- uint256 amount
- ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) {
- return CMTATBaseCommon._update(from, to, amount);
- }
-}
\ No newline at end of file
+}
diff --git a/contracts/modules/6_CMTATBaseDebtEngine.sol b/contracts/modules/6_CMTATBaseDebtEngine.sol
new file mode 100644
index 00000000..417cfef4
--- /dev/null
+++ b/contracts/modules/6_CMTATBaseDebtEngine.sol
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+/* ==== OpenZeppelin === */
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+/* ==== Module === */
+import {DebtEngineModule} from "./wrapper/options/DebtEngineModule.sol";
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseSnapshot} from "./0_CMTATBaseSnapshot.sol";
+import {SnapshotEngineModule} from "./wrapper/extensions/SnapshotEngineModule.sol";
+
+/**
+* @title Extend CMTAT Base with DebtEngine module and snapshot engine support
+*/
+abstract contract CMTATBaseDebtEngine is DebtEngineModule, CMTATBaseERC20CrossChain, CMTATBaseSnapshot {
+
+ /*//////////////////////////////////////////////////////////////
+ ERC-20 / CMTATBaseSnapshot disambiguation
+ //////////////////////////////////////////////////////////////*/
+
+ function _update(address from, address to, uint256 amount)
+ internal virtual override(ERC20Upgradeable, CMTATBaseSnapshot)
+ {
+ CMTATBaseSnapshot._update(from, to, amount);
+ }
+
+ function transfer(address to, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.transfer(to, value);
+ }
+
+ function transferFrom(address from, address to, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ }
+
+ function approve(address spender, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.approve(spender, value);
+ }
+
+ function decimals()
+ public view virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (uint8)
+ {
+ return CMTATBaseERC20CrossChain.decimals();
+ }
+
+ function name()
+ public view virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (string memory)
+ {
+ return CMTATBaseERC20CrossChain.name();
+ }
+
+ function symbol()
+ public view virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (string memory)
+ {
+ return CMTATBaseERC20CrossChain.symbol();
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ Access Control
+ //////////////////////////////////////////////////////////////*/
+
+ function _authorizeDebtEngineManagement() internal virtual override(DebtEngineModule) onlyRole(DEBT_ENGINE_ROLE) {}
+
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+}
diff --git a/contracts/modules/6_CMTATBaseERC2612.sol b/contracts/modules/6_CMTATBaseERC2612.sol
new file mode 100644
index 00000000..24aa1350
--- /dev/null
+++ b/contracts/modules/6_CMTATBaseERC2612.sol
@@ -0,0 +1,130 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+/* ==== OpenZeppelin === */
+import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {MulticallUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol";
+/* ==== Module === */
+import {CMTATBaseERC20CrossChain, CMTATBaseRuleEngine} from "./5_CMTATBaseERC20CrossChain.sol";
+/* ==== Interface and other library === */
+import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
+
+/**
+* @title Extend CMTAT Base with ERC-2612 Permit and Multicall
+*/
+abstract contract CMTATBaseERC2612 is CMTATBaseERC20CrossChain, ERC20PermitUpgradeable, MulticallUpgradeable {
+ /*//////////////////////////////////////////////////////////////
+ INITIALIZER FUNCTION
+ //////////////////////////////////////////////////////////////*/
+ /**
+ * @dev initializer function
+ */
+ function __CMTAT_openzeppelin_init_unchained(
+ ICMTATConstructor.ERC20Attributes memory ERC20Attributes_
+ ) internal virtual override onlyInitializing {
+ CMTATBaseRuleEngine.__CMTAT_openzeppelin_init_unchained(ERC20Attributes_);
+ __EIP712_init_unchained(ERC20Attributes_.name, "1");
+ __ERC20Permit_init_unchained(ERC20Attributes_.name);
+ __Multicall_init_unchained();
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ PUBLIC/EXTERNAL FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+ /**
+ * @inheritdoc ERC20PermitUpgradeable
+ * @dev Reverts if the contract is paused or if owner/spender is frozen.
+ */
+ function permit(
+ address owner,
+ address spender,
+ uint256 value,
+ uint256 deadline,
+ uint8 v,
+ bytes32 r,
+ bytes32 s
+ ) public virtual override(ERC20PermitUpgradeable) {
+ _canAuthorizeAllowanceByModuleAndRevert(owner, spender);
+ ERC20PermitUpgradeable.permit(owner, spender, value, deadline, v, r, s);
+ }
+
+ /* ============ State functions ============ */
+ /**
+ * @dev revert if the contract is in pause state
+ */
+ function approve(
+ address spender,
+ uint256 value
+ ) public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (bool) {
+ return CMTATBaseERC20CrossChain.approve(spender, value);
+ }
+
+ /**
+ * @inheritdoc CMTATBaseERC20CrossChain
+ */
+ function transfer(
+ address to,
+ uint256 value
+ ) public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (bool) {
+ return CMTATBaseERC20CrossChain.transfer(to, value);
+ }
+
+ /**
+ * @inheritdoc CMTATBaseERC20CrossChain
+ */
+ function transferFrom(
+ address sender,
+ address recipient,
+ uint256 amount
+ )
+ public
+ virtual
+ override(ERC20Upgradeable, CMTATBaseERC20CrossChain)
+ returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.transferFrom(sender, recipient, amount);
+ }
+
+ /* ============ View functions ============ */
+ /**
+ * @inheritdoc CMTATBaseERC20CrossChain
+ */
+ function decimals()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseERC20CrossChain)
+ returns (uint8)
+ {
+ return CMTATBaseERC20CrossChain.decimals();
+ }
+
+ /**
+ * @inheritdoc CMTATBaseERC20CrossChain
+ */
+ function name()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseERC20CrossChain)
+ returns (string memory)
+ {
+ return CMTATBaseERC20CrossChain.name();
+ }
+
+ /**
+ * @inheritdoc CMTATBaseERC20CrossChain
+ */
+ function symbol()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseERC20CrossChain)
+ returns (string memory)
+ {
+ return CMTATBaseERC20CrossChain.symbol();
+ }
+
+}
diff --git a/contracts/modules/5_CMTATBaseERC2771.sol b/contracts/modules/6_CMTATBaseERC2771.sol
similarity index 96%
rename from contracts/modules/5_CMTATBaseERC2771.sol
rename to contracts/modules/6_CMTATBaseERC2771.sol
index 4b551884..6c41d13d 100644
--- a/contracts/modules/5_CMTATBaseERC2771.sol
+++ b/contracts/modules/6_CMTATBaseERC2771.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.20;
/* ==== OpenZeppelin === */
import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
/* ==== Module === */
-import {CMTATBaseERC20CrossChain} from "./4_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
import {ERC2771Module, ERC2771ContextUpgradeable} from "./wrapper/options/ERC2771Module.sol";
/**
* @title Extend CMTAT Base with ERC2771Module
diff --git a/contracts/modules/7_CMTATBaseERC2771Snapshot.sol b/contracts/modules/7_CMTATBaseERC2771Snapshot.sol
new file mode 100644
index 00000000..1d0499ac
--- /dev/null
+++ b/contracts/modules/7_CMTATBaseERC2771Snapshot.sol
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {CMTATBaseERC2771} from "./6_CMTATBaseERC2771.sol";
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseSnapshot} from "./0_CMTATBaseSnapshot.sol";
+import {SnapshotEngineModule} from "./wrapper/extensions/SnapshotEngineModule.sol";
+
+/**
+* @title Extend CMTATBaseERC2771 with snapshot engine support
+*/
+abstract contract CMTATBaseERC2771Snapshot is CMTATBaseERC2771, CMTATBaseSnapshot {
+
+ /*//////////////////////////////////////////////////////////////
+ ERC-20 / CMTATBaseSnapshot disambiguation
+ //////////////////////////////////////////////////////////////*/
+
+ function _update(address from, address to, uint256 amount)
+ internal virtual override(ERC20Upgradeable, CMTATBaseSnapshot)
+ {
+ CMTATBaseSnapshot._update(from, to, amount);
+ }
+
+ function transfer(address to, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.transfer(to, value);
+ }
+
+ function transferFrom(address from, address to, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ }
+
+ function approve(address spender, uint256 value)
+ public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.approve(spender, value);
+ }
+
+ function decimals()
+ public view virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (uint8)
+ {
+ return CMTATBaseERC20CrossChain.decimals();
+ }
+
+ function name()
+ public view virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (string memory)
+ {
+ return CMTATBaseERC20CrossChain.name();
+ }
+
+ function symbol()
+ public view virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) returns (string memory)
+ {
+ return CMTATBaseERC20CrossChain.symbol();
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ ERC2771 / Context disambiguation
+ //////////////////////////////////////////////////////////////*/
+
+ function _msgSender()
+ internal virtual view override(CMTATBaseERC2771, ContextUpgradeable) returns (address sender)
+ {
+ return CMTATBaseERC2771._msgSender();
+ }
+
+ function _msgData()
+ internal virtual view override(CMTATBaseERC2771, ContextUpgradeable) returns (bytes calldata)
+ {
+ return CMTATBaseERC2771._msgData();
+ }
+
+ function _contextSuffixLength()
+ internal virtual view override(CMTATBaseERC2771, ContextUpgradeable) returns (uint256)
+ {
+ return CMTATBaseERC2771._contextSuffixLength();
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ Access Control
+ //////////////////////////////////////////////////////////////*/
+
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+}
diff --git a/contracts/modules/7_CMTATBaseERC7551Enforcement.sol b/contracts/modules/7_CMTATBaseERC7551Enforcement.sol
new file mode 100644
index 00000000..fc81586b
--- /dev/null
+++ b/contracts/modules/7_CMTATBaseERC7551Enforcement.sol
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+/* ==== OpenZeppelin === */
+import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+/* ==== Module === */
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseERC2771} from "./6_CMTATBaseERC2771.sol";
+import {ERC20EnforcementModule, ERC20EnforcementERC7551Module} from "./wrapper/options/ERC20EnforcementERC7551Module.sol";
+
+/**
+ * @title Extend CMTAT standard path with ERC-7551 enforcement functions
+ */
+abstract contract CMTATBaseERC7551Enforcement is CMTATBaseERC2771, ERC20EnforcementERC7551Module {
+ /*//////////////////////////////////////////////////////////////
+ ACCESS CONTROL
+ //////////////////////////////////////////////////////////////*/
+ function _authorizeERC20Enforcer() internal virtual override(CMTATBaseAccessControl, ERC20EnforcementModule) {
+ CMTATBaseAccessControl._authorizeERC20Enforcer();
+ }
+
+ function _authorizeForcedTransfer() internal virtual override(CMTATBaseAccessControl, ERC20EnforcementModule) {
+ CMTATBaseAccessControl._authorizeForcedTransfer();
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ ERC2771 / CONTEXT DISAMBIGUATION
+ //////////////////////////////////////////////////////////////*/
+ function _msgSender()
+ internal virtual view
+ override(CMTATBaseERC2771, ContextUpgradeable)
+ returns (address sender)
+ {
+ return CMTATBaseERC2771._msgSender();
+ }
+
+ function _msgData()
+ internal virtual view
+ override(CMTATBaseERC2771, ContextUpgradeable)
+ returns (bytes calldata)
+ {
+ return CMTATBaseERC2771._msgData();
+ }
+
+ function _contextSuffixLength()
+ internal virtual view
+ override(CMTATBaseERC2771, ContextUpgradeable)
+ returns (uint256)
+ {
+ return CMTATBaseERC2771._contextSuffixLength();
+ }
+
+ /*//////////////////////////////////////////////////////////////
+ ERC-20 DISAMBIGUATION
+ //////////////////////////////////////////////////////////////*/
+ function transfer(address to, uint256 value)
+ public virtual
+ override(CMTATBaseERC20CrossChain, ERC20Upgradeable)
+ returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.transfer(to, value);
+ }
+
+ function transferFrom(address from, address to, uint256 value)
+ public virtual
+ override(CMTATBaseERC20CrossChain, ERC20Upgradeable)
+ returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ }
+
+ function approve(address spender, uint256 value)
+ public virtual
+ override(CMTATBaseERC20CrossChain, ERC20Upgradeable)
+ returns (bool)
+ {
+ return CMTATBaseERC20CrossChain.approve(spender, value);
+ }
+
+ function name()
+ public view virtual
+ override(CMTATBaseERC20CrossChain, ERC20Upgradeable)
+ returns (string memory)
+ {
+ return CMTATBaseERC20CrossChain.name();
+ }
+
+ function symbol()
+ public view virtual
+ override(CMTATBaseERC20CrossChain, ERC20Upgradeable)
+ returns (string memory)
+ {
+ return CMTATBaseERC20CrossChain.symbol();
+ }
+
+ function decimals()
+ public view virtual
+ override(CMTATBaseERC20CrossChain, ERC20Upgradeable)
+ returns (uint8)
+ {
+ return CMTATBaseERC20CrossChain.decimals();
+ }
+
+ function getFrozenTokens(address account)
+ public view virtual
+ override(ERC20EnforcementModule, ERC20EnforcementERC7551Module)
+ returns (uint256 frozenBalance_)
+ {
+ return ERC20EnforcementERC7551Module.getFrozenTokens(account);
+ }
+}
+
diff --git a/contracts/modules/6_CMTATBaseERC1363.sol b/contracts/modules/8_CMTATBaseERC1363.sol
similarity index 62%
rename from contracts/modules/6_CMTATBaseERC1363.sol
rename to contracts/modules/8_CMTATBaseERC1363.sol
index dff03c79..dcc9c7b4 100644
--- a/contracts/modules/6_CMTATBaseERC1363.sol
+++ b/contracts/modules/8_CMTATBaseERC1363.sol
@@ -6,15 +6,16 @@ import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/Cont
import {ERC1363Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC1363Upgradeable.sol";
import {ERC20Upgradeable, IERC20} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
/* ==== Module === */
-import {CMTATBaseRuleEngine} from "./2_CMTATBaseRuleEngine.sol";
-import {CMTATBaseERC2771, CMTATBaseERC20CrossChain} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseRuleEngine} from "./3_CMTATBaseRuleEngine.sol";
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseERC7551Enforcement} from "./7_CMTATBaseERC7551Enforcement.sol";
/* ==== Interface and other library === */
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT Base for ERC-1363
*/
-abstract contract CMTATBaseERC1363 is ERC1363Upgradeable,CMTATBaseERC2771{
+abstract contract CMTATBaseERC1363 is ERC1363Upgradeable, CMTATBaseERC7551Enforcement {
/*//////////////////////////////////////////////////////////////
INITIALIZER FUNCTION
//////////////////////////////////////////////////////////////*/
@@ -34,19 +35,19 @@ abstract contract CMTATBaseERC1363 is ERC1363Upgradeable,CMTATBaseERC2771{
/**
* @dev revert if the contract is in pause state
*/
- function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain, IERC20) returns (bool) {
- return CMTATBaseERC20CrossChain.approve(spender, value);
+ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) {
+ return CMTATBaseERC7551Enforcement.approve(spender, value);
}
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
- function transfer(address to, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain, IERC20) returns (bool) {
- return CMTATBaseERC20CrossChain.transfer(to, value);
+ function transfer(address to, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) {
+ return CMTATBaseERC7551Enforcement.transfer(to, value);
}
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
function transferFrom(
address sender,
@@ -55,10 +56,10 @@ abstract contract CMTATBaseERC1363 is ERC1363Upgradeable,CMTATBaseERC2771{
)
public
virtual
- override(ERC20Upgradeable, CMTATBaseERC20CrossChain, IERC20)
+ override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20)
returns (bool)
{
- return CMTATBaseERC20CrossChain.transferFrom(sender, recipient, amount);
+ return CMTATBaseERC7551Enforcement.transferFrom(sender, recipient, amount);
}
/* ============ View functions ============ */
@@ -71,31 +72,31 @@ abstract contract CMTATBaseERC1363 is ERC1363Upgradeable,CMTATBaseERC2771{
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
function decimals()
public
view
virtual
- override(ERC20Upgradeable, CMTATBaseERC20CrossChain)
+ override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
returns (uint8)
{
- return CMTATBaseERC20CrossChain.decimals();
+ return CMTATBaseERC7551Enforcement.decimals();
}
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
- function name() public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) view returns (string memory) {
- return CMTATBaseERC20CrossChain.name();
+ function name() public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement) view returns (string memory) {
+ return CMTATBaseERC7551Enforcement.name();
}
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
- function symbol() public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain) view returns (string memory) {
- return CMTATBaseERC20CrossChain.symbol();
+ function symbol() public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement) view returns (string memory) {
+ return CMTATBaseERC7551Enforcement.symbol();
}
@@ -103,50 +104,39 @@ abstract contract CMTATBaseERC1363 is ERC1363Upgradeable,CMTATBaseERC2771{
/*//////////////////////////////////////////////////////////////
INTERNAL/PRIVATE FUNCTIONS
//////////////////////////////////////////////////////////////*/
- /**
- * @inheritdoc CMTATBaseERC20CrossChain
- */
- function _update(
- address from,
- address to,
- uint256 amount
- ) internal override(ERC20Upgradeable, CMTATBaseERC20CrossChain) {
- CMTATBaseERC20CrossChain._update(from, to, amount);
- }
-
/*//////////////////////////////////////////////////////////////
ERC2771 MODULE
//////////////////////////////////////////////////////////////*/
/**
- * @inheritdoc CMTATBaseERC2771
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
function _msgSender()
internal
view
- override(ContextUpgradeable, CMTATBaseERC2771)
+ override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
returns (address sender)
{
- return CMTATBaseERC2771._msgSender();
+ return CMTATBaseERC7551Enforcement._msgSender();
}
/**
- * @inheritdoc CMTATBaseERC2771
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
function _contextSuffixLength() internal view
- override(ContextUpgradeable, CMTATBaseERC2771)
+ override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
returns (uint256) {
- return CMTATBaseERC2771._contextSuffixLength();
+ return CMTATBaseERC7551Enforcement._contextSuffixLength();
}
/**
- * @inheritdoc CMTATBaseERC2771
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
function _msgData()
internal
view
- override(ContextUpgradeable, CMTATBaseERC2771)
+ override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
returns (bytes calldata)
{
- return CMTATBaseERC2771._msgData();
+ return CMTATBaseERC7551Enforcement._msgData();
}
}
diff --git a/contracts/modules/6_CMTATBaseERC7551.sol b/contracts/modules/8_CMTATBaseERC7551.sol
similarity index 51%
rename from contracts/modules/6_CMTATBaseERC7551.sol
rename to contracts/modules/8_CMTATBaseERC7551.sol
index c671cc3f..8d0d90b4 100644
--- a/contracts/modules/6_CMTATBaseERC7551.sol
+++ b/contracts/modules/8_CMTATBaseERC7551.sol
@@ -2,20 +2,21 @@
pragma solidity ^0.8.20;
+/* ==== OpenZeppelin === */
/* ==== Module === */
-import {CMTATBaseAccessControl} from "./1_CMTATBaseAccessControl.sol";
-import {CMTATBaseERC2771} from "./5_CMTATBaseERC2771.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
+import {CMTATBaseERC7551Enforcement} from "./7_CMTATBaseERC7551Enforcement.sol";
import {ExtraInformationModule, ERC7551Module} from "./wrapper/options/ERC7551Module.sol";
/**
-* @title Extend CMTAT Base with ERC7551Module
+* @title Extend CMTAT Base with ERC7551Module and ERC20EnforcementERC7551Module
*/
-abstract contract CMTATBaseERC7551 is CMTATBaseERC2771, ERC7551Module{
+abstract contract CMTATBaseERC7551 is CMTATBaseERC7551Enforcement, ERC7551Module {
/*//////////////////////////////////////////////////////////////
PUBLIC/EXTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
/* ==== Access Control ==== */
- function _authorizeExtraInfoManagement() internal virtual override(CMTATBaseAccessControl, ExtraInformationModule){
+ function _authorizeExtraInfoManagement() internal virtual override(CMTATBaseAccessControl, ExtraInformationModule) {
CMTATBaseAccessControl._authorizeExtraInfoManagement();
}
}
diff --git a/contracts/modules/internal/ERC20EnforcementModuleInternal.sol b/contracts/modules/internal/ERC20EnforcementModuleInternal.sol
index 7fea2100..fff7ded1 100644
--- a/contracts/modules/internal/ERC20EnforcementModuleInternal.sol
+++ b/contracts/modules/internal/ERC20EnforcementModuleInternal.sol
@@ -5,7 +5,6 @@ pragma solidity ^0.8.20;
/* ==== OpenZeppelin === */
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
/* ==== Tokenization === */
-import {IERC7551ERC20EnforcementTokenFrozenEvent, IERC7551ERC20EnforcementEvent} from "../../interfaces/tokenization/draft-IERC7551.sol";
import {IERC7943FungibleEnforcementEventAndError} from "../../interfaces/tokenization/draft-IERC7943.sol";
/**
@@ -14,8 +13,9 @@ import {IERC7943FungibleEnforcementEventAndError} from "../../interfaces/tokeniz
*
* Contains specific ERC-20 enforcement actions
*/
-abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable,IERC7551ERC20EnforcementEvent, IERC7551ERC20EnforcementTokenFrozenEvent, IERC7943FungibleEnforcementEventAndError {
+abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable, IERC7943FungibleEnforcementEventAndError {
// no argument to reduce contract code size
+ error CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed();
error CMTAT_ERC20EnforcementModule_ValueExceedsAvailableBalance();
error CMTAT_ERC20EnforcementModule_ValueExceedsFrozenBalance();
error CMTAT_ERC20EnforcementModule_ValueEqualCurrentFrozenTokens();
@@ -37,19 +37,22 @@ abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable,IERC7551ERC
if(value < frozenTokensLocal) {
uint256 difference = frozenTokensLocal - value;
$ ._frozenTokens[account] = value ;
- _unfreezeTokensEmitEvents(account,difference, value,"");
+ _unfreezeTokensEmitEvents(account,difference, value);
} else if(value > frozenTokensLocal) {
// No underflow possible due to previous check
uint256 difference = value - frozenTokensLocal;
$._frozenTokens[account] = value;
- _freezeTokensEmitEvents(account, difference, value, "");
+ _freezeTokensEmitEvents(account, difference, value);
} else { // Less probable path at the end
revert CMTAT_ERC20EnforcementModule_ValueEqualCurrentFrozenTokens();
}
return true;
}
- function _freezePartialTokens(address account, uint256 value, bytes memory data) internal virtual{
+ function _freezePartialTokens(address account, uint256 value) internal virtual{
+ if (account == address(0)) {
+ revert CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed();
+ }
ERC20EnforcementModuleStorage storage $ = _getEnforcementModuleStorage();
// Retrieve current value
uint256 balance = ERC20Upgradeable.balanceOf(account);
@@ -58,39 +61,47 @@ abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable,IERC7551ERC
require(balance >= frozenTokensLocal, CMTAT_ERC20EnforcementModule_ValueExceedsAvailableBalance());
// Update frozenTokens
$._frozenTokens[account] = frozenTokensLocal;
- _freezeTokensEmitEvents(account, value, frozenTokensLocal, data);
+ _freezeTokensEmitEvents(account, value, frozenTokensLocal);
}
- function _unfreezePartialTokens(address account, uint256 value, bytes memory data) internal virtual{
+ function _unfreezePartialTokens(address account, uint256 value) internal virtual{
+ if (account == address(0)) {
+ revert CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed();
+ }
ERC20EnforcementModuleStorage storage $ = _getEnforcementModuleStorage();
require($._frozenTokens[account] >= value, CMTAT_ERC20EnforcementModule_ValueExceedsFrozenBalance());
// Update frozenBalance
uint256 frozenTokensLocal = $._frozenTokens[account] - value;
$._frozenTokens[account] = frozenTokensLocal ;
- _unfreezeTokensEmitEvents(account, value, frozenTokensLocal,data);
+ _unfreezeTokensEmitEvents(account, value, frozenTokensLocal);
}
/**
* @dev unfreeze tokens during a forced transfer/burn
*/
- function _unfreezeTokens(address account, uint256 value, bytes memory data) internal virtual{
+ function _unfreezeTokens(address account, uint256 value) internal virtual{
uint256 balance = ERC20Upgradeable.balanceOf(account);
if(value > balance){
revert CMTAT_ERC20EnforcementModule_ValueExceedsAvailableBalance();
}
ERC20EnforcementModuleStorage storage $ = _getEnforcementModuleStorage();
- // Frozen tokens can not be > balance
- uint256 activeBalance = balance - $._frozenTokens[account];
+ uint256 frozenTokensLocal = $._frozenTokens[account];
+ // default value is 0 for uninitialized variable
+ uint256 activeBalance;
+ // Frozen amounts can be > balance through setFrozenTokens.
+ if (frozenTokensLocal < balance) {
+ activeBalance = balance - frozenTokensLocal;
+ }
if (value > activeBalance) {
uint256 tokensToUnfreeze = value - activeBalance;
- uint256 frozenTokensLocal = $._frozenTokens[account] - tokensToUnfreeze;
+ frozenTokensLocal = frozenTokensLocal - tokensToUnfreeze;
$._frozenTokens[account] = frozenTokensLocal;
- _unfreezeTokensEmitEvents(account, tokensToUnfreeze, frozenTokensLocal,data);
+ _unfreezeTokensEmitEvents(account, tokensToUnfreeze, frozenTokensLocal);
}
}
- function _forcedTransfer(address from, address to, uint256 value, bytes memory data) internal virtual {
- _unfreezeTokens(from, value, data);
+ function _forcedTransfer(address from, address to, uint256 value) internal virtual {
+ _unfreezeTokens(from, value);
if(to == address(0)){
ERC20Upgradeable._burn(from, value);
} else{
@@ -111,17 +122,14 @@ abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable,IERC7551ERC
}
ERC20Upgradeable._transfer(from, to, value);
}
- emit Enforcement(_msgSender(), from, value, data);
emit ForcedTransfer(from, to, value);
}
- function _freezeTokensEmitEvents(address account, uint256 difference, uint256 frozenTokens, bytes memory data) internal virtual {
- emit TokensFrozen(account, difference, data);
+ function _freezeTokensEmitEvents(address account, uint256 /* difference */, uint256 frozenTokens) internal virtual {
emit IERC7943FungibleEnforcementEventAndError.Frozen(account, frozenTokens);
}
- function _unfreezeTokensEmitEvents(address account, uint256 difference, uint256 frozenTokens, bytes memory data) internal virtual {
- emit TokensUnfrozen(account, difference, data);
+ function _unfreezeTokensEmitEvents(address account, uint256 /* difference */, uint256 frozenTokens) internal virtual {
emit IERC7943FungibleEnforcementEventAndError.Frozen(account, frozenTokens );
}
@@ -139,8 +147,15 @@ abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable,IERC7551ERC
function _checkActiveBalance(address from, uint256 value) internal virtual view returns(bool isValid, uint256 activeBalance){
uint256 frozenTokensLocal = _getFrozenTokens(from);
if(frozenTokensLocal > 0 ){
- // Frozen amounts can not be > balance
- activeBalance = ERC20Upgradeable.balanceOf(from) - frozenTokensLocal;
+ uint256 balance = ERC20Upgradeable.balanceOf(from);
+ // Frozen amounts can be > balance through setFrozenTokens.
+ if (frozenTokensLocal >= balance) {
+ if (value == 0) {
+ return (true, 0);
+ }
+ return (false, 0);
+ }
+ activeBalance = balance - frozenTokensLocal;
if(value > activeBalance) {
return (false, activeBalance);
}
@@ -157,7 +172,13 @@ abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable,IERC7551ERC
function _getActiveBalanceOf(address account) internal view returns (uint256){
ERC20EnforcementModuleStorage storage $ = _getEnforcementModuleStorage();
- return ERC20Upgradeable.balanceOf(account) - $._frozenTokens[account];
+ uint256 balance = ERC20Upgradeable.balanceOf(account);
+ uint256 frozenTokens = $._frozenTokens[account];
+ // Frozen amounts can be > balance through setFrozenTokens.
+ if (frozenTokens >= balance) {
+ return 0;
+ }
+ return balance - frozenTokens;
}
/* ============ ERC-7201 ============ */
diff --git a/contracts/modules/internal/EnforcementModuleInternal.sol b/contracts/modules/internal/EnforcementModuleInternal.sol
index 20a974de..a773bbac 100644
--- a/contracts/modules/internal/EnforcementModuleInternal.sol
+++ b/contracts/modules/internal/EnforcementModuleInternal.sol
@@ -16,6 +16,7 @@ abstract contract EnforcementModuleInternal is
Initializable,
ContextUpgradeable
{
+ error CMTAT_Enforcement_ZeroAddressNotAllowed();
/* ============ ERC-7201 ============ */
// keccak256(abi.encode(uint256(keccak256("CMTAT.storage.EnforcementModuleInternal")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant EnforcementModuleInternalStorageLocation = 0x0c7bc8a17be064111d299d7669f49519cb26c58611b72d9f6ccc40a1e1184e00;
@@ -35,6 +36,9 @@ abstract contract EnforcementModuleInternal is
}
function _addAddressToTheList(EnforcementModuleInternalStorage storage $,address account, bool status, bytes memory /*data */) internal virtual{
+ if (account == address(0)) {
+ revert CMTAT_Enforcement_ZeroAddressNotAllowed();
+ }
$._list[account] = status;
}
diff --git a/contracts/modules/wrapper/controllers/ValidationModule.sol b/contracts/modules/wrapper/controllers/ValidationModule.sol
index 74ecc41a..5ff108f4 100644
--- a/contracts/modules/wrapper/controllers/ValidationModule.sol
+++ b/contracts/modules/wrapper/controllers/ValidationModule.sol
@@ -5,8 +5,7 @@ pragma solidity ^0.8.20;
/* ==== Module === */
import {PauseModule} from "../core/PauseModule.sol";
import {EnforcementModule} from "../core/EnforcementModule.sol";
-import {IERC7943TransactError} from "../../../interfaces/tokenization/draft-IERC7943.sol";
-import {IERC7943TransactCheck} from "../../../interfaces/tokenization/draft-IERC7943.sol";
+import {IERC7943FungibleSendReceiveError, IERC7943FungibleSendReceiveCheck} from "../../../interfaces/tokenization/draft-IERC7943.sol";
/**
* @title Validation module
* @dev
@@ -16,15 +15,21 @@ import {IERC7943TransactCheck} from "../../../interfaces/tokenization/draft-IERC
abstract contract ValidationModule is
PauseModule,
EnforcementModule,
- IERC7943TransactError,
- IERC7943TransactCheck
+ IERC7943FungibleSendReceiveError,
+ IERC7943FungibleSendReceiveCheck
{
/*//////////////////////////////////////////////////////////////
PUBLIC FUNCTIONS
//////////////////////////////////////////////////////////////*/
- function canTransact(address account) public view virtual override(IERC7943TransactCheck) returns (bool allowed) {
- return _canTransact(account);
+ /// @inheritdoc IERC7943FungibleSendReceiveCheck
+ function canSend(address account) public view virtual override(IERC7943FungibleSendReceiveCheck) returns (bool allowed) {
+ return _canSend(account);
+ }
+
+ /// @inheritdoc IERC7943FungibleSendReceiveCheck
+ function canReceive(address account) public view virtual override(IERC7943FungibleSendReceiveCheck) returns (bool allowed) {
+ return _canReceive(account);
}
/*//////////////////////////////////////////////////////////////
INTERNAL/PRIVATE FUNCTIONS
@@ -58,10 +63,10 @@ abstract contract ValidationModule is
) internal view virtual {
// Mint
if(from == address(0)){
- _canMintBurnByModuleAndRevert(to);
+ _canMintByModuleAndRevert(to);
} // burn
else if(to == address(0)){
- _canMintBurnByModuleAndRevert(from);
+ _canBurnByModuleAndRevert(from);
} // Standard transfer
else {
_canTransferStandardByModuleAndRevert(spender, from, to);
@@ -86,19 +91,28 @@ abstract contract ValidationModule is
}
/**
- * @dev check if the contract is deactivated or the address is frozen
- * check relevant for mint and burn operations
- * Use forcedTransfer (or forcedBurn) to burn tokens from a frozen address
- */
- function _canMintBurnByModuleAndRevert(
- address target
+ * @dev Reverts if mint is not allowed for `to`.
+ * Checks deactivation and frozen status of the recipient.
+ */
+ function _canMintByModuleAndRevert(
+ address to
+ ) internal view virtual {
+ _requireNotDeactivated();
+ if(EnforcementModule.isFrozen(to)){
+ revert ERC7943CannotReceive(to);
+ }
+ }
+
+ /**
+ * @dev Reverts if burn is not allowed for `from`.
+ * Checks deactivation and frozen status of the token holder.
+ */
+ function _canBurnByModuleAndRevert(
+ address from
) internal view virtual {
- // can not mint or burn if the contract is deactivated
_requireNotDeactivated();
- // cannot burn if target is frozen (used forcedTransfer instead if available)
- // cannot mint if target is frozen
- if(EnforcementModule.isFrozen(target)){
- revert ERC7943CannotTransact(target);
+ if(EnforcementModule.isFrozen(from)){
+ revert ERC7943CannotSend(from);
}
}
@@ -126,17 +140,13 @@ abstract contract ValidationModule is
address from,
address to
) internal view virtual {
- address target;
if (EnforcementModule.isFrozen(spender)){
- target = spender;
+ revert ERC7943CannotSend(spender);
} else if (EnforcementModule.isFrozen(from)) {
- target = from;
+ revert ERC7943CannotSend(from);
} else if(EnforcementModule.isFrozen(to) ){
- target = to;
- } else {
- return;
+ revert ERC7943CannotReceive(to);
}
- revert ERC7943CannotTransact(target);
}
function _canTransferStandardByModule(
@@ -160,24 +170,28 @@ abstract contract ValidationModule is
/**
* We don't check the deactivate status because
* the contract will be in the pause state if deactivated
- * This remove a supplementary check and reduce runtime gas sot
+ * This removes a supplementary check and reduces runtime gas cost
*/
_requireNotPaused();
_canTransferisFrozenAndRevert(spender, from, to);
}
- /**
- * @notice Checks if a specific account is allowed to transact according to token rules.
- * @dev This is often used for allowlist/KYC/KYB/AML checks.
- * @param account The address to check.
- * @return allowed True if the account is allowed, false otherwise.
+ /**
+ * @dev Returns true if `account` is allowed to send tokens.
+ * Base check: account must not be frozen.
+ * Override in subclasses to add allowlist or other checks.
*/
- function _canTransact(address account) internal view virtual returns (bool allowed) {
- if(EnforcementModule.isFrozen(account)) {
- return false;
- } else {
- return true;
- }
+ function _canSend(address account) internal view virtual returns (bool allowed) {
+ return !EnforcementModule.isFrozen(account);
+ }
+
+ /**
+ * @dev Returns true if `account` is allowed to receive tokens.
+ * Base check: account must not be frozen.
+ * Override in subclasses to add allowlist or other checks.
+ */
+ function _canReceive(address account) internal view virtual returns (bool allowed) {
+ return !EnforcementModule.isFrozen(account);
}
}
diff --git a/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol b/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol
index fe7c1134..51991d5a 100644
--- a/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol
+++ b/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol
@@ -62,22 +62,44 @@ abstract contract ValidationModuleAllowlist is
return ValidationModule._canTransferStandardByModule(spender, from, to);
}
- function _canTransact(address account) internal view virtual override(ValidationModule) returns (bool allowed) {
+ /// @inheritdoc ValidationModule
+ function _canSend(address account) internal view virtual override(ValidationModule) returns (bool allowed) {
if(_isAllowlistEnabled() && !isAllowlisted(account)){
return false;
} else {
- return ValidationModule._canTransact(account);
+ return ValidationModule._canSend(account);
+ }
+ }
+
+ /// @inheritdoc ValidationModule
+ function _canReceive(address account) internal view virtual override(ValidationModule) returns (bool allowed) {
+ if(_isAllowlistEnabled() && !isAllowlisted(account)){
+ return false;
+ } else {
+ return ValidationModule._canReceive(account);
}
}
/* ============ View functions which revert ============ */
- function _canMintBurnByModuleAndRevert(
- address account
+ /// @inheritdoc ValidationModule
+ function _canMintByModuleAndRevert(
+ address to
) internal view virtual override(ValidationModule) {
- if(_isAllowlistEnabled() && !isAllowlisted(account)){
- revert ERC7943CannotTransact(account);
+ if(_isAllowlistEnabled() && !isAllowlisted(to)){
+ revert ERC7943CannotReceive(to);
+ } else {
+ ValidationModule._canMintByModuleAndRevert(to);
+ }
+ }
+
+ /// @inheritdoc ValidationModule
+ function _canBurnByModuleAndRevert(
+ address from
+ ) internal view virtual override(ValidationModule) {
+ if(_isAllowlistEnabled() && !isAllowlisted(from)){
+ revert ERC7943CannotSend(from);
} else {
- ValidationModule._canMintBurnByModuleAndRevert(account);
+ ValidationModule._canBurnByModuleAndRevert(from);
}
}
@@ -87,7 +109,7 @@ abstract contract ValidationModuleAllowlist is
address to
) internal view virtual override(ValidationModule) {
_canTransferStandardByModuleAllowlistAndRevert(spender, from, to);
- ValidationModule._canTransferStandardByModuleAndRevert(spender, from, to);
+ ValidationModule._canTransferStandardByModuleAndRevert(spender, from, to);
}
function _canTransferStandardByModuleAllowlistAndRevert(
@@ -95,19 +117,14 @@ abstract contract ValidationModuleAllowlist is
address from,
address to
) internal view virtual {
- address account;
if(_isAllowlistEnabled()){
if (spender != address(0) && !isAllowlisted(spender)){
- account = spender;
+ revert ERC7943CannotSend(spender);
} else if (!isAllowlisted(from)) {
- account = from;
- } else if(!isAllowlisted(to) ){
- account = to;
- } else {
- return;
+ revert ERC7943CannotSend(from);
+ } else if(!isAllowlisted(to)){
+ revert ERC7943CannotReceive(to);
}
- // Will revert if the last else branch has not be taken
- revert ERC7943CannotTransact(account);
}
}
}
diff --git a/contracts/modules/wrapper/core/ERC20BurnModule.sol b/contracts/modules/wrapper/core/ERC20BurnModule.sol
index 9ec3b9ae..1f84fecd 100644
--- a/contracts/modules/wrapper/core/ERC20BurnModule.sol
+++ b/contracts/modules/wrapper/core/ERC20BurnModule.sol
@@ -60,6 +60,8 @@ abstract contract ERC20BurnModule is ERC20BurnModuleInternal, IBurnBatchERC20, I
/**
*
* @inheritdoc IBurnBatchERC20
+ * @dev `data` is batch-level metadata emitted in {BatchBurn} only.
+ * It is not forwarded to each internal burn item.
* @custom:access-control
* - the caller must have the `BURNER_ROLE`.
*/
diff --git a/contracts/modules/wrapper/core/PauseModule.sol b/contracts/modules/wrapper/core/PauseModule.sol
index ce221b3e..35aad82b 100644
--- a/contracts/modules/wrapper/core/PauseModule.sol
+++ b/contracts/modules/wrapper/core/PauseModule.sol
@@ -85,6 +85,9 @@ abstract contract PauseModule is PausableUpgradeable, IERC3643Pause, IERC7551Pau
// Contract must be in pause state
PausableUpgradeable._requirePaused();
PauseModuleStorage storage $ = _getPauseModuleStorage();
+ if ($._isDeactivated) {
+ revert AlreadyDeactivated();
+ }
$._isDeactivated = true;
emit Deactivated(_msgSender());
}
diff --git a/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol b/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol
new file mode 100644
index 00000000..00ba1fbf
--- /dev/null
+++ b/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+import {IERC1643} from "../../../interfaces/tokenization/draft-IERC1643.sol";
+
+/**
+ * @title DocumentERC1643 module
+ * @dev In-contract ERC-1643 document management.
+ */
+abstract contract DocumentERC1643Module is Initializable, IERC1643 {
+ bytes32 public constant DOCUMENT_ROLE = keccak256("DOCUMENT_ROLE");
+ // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.DocumentERC1643Module")) - 1)) & ~bytes32(uint256(0xff))
+ bytes32 private constant DocumentERC1643ModuleStorageLocation = 0x24fbb1cf6345ced60d5278ef6f68f4f7576fd9068704b4c8f1eec8f0bbd8a200;
+
+ struct DocumentERC1643ModuleStorage {
+ mapping(bytes32 => Document) _documents;
+ mapping(bytes32 => uint256) _documentKey;
+ bytes32[] _documentNames;
+ }
+
+ modifier onlyDocumentManager() {
+ _authorizeDocumentManagement();
+ _;
+ }
+
+ function getDocument(bytes32 name) public view virtual override returns (Document memory document) {
+ return _getDocumentERC1643ModuleStorage()._documents[name];
+ }
+
+ function getAllDocuments() public view virtual override returns (bytes32[] memory documentNames_) {
+ return _getDocumentERC1643ModuleStorage()._documentNames;
+ }
+
+ function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) public virtual override onlyDocumentManager {
+ DocumentERC1643ModuleStorage storage $ = _getDocumentERC1643ModuleStorage();
+ Document storage document = $._documents[name];
+ document.uri = uri;
+ document.documentHash = documentHash;
+ document.lastModified = block.timestamp;
+
+ if ($._documentKey[name] == 0) {
+ $._documentNames.push(name);
+ $._documentKey[name] = $._documentNames.length;
+ }
+
+ emit DocumentUpdated(name, uri, documentHash);
+ }
+
+ function removeDocument(bytes32 name) public virtual override onlyDocumentManager {
+ DocumentERC1643ModuleStorage storage $ = _getDocumentERC1643ModuleStorage();
+ uint256 key = $._documentKey[name];
+ require(key != 0, "CMTAT: document does not exist");
+
+ Document memory document = $._documents[name];
+ uint256 index = key - 1;
+ uint256 lastIndex = $._documentNames.length - 1;
+
+ if (index != lastIndex) {
+ bytes32 movedName = $._documentNames[lastIndex];
+ $._documentNames[index] = movedName;
+ $._documentKey[movedName] = key;
+ }
+
+ $._documentNames.pop();
+ delete $._documents[name];
+ delete $._documentKey[name];
+
+ emit DocumentRemoved(name, document.uri, document.documentHash);
+ }
+
+ function _authorizeDocumentManagement() internal virtual;
+
+ function _getDocumentERC1643ModuleStorage() private pure returns (DocumentERC1643ModuleStorage storage $) {
+ assembly {
+ $.slot := DocumentERC1643ModuleStorageLocation
+ }
+ }
+}
diff --git a/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol b/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol
index 2e989302..4f2db67c 100644
--- a/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol
+++ b/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol
@@ -6,15 +6,17 @@ pragma solidity ^0.8.20;
import {ERC20EnforcementModuleInternal} from "../../internal/ERC20EnforcementModuleInternal.sol";
/* ==== Tokenization === */
import {IERC3643ERC20Enforcement, IERC7943FungibleEnforcement} from "../../../interfaces/tokenization/IERC3643Partial.sol";
-import {IERC7551ERC20Enforcement, IERC7551ERC20EnforcementEvent} from "../../../interfaces/tokenization/draft-IERC7551.sol";
import {IERC7943FungibleEnforcementSpecific} from "../../../interfaces/tokenization/draft-IERC7943.sol";
+
/**
* @title ERC20Enforcement module.
- * @dev
+ * @dev
*
- * ERC-20 Enforcement related functions (freeze tokens, forced transfer)
+ * ERC-20 Enforcement related functions (freeze tokens, forced transfer).
+ * Implements ERC-3643 and ERC-7943 enforcement interfaces.
+ * For ERC-7551 enforcement (bytes data overloads), see ERC20EnforcementERC7551Module.
*/
-abstract contract ERC20EnforcementModule is ERC20EnforcementModuleInternal, IERC7551ERC20Enforcement, IERC3643ERC20Enforcement, IERC7943FungibleEnforcementSpecific {
+abstract contract ERC20EnforcementModule is ERC20EnforcementModuleInternal, IERC3643ERC20Enforcement, IERC7943FungibleEnforcementSpecific {
/* ============ State Variables ============ */
bytes32 public constant ERC20ENFORCER_ROLE = keccak256("ERC20ENFORCER_ROLE");
@@ -35,109 +37,71 @@ abstract contract ERC20EnforcementModule is ERC20EnforcementModuleInternal, IERC
PUBLIC/EXTERNAL FUNCTIONS
//////////////////////////////////////////////////////////////*/
- /**
- *
- * @inheritdoc IERC7551ERC20Enforcement
- */
- function getFrozenTokens(address account) public override(IERC7551ERC20Enforcement, IERC7943FungibleEnforcement) view virtual returns (uint256 frozenBalance_) {
- return _getFrozenTokens(account);
- }
-
- /**
- *
- * @inheritdoc IERC7551ERC20Enforcement
- */
- function getActiveBalanceOf(address account) public view override(IERC7551ERC20Enforcement) returns (uint256 activeBalance_){
- return _getActiveBalanceOf(account);
- }
-
- /* ============ ERC-20 Enforcement ============ */
/**
- *
- * @inheritdoc IERC7551ERC20Enforcement
- * @custom:access-control
- * - Protected by `onlyForcedTransferManager`.
- */
- function forcedTransfer(address from, address to, uint256 value, bytes calldata data)
- public virtual override(IERC7551ERC20Enforcement) onlyForcedTransferManager returns (bool) {
- _forcedTransfer(from, to, value, data);
- return true;
+ * @inheritdoc IERC7943FungibleEnforcement
+ */
+ function getFrozenTokens(address account) public view virtual override(IERC7943FungibleEnforcement) returns (uint256 frozenBalance_) {
+ return _getFrozenTokens(account);
}
+ /* ============ ERC-20 Enforcement ============ */
/**
- *
- * @inheritdoc IERC7943FungibleEnforcement
- * @custom:access-control
- * - Protected by `onlyForcedTransferManager`.
- */
- function forcedTransfer(address from, address to, uint256 value)
- public virtual override(IERC7943FungibleEnforcement) onlyForcedTransferManager returns (bool) {
- _forcedTransfer(from, to, value, "");
- return true;
+ * @inheritdoc IERC7943FungibleEnforcement
+ * @custom:access-control
+ * - Protected by `onlyForcedTransferManager`.
+ */
+ function forcedTransfer(address from, address to, uint256 value)
+ public virtual override(IERC7943FungibleEnforcement) onlyForcedTransferManager returns (bool) {
+ _forcedTransfer(from, to, value);
+ return true;
}
/**
- *
- * @inheritdoc IERC3643ERC20Enforcement
- * @custom:access-control
- * - Protected by `onlyERC20Enforcer`.
- */
- function freezePartialTokens(address account, uint256 value)
- public virtual override(IERC3643ERC20Enforcement) onlyERC20Enforcer{
- _freezePartialTokens(account, value, "");
+ * @inheritdoc IERC3643ERC20Enforcement
+ * @custom:access-control
+ * - Protected by `onlyERC20Enforcer`.
+ */
+ function freezePartialTokens(address account, uint256 value)
+ public virtual override(IERC3643ERC20Enforcement) onlyERC20Enforcer {
+ _freezePartialTokens(account, value);
}
/**
- *
- * @inheritdoc IERC3643ERC20Enforcement
- * @custom:access-control
- * - Protected by `onlyERC20Enforcer`.
- */
- function unfreezePartialTokens(address account, uint256 value)
+ * @inheritdoc IERC3643ERC20Enforcement
+ * @custom:access-control
+ * - Protected by `onlyERC20Enforcer`.
+ */
+ function unfreezePartialTokens(address account, uint256 value)
public virtual override(IERC3643ERC20Enforcement) onlyERC20Enforcer {
- _unfreezePartialTokens(account, value, "");
+ _unfreezePartialTokens(account, value);
}
/**
- *
- * @inheritdoc IERC7943FungibleEnforcementSpecific
- * @custom:access-control
- * - Protected by `onlyERC20Enforcer `.
- */
- function setFrozenTokens(address account, uint256 value)
- public virtual override(IERC7943FungibleEnforcementSpecific) onlyERC20Enforcer
- returns(bool result) {
- return _setFrozenTokens(account, value);
+ * @inheritdoc IERC7943FungibleEnforcementSpecific
+ * @custom:access-control
+ * - Protected by `onlyERC20Enforcer`.
+ */
+ function setFrozenTokens(address account, uint256 value)
+ public virtual override(IERC7943FungibleEnforcementSpecific) onlyERC20Enforcer
+ returns (bool result) {
+ return _setFrozenTokens(account, value);
}
- /**
- *
- * @inheritdoc IERC7551ERC20Enforcement
- * @custom:access-control
- * - Protected by `onlyERC20Enforcer`.
- */
- function freezePartialTokens(address account, uint256 value, bytes calldata data)
- public virtual override(IERC7551ERC20Enforcement) onlyERC20Enforcer {
- _freezePartialTokens(account, value, data);
+ /*//////////////////////////////////////////////////////////////
+ INTERNAL/PRIVATE FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+ /* ============ Events ============ */
+ function _freezeTokensEmitEvents(address account, uint256 difference, uint256 frozenTokens) internal virtual override {
+ super._freezeTokensEmitEvents(account, difference, frozenTokens);
+ emit IERC3643ERC20Enforcement.TokensFrozen(account, difference);
}
- /**
- *
- * @inheritdoc IERC7551ERC20Enforcement
- * @custom:access-control
- * - Protected by `onlyERC20Enforcer`.
- */
- function unfreezePartialTokens(address account, uint256 value, bytes calldata data)
- public virtual override(IERC7551ERC20Enforcement) onlyERC20Enforcer {
- _unfreezePartialTokens(account, value, data);
+ function _unfreezeTokensEmitEvents(address account, uint256 difference, uint256 frozenTokens) internal virtual override {
+ super._unfreezeTokensEmitEvents(account, difference, frozenTokens);
+ emit IERC3643ERC20Enforcement.TokensUnfrozen(account, difference);
}
-
- /*//////////////////////////////////////////////////////////////
- INTERNAL/PRIVATE FUNCTIONS
- //////////////////////////////////////////////////////////////*/
/* ============ Access Control ============ */
function _authorizeERC20Enforcer() internal virtual;
function _authorizeForcedTransfer() internal virtual;
-
}
diff --git a/contracts/modules/wrapper/extensions/ExtraInformationModule.sol b/contracts/modules/wrapper/extensions/ExtraInformationModule.sol
index 5db1c50f..0249ce44 100644
--- a/contracts/modules/wrapper/extensions/ExtraInformationModule.sol
+++ b/contracts/modules/wrapper/extensions/ExtraInformationModule.sol
@@ -5,7 +5,7 @@ pragma solidity ^0.8.20;
/* ==== Openzeppelin === */
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
/* ==== Tokenization === */
-import {IERC1643CMTAT, IERC1643} from "../../../interfaces/tokenization/draft-IERC1643CMTAT.sol";
+import {IERC1643CMTAT} from "../../../interfaces/tokenization/draft-IERC1643CMTAT.sol";
import {ICMTATBase} from "../../../interfaces/tokenization/ICMTAT.sol";
/**
diff --git a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol
new file mode 100644
index 00000000..04017b4f
--- /dev/null
+++ b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+/* ==== ValidationModule === */
+import {ValidationModuleCore} from "../../core/ValidationModuleCore.sol";
+
+/**
+ * @dev Validation module for allowance authorization (`approve` and `permit`).
+ *
+ * It validates the allowance domain (`owner` + `spender`) instead of
+ * transfer semantics (`spender` + `from` + `to`).
+ */
+abstract contract ValidationModuleAllowance is ValidationModuleCore {
+ /**
+ * @dev Reverts when allowance authorization cannot be performed.
+ *
+ * Requirements:
+ * - contract must not be paused.
+ * - `owner` must be allowed to send (`canSend` returns true).
+ * - `spender` must be allowed to send (`canSend` returns true).
+ */
+ function _canAuthorizeAllowanceByModuleAndRevert(
+ address owner,
+ address spender
+ ) internal view virtual {
+ _requireNotPaused();
+ if (!_canSend(owner)) {
+ revert ERC7943CannotSend(owner);
+ }
+ if (!_canSend(spender)) {
+ revert ERC7943CannotSend(spender);
+ }
+ }
+}
diff --git a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol
index cd2cb4e5..5ffb891a 100644
--- a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol
+++ b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol
@@ -6,6 +6,7 @@ pragma solidity ^0.8.20;
/* ==== Engine === */
import {IRuleEngine} from "../../../../interfaces/engine/IRuleEngine.sol";
/* ==== ValidationModule === */
+import {ValidationModuleAllowance} from "./ValidationModuleAllowance.sol";
import {ValidationModuleCore} from "../../core/ValidationModuleCore.sol";
import {ValidationModuleRuleEngineInternal} from "../../../internal/ValidationModuleRuleEngineInternal.sol";
/**
@@ -14,7 +15,7 @@ import {ValidationModuleRuleEngineInternal} from "../../../internal/ValidationMo
* Useful for to restrict and validate transfers
*/
abstract contract ValidationModuleRuleEngine is
- ValidationModuleCore,
+ ValidationModuleAllowance,
ValidationModuleRuleEngineInternal
{
/**
diff --git a/contracts/modules/wrapper/options/DebtModule.sol b/contracts/modules/wrapper/options/DebtModule.sol
index cb9bc3c2..0d10b099 100644
--- a/contracts/modules/wrapper/options/DebtModule.sol
+++ b/contracts/modules/wrapper/options/DebtModule.sol
@@ -3,7 +3,7 @@
pragma solidity ^0.8.20;
/* ==== Engine === */
-import {IDebtEngine, ICMTATDebt, ICMTATCreditEvents} from "../../../interfaces/engine/IDebtEngine.sol";
+import {ICMTATDebt, ICMTATCreditEvents} from "../../../interfaces/engine/IDebtEngine.sol";
import {IDebtModule} from "../../../interfaces/modules/IDebtModule.sol";
/**
@@ -103,4 +103,4 @@ abstract contract DebtModule is IDebtModule {
$.slot := DebtModuleStorageLocation
}
}
-}
\ No newline at end of file
+}
diff --git a/contracts/modules/wrapper/extensions/DocumentEngineModule.sol b/contracts/modules/wrapper/options/DocumentEngineModule.sol
similarity index 83%
rename from contracts/modules/wrapper/extensions/DocumentEngineModule.sol
rename to contracts/modules/wrapper/options/DocumentEngineModule.sol
index ba578c99..0a6286cc 100644
--- a/contracts/modules/wrapper/extensions/DocumentEngineModule.sol
+++ b/contracts/modules/wrapper/options/DocumentEngineModule.sol
@@ -5,7 +5,7 @@ pragma solidity ^0.8.20;
/* ==== OpenZeppelin=== */
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
/* ==== Engine === */
-import {IERC1643, IDocumentEngine} from "../../../interfaces/engine/IDocumentEngine.sol";
+import {IERC1643} from "../../../interfaces/engine/IDocumentEngine.sol";
import {IDocumentEngineModule} from "../../../interfaces/modules/IDocumentEngineModule.sol";
/**
@@ -16,7 +16,7 @@ import {IDocumentEngineModule} from "../../../interfaces/modules/IDocumentEngine
*/
abstract contract DocumentEngineModule is Initializable, IDocumentEngineModule {
/* ============ ERC-7201 ============ */
- bytes32 public constant DOCUMENT_ROLE = keccak256("DOCUMENT_ROLE");
+ bytes32 public constant DOCUMENT_ENGINE_ROLE = keccak256("DOCUMENT_ENGINE_ROLE");
// keccak256(abi.encode(uint256(keccak256("CMTAT.storage.DocumentEngineModule")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant DocumentEngineModuleStorageLocation = 0xbd0905600c85d707dc53eba2e146c1c2527cd32ac3ff6b86846155151b3e2700;
/* ==== ERC-7201 State Variables === */
@@ -61,7 +61,7 @@ abstract contract DocumentEngineModule is Initializable, IDocumentEngineModule {
/**
* @inheritdoc IERC1643
*/
- function getDocument(string memory name) public view virtual override(IERC1643) returns (Document memory document){
+ function getDocument(bytes32 name) public view virtual override(IERC1643) returns (Document memory document){
DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage();
if(address($._documentEngine) != address(0)){
return $._documentEngine.getDocument(name);
@@ -73,13 +73,23 @@ abstract contract DocumentEngineModule is Initializable, IDocumentEngineModule {
/**
* @inheritdoc IERC1643
*/
- function getAllDocuments() public view virtual override(IERC1643) returns (string[] memory documentNames_){
+ function getAllDocuments() public view virtual override(IERC1643) returns (bytes32[] memory documentNames_){
DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage();
if(address($._documentEngine) != address(0)){
documentNames_ = $._documentEngine.getAllDocuments();
}
}
+ function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) public virtual override(IERC1643) onlyDocumentManager {
+ DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage();
+ $._documentEngine.setDocument(name, uri, documentHash);
+ }
+
+ function removeDocument(bytes32 name) public virtual override(IERC1643) onlyDocumentManager {
+ DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage();
+ $._documentEngine.removeDocument(name);
+ }
+
/* ============ Restricted Functions ============ */
/**
diff --git a/contracts/modules/wrapper/options/ERC20CrossChainModule.sol b/contracts/modules/wrapper/options/ERC20CrossChainModule.sol
index c1d58cad..9f8a8924 100644
--- a/contracts/modules/wrapper/options/ERC20CrossChainModule.sol
+++ b/contracts/modules/wrapper/options/ERC20CrossChainModule.sol
@@ -9,8 +9,8 @@ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/
import {IERC7802} from "../../../interfaces/technical/IERC7802.sol";
import {IBurnFromERC20} from "../../../interfaces/technical/IMintBurnToken.sol";
import {IERC20Allowance} from "../../../interfaces/technical/IERC20Allowance.sol";
-import {ERC20BurnModule, ERC20BurnModuleInternal} from "../core/ERC20BurnModule.sol";
-import {ERC20MintModule, ERC20MintModuleInternal} from "../core/ERC20MintModule.sol";
+import {ERC20BurnModule} from "../core/ERC20BurnModule.sol";
+import {ERC20MintModule} from "../core/ERC20MintModule.sol";
/**
* @title ERC20CrossChainModule (ERC-7802)
* @dev
@@ -95,10 +95,8 @@ abstract contract ERC20CrossChainModule is ERC20MintModule, ERC20BurnModule, ERC
function burn(
uint256 value
) public virtual override(IBurnFromERC20) onlySelfBurn{
- // Don't emit Spend event because allowance is not used here
address sender = _msgSender();
- // burn from itself
- _burn(sender, sender, value);
+ _burnFromOperator(sender, sender, value);
}
/* ============ View functions ============ */
@@ -115,16 +113,11 @@ abstract contract ERC20CrossChainModule is ERC20MintModule, ERC20BurnModule, ERC
// Specific event for the spend operation, same as transferFrom (ERC20BaseModule)
// Importing the event through inheritance will result in the following error: "Linearization of inheritance graph impossible"
emit IERC20Allowance.Spend(account, sender, value);
- _burn(sender, account, value);
+ _burnFromOperator(sender, account, value);
}
- function _burn(
- address sender, address account, uint256 value
- ) internal virtual{
- // burn
+ function _burnFromOperator(address sender, address account, uint256 value) internal virtual {
_burnOverride(account, value);
- // Specific event to burnFrom and self-burn (burn)
- // Don't emit CrossChainBurn because this function burn is not part of the IERC7802 interface
emit BurnFrom(sender, account, sender, value);
}
@@ -139,4 +132,4 @@ abstract contract ERC20CrossChainModule is ERC20MintModule, ERC20BurnModule, ERC
function _authorizeBurnFrom() internal virtual;
function _authorizeSelfBurn() internal virtual;
-}
\ No newline at end of file
+}
diff --git a/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol b/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol
new file mode 100644
index 00000000..51512324
--- /dev/null
+++ b/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+/* ==== Module === */
+import {ERC20EnforcementModule} from "../extensions/ERC20EnforcementModule.sol";
+/* ==== Tokenization === */
+import {IERC7551ERC20Enforcement, IERC7551ERC20EnforcementEvent, IERC7551ERC20EnforcementTokenFrozenEvent} from "../../../interfaces/tokenization/draft-IERC7551.sol";
+
+/**
+ * @title ERC20EnforcementERC7551 module.
+ * @dev
+ *
+ * Extends ERC20EnforcementModule with ERC-7551 specific functions:
+ * - getActiveBalanceOf view function
+ * - bytes data overloads for forcedTransfer, freezePartialTokens, unfreezePartialTokens
+ */
+abstract contract ERC20EnforcementERC7551Module is ERC20EnforcementModule, IERC7551ERC20Enforcement {
+
+ /*//////////////////////////////////////////////////////////////
+ PUBLIC/EXTERNAL FUNCTIONS
+ //////////////////////////////////////////////////////////////*/
+
+ /**
+ * @inheritdoc IERC7551ERC20Enforcement
+ */
+ function getFrozenTokens(address account)
+ public view virtual override(ERC20EnforcementModule, IERC7551ERC20Enforcement)
+ returns (uint256 frozenBalance_) {
+ return ERC20EnforcementModule.getFrozenTokens(account);
+ }
+
+ /**
+ * @inheritdoc IERC7551ERC20Enforcement
+ */
+ function getActiveBalanceOf(address account)
+ public view virtual override(IERC7551ERC20Enforcement)
+ returns (uint256 activeBalance_) {
+ return _getActiveBalanceOf(account);
+ }
+
+ /**
+ * @inheritdoc IERC7551ERC20Enforcement
+ * @custom:access-control
+ * - Protected by `onlyForcedTransferManager`.
+ */
+ function forcedTransfer(address from, address to, uint256 value, bytes calldata data)
+ public virtual override(IERC7551ERC20Enforcement) onlyForcedTransferManager returns (bool) {
+ uint256 frozenTokensBefore = _getFrozenTokens(from);
+ _forcedTransfer(from, to, value);
+ uint256 frozenTokensAfter = _getFrozenTokens(from);
+ if (frozenTokensAfter < frozenTokensBefore) {
+ emit IERC7551ERC20EnforcementTokenFrozenEvent.TokensUnfrozen(from, frozenTokensBefore - frozenTokensAfter, data);
+ }
+ emit IERC7551ERC20EnforcementEvent.ForcedTransfer(_msgSender(), from, to, value, data);
+ return true;
+ }
+
+ /**
+ * @inheritdoc IERC7551ERC20Enforcement
+ * @custom:access-control
+ * - Protected by `onlyERC20Enforcer`.
+ */
+ function freezePartialTokens(address account, uint256 value, bytes calldata data)
+ public virtual override(IERC7551ERC20Enforcement) onlyERC20Enforcer {
+ _freezePartialTokens(account, value);
+ emit IERC7551ERC20EnforcementTokenFrozenEvent.TokensFrozen(account, value, data);
+ }
+
+ /**
+ * @inheritdoc IERC7551ERC20Enforcement
+ * @custom:access-control
+ * - Protected by `onlyERC20Enforcer`.
+ */
+ function unfreezePartialTokens(address account, uint256 value, bytes calldata data)
+ public virtual override(IERC7551ERC20Enforcement) onlyERC20Enforcer {
+ _unfreezePartialTokens(account, value);
+ emit IERC7551ERC20EnforcementTokenFrozenEvent.TokensUnfrozen(account, value, data);
+ }
+}
diff --git a/contracts/modules/wrapper/options/ERC7551Module.sol b/contracts/modules/wrapper/options/ERC7551Module.sol
index 3d27f614..b3502517 100644
--- a/contracts/modules/wrapper/options/ERC7551Module.sol
+++ b/contracts/modules/wrapper/options/ERC7551Module.sol
@@ -5,7 +5,7 @@ pragma solidity ^0.8.20;
/* ==== Module === */
import {ExtraInformationModule} from "../extensions/ExtraInformationModule.sol";
/* ==== Tokenization === */
-import {IERC1643CMTAT, IERC1643} from "../../../interfaces/tokenization/draft-IERC1643CMTAT.sol";
+import {IERC1643CMTAT} from "../../../interfaces/tokenization/draft-IERC1643CMTAT.sol";
import {IERC7551Document} from "../../../interfaces/tokenization/draft-IERC7551.sol";
/**
diff --git a/doc/ERCSpecification/draft-erc-1404-restricted.md b/doc/ERCSpecification/draft-erc-1404-restricted.md
new file mode 100644
index 00000000..267cc183
--- /dev/null
+++ b/doc/ERCSpecification/draft-erc-1404-restricted.md
@@ -0,0 +1,172 @@
+---
+eip: 1404
+title: Simple Restricted Token
+description: A token interface extension for enforcing transfer restrictions with machine-readable status codes.
+author: Ron Gierlach (@rongierlach), James Poole (@pooleja), Mason Borda (@masonicgit), Lawson Baker (@lwsnbaker), Ryan Sauge (@rya-sge)
+discussions-to: https://ethereum-magicians.org/t/erc-1404-simple-restricted-token-standard/1405
+status: Draft
+type: Standards Track
+category: ERC
+created: 2018-07-27
+requires: 20
+---
+
+## Abstract
+
+Current token standards have provided the community with a platform on which to develop a decentralized economy that is focused on building Ethereum applications for the real world. As these applications mature and face consumer adoption, they begin to interface with corporate governance requirements as well as regulations. They must not only be able to meet corporate and regulatory requirements but must also be able to integrate with technology platforms underpinning their associated businesses. What follows is a simple and extendable standard that seeks to ease the burden of integration for wallets, exchanges, and issuers.
+
+## Motivation
+
+Token issuers need a way to restrict transfers of [ERC-20](./eip-20.md) tokens to be compliant with securities laws and other contractual obligations. Current implementations do not address these requirements.
+
+A few examples:
+
+- Enforcing Token Lock-Up Periods
+- Enforcing Passed AML/KYC Checks
+- Private Real-Estate Investment Trusts
+- Delaware General Corporations Law Shares
+
+Furthermore, standards adoption amongst token issuers has the potential to evolve into a dynamic and interoperable landscape of automated compliance.
+
+The following design gives greater freedom / upgradability to token issuers and simultaneously decreases the burden of integration for developers and exchanges.
+
+Additionally, this standard provides a pattern by which human-readable messages may be returned when token transfers are reverted. Transparency as to _why_ a token's transfer was reverted is of equal importance to the successful enforcement of the transfer restriction itself.
+
+## Specification
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
+
+[ERC-1404](./eip-1404.md) extends [ERC-20](./eip-20.md). All [ERC-20](./eip-20.md) functions, events, and semantics remain unchanged; compliant tokens MUST additionally implement the following methods.
+
+### Methods
+
+- #### `detectTransferRestriction(address,address,uint256)`
+
+ Returns a restriction code for the proposed transfer of `value` tokens from `from` to `to`, or `0` if the transfer is unrestricted. The restriction logic is defined by the issuer.
+
+ MUST be called inside the token's `transfer` and `transferFrom` methods. When a non-zero code is returned, the transfer SHOULD fail consistently with [ERC-20](./eip-20.md) expectations; reverting is RECOMMENDED. Implementations MAY return `false` instead.
+
+ ```solidity
+ function detectTransferRestriction(address from, address to, uint256 value) external view returns (uint8);
+ ```
+
+- #### `messageForTransferRestriction(uint8)`
+
+ Returns the human-readable message corresponding to `restrictionCode`.
+
+ ```solidity
+ function messageForTransferRestriction(uint8 restrictionCode) external view returns (string memory);
+ ```
+
+### Additional Specifications
+
+- Implementations MAY add [ERC-165](./eip-165.md) interface detection support for [ERC-1404](./eip-1404.md).
+
+- Implementations MAY apply analogous restriction checks to token supply-changing operations (for example, mint and burn). Such checks are optional and are not required for [ERC-1404](./eip-1404.md) compliance.
+
+- The [ERC-165](./eip-165.md) interface identifier for [ERC-1404](./eip-1404.md) is `0xab84a5c8`.
+
+- Compliance-related contracts MAY implement [ERC-1404](./eip-1404.md) restriction interfaces without directly implementing the full [ERC-20](./eip-20.md) token interface. In such cases, this standard only defines the behavior of `detectTransferRestriction` and `messageForTransferRestriction`.
+
+- Restriction checks SHOULD be deterministic for the same state and inputs, and SHOULD avoid reliance on manipulable off-chain data during execution.
+
+- The string returned by `messageForTransferRestriction` SHOULD NOT be treated as an authorization primitive.
+
+- Implementations SHOULD define and manage restriction code allocation carefully, because `uint8` limits the available code space to 256 values (`0` to `255`).
+
+## Rationale
+
+The standard proposes two functions on top of the [ERC-20](./eip-20.md) standard. The rationale for each is described below.
+
+1. `detectTransferRestriction` - This function is where an issuer enforces the restriction logic of their token transfers. Some examples of this might include, checking if the token recipient is whitelisted, checking if a sender's tokens are frozen in a lock-up period, etc. Because implementation is up to the issuer, this function serves solely to standardize _where_ execution of such logic should be initiated. Additionally, 3rd parties may publicly call this function to check the expected outcome of a transfer. Because this function returns a `uint8` code rather than a boolean or just reverting, it allows the function caller to know the reason why a transfer might fail and report this to relevant counterparties.
+2. `messageForTransferRestriction` - This function is effectively an accessor for the "message", a human-readable explanation as to _why_ a transaction is restricted. By standardizing message look-ups, we empower user interface builders to effectively report errors to users.
+3. Optional [ERC-165](./eip-165.md) support - Implementations may expose [ERC-165](./eip-165.md) support for interface discovery.
+
+## Backwards Compatibility
+
+By design [ERC-1404](./eip-1404.md) is interface-compatible with [ERC-20](./eip-20.md), while transfer restrictions may introduce behavioral differences.
+
+## Test Cases
+
+The following table-driven cases SHOULD be verified for every implementation. The examples use a whitelist-based policy (code `0` = no restriction, `1` = sender not whitelisted, `2` = recipient not whitelisted) to keep the expected values concrete, but the same structure applies to any issuer-defined policy.
+
+### `detectTransferRestriction`
+
+| Scenario | Expected return |
+|---|---|
+| Both `from` and `to` satisfy the policy | `0` |
+| `from` violates the policy | Non-zero restriction code |
+| `to` violates the policy; `from` does not | Non-zero restriction code distinct from the sender case |
+| Both `from` and `to` violate the policy | Non-zero code; the specific code returned depends on the implementation's evaluation order |
+
+### `messageForTransferRestriction`
+
+| Input | Expected output |
+|---|---|
+| `0` | A deterministic human-readable string indicating no restriction (e.g., `"No restriction"`) |
+| Any known restriction code | The corresponding deterministic human-readable message |
+
+### Transfer enforcement
+
+| Scenario | Expected behavior for `transfer` and `transferFrom` |
+|---|---|
+| `detectTransferRestriction` returns `0` | Transfer succeeds |
+| `detectTransferRestriction` returns a non-zero code | Transfer reverts (preferred) or returns `false` |
+
+### ERC-165 interface detection (optional)
+
+For implementations that expose [ERC-165](./eip-165.md) support:
+
+| Input to `supportsInterface` | Expected return |
+|---|---|
+| `0xab84a5c8` ([ERC-1404](./eip-1404.md) interface identifier) | `true` |
+| `0x01ffc9a7` ([ERC-165](./eip-165.md) interface identifier) | `true` |
+| Any unrecognized selector | `false` |
+
+A complete Foundry test suite covering all the cases above is available at [`test/ERC1404.t.sol`](../assets/eip-1404/test/ERC1404.t.sol).
+
+## Reference Implementation
+
+A complete reference implementation built with Foundry and OpenZeppelin Contracts v5 is provided in the assets folder:
+
+| File | Description |
+|------|-------------|
+| [`src/IERC1404.sol`](../assets/eip-1404/src/IERC1404.sol) | Interface — extends `IERC20` with the two [ERC-1404](./eip-1404.md) functions |
+| [`src/ERC1404.sol`](../assets/eip-1404/src/ERC1404.sol) | Concrete implementation — whitelist-based, with [ERC-165](./eip-165.md) support |
+| [`test/ERC1404.t.sol`](../assets/eip-1404/test/ERC1404.t.sol) | Foundry test suite covering all mandatory behaviors |
+
+The concrete implementation applies a whitelist policy and defines the following restriction codes. Note that codes `1` and `2` are specific to this implementation; [ERC-1404](./eip-1404.md) does not standardize restriction code values beyond reserving `0` as the "no restriction" sentinel.
+
+| Code | Constant | Message |
+|------|----------|---------|
+| `0` | `TRANSFER_OK` | `"No restriction"` |
+| `1` | `SENDER_NOT_WHITELISTED` | `"Sender not whitelisted"` |
+| `2` | `RECIPIENT_NOT_WHITELISTED` | `"Recipient not whitelisted"` |
+
+Notable design decisions in this implementation:
+
+- `transfer` and `transferFrom` revert with a typed `TransferRestricted(uint8 code, string message)` error on non-zero codes, rather than returning `false`.
+- `detectTransferRestriction` checks the sender before the recipient, so callers can distinguish the two failure cases with a single view call before submitting a transaction.
+- `supportsInterface(0xab84a5c8)` returns `true`, enabling on-chain interface discovery.
+- Mint and burn operations apply analogous restriction checks, as permitted by the specification.
+- Implementations that also conform to [ERC-7943](./eip-7943.md) will likely revert with that standard's typed errors rather than `TransferRestricted(uint8 code, string message)`. Those errors do not carry a restriction code or human-readable message.
+
+This example is provided for educational purposes only and has not been audited. Do not use in production without a thorough independent security review.
+
+## Security Considerations
+
+- Implementations are expected to encode policy in `detectTransferRestriction`, so mistakes in this logic can block valid transfers or allow restricted transfers.
+
+- Restriction checks that are not deterministic for the same state and inputs can create inconsistent behavior, and reliance on manipulable off-chain data can undermine enforcement.
+
+- Returning machine-readable codes improves integration, but the string returned by `messageForTransferRestriction` remains informational and is not an authorization primitive.
+
+- Using `uint8` for restriction codes limits the available code space to 256 values (`0` to `255`), which can create ambiguity if code allocation is not managed carefully.
+
+- [ERC-1404](./eip-1404.md) interface support alone is not evidence that a contract implements full [ERC-20](./eip-20.md) transfer behavior; a compliance-focused contract can expose [ERC-1404](./eip-1404.md) restriction interfaces and interface support while omitting parts of the [ERC-20](./eip-20.md) interface.
+
+- The original [ERC-1404](./eip-1404.md) text did not require [ERC-165](./eip-165.md) signaling. Therefore, older implementations may still implement [ERC-1404](./eip-1404.md) while not returning `true` for the [ERC-165](./eip-165.md) interface identifier `0xab84a5c8`.
+
+## Copyright
+
+Copyright and related rights waived via [CC0](../LICENSE.md).
diff --git a/doc/ERCSpecification/draft-erc-1643-document.md b/doc/ERCSpecification/draft-erc-1643-document.md
new file mode 100644
index 00000000..20cc0737
--- /dev/null
+++ b/doc/ERCSpecification/draft-erc-1643-document.md
@@ -0,0 +1,158 @@
+---
+eip: 1643
+title: Document Management for Security Tokens
+description: Interface to attach, update, remove, and enumerate legal or operational documents for token contracts.
+author: Adam Dossa (@adamdossa), Pablo Ruiz (@pabloruiz55), Fabian Vogelsteller (@frozeman), Stephane Gosselin (@thegostep), Ryan Sauge (@rya-sge)
+discussions-to: https://ethereum-magicians.org/t/erc-1643-document-management-standard-erc-1400/27437
+status: Draft
+type: Standards Track
+category: ERC
+created: 2018-09-09
+---
+
+## Abstract
+
+This ERC defines a standard interface for associating documents with a token contract and for notifying off-chain systems when those documents change. Documents can represent legal agreements, offering materials, disclosures, or other issuer-provided references needed for security token operations.
+
+## Motivation
+
+Security tokens commonly represent assets with legal rights and obligations that depend on external documents. Wallets, exchanges, custodians, and compliance tools need a predictable way to discover those documents and track updates.
+
+Without a standard, each implementation exposes different storage and retrieval methods, increasing integration cost and operational risk. A common interface allows ecosystem participants to read and monitor document metadata consistently.
+
+Within security token frameworks, the document management component highlights that security tokens usually have associated documentation such as offering documents and legend details. The ability to set, remove, and retrieve these documents, with events emitted on those actions, allows investors and integrators to remain up to date.
+
+This ERC intentionally does not define an on-chain mechanism for investors to attest they have read or agreed to any document.
+
+Although originally designed for security tokens built on [ERC-20](./eip-20.md) as part of a broader real-world asset token suite, this interface is not restricted to that context. It can be adopted by any token standard, including [ERC-721](./eip-721.md) non-fungible tokens and [ERC-1155](./eip-1155.md) multi-tokens, as well as by decentralized applications, vaults, and any other on-chain product that requires structured document management.
+
+Historically, this proposal was authored as part of a broader security token standards suite that had not yet been merged in this repository when this proposal was added.
+
+## Specification
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
+
+Implementations MUST support querying and subscribing to updates on any relevant documentation for the security.
+
+A document entry is identified by a name (`bytes32`) and stores:
+
+- A URI (`string`) pointing to the document location.
+- A content hash (`bytes32`) for integrity checks.
+- A last-modified timestamp (`uint256`) set when the entry is written.
+
+### Interface
+
+```solidity
+/// @title IERC1643 Document Management
+interface IERC1643 {
+ /// @notice Reverts when `setDocument` is called with `name == bytes32(0)`.
+ error ERC1643InvalidName();
+
+ /// @notice Reverts when `removeDocument` is called for a missing document.
+ error ERC1643MissingDocument();
+
+ /// @notice Returns metadata for a document identified by `name`.
+ /// @return uri Document location.
+ /// @return documentHash Hash of the document contents.
+ /// @return lastModified Last update timestamp.
+ function getDocument(bytes32 name) external view returns (string memory uri, bytes32 documentHash, uint256 lastModified);
+
+ /// @notice Creates or updates a document entry.
+ /// @dev MUST emit `DocumentUpdated` on success.
+ function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external;
+
+ /// @notice Removes an existing document entry.
+ /// @dev MUST emit `DocumentRemoved` on success.
+ function removeDocument(bytes32 name) external;
+
+ /// @notice Returns all document names currently tracked by the contract.
+ function getAllDocuments() external view returns (bytes32[] memory documentNames);
+
+ /// @notice Emitted when a document is created or updated.
+ event DocumentUpdated(bytes32 indexed name, string uri, bytes32 documentHash);
+
+ /// @notice Emitted when a document is removed.
+ event DocumentRemoved(bytes32 indexed name, string uri, bytes32 documentHash);
+}
+```
+
+### Interface Detection ([ERC-165](./eip-165.md))
+
+Implementations SHOULD support ERC-165 interface detection.
+
+When ERC-165 is implemented, `supportsInterface` SHOULD return `true` for `type(IERC1643).interfaceId` and for the ERC-165 interface id.
+
+### Function Requirements
+
+- `getDocument`:
+ - MUST return the latest values for the provided document name.
+ - MUST return empty values when the entry does not exist (`""`, `bytes32(0)`, `0`).
+ - MUST NOT revert solely because the entry does not exist.
+
+- `setDocument`:
+ - MUST create a new entry when `name` is not present.
+ - MUST overwrite the existing entry when `name` already exists.
+ - MUST update the stored last-modified timestamp.
+ - MUST emit `DocumentUpdated` after state changes.
+ - MUST revert if the update cannot be persisted.
+ - SHOULD revert when `name == bytes32(0)` to avoid ambiguous/default-key usage.
+ - `uri` and `documentHash` MAY be empty (`""` and `bytes32(0)`), depending on issuer workflow and document lifecycle stage.
+ - Implementations MAY decide to reject empty `uri` and/or empty `documentHash` based on policy requirements.
+ - Implementations SHOULD use the custom error defined in the interface (`ERC1643InvalidName()`) when rejecting `name == bytes32(0)`.
+ - Implementations MAY use different error names/signatures than those shown in this specification.
+
+- `removeDocument`:
+ - MUST remove the entry identified by `name`.
+ - MUST emit `DocumentRemoved` with the removed metadata.
+ - MUST revert if removal cannot be completed.
+ - Implementations SHOULD use the custom error defined in the interface (`ERC1643MissingDocument()`) when the named document does not exist.
+ - Implementations MAY use different error names/signatures than those shown in this specification.
+
+- `getAllDocuments`:
+ - MUST include every document name added by `setDocument` and not removed by `removeDocument`.
+ - MUST NOT include removed document names.
+
+## Rationale
+
+The standard uses `bytes32` names to keep keys compact and deterministic, while leaving naming conventions to implementations. A URI-based pointer is used instead of on-chain document storage to avoid high gas costs and to support existing off-chain document systems.
+
+Including a document hash enables clients to verify that fetched off-chain content matches issuer-published metadata. Emitting update and removal events supports indexing and near-real-time monitoring without repeated full-state polling.
+
+While a human-readable document title cannot always be represented directly in `bytes32` without hashing or canonicalization, `bytes32` remains practical for on-chain identifiers because fixed-size values can be compared directly (`a == b`). By contrast, `string` comparisons generally require hashing (for example, `keccak256(bytes(s))`), which increases contract code size and gas usage when repeated comparisons are needed on-chain, such as locating and removing a document name from an array.
+
+## Backwards Compatibility
+
+This ERC is additive and does not alter base token transfer semantics. It can be implemented alongside existing token standards and permissioning systems without changing their core behavior.
+
+## Test Cases
+
+Implementations should verify at least the following:
+
+- Adding a new document and reading it through `getDocument`.
+- Updating an existing document and validating changed URI/hash/timestamp.
+- Removing a document and ensuring it is no longer returned by `getAllDocuments`.
+- Emission of `DocumentUpdated` on create/update and `DocumentRemoved` on delete.
+- Enumeration consistency after multiple add/update/remove operations.
+
+## Reference Implementation
+
+The interface is provided in [the reference interface](../assets/eip-1643/src/erc-1643/IERC1643.sol). A reusable abstract module implementing the full interface is provided in [the reference module](../assets/eip-1643/src/erc-1643/ERC1643.sol). Example integrations attaching the module to [ERC-20](./eip-20.md) and [ERC-721](./eip-721.md) tokens are provided in [the ERC-20 example](../assets/eip-1643/src/ERC20DocumentToken.sol) and [the ERC-721 example](../assets/eip-1643/src/ERC721DocumentToken.sol). These examples use the OpenZeppelin library and restrict document mutation to the contract owner. They are provided for educational purposes only and have not been audited.
+
+The module maintains:
+
+- Mapping from `bytes32` name to document metadata.
+- Array/set for enumeration of active names.
+- Index tracking to support O(1) removals from the enumeration set.
+
+## Security Considerations
+
+- Document URIs may reference mutable off-chain content. Consumers are strongly encouraged to verify content using the published `documentHash` and trusted retrieval channels.
+- Implementations should protect `setDocument` and `removeDocument` with appropriate authorization, otherwise unauthorized actors can modify legal or operational references.
+- Applications should treat event streams as advisory and reconcile against on-chain state when correctness is critical.
+- Document names may not always fit cleanly into `bytes32`, especially for long legal titles. Implementations should avoid lossy truncation of human-readable names; using a deterministic hash-based identifier (for example, the document content hash or a hash of a canonical full title) as the `bytes32` name is a safer alternative.
+- The custom errors `ERC1643InvalidName()` and `ERC1643MissingDocument()` are defined in this interface but were absent from the original [ERC-1643](./eip-1643.md) proposal text. Older implementations may not define these errors and may instead revert with strings or implementation-specific error patterns. Integrators should not assume all ERC-1643 contracts expose identical revert data.
+- ERC-165 interface detection was also not part of the earlier ERC-1643 draft text. Older implementations may not expose `supportsInterface` for ERC-165 or `IERC1643`, so integrators should treat ERC-165 support as optional when interacting with legacy deployments.
+
+## Copyright
+
+Copyright and related rights waived via [CC0](../LICENSE.md).
diff --git a/.claude/skills/erc7551-ewpg/SKILL.md b/doc/ERCSpecification/draft-erc-7551-ewpg.md
similarity index 100%
rename from .claude/skills/erc7551-ewpg/SKILL.md
rename to doc/ERCSpecification/draft-erc-7551-ewpg.md
diff --git a/doc/ERCSpecification/draft-erc-deactivation.md b/doc/ERCSpecification/draft-erc-deactivation.md
new file mode 100644
index 00000000..3928e95a
--- /dev/null
+++ b/doc/ERCSpecification/draft-erc-deactivation.md
@@ -0,0 +1,144 @@
+---
+eip: xxxx
+title: Contract Deactivation Interface
+description: Interface for permanently deactivating a token contract and exposing its deactivation status
+author: Ryan Sauge (@rya-sge)
+discussions-to: https://ethereum-magicians.org/t/contract-deactivation-interface/0
+status: Draft
+type: Standards Track
+category: ERC
+created: 2026-02-12
+requires: 165
+---
+
+
+
+## Abstract
+
+This ERC defines a minimal interface for permanently deactivating a contract and exposing that terminal state on-chain. It introduces a one-way `deactivateContract()` operation and a `deactivated()` status view so wallets, exchanges, custodians, and protocols can reliably detect that a contract is no longer active.
+
+The proposal is motivated by regulated Real-World Asset (RWA) use cases where issuers may need to irreversibly stop token operations due to corporate actions, legal migration, or end-of-life lifecycle events. It is also useful for DeFi applications (for example lending markets or AMM pools) that need to publish a clear on-chain signal that an instance is no longer active. The interface is intentionally small and can be combined with existing token standards such as [ERC-20](./eip-20.md), [ERC-721](./eip-721.md), or [ERC-1155](./eip-1155.md). The proposal adopts [ERC-165](./eip-165.md) so integrators can discover support programmatically.
+
+## Motivation
+
+Pause mechanisms are useful for temporary incidents. They are not enough for terminal lifecycle events where the issuer must communicate that the contract is no longer meant to be reactivated.
+
+Common examples:
+
+- security migration to a new contract after a legal restructuring,
+- capitalization events (e.g. merger, split, reverse split) requiring old units to be immobilized,
+- issuer decision to discontinue a ledger-based representation,
+- DeFi market shutdowns (for example lending pool or AMM pair retirement) where operators need to signal permanent inactivity.
+
+Without a standard signal, integrations cannot distinguish:
+
+- a temporary pause,
+- an operational outage,
+- a permanent deactivation.
+
+This ERC standardizes that signal.
+
+This ERC is primarily designed for token contracts, but it is not limited to ERC-20 semantics and can be applied to contracts implementing other asset models.
+
+## Specification
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
+
+### Interface
+
+```solidity
+interface IERCDeactivation is IERC165 {
+ /// @notice Emitted when the contract is permanently deactivated.
+ /// @param account The address that triggered deactivation.
+ event Deactivated(address indexed account);
+
+ /// @notice Error raised when deactivation is attempted after deactivation is already final.
+ error AlreadyDeactivated();
+
+ /// @notice Permanently deactivates the contract.
+ function deactivateContract() external;
+
+ /// @notice Returns whether the contract has been deactivated.
+ function deactivated() external view returns (bool isDeactivated);
+}
+```
+
+### ERC-165 Support
+
+Implementations MUST implement [ERC-165](./eip-165.md) and MUST return `true` from `supportsInterface` for:
+
+- `0x01ffc9a7` (`IERC165`)
+- `0xe9cd80b0` (`IERCDeactivation`)
+
+Implementations MUST return `false` for `supportsInterface(0xffffffff)`.
+
+### Required Behavior
+
+1. **One-way state**
+ - `deactivated()` MUST return `false` before successful deactivation and `true` after successful deactivation.
+ - Once `deactivated()` becomes `true`, it MUST NOT return to `false` in the active implementation.
+ - In upgradeable proxy systems, a future implementation MAY alter behavior. This does not break interface compatibility, but changes permanence assumptions and SHOULD be clearly disclosed to integrators.
+ - Implementations behind upgradeable proxies SHOULD NOT present `deactivated()` as an on-chain technical guarantee of irreversible finality unless upgrade authority is effectively removed.
+
+2. **Deactivation call**
+ - `deactivateContract()` MUST set the deactivation state to `true`.
+ - `deactivateContract()` MUST emit `Deactivated(account)`.
+ - `deactivateContract()` MUST revert with `AlreadyDeactivated()` if deactivation has already happened.
+ - `deactivateContract()` MUST be access-controlled.
+
+3. **Pause precondition**
+ - Implementations using a pause mechanism SHOULD require the contract to be paused before `deactivateContract()` succeeds.
+ - If a pause precondition is used and not met, `deactivateContract()` MUST revert.
+
+4. **Post-deactivation operational guarantees**
+ - After deactivation, holder-initiated asset movement operations MUST revert. For example:
+ - ERC-20: `transfer`, `transferFrom`
+ - ERC-721
+ - ERC-1155
+ - After `deactivated() == true`, all non-privileged, non-view, and non-pure holder operations MUST revert.
+ - After deactivation, supply-changing operations intended for normal lifecycle management (for example standard `mint` and `burn`) MUST revert.
+ - If the implementation includes `unpause`, it MUST revert when `deactivated() == true`.
+ - Implementations MAY keep only explicitly named privileged emergency/regulatory operations (for example `forcedTransfer`) available after deactivation.
+ - Any privileged operation that remains available after deactivation MUST be listed in the implementation documentation and clearly marked as post-deactivation-enabled.
+ - Privileged operations that are not explicitly named as post-deactivation-enabled MUST revert when `deactivated() == true`.
+
+5. **Observability**
+ - `deactivated()` MUST be a non-reverting view function.
+ - Indexers and off-chain systems SHOULD treat `Deactivated` as a terminal lifecycle event for public holder operations, rather than as a guarantee that no privileged operation can ever execute.
+ - This interpretation does not imply restrictions on view or pure read-only functions.
+ - For upgradeable proxy deployments, integrators are RECOMMENDED to adopt a conservative default assumption that once deactivated, the contract remains permanently deactivated, unless governance documentation explicitly states otherwise.
+
+## Rationale
+
+- **Minimalism**: Two functions and one event are sufficient for broad interoperability.
+- **Separation of concerns**: This ERC does not mandate any access-control model, pause design, or legal workflow.
+- **RWA and DeFi lifecycle signaling**: The standard addresses regulated token lifecycle events and DeFi lifecycle events (such as lending/AMM retirements) with a shared, auditable "no longer active" signal.
+- **Compatibility with existing pause modules**: The interface composes naturally with existing pause implementations where deactivation acts as a permanent terminal pause.
+- **Deployment-model neutrality**: Both immutable contracts and upgradeable proxies are compatible with this ERC. The interface standardizes signaling, not governance guarantees.
+
+## Backwards Compatibility
+
+This ERC is additive and does not modify existing token standards. Existing wallets and protocols can continue using base token interfaces and optionally integrate this ERC to detect terminal deactivation status.
+
+## Reference Implementation
+
+A reference pattern is:
+
+- store a boolean `isDeactivated`,
+- gate `deactivateContract()` behind authorization,
+- require paused state (if pause exists),
+- set `isDeactivated = true`,
+- emit `Deactivated(msg.sender)`,
+- reject `unpause` and normal transfer/mint/burn flows when deactivated.
+
+## Security Considerations
+
+- **Authorization risk**: Unauthorized access to `deactivateContract()` creates irreversible denial of service. Use robust access control (multisig, timelock, separation of duties).
+- **Proxy nuance**: In upgradeable systems, deactivation may be bypassed by deploying a new implementation that changes logic. If strict permanence is required, implementations should use immutable deployments or disable upgrades (for example by irrevocably renouncing upgrade authority).
+- **Integrator default for proxies**: For upgradeable proxy deployments, integrators should apply a conservative trust model and treat deactivation as permanent by default, unless issuer governance documentation explicitly communicates a different policy.
+- **Operational risk**: Because deactivation is terminal, operators should use staged procedures (pause first, confirm terms/migration, then deactivate).
+- **Integration risk**: Integrators should check `deactivated()` before presenting token actions to users.
+
+## Copyright
+
+Copyright and related rights waived via [CC0](../LICENSE.md).
diff --git a/doc/ERCSpecification/erc-2612-permit.md b/doc/ERCSpecification/erc-2612-permit.md
new file mode 100644
index 00000000..a70cf591
--- /dev/null
+++ b/doc/ERCSpecification/erc-2612-permit.md
@@ -0,0 +1,198 @@
+---
+eip: 2612
+title: Permit Extension for EIP-20 Signed Approvals
+description: EIP-20 approvals via EIP-712 secp256k1 signatures
+author: Martin Lundfall (@Mrchico)
+discussions-to: https://github.com/ethereum/EIPs/issues/2613
+status: Final
+type: Standards Track
+category: ERC
+created: 2020-04-13
+requires: 20, 712
+---
+
+## Abstract
+
+Arguably one of the main reasons for the success of [EIP-20](./eip-20.md) tokens lies in the interplay between `approve` and `transferFrom`, which allows for tokens to not only be transferred between externally owned accounts (EOA), but to be used in other contracts under application specific conditions by abstracting away `msg.sender` as the defining mechanism for token access control.
+
+However, a limiting factor in this design stems from the fact that the EIP-20 `approve` function itself is defined in terms of `msg.sender`. This means that user's _initial action_ involving EIP-20 tokens must be performed by an EOA (_but see Note below_). If the user needs to interact with a smart contract, then they need to make 2 transactions (`approve` and the smart contract call which will internally call `transferFrom`). Even in the simple use case of paying another person, they need to hold ETH to pay for transaction gas costs.
+
+This ERC extends the EIP-20 standard with a new function `permit`, which allows users to modify the `allowance` mapping using a signed message, instead of through `msg.sender`.
+
+For an improved user experience, the signed data is structured following [EIP-712](./eip-712.md), which already has wide spread adoption in major RPC providers.
+
+**_Note:_** EIP-20 must be performed by an EOA unless the address owning the token is actually a contract wallet. Although contract wallets solves many of the same problems that motivates this EIP, they are currently only scarcely adopted in the ecosystem. Contract wallets suffer from a UX problem -- since they separate the EOA `owner` of the contract wallet from the contract wallet itself (which is meant to carry out actions on the `owner`s behalf and holds all of their funds), user interfaces need to be specifically designed to support them. The `permit` pattern reaps many of the same benefits while requiring little to no change in user interfaces.
+
+## Motivation
+
+While EIP-20 tokens have become ubiquitous in the Ethereum ecosystem, their status remains that of second class tokens from the perspective of the protocol. The ability for users to interact with Ethereum without holding any ETH has been a long outstanding goal and the subject of many EIPs.
+
+So far, many of these proposals have seen very little adoption, and the ones that have been adopted (such as [EIP-777](./eip-777.md)), introduce a lot of additional functionality, causing unexpected behavior in mainstream contracts.
+
+This ERC proposes an alternative solution which is designed to be as minimal as possible and to only address _one problem_: the lack of abstraction in the EIP-20 `approve` method.
+
+While it may be tempting to introduce `*_by_signature` counterparts for every EIP-20 function, they are intentionally left out of this EIP-20 for two reasons:
+
+- the desired specifics of such functions, such as decision regarding fees for `transfer_by_signature`, possible batching algorithms, varies depending on the use case, and,
+- they can be implemented using a combination of `permit` and additional helper contracts without loss of generality.
+
+## Specification
+
+Compliant contracts must implement 3 new functions in addition to EIP-20:
+
+```sol
+function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external
+function nonces(address owner) external view returns (uint)
+function DOMAIN_SEPARATOR() external view returns (bytes32)
+```
+
+The semantics of which are as follows:
+
+For all addresses `owner`, `spender`, uint256s `value`, `deadline` and `nonce`, uint8 `v`, bytes32 `r` and `s`,
+a call to `permit(owner, spender, value, deadline, v, r, s)` will set
+`allowance[owner][spender]` to `value`,
+increment `nonces[owner]` by 1,
+and emit a corresponding `Approval` event,
+if and only if the following conditions are met:
+
+- The current blocktime is less than or equal to `deadline`.
+- `owner` is not the zero address.
+- `nonces[owner]` (before the state update) is equal to `nonce`.
+- `r`, `s` and `v` is a valid `secp256k1` signature from `owner` of the message:
+
+If any of these conditions are not met, the `permit` call must revert.
+
+```sol
+keccak256(abi.encodePacked(
+ hex"1901",
+ DOMAIN_SEPARATOR,
+ keccak256(abi.encode(
+ keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"),
+ owner,
+ spender,
+ value,
+ nonce,
+ deadline))
+))
+```
+
+where `DOMAIN_SEPARATOR` is defined according to EIP-712. The `DOMAIN_SEPARATOR` should be unique to the contract and chain to prevent replay attacks from other domains,
+and satisfy the requirements of EIP-712, but is otherwise unconstrained.
+A common choice for `DOMAIN_SEPARATOR` is:
+
+```solidity
+DOMAIN_SEPARATOR = keccak256(
+ abi.encode(
+ keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
+ keccak256(bytes(name)),
+ keccak256(bytes(version)),
+ chainid,
+ address(this)
+));
+```
+
+In other words, the message is the EIP-712 typed structure:
+
+```js
+{
+ "types": {
+ "EIP712Domain": [
+ {
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "name": "version",
+ "type": "string"
+ },
+ {
+ "name": "chainId",
+ "type": "uint256"
+ },
+ {
+ "name": "verifyingContract",
+ "type": "address"
+ }
+ ],
+ "Permit": [
+ {
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "name": "value",
+ "type": "uint256"
+ },
+ {
+ "name": "nonce",
+ "type": "uint256"
+ },
+ {
+ "name": "deadline",
+ "type": "uint256"
+ }
+ ],
+ },
+ "primaryType": "Permit",
+ "domain": {
+ "name": erc20name,
+ "version": version,
+ "chainId": chainid,
+ "verifyingContract": tokenAddress
+ },
+ "message": {
+ "owner": owner,
+ "spender": spender,
+ "value": value,
+ "nonce": nonce,
+ "deadline": deadline
+ }
+}
+```
+
+Note that nowhere in this definition we refer to `msg.sender`. The caller of the `permit` function can be any address.
+
+## Rationale
+
+The `permit` function is sufficient for enabling any operation involving EIP-20 tokens to be paid for using the token itself, rather than using ETH.
+
+The `nonces` mapping is given for replay protection.
+
+A common use case of `permit` has a relayer submit a `Permit` on behalf of the `owner`. In this scenario, the relaying party is essentially given a free option to submit or withhold the `Permit`. If this is a cause of concern, the `owner` can limit the time a `Permit` is valid for by setting `deadline` to a value in the near future. The `deadline` argument can be set to `uint(-1)` to create `Permit`s that effectively never expire.
+
+EIP-712 typed messages are included because of its wide spread adoption in many wallet providers.
+
+## Backwards Compatibility
+
+There are already a couple of `permit` functions in token contracts implemented in contracts in the wild, most notably the one introduced in the `dai.sol`.
+
+Its implementation differs slightly from the presentation here in that:
+
+- instead of taking a `value` argument, it takes a bool `allowed`, setting approval to 0 or `uint(-1)`.
+- the `deadline` argument is instead called `expiry`. This is not just a syntactic change, as it effects the contents of the signed message.
+
+There is also an implementation in the token `Stake` (Ethereum address `0x0Ae055097C6d159879521C384F1D2123D1f195e6`) with the same ABI as `dai` but with different semantics: it lets users issue "expiring approvals", that only allow `transferFrom` to occur while `expiry >= block.timestamp`.
+
+The specification presented here is in line with the implementation in Uniswap V2.
+
+The requirement to revert if the permit is invalid was added when the EIP was already widely deployed, but at the moment it was consistent with all found implementations.
+
+## Security Considerations
+
+Though the signer of a `Permit` may have a certain party in mind to submit their transaction, another party can always front run this transaction and call `permit` before the intended party. The end result is the same for the `Permit` signer, however.
+
+Since the ecrecover precompile fails silently and just returns the zero address as `signer` when given malformed messages, it is important to ensure `owner != address(0)` to avoid `permit` from creating an approval to spend "zombie funds" belong to the zero address.
+
+Signed `Permit` messages are censorable. The relaying party can always choose to not submit the `Permit` after having received it, withholding the option to submit it. The `deadline` parameter is one mitigation to this. If the signing party holds ETH they can also just submit the `Permit` themselves, which can render previously signed `Permit`s invalid.
+
+The standard EIP-20 race condition for approvals (SWC-114) applies to `permit` as well.
+
+If the `DOMAIN_SEPARATOR` contains the `chainId` and is defined at contract deployment instead of reconstructed for every signature, there is a risk of possible replay attacks between chains in the event of a future chain split.
+
+## Copyright
+
+Copyright and related rights waived via [CC0](../LICENSE.md).
diff --git a/.claude/skills/erc3643/SKILL.md b/doc/ERCSpecification/erc-3643-trex.md
similarity index 100%
rename from .claude/skills/erc3643/SKILL.md
rename to doc/ERCSpecification/erc-3643-trex.md
diff --git a/doc/ERCSpecification/erc-6357-multicall.md b/doc/ERCSpecification/erc-6357-multicall.md
new file mode 100644
index 00000000..9664ba7f
--- /dev/null
+++ b/doc/ERCSpecification/erc-6357-multicall.md
@@ -0,0 +1,91 @@
+---
+eip: 6357
+title: Single-contract Multi-delegatecall
+description: Allows an EOA to call multiple functions of a smart contract in a single transaction
+author: Gavin John (@Pandapip1)
+discussions-to: https://ethereum-magicians.org/t/eip-6357-single-contract-multicall/12621
+status: Last Call
+last-call-deadline: 2023-11-10
+type: Standards Track
+category: ERC
+created: 2023-01-18
+---
+
+## Abstract
+
+This EIP standardizes an interface containing a single function, `multicall`, allowing EOAs to call multiple functions of a smart contract in a single transaction, and revert all calls if any call fails.
+
+## Motivation
+
+Currently, in order to transfer several [ERC-721](./eip-721.md) NFTs, one needs to submit a number of transactions equal to the number of NFTs being tranferred. This wastes users' funds by requiring them to pay 21000 gas fee for every NFT they transfer.
+
+## Specification
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
+
+Contracts implementing this EIP must implement the following interface:
+
+```solidity
+pragma solidity ^0.8.0;
+
+interface IMulticall {
+ /// @notice Takes an array of abi-encoded call data, delegatecalls itself with each calldata, and returns the abi-encoded result
+ /// @dev Reverts if any delegatecall reverts
+ /// @param data The abi-encoded data
+ /// @returns results The abi-encoded return values
+ function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results);
+
+ /// @notice OPTIONAL. Takes an array of abi-encoded call data, delegatecalls itself with each calldata, and returns the abi-encoded result
+ /// @dev Reverts if any delegatecall reverts
+ /// @param data The abi-encoded data
+ /// @param values The effective msg.values. These must add up to at most msg.value
+ /// @returns results The abi-encoded return values
+ function multicallPayable(bytes[] calldata data, uint256[] values) external payable virtual returns (bytes[] memory results);
+}
+```
+
+## Rationale
+
+`multicallPayable` is optional because it isn't always feasible to implement, due to the `msg.value` splitting.
+
+## Backwards Compatibility
+
+This is compatible with most existing multicall functions.
+
+## Test Cases
+
+The following JavaScript code, using the Ethers library, should atomically transfer `amt` units of an [ERC-20](./eip-20.md) token to both `addressA` and `addressB`.
+
+```js
+await token.multicall(await Promise.all([
+ token.interface.encodeFunctionData('transfer', [ addressA, amt ]),
+ token.interface.encodeFunctionData('transfer', [ addressB, amt ]),
+]));
+```
+
+## Reference Implementation
+
+```solidity
+pragma solidity ^0.8.0;
+
+/// Derived from OpenZeppelin's implementation
+abstract contract Multicall is IMulticall {
+ function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
+ results = new bytes[](data.length);
+ for (uint256 i = 0; i < data.length; i++) {
+ (bool success, bytes memory returndata) = address(this).delegatecall(data);
+ require(success);
+ results[i] = returndata;
+ }
+ return results;
+ }
+}
+```
+
+## Security Considerations
+
+`multicallPayable` should only be used if the contract is able to support it. A naive attempt at implementing it could allow an attacker to call a payable function multiple times with the same ether.
+
+## Copyright
+
+Copyright and related rights waived via [CC0](../LICENSE.md).
diff --git a/doc/ERCSpecification/erc-7943-uRWA.md b/doc/ERCSpecification/erc-7943-uRWA.md
new file mode 100644
index 00000000..cd92d394
--- /dev/null
+++ b/doc/ERCSpecification/erc-7943-uRWA.md
@@ -0,0 +1,447 @@
+---
+eip: 7943
+title: uRWA - Universal Real World Asset Interface
+description: Interfaces for common base tokens defining compliance checks, transfer controls, and enforcement actions for Real World Assets (RWAs).
+author: Dario Lo Buglio (@xaler5), Tino Martinez Molina (@tinom9), Mihai Colceriu (@mihaic195)
+discussions-to: https://ethereum-magicians.org/t/erc-universal-rwa-interface/23972
+status: Last Call
+last-call-deadline: 2026-01-30
+type: Standards Track
+category: ERC
+created: 2025-06-10
+requires: 165
+---
+
+## Abstract
+
+This EIP proposes the Universal RWA (uRWA) standard, a set of interfaces for tokenized Real World Assets (RWAs) such as securities, real estate, commodities, or other physical/financial assets on the blockchain.
+
+Real World Assets often require regulatory compliance features not found in standard tokens, including the ability to freeze assets, perform enforcement transfers for legal compliance, and restrict transfers to authorized users. The uRWA standard extends common token standards like [ERC-20](./eip-20.md), [ERC-721](./eip-721.md), or [ERC-1155](./eip-1155.md) by introducing essential compliance functions while remaining minimal and not opinionated about specific implementation details.
+
+This enables DeFi protocols and applications to interact with tokenized real-world assets in a standardized way, knowing they can check transfer permissions, whether users are allowed to interact, handle frozen assets appropriately, and integrate with compliant RWA tokens regardless of the underlying asset type or internal compliance logic. It also adopts [ERC-165](./eip-165.md) for introspection.
+
+## Motivation
+
+Real World Assets (RWAs) represent a significant opportunity to bridge traditional finance and decentralized finance (DeFi). By tokenizing assets like real estate, corporate bonds, commodities, art, or securities, we can unlock benefits such as fractional ownership, programmable compliance, enhanced liquidity through secondary markets for traditionally illiquid assets, and integration with decentralized protocols.
+
+However, tokenizing real world assets introduces regulatory requirements often absent in purely digital assets, such as allowlists for users, transfer restrictions, asset freezing, or law enforcement rules. Existing token standards like [ERC-20](./eip-20.md), [ERC-721](./eip-721.md), and [ERC-1155](./eip-1155.md) lack the inherent structure to address these compliance needs directly within the standard itself.
+
+Attempts at defining universal RWA standards historically imposed unnecessary complexity and gas overhead for simpler use cases that do not require the full spectrum of features like granular role-based access control, mandatory on-chain whitelisting, specific on-chain identity solutions, or metadata handling solutions mandated by the standard.
+
+Additionally, the broad spectrum of RWA classes inherently suggests the need to move away from a one-size-fits-all solution. This means a minimalistic approach, an unopinionated features list, and maximal compatibility have been kept in mind as design goals.
+
+The uRWA standard seeks a more refined balance by defining an essential interface, establishing a common ground for interaction regarding compliance and control, without dictating the underlying implementation mechanisms. This allows core token implementations to remain lean while providing standard functions for RWA-specific interactions.
+
+The final goal is to build composable DeFi around RWAs, providing the same interface when dealing with compliance and regulation.
+
+## Specification
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", and "MAY" in this document are to be interpreted as described in RFC 2119 and RFC 8174.
+
+The following defines the standard interfaces for an [ERC-7943](./eip-7943.md) token contract, which MUST extend from one base token interface such as [ERC-20](./eip-20.md), [ERC-721](./eip-721.md), [ERC-1155](./eip-1155.md), or [ERC-6909](./eip-6909.md). Note that [ERC-6909](./eip-6909.md)-based implementations can use the multi token interface:
+
+```solidity
+/// @notice Interface for ERC-20 based implementations.
+interface IERC7943Fungible is IERC165 {
+ /// @notice Emitted when tokens are taken from one address and transferred to another.
+ /// @param from The address from which tokens were taken.
+ /// @param to The address to which seized tokens were transferred.
+ /// @param amount The amount seized.
+ event ForcedTransfer(address indexed from, address indexed to, uint256 amount);
+
+ /// @notice Emitted when `setFrozenTokens` is called, changing the frozen `amount` of tokens for `account`.
+ /// @param account The address of the account whose tokens are being frozen.
+ /// @param amount The amount of tokens frozen after the change.
+ event Frozen(address indexed account, uint256 amount);
+
+ /// @notice Error reverted when an account is not allowed to send tokens.
+ /// @param account The address of the account which is not allowed to send.
+ error ERC7943CannotSend(address account);
+
+ /// @notice Error reverted when an account is not allowed to receive tokens.
+ /// @param account The address of the account which is not allowed to receive.
+ error ERC7943CannotReceive(address account);
+
+ /// @notice Error reverted when a transfer is not allowed according to internal rules.
+ /// @param from The address from which tokens are being sent.
+ /// @param to The address to which tokens are being sent.
+ /// @param amount The amount sent.
+ error ERC7943CannotTransfer(address from, address to, uint256 amount);
+
+ /// @notice Error reverted when a transfer is attempted from `account` with an `amount` less than or equal to its balance, but greater than its unfrozen balance.
+ /// @param account The address holding the tokens.
+ /// @param amount The amount being transferred.
+ /// @param unfrozen The amount of tokens that are unfrozen and available to transfer.
+ error ERC7943InsufficientUnfrozenBalance(address account, uint256 amount, uint256 unfrozen);
+
+ /// @notice Takes tokens from one address and transfers them to another.
+ /// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
+ /// @param from The address from which `amount` is taken.
+ /// @param to The address that receives `amount`.
+ /// @param amount The amount to force transfer.
+ /// @return result True if the transfer executed correctly. Reverts on failure.
+ function forcedTransfer(address from, address to, uint256 amount) external returns (bool result);
+
+ /// @notice Changes the frozen status of `amount` tokens belonging to `account`.
+ /// @dev Overwrites the current value, similar to an `approve` function.
+ /// Requires specific authorization. Frozen tokens cannot be transferred by the account.
+ /// @param account The address of the account whose tokens are to be frozen.
+ /// @param amount The amount of tokens to freeze. It can be greater than the account balance.
+ /// @return result True if the freezing executed correctly. Reverts on failure.
+ function setFrozenTokens(address account, uint256 amount) external returns (bool result);
+
+ /// @notice Checks if a specific account is allowed to send tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to send, false otherwise.
+ function canSend(address account) external view returns (bool allowed);
+
+ /// @notice Checks if a specific account is allowed to receive tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to receive, false otherwise.
+ function canReceive(address account) external view returns (bool allowed);
+
+ /// @notice Checks the frozen status/amount.
+ /// @param account The address of the account.
+ /// @dev It could return an amount higher than the account's balance.
+ /// @return amount The amount of tokens currently frozen for `account`.
+ function getFrozenTokens(address account) external view returns (uint256 amount);
+
+ /// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
+ /// @dev This can involve checks like allowlists, blocklists, transfer limits, and other policy-defined restrictions.
+ /// @param from The address sending tokens.
+ /// @param to The address receiving tokens.
+ /// @param amount The amount being transferred.
+ /// @return allowed True if the transfer is allowed, false otherwise.
+ function canTransfer(address from, address to, uint256 amount) external view returns (bool allowed);
+}
+
+/// @notice Interface for ERC-721 based implementations.
+interface IERC7943NonFungible is IERC165 {
+ /// @notice Emitted when `tokenId` is taken from one address and transferred to another.
+ /// @param from The address from which `tokenId` is taken.
+ /// @param to The address to which seized `tokenId` is transferred.
+ /// @param tokenId The ID of the token being transferred.
+ event ForcedTransfer(address indexed from, address indexed to, uint256 indexed tokenId);
+
+ /// @notice Emitted when `setFrozenTokens` is called, changing the frozen status of `tokenId` for `account`.
+ /// @param account The address of the account whose `tokenId` is subjected to freeze/unfreeze.
+ /// @param tokenId The ID of the token subjected to freeze/unfreeze.
+ /// @param frozenStatus Whether `tokenId` has been frozen or unfrozen.
+ event Frozen(address indexed account, uint256 indexed tokenId, bool indexed frozenStatus);
+
+ /// @notice Error reverted when an account is not allowed to send tokens.
+ /// @param account The address of the account which is not allowed to send.
+ error ERC7943CannotSend(address account);
+
+ /// @notice Error reverted when an account is not allowed to receive tokens.
+ /// @param account The address of the account which is not allowed to receive.
+ error ERC7943CannotReceive(address account);
+
+ /// @notice Error reverted when a transfer is not allowed according to internal rules.
+ /// @param from The address from which tokens are being sent.
+ /// @param to The address to which tokens are being sent.
+ /// @param tokenId The ID of the token being sent.
+ error ERC7943CannotTransfer(address from, address to, uint256 tokenId);
+
+ /// @notice Error reverted when a transfer is attempted from `account` with a `tokenId` which has been previously frozen.
+ /// @param account The address holding the token with `tokenId`.
+ /// @param tokenId The ID of the token being frozen and unavailable to be transferred.
+ error ERC7943InsufficientUnfrozenBalance(address account, uint256 tokenId);
+
+ /// @notice Takes `tokenId` from one address and transfers it to another.
+ /// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
+ /// @param from The address from which `tokenId` is taken.
+ /// @param to The address that receives `tokenId`.
+ /// @param tokenId The ID of the token being transferred.
+ /// @return result True if the transfer executed correctly. Reverts on failure.
+ function forcedTransfer(address from, address to, uint256 tokenId) external returns (bool result);
+
+ /// @notice Changes the frozen status of `tokenId` belonging to an `account`.
+ /// @dev Overwrites the current value, similar to an `approve` function.
+ /// Requires specific authorization. Frozen tokens cannot be transferred by the account.
+ /// @param account The address of the account whose tokens are to be frozen.
+ /// @param tokenId The ID of the token to freeze.
+ /// @param frozenStatus Whether `tokenId` is being frozen or not.
+ /// @return result True if the freezing executed correctly. Reverts on failure.
+ function setFrozenTokens(address account, uint256 tokenId, bool frozenStatus) external returns (bool result);
+
+ /// @notice Checks if a specific account is allowed to send tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to send, false otherwise.
+ function canSend(address account) external view returns (bool allowed);
+
+ /// @notice Checks if a specific account is allowed to receive tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to receive, false otherwise.
+ function canReceive(address account) external view returns (bool allowed);
+
+ /// @notice Checks the frozen status of a specific `tokenId`.
+ /// @dev It could return true even if the account does not hold the token.
+ /// @param account The address of the account.
+ /// @param tokenId The ID of the token.
+ /// @return frozenStatus Whether `tokenId` is currently frozen for `account`.
+ function getFrozenTokens(address account, uint256 tokenId) external view returns (bool frozenStatus);
+
+ /// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
+ /// @dev This can involve checks like allowlists, blocklists, transfer limits, and other policy-defined restrictions.
+ /// @param from The address sending tokens.
+ /// @param to The address receiving tokens.
+ /// @param tokenId The ID of the token being transferred.
+ /// @return allowed True if the transfer is allowed, false otherwise.
+ function canTransfer(address from, address to, uint256 tokenId) external view returns (bool allowed);
+}
+
+/// @notice Interface for ERC-1155 based implementations.
+interface IERC7943MultiToken is IERC165 {
+ /// @notice Emitted when tokens are taken from one address and transferred to another.
+ /// @param from The address from which tokens were taken.
+ /// @param to The address to which seized tokens were transferred.
+ /// @param tokenId The ID of the token being transferred.
+ /// @param amount The amount seized.
+ event ForcedTransfer(address indexed from, address indexed to, uint256 indexed tokenId, uint256 amount);
+
+ /// @notice Emitted when `setFrozenTokens` is called, changing the frozen `amount` of `tokenId` tokens for `account`.
+ /// @param account The address of the account whose tokens are being frozen.
+ /// @param tokenId The ID of the token being frozen.
+ /// @param amount The amount of tokens frozen after the change.
+ event Frozen(address indexed account, uint256 indexed tokenId, uint256 amount);
+
+ /// @notice Error reverted when an account is not allowed to send tokens.
+ /// @param account The address of the account which is not allowed to send.
+ error ERC7943CannotSend(address account);
+
+ /// @notice Error reverted when an account is not allowed to receive tokens.
+ /// @param account The address of the account which is not allowed to receive.
+ error ERC7943CannotReceive(address account);
+
+ /// @notice Error reverted when a transfer is not allowed according to internal rules.
+ /// @param from The address from which tokens are being sent.
+ /// @param to The address to which tokens are being sent.
+ /// @param tokenId The ID of the token being sent.
+ /// @param amount The amount sent.
+ error ERC7943CannotTransfer(address from, address to, uint256 tokenId, uint256 amount);
+
+ /// @notice Error reverted when a transfer is attempted from `account` with an `amount` of `tokenId` less than or equal to its balance, but greater than its unfrozen balance.
+ /// @param account The address holding the `amount` of `tokenId` tokens.
+ /// @param tokenId The ID of the token being transferred.
+ /// @param amount The amount of `tokenId` tokens being transferred.
+ /// @param unfrozen The amount of tokens that are unfrozen and available to transfer.
+ error ERC7943InsufficientUnfrozenBalance(address account, uint256 tokenId, uint256 amount, uint256 unfrozen);
+
+ /// @notice Takes tokens from one address and transfers them to another.
+ /// @dev Requires specific authorization. Used for regulatory compliance or recovery scenarios.
+ /// @param from The address from which `amount` is taken.
+ /// @param to The address that receives `amount`.
+ /// @param tokenId The ID of the token being transferred.
+ /// @param amount The amount to force transfer.
+ /// @return result True if the transfer executed correctly. Reverts on failure.
+ function forcedTransfer(address from, address to, uint256 tokenId, uint256 amount) external returns (bool result);
+
+ /// @notice Changes the frozen status of `amount` of `tokenId` tokens belonging to an `account`.
+ /// @dev Overwrites the current value, similar to an `approve` function.
+ /// Requires specific authorization. Frozen tokens cannot be transferred by the account.
+ /// @param account The address of the account whose tokens are to be frozen.
+ /// @param tokenId The ID of the token to freeze.
+ /// @param amount The amount of tokens to freeze. It can be greater than the account balance.
+ /// @return result True if the freezing executed correctly. Reverts on failure.
+ function setFrozenTokens(address account, uint256 tokenId, uint256 amount) external returns (bool result);
+
+ /// @notice Checks if a specific account is allowed to send tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to send, false otherwise.
+ function canSend(address account) external view returns (bool allowed);
+
+ /// @notice Checks if a specific account is allowed to receive tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to receive, false otherwise.
+ function canReceive(address account) external view returns (bool allowed);
+
+ /// @notice Checks the frozen status/amount of a specific `tokenId`.
+ /// @dev It could return an amount higher than the account's balance.
+ /// @param account The address of the account.
+ /// @param tokenId The ID of the token.
+ /// @return amount The amount of `tokenId` tokens currently frozen for `account`.
+ function getFrozenTokens(address account, uint256 tokenId) external view returns (uint256 amount);
+
+ /// @notice Checks if a transfer is currently possible according to token rules. It enforces validations on the frozen tokens.
+ /// @dev This can involve checks like allowlists, blocklists, transfer limits, and other policy-defined restrictions.
+ /// @param from The address sending tokens.
+ /// @param to The address receiving tokens.
+ /// @param tokenId The ID of the token being transferred.
+ /// @param amount The amount being transferred.
+ /// @return allowed True if the transfer is allowed, false otherwise.
+ function canTransfer(address from, address to, uint256 tokenId, uint256 amount) external view returns (bool allowed);
+}
+```
+
+### `canSend`, `canReceive`, `canTransfer`, and `getFrozenTokens`
+
+These provide views into the implementing contract's compliance, transfer policy logic, and freezing status.
+
+- `canSend` and `canReceive` are account-level eligibility checks, independent of any specific transfer parameters (counterparty, amount, or token identifier). These functions:
+ - MUST NOT revert.
+ - MUST NOT change the storage of the contract.
+ - MAY depend on on-chain state such as current timestamp, block number, or `msg.sender`.
+ - MUST NOT encode transfer-specific or quantitative rules (e.g., balance checks, amount limits). Those belong in `canTransfer`.
+
+- `canTransfer` is a transfer-level authorization check that evaluates whether a specific transfer is permissible under permissioned compliance rules. This function:
+ - MUST NOT revert.
+ - MUST NOT change the storage of the contract.
+ - MAY depend on on-chain state such as current timestamp, block number, or `msg.sender`.
+ - MUST validate that the `amount` being transferred doesn't exceed the unfrozen amount (which is the difference between the current balance and the frozen balance).
+ - MUST perform a `canSend` check on the `from` parameter and a `canReceive` check on the `to` parameter. Note that [ERC-3643](./eip-3643.md) does not perform this check within `canTransfer` as this standard requires.
+ - MUST return false if any permissioned rule would prevent a given transfer from succeeding. A transfer refers to any operation that emits the token's canonical transfer event. A permissioned check can be a pausing mechanism, a call to `canSend`/`canReceive`, or anything else that requires privileged actors.
+ - MUST NOT return false based on token-specific, non-permissioned validations such as balance or allowance checks. These checks belong to the underlying base token standard (e.g., [ERC-20](./eip-20.md), [ERC-721](./eip-721.md), [ERC-1155](./eip-1155.md)).
+
+- `getFrozenTokens` will return the absolute frozen amount, which MAY exceed the account's current balance. In [ERC-721](./eip-721.md) tokens, it MAY return true even if the account does not hold the token.
+
+### `forcedTransfer`
+
+This function provides a standard mechanism for forcing a transfer from a `from` address to a `to` address. The function:
+
+- MUST directly manipulate balances or ownership to transfer the asset from `from` to `to` either by transferring or burning from `from` and minting to `to`.
+- MUST be restricted in access.
+- MUST perform necessary validation checks (e.g., sufficient balance/ownership of a specific token).
+- MUST emit the base standard's canonical transfer event(s), consistent with the mechanism used (transfer or burn and mint), and MUST emit the `ForcedTransfer` event.
+- In single-party permissioned contexts:
+ - It MAY bypass the `canTransfer` checks. If this happens, and the transfer involves tokens that are currently counted as frozen, it MUST unfreeze the assets first and emit a `Frozen` event before the underlying base token transfer event reflecting the change. Having the unfrozen amount changed before the actual transfer is critical for tokens that might be susceptible to reentrancy attacks doing external checks on recipients, as is the case for [ERC-721](./eip-721.md) and [ERC-1155](./eip-1155.md) tokens.
+ - It SHOULD at least perform a `canReceive` check on the `to` parameter to ensure compliance.
+- In multi-party permissioned contexts:
+ - It SHOULD perform the `canTransfer` checks and SHOULD NOT bypass the frozen constraints.
+- MUST revert in cases where validations and/or `canReceive` checks return false or fail.
+
+### `setFrozenTokens`
+
+It provides a way to freeze or unfreeze assets held by a specific account. This is useful for temporary lock mechanisms. This function:
+
+- MUST emit the `Frozen` event.
+- MUST be restricted in access.
+- MUST allow freezing more assets than those held. This allows for future balances withholding.
+- MUST revert in cases of logical issues or validation checks failure.
+
+### Additional Specifications
+
+The contract MUST implement the [ERC-165](./eip-165.md) `supportsInterface` function and MUST return true for the `bytes4` value (representing the `interfaceId`):
+
+- `0x3edbb4c4` for the fungible interface.
+- `0xbf1ef5fe` for the non-fungible interface.
+- `0x41c4fbad` for the multi token interface.
+
+Implementations of these interfaces MUST implement the necessary functions of their chosen base standard (e.g., [ERC-20](./eip-20.md) for the fungible interface, [ERC-721](./eip-721.md) for the non-fungible interface, [ERC-1155](./eip-1155.md) or [ERC-6909](./eip-6909.md) for the multi token interface) and MUST also restrict access to sensitive functions like `forcedTransfer` and `setFrozenTokens` using an appropriate access control mechanism (e.g., `onlyOwner`, Role-Based Access Control). The specific mechanism is NOT mandated by this interface standard.
+
+Implementations MUST ensure their transfer methods exhibit the following behavior:
+
+- **Public transfers** (`transfer`, `transferFrom`, `safeTransferFrom`, etc.) MUST NOT succeed in cases where `canTransfer` would return `false`, or where `canSend` would return `false` for the `from` address, or `canReceive` would return `false` for the `to` address.
+- **Minting** in permissionless contexts (e.g., public `mint` functions) MUST NOT succeed for accounts where `canReceive` on the recipient would return `false`. In permissioned contexts (e.g., authorized minting by privileged roles), minting SHOULD respect `canReceive` checks on the recipient, though implementations MAY bypass these checks when necessary for operational or compliance reasons.
+- **Burning** in permissionless contexts (e.g., public `burn` functions) MUST respect the `canTransfer` check, MUST respect the `canSend` check on the token holder, and MUST NOT allow burning more assets than the unfrozen amount. In permissioned contexts (e.g., authorized burning by privileged roles), burning MAY succeed for accounts where `canSend` on the token holder would return `false`, and MAY burn more assets than the unfrozen amount, in which case the contract MUST update the frozen status accordingly and emit a `Frozen` event before the underlying base token transfer event.
+
+The `ERC7943CannotSend`/`ERC7943CannotReceive`/`ERC7943CannotTransfer` errors MAY be used as a general revert mechanism whenever internal calls to `canSend`/`canReceive`/`canTransfer` return false. They MAY be replaced by more specific errors depending on the custom checks performed inside those calls, or simply not used.
+
+In general, the standard prioritizes error specificity, meaning that specific errors such as `ERC7943InsufficientUnfrozenBalance` SHOULD be thrown when applicable. The `ERC7943InsufficientUnfrozenBalance` error SHOULD be triggered when a transfer is attempted from `account` with an `amount` less than or equal to its balance, but greater than its unfrozen balance, or with a `tokenId` which is currently frozen. If the `amount` is greater than the whole balance or the `tokenId` is not owned by the `account`, unrelated to the frozen amount, more specific errors from the base standard SHOULD be used instead.
+
+## Rationale
+
+- **Minimalism**: Defines only the essential functions (`forcedTransfer`, `setFrozenTokens`, `canSend`, `canReceive`, `canTransfer`, `getFrozenTokens`) and associated events/errors needed for common RWA compliance and control patterns, avoiding mandated complexity or opinionated features. The reason to introduce specific errors (`ERC7943CannotSend`, `ERC7943CannotReceive`, `ERC7943CannotTransfer`, and `ERC7943InsufficientUnfrozenBalance`) is to provide completeness with the introduced functionalities (`canSend`, `canReceive`, `canTransfer`, and `getFrozenTokens`). As dictated in the specifications, error specificity is prioritized, leaving space for implementations to accommodate more explicit errors. Regarding the events `Frozen` and `ForcedTransfer`, the reason for their existence is to signal _uncommon_ transfers (like in `forcedTransfer`) but also to help off-chain indexers correctly keep track and account for asset seizures and freezing. As mentioned in the specifications, the order in which these events are emitted in relation to the base token contract events is important in practice and merits special attention.
+- **Separation of concerns**: The standard separates account-level eligibility (`canSend`, `canReceive`) from transfer-level authorization (`canTransfer`). `canSend` and `canReceive` evaluate whether an account is eligible to participate independently of any specific transfer parameters such as counterparty, amount, or token identifier. `canTransfer` evaluates whether a specific transfer is permissible under permissioned compliance rules, taking into account frozen balances, transfer limits, counterparty restrictions, and account eligibility. This separation provides clear semantics for integrators and avoids confusion between account eligibility and transfer-specific validation. It also enables one-way restrictions where an account may be blocked from receiving but still allowed to send, which is common in regulated environments.
+- **Flexible compliance**: Provides standard view functions (`canSend`, `canReceive`, `canTransfer`, `getFrozenTokens`) for compliance checks without dictating _how_ those checks are implemented internally by the token contract. This allows diverse compliance strategies.
+- **Compatibility**: Designed as an interface layer compatible with existing base standards like [ERC-20](./eip-20.md), [ERC-721](./eip-721.md), [ERC-1155](./eip-1155.md), and [ERC-6909](./eip-6909.md). Implementations extend from [ERC-7943](./eip-7943.md) alongside their base standard interface.
+- **Essential enforcement rules**: Includes `forcedTransfer` and `setFrozenTokens` as standard functions, acknowledging their importance for regulatory enforcement in the RWA space, distinct from standard transfers. Mandates access control for these sensitive functions. To maintain a lean EIP, a single `setFrozenTokens` function (which overwrites the frozen asset quantity) and one `Frozen` event were favored over distinct `freeze`/`unfreeze` functions and events.
+- **[ERC-165](./eip-165.md)**: Ensures implementing contracts can signal support for this interface.
+
+As an example, an AMM pool or a lending protocol can integrate with [ERC-7943](./eip-7943.md)-based [ERC-20](./eip-20.md) tokens by calling `canSend`, `canReceive`, or `canTransfer` to handle these assets in a compliant manner. Enforcement actions like `forcedTransfer` and `setFrozenTokens` can either be called by third-party entities or be integrated by external protocols to allow for automated and programmable compliance. Users can then expand these tokens with additional features to fit the specific needs of individual asset types, such as on-chain identity systems, historical balance tracking for dividend distributions, semi-fungibility with token metadata, and other custom functionalities.
+
+### Extensibility
+
+While this ERC provides the necessary primitives for regulated assets, any additional feature can be added through extensions. A few examples:
+
+1) If for any administrative function like `setFrozenTokens` it is necessary to attach a proof to the call, the contract can have a function that batches operations like:
+
+```solidity
+contract TokenWithLegalProofs is IERC7943MultiToken {
+ ...
+
+ function setFrozenTokensWithProof(address account, uint256 tokenId, uint256 amount, bytes calldata legalProof) external onlyOwner returns (bool result) {
+ /// do anything with `legalProof`
+ return setFrozenTokens(account, tokenId, amount);
+ }
+}
+```
+
+2) Since the `setFrozenTokens` function overwrites the absolute frozen amount and given the fact that the standard allows for multiple privileged accounts, some race-conditions might happen. If that's the case, one can build an extension function that works with expected values of amounts frozen, like:
+
+```solidity
+function setFrozenTokensIf(address account, uint256 expectedPrev, uint256 newAmount) external onlyOwner returns (bool result) {
+ require(frozenTokens[account] == expectedPrev, ERC7943ExpectedValueMismatch(expectedPrev, frozenTokens[account]));
+ return setFrozenTokens(account, newAmount);
+}
+```
+
+Alternatively, another solution can be using delta amounts:
+
+```solidity
+function setFrozenTokensDelta(address account, int256 deltaAmount) external onlyOwner returns (bool result) {
+ uint256 actualValue = frozenTokens[account];
+ if(deltaAmount >= 0) actualValue += uint256(deltaAmount);
+ else {
+ uint256 sub = uint256(-deltaAmount);
+ require(sub <= actualValue, ERC7943ExpectedValueMismatch(sub, actualValue));
+ actualValue -= sub;
+ }
+ return setFrozenTokens(account, actualValue);
+}
+```
+
+_Note:_ These helpers reduce accidental overwrites and expand in functionalities but do not prevent same-block conflicting updates or mempool ordering races by different privileged actors.
+
+3) Developers can also perform several operations through the use of `multicall` patterns similar to the one defined in [ERC-6357](./eip-6357.md) so that a mix of the given primitives with additional features can be batched in one transaction:
+
+```solidity
+contract ERC7943Fungible is IERC7943Fungible, Multicall {
+ // Now any combination of `setFrozenTokens`/`forcedTransfer`
+ // coupled with other functionalities like the ones to blacklist/whitelist users
+ // can be submitted in one transaction through the use of `multicall` function
+}
+```
+
+4) Functionalities like pausability can be added on top, either through the use of modifiers or directly within functions implementations:
+
+```solidity
+function canTransfer(address from, address to, uint256 amount) external view returns (bool allowed) {
+ if(paused()) return allowed;
+ // ... other checks
+}
+```
+
+### Notes on Naming
+
+The naming conventions in this ERC were carefully chosen to establish clarity and semantic consistency within the broader RWA ecosystem while maintaining neutrality and broad applicability.
+
+- **`forcedTransfer`**: This term was selected for its neutrality. While names like _confiscation_, _revocation_, or _recovery_ describe specific motivations, `forcedTransfer` purely denotes the direct action of transferring assets, irrespective of the underlying reason. `forcedTransfer` was preferred over `forceTransfer` to maintain backward compatibility with [ERC-3643](./eip-3643.md).
+- **`canSend` / `canReceive`**: These names were chosen to clearly express the directional nature of account eligibility: whether an account is allowed to send or receive tokens. This separation enables one-way restrictions (e.g., an account blocked from receiving but still allowed to send), which are common in regulated environments such as KYC expiry, AML alerts, or jurisdictional constraints.
+- **`canTransfer`**: This name was preferred over `isTransferAllowed` for consistency with established RWA standards including [ERC-3643](./eip-3643.md) and [ERC-7518](./eip-7518.md). This alignment promotes interoperability and reduces cognitive overhead when working across different RWA tokens.
+- **`setFrozenTokens` / `getFrozenTokens`**: These names were chosen for managing transfer restrictions and align with [ERC-3643](./eip-3643.md) naming patterns. _Frozen_ was also selected for its general applicability to both fungible (amount-based) and non-fungible (status-based) assets, as terms like _amount_ or _asset(s)_ might not be universally fitting.
+- **`ERC7943InsufficientUnfrozenBalance`**: Discussions around _insufficient_ being similar to _unavailable_ arose, where _unavailable_ might have better suggested a temporal condition like a freezing status. However, the term _available_/_unavailable_ was also overlapping with _frozen_/_unfrozen_ creating more confusion and duality. Finally, coupling _insufficient_ with the specified _unfrozen balance_ better represents the domain, prefix, and subject of the error, according to [ERC-6093](./eip-6093.md) guidelines.
+
+## Backwards Compatibility
+
+This EIP defines a new interface standard and does not alter existing ones like [ERC-20](./eip-20.md), [ERC-721](./eip-721.md), and [ERC-1155](./eip-1155.md). Standard wallets and explorers can interact with the base token functionality of implementing contracts, subject to the rules enforced by that contract's implementation of `canSend`, `canReceive`, `canTransfer`, and `getFrozenTokens` functions. Full support for the [ERC-7943](./eip-7943.md) functions requires explicit integration.
+
+## Reference Implementation
+
+Reference implementations of uRWA for [ERC-20](../assets/eip-7943/contracts/uRWA20.sol), [ERC-721](../assets/eip-7943/contracts/uRWA721.sol), and [ERC-1155](../assets/eip-7943/contracts/uRWA1155.sol) token implementations are provided in the assets folder. They use the OpenZeppelin library and include separate send/receive whitelists and enumerable role-based access control. These examples are provided for educational purposes only and are not audited.
+
+## Security Considerations
+
+- **Access Control for `forcedTransfer` and `setFrozenTokens`**: The security of the mechanism chosen by the implementer to restrict access to these functions is paramount. Unauthorized access could lead to asset theft. Secure patterns (multisig, timelocks) are highly recommended.
+- **Front-running of the `forcedTransfer` and `setFrozenTokens` functions**: Both functions are susceptible to front-running, similar to the `approve` function of [ERC-20](./eip-20.md). Furthermore, if the suggestion to allow freezing more than what an account owns is not followed, any account may be incentivized to front-run attempts to freeze its balance when receiving new funds. Additional features to gradually increment or decrement the frozen status MAY be considered for implementation.
+- **Standard Contract Security**: Implementations MUST adhere to general smart contract security best practices (reentrancy guards where applicable, checks-effects-interactions, etc.). Specifically, in the checks-effects-interactions consideration, implementations need to be aware of tokens having hooks, especially on recipients as in [ERC-721](./eip-721.md) or [ERC-1155](./eip-1155.md). In such circumstances, it might be convenient to adopt reentrancy guards to prevent unwanted executions.
+
+## Copyright
+
+Copyright and related rights waived via [CC0](../LICENSE.md).
diff --git a/doc/README.md b/doc/README.md
new file mode 100644
index 00000000..1cac701b
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,3314 @@
+# CMTA Token
+
+> To use the CMTAT, we recommend the latest audited version, from the [Releases](https://github.com/CMTA/CMTAT/releases) page. Currently, it is the version [v3.0.0](https://github.com/CMTA/CMTAT/releases/tag/v3.0.0).
+>
+> PDF files of README are available here: [CMTATSpecificationV3.0.0.pdf](./specification/CMTATSpecificationV3.0.0.pdf), [CMTATSpecificationV3.2.0.pdf](./specification/CMTATSpecificationV3.2.0.pdf)
+
+## Introduction
+
+The CMTA token (CMTAT) is a blockchain-agnostic security token framework for regulated real-world financial assets.
+This repository provides CMTA's reference Solidity implementation for EVM-compatible blockchains such as Ethereum, Optimism, Arbitrum, and Polygon PoS.
+
+The framework focuses on regulated issuance and lifecycle management, including:
+- transfer validation and compliance checks
+- account and partial-token freezing
+- pause and contract deactivation controls
+- controlled mint/burn and forced-transfer capabilities
+- optional modules for snapshot/document engines, cross-chain, and product-specific deployments
+
+[TOC]
+
+### History
+
+The CMTA token (CMTAT) is a security token framework that includes various compliance features such as conditional transfer, account freeze, and token pause. CMTAT was initially optimized for the Swiss law framework, however, these numerous features and extensions make it suitable for other jurisdictions too.
+
+The CMTAT is an open standard from the [Capital Markets and Technology Association](https://www.cmta.ch/) (CMTA), which gathers organizations from the financial, legal and technology sectors.
+The CMTAT was first developed by a working group of CMTA's [members](https://cmta.ch/members) and its development is now overseen by the [Technical Committee of CMTA's Advisory Board](https://cmta.ch/advisory-board).
+
+### Goal
+
+CMTAT has been built with five main goals:
+
+1. Suitable for various regulatory financial assets and instruments (Equities, Structured products, Debt and Stablecoin) and adapted to any jurisdiction (international)
+
+2. Easy to modify and adapt for specific use-case (customization) through its modular architecture
+3. Interoperability with the Ethereum ecosystem by implementing recognized standards:
+ - Tokenization: [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) (without on-chain identity), [ERC-7943 (uRWA)](https://eips.ethereum.org/EIPS/eip-7943), [ERC-1404](https://github.com/ethereum/EIPs/issues/1404), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477), [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363), [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612),...
+ - Technicals: [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (MetaTx/Gasless), [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201), [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802),...
+
+4. Security by undergoing audits from trusted firms like [ADBK](https://abdk.consulting) and [Halborn](https://www.halborn.com), and by implementing a range of industry best practices.
+ - Strong code statements coverage(~99.43%) with 5630 automated tests executed
+ - Run static analyzer ([Aderyn](https://github.com/Cyfrin/aderyn), [Slither](https://github.com/crytic/slither/tree/master)), as well as AI Auditing tools ([Nethermind Audit Agent](https://auditagent.nethermind.io), [Wake Arena](https://ackee.xyz)), before and after the audits
+ - RBAC Access Control to clearly separates the different roles and permissions
+
+5. Freedom of use through an open-source weak copyleft license ([MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/FAQ/))
+
+### License explanation
+
+CMTAT is released under **MPL-2.0** (weak copyleft).
+In practice, this means:
+- commercial use is allowed,
+- proprietary modules can coexist with CMTAT,
+- but modifications to MPL-covered files must remain available under MPL-2.0.
+
+#### Quick comparison
+
+| Topic | MPL-2.0 | MIT | GNU GPL v3 | Apache-2.0 |
+|---|---|---|---|---|
+| Open source | ✔ | ✔ | ✔ | ✔ |
+| Commercial use | ✔ | ✔ | ✔ | ✔ |
+| Copyleft level | Weak (file-level) | None (permissive) | Strong (project-level) | None (permissive) |
+| Patent license | ✔ (explicit) | ✘ (not explicit) | ✔ (via GPLv3 terms) | ✔ (explicit) |
+
+The explicit patent grant in MPL-2.0 helps reduce patent risk for adopters and integrators.
+
+
+
+By taking these five main goals, here a comparison with others known implementations to deploy financial instruments on-chain.
+
+| | CMTAT | ERC-3643 (Tokeny implementation) | ERC-1400 (UniversalToken) | TokenF | ERC-20 Smart Coin (Cast framework) |
+| ----------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Version/Commit | v3.0.0 (09/2025) | [4.2.0-beta2](https://github.com/TokenySolutions/T-REX/releases/tag/4.2.0-beta2) (01/2025) | [54320c6](https://github.com/Consensys/UniversalToken/commit/54320c6f7a8ee1fd7fcb19073e9c122e1e8f96f9) (01/2024) | [0c1c2ac](https://github.com/dl-tokenf/contracts/commit/0c1c2ac0aa8c95423928a9ed09ab14bce64054f5) (04/2025) | [dd8bf5e](https://github.com/castframework/smartcoin/commit/dd8bf5e1ba24d2379b102db74bfc8326fb649b65) (01/2025) |
+| Company / Association behind | [CMTA](https://cmta.ch/) | [Tokeny](https://tokeny.com/), [ERC3643 Association](https://www.erc3643.org/) | [Consensys](https://consensys.io/) | [Distributed Lab](https://distributedlab.com/) | [SOCIÉTÉ GÉNÉRALE FORGE](https://www.sgforge.com) |
+| 1 (suitable for various financial instruments) | ✔ | Partial | ✔ | Partial | Partial |
+| Details | - | Lack of support for Debt product
On-chain identity management can potentially make it too complex for stablecoins Also lacks support for adding information related to on-chain terms (hash, uri) | - | Lacks support for adding information related to on-chain terms (hash, uri) as well as Debt product but contracts could be extended. | Lacks support for adding information related to on-chain terms (hash, uri) as well as Debt product |
+| 2 (customizable) | ✔ | ✘ | ✘ | ✔ | ✔ |
+| Details | Modular architecture | Code difficult to modify because functionalities are not clearly separated and onchain identity management is required | Code difficult to modify because functionalities are not clearly separated | Customizable but uses the [Diamant proxy](https://eips.ethereum.org/EIPS/eip-2535) pattern structure which makes it more complex to implement | Contracts are minimalist and easy to modify |
+| 3 (interoperability) | ✔ | ✔ | Partial | ✔ | ✔ |
+| Details | Tokenization: [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) (without on-chain identity), [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) (uRWA), [ERC-1404](https://github.com/ethereum/EIPs/issues/1404), [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477), [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363),... Technicals: [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771), [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201), [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802),... | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) and [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) | While ERC-1400 is an [ERC-20](https://eips.ethereum.org/EIPS/eip-20), the standard ERC-1400 is not itself an official standard It has also a dependence with [ERC-1820](https://eips.ethereum.org/EIPS/eip-1820) registry contract, which is not always available/deployed on some layer2. | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) and [ERC-2535](https://eips.ethereum.org/EIPS/eip-2535) | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) |
+| 4 (Security) | ✔ | ✔ | ✘ | ✘ | ✘ |
+| | - 1.0 and 2.3.0: audited by [ABDK](https://abdk.consulting) 3.0.0 audited by [Halborn](https://www.halborn.com) - RBAC Access Control | - Past version audited by [Hacken](https://hacken.io). - Lack of granularity in term of Access Control (only two roles: Agent and Owner) | No official public audit for the last commits, last audit was done in 2020 | No official audit available | No official audit available |
+| 5 (License - Open source & Allow Commercial use) | ✔ | Partial (only ERC-3643 core) | ✔ | ✔ | |
+| | [MPL-2.0](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) (weak copyleft) | - ERC-3643 core: GPL 3.0 (strong copyleft) - Compliance module: CC-BY-NC-4.0(forbid commercial use) | Apache 2.0 (permissive) | MIT (permissive) | [Apache-2.0 license](https://github.com/castframework/smartcoin/tree/main#Apache-2.0-1-ov-file) (permissive) |
+
+
+
+### Who uses CMTAT and for what?
+
+CMTAT is suitable for the digitalization of various financial assets. Below is a selection of public case studies
+
+More details are available here: [cmta.ch/faqs](https://cmta.ch/faqs#what-cases-has-cmtat-already-been-used-in)
+
+#### Digitalization of equity securities
+
+The CMTAT was initially designed for the digitalization of company shares. For SMEs, digitalization provides an opportunity to access new financing and investment models by selling digital shares through online exchanges. Some companies that have digitalized shares using the CMTAT include:
+
+- [Daura](https://thetokenizer.io/2022/12/13/daura-counts-on-smart-contract-standard-cmtat-for-the-tokenization-of-swiss-shares/) uses the CMTAT through their own fork to digitalize the shares of companies using its [platform](https://www.daura.ch), deployed on [zkSync](https://zksync.io/).
+- [Taurus SA](https://www.taurushq.com) (partial list): [Magic Tomato SA (2022)](https://www.taurushq.com/blog/magictomato-1st-foodtech-to-tokenise-its-shares-and-raise-equity/) - an online grocery platform opened its governance and capital to its community, by issuing digital non-voting shares (bons de participation), [Qoqa Brew (2022)](https://www.taurushq.com/blog/qoqa-brew-brasserie-du-futur-tokenisation-et-financement-by-taurus/) - an online retailer opened the capital of its on-site brewery Q-Brew to its community by issuing digital non-voting shares, [Cité Gestion SA (2023)](https://cmta.ch/news-articles/cite-gestion-becomes-cmta-certified-issuer-of-tokenized-shares) - a Swiss bank and wealth manager, issued digitalized shares in 2022, using the CMTAT, [CODE41 (2023)](https://www.taurushq.com/blog/code41-tokenises-its-shares-for-a-capital-increase-amongst-its-community-through-taurus-technology/) - a Swiss watchmaking company tokenized its shares for a capital increase using CMTAT.
+
+#### Digitalization of debt securities
+
+- [Project Guardian - UBS (2024)](https://www.linkedin.com/posts/cmta-ch_shareubs-activity-7137735139438002177-oDUL): CMTAT was used to issue a digital bond by UBS, as part of the first live repo transaction with a natively-issued digital bond on a public blockchain as part of the Monetary Authority of Singapore’s (MAS) Project Guardian.
+- The Obligate platform [Enote Protocol](https://docs.obligate.com/obligate/enote-protocol) enables BulletBond issuances using smart contracts, deployed on Polygon PoS. For this purpose, they use a fork of CMTAT with the `SnapshotModule`(replaced in CMTAT v3.0.0 by the SnapshotEngine) and the DebtModule.
+- [SCCF (2023)](https://www.taurushq.com/blog/sccf-and-horizon-capital-leverage-taurus-technology-to-execute-landmark-tokenized-trade-finance-debt-transaction/): trade finance firm SCCF issued short term tokenized notes to refinance a loan to a commodity trading firm active in biofuels through [Taurus SA](https://www.taurushq.com). See also [SCCF and Taurus Announce Successful Tokenization of End-to-End Trade Finance Transaction on TDX Marketplace (2024)](https://www.taurushq.com/blog/sccf-and-taurus-announce-successful-tokenization-of-end-to-end-trade-finance-transaction-on-tdx-marketplace/)
+
+#### Digitalization of structured products
+
+- In early 2024, [UBS](https://www.ubs.com/global/en/investment-bank/tokenize.html) executed a pilot transaction with OSL, a licensed professional investor in Hong Kong, to issue a tokenized warrant on Ethereum using the CMTAT smart contract framework. The tokenization arrangement for this warrant utilizes the CMTAT codebase to represent the warrant smart contract, which forms part of the tokenized register of holders. See [ubs.com - UBS expands its digital asset capabilities by launching Hong Kong’s first-ever tokenized warrant on the Ethereum network [ubs.com]](https://www.ubs.com/global/en/media/display-page-ndp/en-20240207-tokenized-warrant.html).
+- [Credit Suisse, Pictet and Vontobel (2022)](https://cmta.ch/news-articles/trading-and-settlement-in-digital-securities) issued tokenized investment products that were traded on [BX Swiss](https://www.bxswiss.com/news/20221213-BX-Swiss-legt-das-technische-Fundament-fuer-die-Zukunft-des-regulierten-Handels-mit-tokenisierten-Wertpapieren) as part of a proof-of-concept leveraging the CMTAT.
+
+#### Digitalization of artwork
+
+- [Syz Group](https://www.syzgroup.com/en), a Swiss private bank, has successfully digitized two pieces of art using CMTAT in 2023, 2024 and 2025. See [Syz Art Tokenisation](https://www.syzgroup.com/en/tokenization-syzart)
+
+#### Stablecoins
+
+- Zand: CMTAT v3.0.0 was used by [Zand Trust](https://zandtrust.com/en) (a wholly-owned subsidiary of Zand Bank) to issue a stablecoin representing the UAE Dirham via [Taurus](https://www.taurushq.com)' infrastructure. See the stablecoin [smart contract here](https://etherscan.io/token/0xfc347c996bd66c1d92e2045c80b413ef3fc84a90).
+
+#### Tokenized market funds
+
+- In 2024, [UBS](https://www.ubs.com/global/en/investment-bank/tokenize.html) launched UBS USD Money Market Investment Fund Token (uMINT), a Money Market investment built on Ethereum distributed ledger technology. The tokenization arrangement for this fund utilizes CMTAT codebase to represent the fund smart contract, which forms part of the fund’s tokenized register of members. See [ubs.com - UBS Asset Management launches its first tokenized investment fund [ubs.com]](https://www.ubs.com/global/en/media/display-page-ndp/en-20241101-first-tokenized-investment-fund.html)
+
+#### Tokenization platform
+
+- Fireblocks integrates CMTAT into their [tokenization platform](https://www.fireblocks.com/platforms/tokenization/). See also [Fireblocks - Fireblocks joins CMTA to define the standards for tokenization in traditional capital markets](https://www.fireblocks.com/blog/fireblocks-joins-cmta-to-define-the-standards-for-tokenization-in-traditional-capital-markets/)
+- Taurus SA integrates CMTAT (Solidity and [Tezos version](https://www.taurushq.com/blog/taurus-supports-tokenisation-of-equity-on-the-tezos-blockchain/)) into their tokenization platform called [Taurus-CAPITAL](https://www.taurushq.com/capital/)
+
+#### Wrapped Tokens
+
+- 21.co (the original parent company of [21Shares](https://www.21shares.com/) acquired by FalconX) used CMTAT through their own [fork](https://github.com/amun/CMTAT) to create Wrapped Tokens on Ethereum. See for example Wrapped Bitcoin(21BTC) on [Etherscan](https://etherscan.io/token/0x3f67093dffd4f0af4f2918703c92b60acb7ad78b) and [their announcement](https://www.globenewswire.com/news-release/2024/09/03/2939399/0/en/21-co-Expands-its-Wrapped-Tokens-Lineup-with-the-Launch-of-Wrapped-Bitcoin-21BTC-on-Ethereum.html)
+
+#### Private DvP settlement
+
+- In 2026, [Seturion](https://group.boerse-stuttgart.com/en/seturion/) successfully achieved private DvP settlement of tokenized assets on a public blockchain stack while keeping all sensitive data confidential using the implementation of [CMTAT on Aztec](https://github.com/CMTA/private-CMTAT-aztec), an Ethereum Layer-2 network that employs zero-knowledge cryptography on protocol level to ensure fully programmable privacy. Read more [here](https://www.linkedin.com/posts/seturion_achieving-private-dvp-settlement-on-public-activity-7424387919538450433-OItI/).
+
+### Where CMTAT is mentioned?
+
+CMTAT is referenced in several reports. Although these reports do not reflect the most recent version, they already provide a good indication of potential use cases. The insights from these reports have also contributed to numerous improvements in CMTAT.
+
+- [Guardian - Fixed Income Framework (2025)](https://www.mas.gov.sg/-/media/mas-media-library/development/fintech/guardian/guardian-fixed-income-framework-v1_1.pdf)
+- [IRJEMS International Research Journal of Economics and Management Studies - Security Token Standards for Institutional Adoption of Tokenized Funds (2025)](https://irjems.org/irjems-v4i8p104.html)
+- [University of Toronto - Blockchain Meets Securities: A Scalable Tokenization Framework](https://dl.acm.org/doi/10.1145/3777461) / [pdf](https://www.eecg.utoronto.ca/~veneris/DLTACM25.pdf) (2025), page 22
+- [Forum - Asset Tokenization in Financial Markets: The Next Generation of Value Exchange (2025)](https://reports.weforum.org/docs/WEF_Asset_Tokenization_in_Financial_Markets_2025.pdf), page 38
+- [King's Business School/Rhys Bidder - What Is The Future Of Stablecoins, And How Do We Get There? (2025)](https://www.kcl.ac.uk/business/assets/PDF/qcgbf-working-papers/taking-the-next-step-v5.pdf), page 33
+- [Nethermind - Tokenization Standards: The Missing Link for Institutional Adoption (2025)](https://www.nethermind.io/blog/tokenization-standards-the-missing-link-for-institutional-adoption): page 2, 16, 19, 33-36 & 39
+- [Nethermind & PwC Germany - Tokenization Standards: Taming the Regulatory Menagerie](https://gftn.co/hubfs/Tokenization_Standards_Nethermind_PwC_GFTN.pdf)
+- [Project Guardian - Fixed Income Framework (2024)](https://www.mas.gov.sg/-/media/mas-media-library/development/fintech/guardian/guardian-fixed-income-framework.pdf): page 13, 39, 59 & 65
+- [ICMA contribution to MAS Guardian Fixed Income Framework (GFIF) publication (2024)](https://www.icmagroup.org/assets/Summary-of-third-party-proposals-for-integrating-ICMAs-Bond-Data-Taxonomy-in-token-frameworks-and-DLT-platforms-complementing-section-6-Data-Model-of-GFIF.pdf)
+
+### What Makes CMTAT Different from a Regular ERC-20 Token?
+
+Standard ERC-20 tokens allow anyone to transfer freely.
+CMTAT adds **compliance features** required for real-world financial assets such as:
+
+| Feature | Purpose |
+| -------------------------------------- | ------------------------------------------------------------ |
+| **Pause** | Freeze all transfers globally (e.g., during corporate actions) |
+| **Account Freeze** | Block specific addresses from transferring |
+| **Transfer Validation - Custom rules** | Custom rules (`RuleEngine`) allowing to restrict transfers based on the origin, the receiver or the amount transferred |
+| **Forced Transfer** | Admins can move tokens from frozen accounts |
+| **Snapshots** | Record balances at specific times (for dividends) |
+| **Documents** | Attach legal documents to the token |
+
+### Use case
+
+#### Financial instruments
+
+This reference implementation allows the issuance and management of tokens representing equity securities, and other forms of financial instruments such as debt securities and structured products. It can also be used for stablecoins.
+
+#### Jurisdiction
+
+CMTAT was initially optimized for the Swiss law framework, it then took a more **international** path with the version v3.0.0. Subsequently, its numerous compliance features, as well as the numerous configuration possibilities during deployment, make it also suitable for other jurisdictions.
+
+Its modular structure allows it to be easily modified to suit specific cases. For example, a deployment version has been made for Germany (ERC-7551 / eWpG).
+
+You may modify the token code by adding, removing, or modifying features. However, the core modules must remain in place for compliance with the CMTA specification.
+
+#### Specific deployment version tailored to use case
+
+##### Product use case (equities, stablecoins)
+
+CMTAT comes with several different deployment versions to meet specific use cases.
+
+| Product | Deployment version | Note |
+| -------------------------- | ------------------ | ------------------------------------------------------------ |
+| Equities | CMTAT Standard | All features, without those directly to Debt |
+| Equities in Germany | CMTAT ERC-7551 | The standard version with a few supplementary functions to meet the standard [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477), tailored for the Germany and eWpg. |
+| Debt/bond | CMTAT Debt | CMTAT Standard is also suitable but this version adds the possibility to put several on-chain information related to debt and bond product |
+| Stablecoin (e.g USDC/USDT) | CMTAT Light | The core features (i.e., minting, burning,address freeze / blacklisting, pause) without additional functions required by equities and debt instruments (e.g., document management, snapshot, partial freeze of balances). |
+
+##### Technical use case (whitelist, upgradeable/proxy)
+
+| Features | Deployment version supported |
+| ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Restrict transfer to inside a whitelist / Allowlist | CMTAT Allowlist Or all other deployment (except Light) version with a `RuleEngine` configured |
+| On-chain snapshot (useful for on-chain dividend distribution) | Snapshot deployment version, Debt version, and DebtEngine version (with a `SnapshotEngine` configured) |
+| Deployment through proxy (Upgradeable) Deployment immutable (standalone / without proxy) | Each deployment version comes with a standalone (immutable) or upgradeable mode. A specific deployment version exists for UUPS Proxy |
+| MetaTx/Gasless with ERC-2771 | All deployment version, except Debt, DebtEngine, Permit & Light version |
+| ERC-2612 Permit + [ERC-6357 Multicall](https://eips.ethereum.org/EIPS/eip-6357) (gas sponsorship approval & batch transaction) | CMTAT Permit (Standalone / Upgradeable) |
+
+#### CMTAT for stablecoins
+
+Here is a comparison between the features present in major custodian stablecoin and the library CMTAT.
+
+| | | **Monerium** | **USDC** | **USDT** | **CMTAT 3.0.0 Light** | CMTAT 3.0.0 Standard |
+| :----------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | ------------------------------------------------------------ |
+| Source | | [ec59a36](https://github.com/monerium/smart-contracts/commit/ec59a3677a17a06610d7e4788211c19da561241b) | [Ethereum USDC implementation contract](https://etherscan.io/address/0x43506849d7c04f9138d1a2050bbf3a0c054402dd#code) | [Ethereum USDT address](https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7) | | |
+| Currency | | $, euros, pound sterling, Icelandic króna | $ | $ | - | - |
+| Company behind | | [Monerium](https://monerium.com) | [Circle](https://www.circle.com) | [Tether](https://tether.to/en/) | [CMTA](https://cmta.ch/) | [CMTA](https://cmta.ch/) |
+| **Standard** | | | | | | |
+| | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) | ✔ | ✔ | ✔ | Same as standard version | ✔ |
+| | [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) | ✔ ([GitHub)](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/Token.sol#L152) | ✔ | ✘ | Available via CMTAT Permit deployment version | Available via CMTAT Permit deployment version |
+| | [ERC-3009](https://eips.ethereum.org/EIPS/eip-3009) (Transfer With Authorization) | ✘ | ✔ | ✘ | Same as standard version | ✘ |
+| | [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (MetaTX) | ✘ | ✘ | ✘ | ✘ | ✔ (ERC2771Module / CMTATBaseERC2771) |
+| ERC-20 extends functionalities | | | | | | |
+| | Mint/issue | ✘ (see mint with allowance) | ✘ (see mint with allowance) | ✔ | Same as standard version | ✔ |
+| | Mint with dedicated allowance ("mintFrom") | ✔ ([Github](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/MintAllowanceUpgradeable.sol#L3)) | ✔ | ✘ | Same as standard version | ✘ |
+| | Batch Mint version | ✘ | ✘ | ✘ | Same as standard version | ✔ |
+| | burn / redeem | ✔ ([Github](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/Token.sol#L74)) | ✔ | ✔ (`redeem`/ `destroyBlackFunds` | Same as standard version | ✔ |
+| | Set name after deployment | ✘ | ✘ | ✘ | Same as standard version | ✔ (ERC20BaseModule) |
+| | Set symbol after deployment | ✘ | ✘ | ✘ | Same as standard version | ✔ (ERC20BaseModule) |
+| Regulatory | | | | | | |
+| | Integrated blacklist (inside token smart contract) | ✘ | ✔ | ✔ | Same as standard version | ✔ |
+| | External blacklist (can be shared with several different tokens) | ✔ [GitHub](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/BlacklistValidatorUpgradeable.sol#L102) | ✘ | ✘ | ✘ | ✔ (through a dedicated smart contract RuleEngine) |
+| | | **Monerium** | **USDC** | **USDT** | **CMTAT 3.0.0 Light** | **CMTAT 3.0 Standard** |
+| Access Control | | | | | | |
+| | [Ownership](https://docs.openzeppelin.com/contracts/5.x/api/access#Ownable) | ✔ [(Github](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/SystemRoleUpgradeable.sol#L8)) | ✔ | ✔ | Same as standard version | ✘ (use Access Control instead, but ownership could be added) |
+| | [RBAC Access control](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl) | ✔ [GitHub](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/SystemRoleUpgradeable.sol#L7) | ✔ (Minter & Blacklister) | ✘ | Same as standard version | ✔ |
+| Upgradeability | | | | | | |
+| | Upgradable (transparent/Beacon) | ✘ | ✔ | ✘ | Same as standard version | ✔ |
+| | Upgradeable UUPS | ✔ ([GitHub](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/Token.sol#L23)) | ✘ | ✘ | ✘ | ✔ (through a dedicated deployment version) |
+| | Migrate function integrated | ✘ | ✘ | ✔ (because USDT was made before the apparition of proxy architecture) | Same as standard version | ✘ |
+| Standalone (immutable) | | ✘ | ✘ | ✔ | Same as standard version | ✔ (through a dedicated deployment version) |
+| Pause transfers | | Partial Could use the `validator` contract to pause all transfers ([GitHub](https://github.com/monerium/smart-contracts/blob/ec59a3677a17a06610d7e4788211c19da561241b/src/Token.sol#L122C13-L122C22)) | ✔ | ✔ | Same as standard version | ✔ (PauseModule) |
+| Fee on transfer | | ✘ | ✘ | ✔ (currently set at 0) | Same as standard version | ✘ |
+
+
+
+#### CMTAT for tokenized market funds
+
+Here is a comparison between the features present in known tokenized market funds and the library CMTAT.
+
+| | | Spiko (EUTBL and USTBL) | Franklin Templeton (FOBXX / Benji) | Blackrock (BUIDL) | CMTAT 3.0.0 Standard | CMTAT 3.00 ERC-1363 |
+| :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Reference | | | [Franklin OnChain U.S. Government Money Fund (FOBXX)](https://www.franklintempleton.com/investments/options/money-market-funds/products/29386/SINGLCLASS/franklin-on-chain-u-s-government-money-fund/FOBXX) [Avalanche - Franklin Templeton Launches Tokenized Money Market Fund BENJI On The Avalanche Network](https://www.avax.network/about/blog/franklin-templeton-launches-tokenized-money-market-fund-benji-avalanche) | Securitize contracts [Proxy](https://etherscan.io/address/0x7712c34205737192402172409a8f7ccef8aa2aec) [Implementation](https://etherscan.io/address/0x603bb6909be14f83282e03632280d91be7fb83b2#code) | - | - |
+| Source | | [9ef58f3](https://github.com/spiko-tech/contracts/commit/9ef58f31bc8dc9cb562dfcbae6091866b3da5121) | [Franklin Templeton Digital Assets - contracts](https://digitalassets.franklintempleton.com/benji/benji-contracts/) [Contract proxy](https://snowtrace.io/token/0xE08b4c1005603427420e64252a8b120cacE4D122?chainid=43114) [Contract implementation](https://snowtrace.io/address/0x5c118e6A0bD2de0AF66655806E3001727C13d105/contract/43114/code) | | - | - |
+| Company behind | | [Spiko](https://www.spiko.io/) | [Franklin Templeton](https://digitalassets.franklintempleton.com) | [Blackrock](https://www.blackrock.com/) through [Securitize](https://securitize.io) | [CMTA](https://cmta.ch/) | [CMTA](https://cmta.ch/) |
+| **Standard** | | | | | | |
+| | [ERC-20](https://eips.ethereum.org/EIPS/eip-20) | ✔ | ✔ | ✔ | ✔ | Same as standard version |
+| | [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) | ✔ | ✘ | ✘ | ✘ | ✔ |
+| | [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) | ✔ ([GitHub)](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L26) | ✘ | ✘ | Available via CMTAT Permit deployment version | Available via CMTAT Permit deployment version |
+| | [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (MetaTX) | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L22)) | ✘ | ✘ | ✔ | Same as standard version |
+| ERC-20 extends functionalities | | | | | | |
+| | Mint/issue | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L59)) | ✔ | ✔ | ✔ | Same as standard version |
+| | Mint with dedicated allowance ("mintFrom") | ✘ | ✘ | ✘ | ✘ | Same as standard version |
+| | Batch Mint version | ✘ | ✘ | ✘ | ✔ | Same as standard version |
+| | burn / redeem | ✔ ([Github](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L63)) | ✔ | ✔ (burn & omnibusBurn) | ✔ | Same as standard version |
+| Regulatory | | | | | | |
+| | Whitelist / Allowlist | ✔ | ✔ (through external contract `moduleRegistry`) | ✔ (through external contract `ComplianceServiceWhitelisted`) | ✔ (through *RuleEngine*) | Same as standard version |
+| | On-chain country investor restriction /banned | ✘ | ✘ | ✔ (though an on-chain list of investor and the library `ComplianceServiceLibrary` ) | | |
+| | Integrated blacklist (inside token smart contract) | ✘ (Could be implemented, but use a whitelist system currently) | ✘ | ✘ | ✔ (EnforcementModule) | Same as standard version |
+| | External blacklist (can be shared with several different tokens) | ✔ [GitHub](https://github.com/monerium/smart-contracts/blob/d2a633e8d2d028dcc6f251a394273a9cac1b1e43/src/BlacklistValidatorUpgradeable.sol#L102) | ✔ (through external contract `moduleRegistry`) | ✘ | ✔ (RuleEngine) | Same as standard version |
+| | Forced Transfer | ✘ | ✔ (called `instantTransfer`) | ✔ (called *size*) | ✔ | Same as standard version |
+| | Restriction on `transferFrom` | ✘ | ✔ (through `disableERC20ThirdPartyTransfer` & `enableERC20ThirdPartyTransfer`) | ✘ | Partial (transfer revert if spender is frozen) | Same as standard version |
+| | | **Spiko** | **Franklin Templeton (FOBXX / Benji)** | **Blackrock (BUILD)** | **CMTAT 3.0.0 Standard** | **CMTAT 3.00 ERC-1363** |
+| Access Control | | | | | | |
+| | [Ownership](https://docs.openzeppelin.com/contracts/5.x/api/access#Ownable) | ✔ [(Github](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L23)) | ✘ (only `ModuleRegistry` is ownable) | ✔ | ✘ (easily adaptable to support this) | Same as standard version |
+| | [RBAC Access control](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl) | ✔ [GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/permissions/PermissionManager.sol) | ✔ | ✔ (several roles: Exchange, Issuer, transfer agent and master) | ✔ | Same as standard version |
+| | [Access Control Manager](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessManaged) | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/permissions/PermissionManager.sol#L14C5-L14C15)) | ✘ | ✘ | ✘ (Could be extended to support it) | Same as standard version |
+| Upgradeability | | | | | | |
+| | Upgradable (transparent/Beacon) | ✔ | ✔ | ✔ | ✔ | Same as standard version |
+| | Upgradeable UUPS | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L29)) | ✔ | ✘ | ✘ (Could be extended to support it) | Same as standard version |
+| Pause transfers | | ✔ ([GitHub](https://github.com/spiko-tech/contracts/blob/9ef58f31bc8dc9cb562dfcbae6091866b3da5121/contracts/token/Token.sol#L67)) | ✔ (trough `enableERC20Transfer` and `disableERC20Transfer`) | ✔ | ✔ | Same as standard version |
+| Lock tokens | | ✘ | ✘ | ✔ | ✘ | Same as standard version |
+| Specific functions for omnibus wallet | | ✘ | ✘ | ✔ | ✘ (see specific deployment version) | Same as standard version |
+| Dedicated function to fetch the list of token holders and their balance | | ✘ | ✔ (`getAccountsBalances`) | ✔ (`checkWalletsForList` & `balanceOfInvestor`) | ✘ | Same as standard version |
+| Price indicated on-chain | | ✘ | ✔ (`lastKnownPrice`) | ✘ | ✘ | Same as standard version |
+
+**Note**
+
+- *Fasanara Capital Ltd* has also tokenized a money market fund. Since they have worked with [Tokeny](https://tokeny.com) and use therefore the ERC-3643 standard, a comparison with this standard is provided in other sections of this document. See also [Tokeny - How Tokeny Powers Fasanara’s Tokenized Money Market Funds](https://tokeny.com/customer-story-fasanaras-tokenized-mmf/)
+- Upgradeability: a specific CMTAT deployment version allows to use UUPS proxy
+
+### Comparison of CMTAT and other tokenization frameworks
+
+Here is a comparison between the features present in known tokenization framework and the library CMTAT.
+
+| Label | CMTAT Solidity code | **E**RC-1400 | ERC-3643 | Cast Framework |
+| :----------------------------------------------------------: | :----------------------------------------------------------: | :----------------------------------------------------------: | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Version/implementation compared | [CMTAT v3.1.0](https://github.com/CMTA/CMTAT/releases/tag/v3.1.0) | [UniversalToken (Consensys)](https://github.com/Consensys/UniversalToken/tree/54320c6f7a8ee1fd7fcb19073e9c122e1e8f96f9) | [Tokeny's T-Rex](https://github.com/TokenySolutions/T-REX)
[3fcf44d](https://github.com/TokenySolutions/T-REX/tree/3fcf44d4fc102fb891aaad27ee58e8936d885542) (06/02/2025) | Smart Coin (ERC-20 version) [dd8bf5e](https://github.com/castframework/smartcoin/tree/dd8bf5e1ba24d2379b102db74bfc8326fb649b65) |
+| Company / Association behind | [CMTA](https://cmta.ch/) | [Consensys](https://consensys.io/) | [Tokeny](https://tokeny.com/), [ERC3643 Association](https://www.erc3643.org/) | [SOCIÉTÉ GÉNÉRALE FORGE](https://www.sgforge.com) |
+| | | | | |
+| ERC-20 | ✔ | ✔ | ✔ | ✔ |
+| **Regulatory features** | | | | |
+| Transfer restriction (blacklist / address freeze) | ✔ | ✔ | ✔ | ✔ |
+| Transfer restriction on the spender address (*transferFrom*) | ✔ | **✘** | **✘** | ✔ [(GitHub)](https://github.com/castframework/smartcoin/blob/dd8bf5e1ba24d2379b102db74bfc8326fb649b65/contracts/smartCoin/SmartCoin.sol#L342) |
+| On-chain identity management | **✘** (could be added with a `RuleEngine`) | **✘** | ✔ | **✘** |
+| Document management | ✔ ([ERC-1643](https://github.com/ethereum/eips/issues/1643)) | ✔ ([ERC-1643](https://github.com/ethereum/eips/issues/1643)) | **✘** | **✘** |
+| Whitelist management | ✔ (deployment version or RuleEngine) | ✔ | ✔ (on-chain id) | **✘** |
+| Token contract pause | ✔ | ✔ | ✔ | ✔ |
+| Conditional Transfer for specific addresses | **✘** | **✘** | **✘** | ✔ (integrated into the token contract) |
+| Conditional Transfer for all addresses | ✔ (through RuleEngine) | **✘** | ✔ (through compliance contract) | **✘** |
+| **Technical features** | | | | |
+| Configurable ERC-20 decimals | ✔ | **✘** Set at 18 ([Github](https://github.com/Consensys/UniversalToken/blob/master/contracts/ERC1400.sol#L680)) | ✔ | **✘** (18 by default) |
+| Role-based access control | ✔ | ✔ | Partial (only one role Agent) | ✔ |
+| Adaptable access control (code can be easily adapted to other type of access control) | ✔ | **✘** | **✘** | Partial |
+| Mint & burn to any address | ✔ | ✔ | ✔ | ✔ |
+| Forced transfer function | ✔ | ✔ | ✔ | Partial Only force burn is available ([GitHub](https://github.com/castframework/smartcoin/blob/dd8bf5e1ba24d2379b102db74bfc8326fb649b65/contracts/smartCoin/SmartCoin.sol#L97)) |
+| Partially fungible token support | **✘** | ✔ | **✘** | **✘** |
+| Contract version on-chain | ✔ | ✔ | ✔ | ✔ ([GitHub](https://github.com/castframework/smartcoin/blob/dd8bf5e1ba24d2379b102db74bfc8326fb649b65/contracts/smartCoin/SmartCoin.sol#L228)) |
+| Deployable on Layer2 and other EVM blockchains | ✔ (require PUSH0) | Partial Requires [ERC-1820](https://eips.ethereum.org/EIPS/eip-1820) Registry contract | ✔ (require PUSH0) | ✔ |
+| **Other** | | | | |
+| License | MPL 2.0 (weak copyleft) | Apache 2.0 (permissive) | GPL 3.0 (strong copyleft) | Apache 2.0 (permissive) |
+| Third-party security audit | ✔ ([ABDK](https://abdk.consulting) & [Halborn](https://www.halborn.com)) | **✘** | ✔ [Hacken](https://hacken.io)) | **✘** |
+| **CMTAT unique features** | | | | |
+| *Regulatory features* | | | | |
+| Security identifiers | ✔ | **✘** | **✘** | **✘** |
+| Explicit support of debt instruments | ✔ | **✘** | **✘** | **✘** |
+| *Technical* | | | | |
+| MetaTx ("Gasless") support ([ERC-2771](https://eips.ethereum.org/EIPS/eip-2771)) | ✔ | **✘** | **✘** | **✘** |
+| Customizable modular design | ✔ | **✘** | **✘** | **✘** |
+| ERC-20 custom errors ([ERC-6093](https://eips.ethereum.org/EIPS/eip-6093)) | ✔ (use OpenZeppelin v5) | **✘** | **✘** (use OpenZeppelin v4) | **✘** (use OpenZeppelin v4) |
+| [ERC-5679: Token minting and Burning](https://eips.ethereum.org/EIPS/eip-5679) | ✔ | **✘** | **✘** | **✘** |
+| Upgradibility with [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) | ✔ | **✘** | **✘** | **✘** |
+| Snapshots/checkpoints | ✔ (external contract or by extending CMTAT) | **✘** | **✘** | **✘** |
+| **Cross-chain bridge** | | | | |
+| [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) Cross-chain transfer | ✔ | **✘** | **✘** | **✘** |
+| [Chainlink CCT](https://docs.chain.link/ccip/concepts/cross-chain-token) support | ✔ | **✘** (Lack burn/burnFrom/mint) | Partial (Lack burn/burnFrom) | **✘** (Lack owner/getCCIPAdmin/burnFrom) |
+
+**Note**
+
+- At the time of our analysis (July 2025), the next version of T-REX/ERC-3643 had not yet been merged into the main branch and officially released. However, we assumed that it would be merged soon and that it would also be audited.
+- Access control: CMTAT Access control is easily adaptable because it is implemented in high level contracts (base modules) instead of low level modules (wrapper).
+
+### Technical
+
+#### Security and contribution
+
+The design and security of the CMTAT was supported by [ABDK](https://abdk.consulting) (CMTAT v1.0 and v2.3.0) and [Halborn](https://www.halborn.com) (CMTAT v3.0.0), two leading audit companies in smart contract security.
+
+- The preferred way to receive comments is through the GitHub issue tracker.
+- Private comments and questions can be sent to the CMTA secretariat at admin@cmta.ch.
+- For security matters, please see [SECURITY.md](../SECURITY.md).
+
+#### Overview
+
+> Core means that they are the main features to build CMTAT
+
+##### Core features
+
+The CMTAT supports the following core features:
+
+* ERC-20:
+ * Mint, burn, and transfer operations
+ * Configure `name`, `symbol`and `decimals`at deployment, as well as [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) functions to update `name`and `symbol`once deployed
+
+* Pause of the contract and mechanism to deactivate it
+* Freeze of specific accounts through ERC-3643 functions.
+
+##### Extended features
+
+> Extended features are nice-to-have features. They are generally included in the majority of deployment version.
+
+The CMTAT supports the following extended features:
+
+- Add information related to several documents ([ERC-1643](https://github.com/ethereum/EIPs/issues/1643)) though an external contract (`DocumentEngine`)
+
+- Perform snapshot on-chain through an external contract (`SnapshotEngine`)
+- Conditional transfers, via an external contract (`RuleEngine`)
+- Put several information on-chain such as `tokenId` (ISIN or other identifier), `terms` (reference to any legally required documentation) and additional information (`information`)
+
+##### Optional features
+
+> Optional means that they are generally specific to deployment version
+
+The CMTAT supports the following optional features:
+
+- Transfer restriction through allowlisting/whitelisting (can be also done with a `RuleEngine`)
+ - Deployment: CMTAT Standalone Allowlist / CMTAT Upgradeable Allowlist
+ - Module: AllowlistModule
+
+- Put Debt information and Credit Events on-chain
+ - Deployment: CMTAT Standalone Debt / CMTAT Upgradeable Debt
+ - Module: DebtModule & DebtEngineModule
+
+- Cross-chain functionalities with [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802)
+ - Define directly in a CMTAT Base contract (not a module)
+
+- "Gasless" (MetaTx) transactions with [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771)
+ - Module: ERC2771Module
+
+
+Furthermore, the present implementation uses standard mechanisms in
+order to support `upgradeability`, via deployment of the token with a proxy by implementing [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201)
+
+## Standard ERC
+
+Here the list of ERC used by CMTAT v3.0.0
+
+### Schema
+
+
+
+
+
+### CMTAT version support
+
+Here the list of ERC supported between different version:
+
+| | Associated contracts/modules | ERC status | CMTAT v1.0.0 | CMTAT v2.3.0 | CMTAT v3.0.0 | CMTAT v3.2.0 | | | | | |
+| ------------------------------------------------------------ | -------------------------------------------- | ------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Deployment version | | | | | (Standalone & Proxy, including Snapshot) | | Light | UUPS | ERC1363 | Allowlist (whitelist) | Debt |
+| **Fungible tokens** | | | | | | | | | | | |
+| [ERC-20](https://eips.ethereum.org/EIPS/eip-20) | ERC20BaseModule | Standard Track (final) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) | CMTATBaseERC1363 | Standard Track (final) | ✘ | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ | ✘ |
+| **Tokenization** | | | | | | | | | | | |
+| [ERC-7943 (uRWA)](https://eips.ethereum.org/EIPS/eip-7943) | ValidationModuleCore, ERC20EnforcementModule | Review | ✘ | ✘ | ✘ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ |
+| [ERC-1404](https://github.com/ethereum/eips/issues/1404) (Simple Restricted Token Standard) | ValidationModuleERC1404 (Exensions) | Draft | ✔ | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ | ✘ | ✘ |
+| [ERC-1643](https://github.com/ethereum/eips/issues/1643) (Document Management Standard) (Standard from [ERC-1400](https://github.com/ethereum/EIPs/issues/1411)) (Slightly improved) | DocumentModule (Exensions) | Draft | ✘ | ✘ | ✔ (through DocumentEngine with small improvement) | ✔ (through DocumentEngine with small improvement) | ✘ | ✔ | ✔ | ✔ | ✔ |
+| [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643)
(Without on-chain identity) | Core + ERC20EnforcementModule (extensions) | Standard Track (final) | ✘ | ✘ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✔ |
+| [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477) | Core + ERC20EnforcementModule (extensions) | Draft | ✘ | ✘ | ✔ | ✔ | Partially | ✔ | ✔ | ✔ | ✔ |
+| **Proxy support related** | | | | | | | | | | | |
+| Deployment with a UUPS proxy ([ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)) | - | Stagnant (but used) | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ | ✘ | ✘ |
+| [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) (Storage namespaces for proxy contract) | All | Standard Track (final) | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| **Technical** | | | | | | | | | | | |
+| [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (Meta Tx / gasless) | ERC2771Module (options) | Standard Track (final) | ✔ | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ | ✔ | ✘ |
+| [ERC-6093](https://eips.ethereum.org/EIPS/eip-6093) (Custom errors for ERC-20 tokens) | - | Standard Track (final) | ✘ | ✘ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) (cross-chain token/transfers) | ERC20CrossChainModule (options) | Draft | ✘ | ✘ | ✔ | ✔ | ✘ | ✔ | ✔ | ✘ | ✘ |
+| [ERC-5679](https://eips.ethereum.org/EIPS/eip-5679) (Token minting and burning with data) | ERC20MintModule ERC20BurnModule | Standard Track (final) | ✘ | ✘ | Partial (without ERC-165 support) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+
+### Details
+
+#### ERC-3643
+
+> [ERC specification](https://eips.ethereum.org/EIPS/eip-3643)
+> Status: Standards Track
+
+The [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643) is an official Ethereum standard, unlike ERC-1400 and ERC-1404. This standard, also built on top of ERC-20, offers a way to manage and perform compliant transfers of security tokens.
+
+ERC-3643 enforces identity management as a core component of the standards by using a decentralized identity system called [onchainid](https://www.onchainid.com/).
+
+While CMTAT does not include directly the identity management system, it shares with ERC-3643 many of the same functions. The interface is available in [IERC3643Partial.sol](../contracts/interfaces/tokenization/IERC3643Partial.sol)
+
+If you want to use CMTAT to create a version implementing all functions from ERC-3643, you can create it through a dedicated deployment version (like what has been done for UUPS and ERC-1363).
+
+The implemented interface is available in [IERC3643Partial](../contracts/interfaces/tokenization/IERC3643Partial.sol).
+
+The main reason the argument names change is because CMTAT relies on OpenZeppelin to name the arguments.
+
+Required modules:
+
+- Core: PauseModule, ERC20BaseModule, ERC20MintModule, VersionModule, EnforcementModule, ValidationModuleCore
+- Extensions: ERC20EnforcementModule
+
+##### All functions
+
+```solidity
+// interface IERC3643Pause
+// PauseModule
+function paused() external view returns (bool)
+function pause() external
+function unpause() external
+
+// interface IERC3643ERC20Base
+// ERC20BaseModule
+function setName(string calldata name) external
+function setSymbol(string calldata symbol) external
+
+// IERC3643BatchTransfer
+// ERC20MintModule
+function batchTransfer(address[] calldata tos,uint256[] calldata values) external returns (bool)
+
+// IERC3643Version
+// VersionModule
+function version() external view returns (string memory)
+
+// IERC3643Enforcement
+// EnforcementModule
+function isFrozen(address account) external view returns (bool)
+function setAddressFrozen(address account, bool freeze) external
+function batchSetAddressFrozen(address[] calldata accounts, bool[] calldata freeze) external;
+
+// IERC3643ERC20Enforcement
+// ERC20EnforcementModule
+function getFrozenTokens(address account) external view returns (uint256);
+function freezePartialTokens(address account, uint256 value) external;
+function unfreezePartialTokens(address account, uint256 value) external;
+function forcedTransfer(address from, address to, uint256 value) external returns (bool);
+
+
+// IERC3643Mint
+// ERC20MintModule
+function mint(address account, uint256 value) external;
+function batchMint( address[] calldata accounts,uint256[] calldata values) external;
+
+// IERC3643Burn
+// ERC20BurnModule
+function burn(address account, uint256 value) external;
+function batchBurn(address[] calldata accounts,uint256[] calldata values) external;
+
+// IERC3643ComplianceRead
+// ValidationModuleCore
+function canTransfer(
+ address from,
+ address to,
+ uint256 value
+ ) external view returns (bool isValid);
+}
+```
+
+
+
+##### Functions not implemented
+
+All functions related to on-chain identity are **not** implemented inside CMTAT:
+
+- ` setOnchainID`
+- `setIdentityRegistry`
+- `recoveryAddress` because this function takes the ` investorOnchainID` as an argument
+
+These following functions to reduce contract code size:
+
+- `batchForcedTransfer`to reduce contract code size
+- `batchFreezePartialTokens` and `batchUnfreezePartialTokens`
+
+All functions related to the interface `IAgentRole`because CMTAT uses a RBAC Access Control to offer more granularity in terms of access control.
+
+And finally `setCompliance` because CMTAT uses a different architecture for its `ruleEngine`.
+
+##### Version
+
+Module: VersionModule
+
+| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
+| :--------------------------------------------------------- | :--------------- | ------------------ |
+| `version() external view returns (string memory version_)` | Same | All |
+
+##### Pause
+
+Module: PauseModule
+
+| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
+| :--------------------------------------- | :-------------------------------- | ------------------ |
+| `pause() external` | Same | All |
+| `unpause() external` | Same | All |
+| `paused() external view returns (bool);` | Same | All |
+| `event Paused(address _userAddress);` | `event Paused(address account)` | All |
+| `event Unpaused(address _userAddress);` | `event Unpaused(address account)` | All |
+
+##### ERC20Base
+
+| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
+| :-------------------------------------------- | :----------------------------------- | ------------------ |
+| `setName(string calldata _name) external;` | `setName(string calldata name_)` | All |
+| `setSymbol(string calldata _symbol) external` | `setSymbol(string calldata symbol_)` | All |
+
+##### Supply Management (burn/mint)
+
+| **ERC-3643** | **CMTAT v3.0.0 Modules** | **CMTAT v3.0.0 Functions** | Deployment version |
+| :----------------------------------------------------------- | :----------------------- | :----------------------------------------------------------- | ------------------ |
+| `batchMint(address[] calldata _toList, uint256[] calldata _amounts) external;` | ERC20MintModule | `mint(address account, uint256 value)` | All |
+| `batchMint(address[] calldata _toList, uint256[] calldata _amounts) external;` | ERC20MintModule | `batchMint(address[] calldata accounts,uint256[] calldata values) ` | All |
+| `batchTransfer(address[] calldata _toList, uint256[] calldata _amounts) external;` | ERC20MintModule | `batchTransfer(address[] calldata tos,uint256[] calldata values)` | All |
+| `burn(address _userAddress, uint256 _amount) external` | ERC20BurnModule | `function burn(address account,uint256 value)` | All |
+| `batchBurn(address[] calldata _userAddresses, uint256[] calldata _amounts) external` | ERC20BurnModule | `batchBurn(address[] calldata accounts,uint256[] calldata values)` | All |
+
+Warning: `batchTransfer` is restricted to the MINTER_ROLE to avoid the possibility to use non-standard function to move tokens.
+
+##### ERC20Enforcement
+
+| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
+| :----------------------------------------------------------- | :----------------------------------------------------------- | --------------------------------------------------- |
+| `isFrozen(address _userAddress)` | `isFrozen(address account)` | All |
+| `forcedTransfer(address _from, address _to, uint256 _amount) external returns (bool)` | `forcedTransfer(address from, address to, uint256 value) external returns (bool)` | All except Light version (replaced by `forcedBurn`) |
+| `batchForcedTransfer(address[] calldata _fromList, address[] calldata _toList, uint256[] calldata _amounts) external` | Not implemented | - |
+
+##### ValidationModuleCore
+
+Note: `canTransfer` is defined for the compliance contract in ERC-3643.
+
+| **ERC-3643** | **CMTAT v3.0.0** | Deployment version |
+| :----------------------------------------------------------- | :----------------------------------------------------- | ------------------ |
+| `canTransfer(address _from, address _to, uint256 _amount) external view returns (bool)` | `canTransfer(address from, address to, uint256 value)` | All |
+
+#### ERC-7943 (uRWA)
+
+> [ERC specification](https://eips.ethereum.org/EIPS/eip-7943) / [Ethereum magician](https://ethereum-magicians.org/t/erc-7943-universal-rwa-interface-urwa/23972)
+>
+> Status: review
+
+See also [technical/erc-7943-uRWA-integration.md](./technical/erc-7943-uRWA-integration.md)
+
+#### ERC-7943 Implementation in CMTAT
+
+ERC-7943 is a standard defining a set of interfaces for tokenized Real World Assets (RWAs) such as securities, real estate, commodities, or other physical/financial assets on the blockchain. The uRWA standard extends common token standards like [ERC-20](https://eips.ethereum.org/EIPS/eip-20), [ERC-721](https://eips.ethereum.org/EIPS/eip-721) or [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) by introducing essential compliance functions while remaining minimal and not opinionated about specific implementation details.
+
+CMTAT implements it by splitting functionality into interfaces and modules.
+
+##### Interface Breakdown
+
+All related interfaces are defined in the interface file [draft-IERC7943.sol](../contracts/interfaces/tokenization/draft-IERC7943.sol).
+
+| Interface | Purpose |
+| ------------------------------------------ | ------------------------------------------------------------ |
+| `IERC7943FungibleEnforcement` | `forcedTransfer`, `getFrozenTokens` |
+| `IERC7943FungibleEnforcementSpecific` | `setFrozenTokens` |
+| `IERC7943FungibleEnforcementEventAndError` | `Frozen`, `ForcedTransfer` events `ERC7943InsufficientUnfrozenBalance` |
+| `IERC7943FungibleSendReceiveError` | `ERC7943CannotSend`, `ERC7943CannotReceive` errors |
+| `IERC7943FungibleTransferError` | `ERC7943CannotTransfer` error |
+| `IERC7943FungibleSendReceiveCheck` | `canSend`, `canReceive` |
+
+##### Implementation Mapping
+
+| ERC-7943 Requirement | CMTAT Implementation |
+| ------------------------------------ | ------------------------------------------------------------ |
+| **Functions** | |
+| `forcedTransfer(from, to, amount)` | `ERC20EnforcementModule.sol` |
+| `setFrozenTokens(account, amount)` | `ERC20EnforcementModule.sol` |
+| `getFrozenTokens(account)` | `ERC20EnforcementModule.sol` |
+| `canSend(account)` | `ValidationModule.sol` |
+| `canReceive(account)` | `ValidationModule.sol` |
+| `canTransfer(from, to, amount)` | `ValidationModuleCore.sol` |
+| **Error** | |
+| `ERC7943CannotSend` | `ValidationModule.sol` |
+| `ERC7943CannotReceive` | `ValidationModule.sol` |
+| `ERC7943CannotTransfer` | Defined in `draft-IERC7943.sol` (interface-level; currently not reverted directly by CMTAT runtime paths) |
+| `ERC7943InsufficientUnfrozenBalance` | [ERC20EnforcementModuleInternal.sol](../contracts/modules/internal/ERC20EnforcementModuleInternal.sol) |
+| **Event** | [ERC20EnforcementModuleInternal.sol](../contracts/modules/internal/ERC20EnforcementModuleInternal.sol) |
+| `Frozen` | |
+| `ForcedTransfer` | [ERC20EnforcementModuleInternal.sol](../contracts/modules/internal/ERC20EnforcementModuleInternal.sol) |
+
+
+
+##### Transfer Flow Diagram
+
+When a transfer is attempted with the standard CMTAT version:
+
+```
+transfer(to, 100)
+│
+├─ Is contract paused? ──────────────→ revert EnforcedPause()
+│
+├─ Is sender/spender frozen? ────────→ revert ERC7943CannotSend(account)
+├─ Is receiver frozen? ──────────────→ revert ERC7943CannotReceive(account)
+│
+├─ RuleEngine says no? ─────────────→ RuleEngine reverts with its own errors
+├─ Other check (transferred) says no? ─────────────→ RuleEngine/custom validation errors
+│
+├─ Not enough active balance? ───────→ revert ERC7943InsufficientUnfrozenBalance(...)
+│
+└─ Transfer executes
+```
+
+There are three ERC-7943 errors currently used in this workflow: `ERC7943CannotSend`, `ERC7943CannotReceive` and `ERC7943InsufficientUnfrozenBalance`.
+`ERC7943CannotTransfer` is kept in the interface for specification completeness and potential future use.
+
+
+
+#### ERC-7551 (eWPG)
+
+> [ERC specification](https://github.com/ethereum/ERCs/blob/60a282eb3c867af2dbed8eff12e7549b548cf1bf/ERCS/erc-7551.md) / [Ethereum magician](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg-reworked/25477)
+>
+> Status: draft
+
+ERC-7551 ([eWpG](https://www.gesetze-im-internet.de/ewpg/)) is a proposal by the German Federal Association of Crypto Registrars for a smart contract interface tailored to *crypto securities* in Germany (eWpG). It aims to provide a flexible, minimal foundational layer so that tokens can meet legal/compliance requirements while leaving the door open on how to restrict the use of the token (on-chain id like ERC-3643).
+
+The implemented interface is available in [IERC7551](../contracts/interfaces/tokenization/draft-IERC7551.sol).
+
+Only the specific deployment version dedicated (CMTATERC7551) implements the full interface.
+
+Required modules:
+
+- Core: EnforcementModule, PauseModule, ERC20MintModule, ERC20BurnModule, ValidationModuleCore
+- Extension: ExtraInformationModule
+- Option: ERC7551Module
+
+##### Link to off-chain document
+
+Contrary to the ERC-7551 specification, CMTAT does not enforce a non-zero value for the `termsHash`.
+
+`unpause`will not revert if `termsHash == 0x0`.
+
+##### Summary tab
+
+The following table compares the functionalities and details how the relevant functionalities are implemented in CMTAT's reference Solidity implementation:
+
+| **N°** | **Functionalities** | **ERC-7551 Functions** | **CMTAT v3.0.0 standard** | CMTAT v3.0.0 ERC7551 | Implementations details | Modules |
+| :--------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | :----------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| 1 | Freeze and unfreeze a specific amount of tokens | `freezePartialTokens(address account, uint256 amount, bytes calldata data)` `unfreezePartialTokens(address account, uint256 amount, bytes calldata data)` | ✔ | ✔ | - | EnforcementModule (core) ERC20EnforcementModule (extensions) |
+| 2 | Pausing transfers The operator can pause and unpause transfers | `pause()/unpause()` | ✔ | ✔ | - | PauseModule (core) |
+| 3 | Link to off-chain document Add the hash of a document | `setTerms(bytes32 _hash, string calldata _uri)` | ✘ | ✔ | The hash is put in the field ` Terms` Terms is represented as a Document (name, uri, hash, last on-chain modification date) based on [ERC-1643](https://github.com/ethereum/eips/issues/1643). | ERC7551Module (options) |
+| | Equivalent functionality | | ✔ | ✔ | `setTerms(IERC1643CMTAT.DocumentInfo calldata terms_)` | ExtraInformationModule (extensions) |
+| 4 | Metadata JSON file | `setMetaData(string calldata _metadata) ` | ✘ (can be put in the field `information`) | ✔ | - | ERC7551Module (options) |
+| 5 | Forced transfers Transfer `amount` tokens to `to` without requiring the consent of `from` | `forcedTransfer(address account, address to, uint256 value, bytes calldata data) ` | ✔ | ✔ | - | ERC20EnforcementERC7551Module |
+| 6 | Token supply management Reduce the balance of `tokenHolder` by `amount` without increasing the amount of tokens of any other holder | `burn(address tokenHolder, uint256 amount, bytes calldata data) ` | ✔ | ✔ | - | ERC20BurnModule (core) |
+| 7 | Token supply management Increase the balance of `to` by `amount` without decreasing the amount of tokens from any other holder. | `mint(address to, uint256 amount, bytes calldata data)` | ✔ | ✔ | - | ERC20MintModule (core) |
+| **View/read-only functions** | | | | | | |
+| 8 | Transfer compliance Check if a transfer is valid | `canTransfer(address from, address to, uint256 value) ` `canTransferFrom()` | ✔ | ✔ | - | ValidationModuleCore |
+| 9 | Transfer compliance Check if a transfer with a spender is valid | `canTransferFrom(address spender, address from, address to, uint256 value) ` | ✔ | ✔ | - | ValidationModuleCore |
+| 10 | Active/Frozen Balance | `getActiveBalanceOf(address tokenHolder)` `getFrozenTokens(address tokenHolder)` | ✔ | ✔ | - | ERC20EnforcementERC7551Module |
+
+##### Full functions
+
+```solidity
+// IERC7551Mint
+// ERC20MintModule
+event Mint(address indexed minter, address indexed account, uint256 value, bytes data);
+function mint(address account, uint256 value, bytes calldata data) external;
+
+// IERC7551Burn
+// ERC20BurnModule
+event Burn(address indexed burner, address indexed account, uint256 value, bytes data);
+function burn(address account, uint256 amount, bytes calldata data) external;
+
+// IERC7551Pause
+// PauseModule
+function paused() external view returns (bool);
+function pause() external;
+function unpause() external;
+
+// IERC7551ERC20Enforcement
+// ERC20EnforcementERC7551Module
+function getActiveBalanceOf(address account) external view returns (uint256);
+function getFrozenTokens(address account) external view returns (uint256);
+function freezePartialTokens(address account, uint256 amount, bytes memory data) external;
+function unfreezePartialTokens(address account, uint256 amount, bytes memory data) external;
+function forcedTransfer(address account, address to, uint256 value, bytes calldata data) external returns (bool);
+
+
+// IERC7551Compliance is IERC3643ComplianceRead
+// ValidationModuleCore
+function canTransferFrom(
+ address spender,
+ address from,
+ address to,
+ uint256 value
+ ) external view returns (bool);
+// From IERC3643ComplianceRead
+function canTransfer(address from, address to, uint256 value) external view returns (bool);
+
+
+// IERC7551Document
+// IERC7551Module
+event Terms(bytes32 hash_, string uri_);
+event MetaData(string newMetaData);
+function termsHash() external view returns (bytes32);
+function setTerms(bytes32 _hash, string calldata _uri) external;
+function metaData() external view returns (string memory);
+function setMetaData(string calldata metaData_) external;
+```
+
+
+
+#### ERC-7802 (Crosschain transfers)
+
+> [ERC specification](https://eips.ethereum.org/EIPS/eip-7802)
+> Status: draft
+
+This standard introduces a minimal and extendable interface, `IERC7802`, for tokens to enable standardized crosschain communication.
+
+CMTAT implements this standard in the option module `ERC20CrossChain`
+
+This standard is notably used by Optimism to provide cross-chain bridge between Optimism chain, see [docs.optimism.io/interop/superchain-erc20](https://docs.optimism.io/interop/superchain-erc20)
+
+More information available in the cross chain section.
+
+Deployment version: since it is an option module, it is not currently used in the deployment version `debt`, `light` & `allowlist`.
+
+```solidity
+interface IERC7802 is IERC165 {
+ /// @notice Emitted when a crosschain transfer mints tokens.
+ event CrosschainMint(address indexed to, uint256 value, address indexed sender);
+
+ /// @notice Emitted when a crosschain transfer burns tokens.
+ event CrosschainBurn(address indexed from, uint256 value, address indexed sender);
+
+ /// @notice Mint tokens through a crosschain transfer.
+ function crosschainMint(address to, uint256 value) external;
+
+ /// @notice Burn tokens through a crosschain transfer.
+ function crosschainBurn(address from, uint256 value) external;
+}
+```
+
+
+
+-----
+
+## Architecture
+
+CMTAT architecture is divided in two main components: modules and engines.
+
+### Overview
+
+#### Schema
+
+Here is an overview on how CMTAT is built:
+
+
+
+#### Tree file structure
+
+Here is the GitHub file structure for CMTAT repository.
+
+```
+contracts/
+ ├── deployment/ # Ready-to-deploy token contracts
+ ├── modules/
+ │ ├── internal/ # Core logic (low-level)
+ │ └── wrapper/ # Public interfaces using internal modules or OpenZeppelin library
+ │ ├── core/ # ERC20, mint, burn, pause
+ │ ├── controllers/ # Transfer validation
+ │ ├── extensions/ # Snapshots, documents
+ │ └── options/ # Optional features (debt, allowlist)
+ └── interfaces/ # Contract interfaces
+```
+
+### Base contract
+
+The base contracts are abstract contracts, so not directly deployable, which inherit from several different modules.
+
+Base contracts are used by the different deployable contracts (CMTATStandardStandalone, CMTATStandardUpgradeable,...) to inherit from the different modules
+
+| Name | Level | Description | Associated contracts deployments |
+| ------------------------------------------------------------ | ----- | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [CMTATBaseCommon](../contracts/modules/0_CMTATBaseCommon.sol) | 0 | Inherits from all core and extension modules, except ValidationModule | No deployment contract directly inherits from this base contract (see next level) |
+| [CMTATBaseCore](../contracts/modules/0_CMTATBaseCore.sol) | 0 | Inherits from all core modules | CMTAT Light (Upgradeable & Standalone |
+| [CMTATBaseGeneric](../contracts/modules/0_CMTATBaseGeneric.sol) | 0 | Inherits from non-ERC20 related modules | - (Only mock available) |
+| [CMTATBaseSnapshot](../contracts/modules/0_CMTATBaseSnapshot.sol) | 0 | Pure mixin: inherits from `ERC20Upgradeable` + `SnapshotEngineModule`. Overrides `_update` with snapshot logic. `_authorizeSnapshots()` is abstract. | - |
+| [CMTATBaseDocument](../contracts/modules/1_CMTATBaseDocument.sol) | 1 | Pure mixin: adds ERC-1643 document management primitives (`DocumentERC1643Module`) | No deployment contract directly inherits from this base contract (see next level) |
+| [CMTATBaseAccessControl](../contracts/modules/2_CMTATBaseAccessControl.sol) | 2 | Inherits from CMTATBaseCommon and OpenZeppelin Access Control | - |
+| [CMTATBaseAllowlist](../contracts/modules/3_CMTATBaseAllowlist.sol) | 3 | Inherits from CMTATBaseAccessControl and ValidationModuleAllowlist | CMTAT Allowlist (upgradeable & Standalone) |
+| [CMTATBaseRuleEngine](../contracts/modules/3_CMTATBaseRuleEngine.sol) | 3 | Add RuleEngine support by inheriting from CMTATBaseAccessControl and ValidationModuleRuleEngine | No deployment contract directly inherits from this base contract (see next level) |
+| [CMTATBaseDebt](../contracts/modules/4_CMTATBaseDebt.sol) | 4 | Add debt support by inheriting from Debt module | CMTAT Debt (Standalone & Upgradeable) |
+| [CMTATBaseERC1404](../contracts/modules/4_CMTATBaseERC1404.sol) | 4 | Add [ERC-1404](https://github.com/ethereum/EIPs/issues/1404) support | CMTAT Standalone / Upgradeable |
+| [CMTATBaseERC20CrossChain](../contracts/modules/5_CMTATBaseERC20CrossChain.sol) | 5 | Add cross-chain support, notably [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) | No deployment contract directly inherits from this base contract (see next level) |
+| [CMTATBaseERC2612](../contracts/modules/6_CMTATBaseERC2612.sol) | 6 | Add [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) + [ERC-6357 Multicall](https://eips.ethereum.org/EIPS/eip-6357) | CMTAT Permit (Standalone / Upgradeable) |
+| [CMTATBaseERC2771](../contracts/modules/6_CMTATBaseERC2771.sol) | 6 | Add [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) support by inheriting from ERC2771Module | CMTAT Standalone / Upgradeable CMTAT Upgradeable UUPS |
+| [CMTATBaseERC2771Snapshot](../contracts/modules/7_CMTATBaseERC2771Snapshot.sol) | 7 | Extends CMTATBaseERC2771 with snapshot engine support by also inheriting CMTATBaseSnapshot. Disambiguates ERC-20 and Context functions. | CMTAT Standalone Snapshot / Upgradeable Snapshot |
+| [CMTATBaseDebtEngine](../contracts/modules/6_CMTATBaseDebtEngine.sol) | 6 | Add DebtEngine support and snapshot engine support by inheriting from DebtEngine module and CMTATBaseSnapshot | CMTAT Standalone DebtEngine / Upgradeable |
+| [CMTATBaseERC1363](../contracts/modules/8_CMTATBaseERC1363.sol) | 8 | Add [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) support on top of `CMTATBaseERC7551Enforcement` | CMTAT ERC1363 (Upgradeable & Standalone) |
+| [CMTATBaseERC7551Enforcement](../contracts/modules/7_CMTATBaseERC7551Enforcement.sol) | 7 | Add ERC-7551 enforcement functions (`forcedTransfer/freezePartialTokens/unfreezePartialTokens` with `bytes` and `getActiveBalanceOf`) | CMTAT Standard (Upgradeable & Standalone) |
+| [CMTATBaseERC7551](../contracts/modules/8_CMTATBaseERC7551.sol) | 8 | Add ERC-7551 support on top of `CMTATBaseERC7551Enforcement` by inheriting from ERC7551 Module | CMTAT ERC7551 (Upgradeable & Standalone) |
+
+#### Level 0 (main modules)
+
+#### CMTAT Base Common
+
+
+
+
+
+CMTAT Base adds several functions:
+
+- `burnAndMint`to burn and mint atomically in the same function.
+
+##### CMTAT Base Core
+
+CMTAT Base Core adds several functions:
+
+- `burnAndMint`to burn and mint atomically in the same function.
+- `forcedBurn`to allow the admin to burn tokens from a frozen address (defined in EnforcementModule)
+
+ - This function is not required in CMTATBase because the function `forcedTransfer` (ERC20EnforcementModule) can be used instead.
+
+ 
+
+
+
+##### CMTAT Base Generic
+
+
+
+
+
+
+
+#### Level 1 (document management)
+
+##### CMTAT Base Document
+
+Document management is introduced at this level through `CMTATBaseDocument`.
+
+#### Level 3 (ERC-20 transfer restriction)
+
+##### CMTAT Base RuleEngine
+
+
+
+##### CMTAT Base Allowlist
+
+
+
+
+
+#### Level 4 (heavy modules)
+
+##### CMTATBaseDebt
+
+
+
+##### CMTATBaseERC1404
+
+
+
+
+
+#### Level 5 (cross-chain transfer)
+
+
+
+#### Level 6 (metaTx)
+
+##### CMTAT Base ERC2771
+
+
+
+#### Level 7 (snapshot + ERC-7551 enforcement)
+
+##### CMTAT Base ERC2771 Snapshot
+
+
+
+##### CMTAT Base ERC7551 Enforcement
+
+
+
+#### Level 8 (use case)
+
+##### CMTAT Base ERC1363 (payable token)
+
+
+
+
+
+
+
+
+
+
+
+##### CMTAT Base ERC7551
+
+
+
+
+
+
+
+
+
+
+
+
+
+### Module
+
+#### Description
+
+Modules describe a **logical** code separation inside CMTAT. They are defined as abstract contracts.
+Their code and functionalities are part of the CMTAT and therefore are also included in the calculation of the contract size and the maximum size limit of 24 kB.
+
+It is always possible to delete a module, but this requires modifying the code and compiling it again, which would require a security audit to be performed on these modifications.
+
+Modules are also separated in different categories.
+
+- **Internal** modules: implementation for a module when OpenZeppelin does not provide a library to use. For example, this is the case for the `EnforcementModule`.
+- **Wrapper** modules: abstract contract around OpenZeppelin contracts or internal module.
+ For example, the wrapper `PauseModule` provides public functions to call the internal functions from OpenZeppelin.
+ - **Core** (Wrapper sub-category): Contains the modules required to be CMTA compliant
+ - **Security**: module related to access control
+ - **Extension** (Wrapper sub-category): not required to be CMTA compliant, "bonus features" (snapshotModule, debtModule)
+ - **Options**: also bonus features to meet specific use cases through specific deployment version.
+
+
+
+
+#### List
+
+Here is the list of modules supported between different versions and the differences.
+
+For simplicity, the module names and function locations are those of version 3.0.0
+
+- "fn" means function
+- Changes made in a release are considered maintained in the following release unless explicitly stated otherwise
+
+##### Controllers
+
+| Modules | Type | Description | File | CMTAT 1.0 | CMTAT 2.30 | CMTAT >= 3.0.0 | | | |
+| ---------------------------------- | ----------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Deployment version | | | | | | Standalone, Upgradeable, Snapshot, UUPS, Debt, ERC1363, ERC7551 | CMTAT Debt | CMTAT Allowlist | CMTAT Light |
+| ValidationModule | Controllers | Check transfer validity by calling the Pause and Enforcement modules | [ValidationModule.sol](../contracts/modules/wrapper/controllers/ValidationModule.sol) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| ValidationModuleAllowlist | Controllers | Check transfer validity by calling Allowlist module | [ValidationModuleAllowlist.sol](../contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol) | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ |
+| ValidationModuleRuleEngineInternal | Internal | Configure a `RuleEngine` | [ValidationModuleRuleEngineInternal.sol](../contracts/modules/internal/ValidationModuleRuleEngineInternal.sol) | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ |
+| ValidationModuleCore | Core | Implements`canTransfer`and `canTransferFrom` The core module does not implement ERC-1404 and the RuleEngine | [ValidationModuleCore.sol](../contracts/modules/wrapper/core/ValidationModuleCore.sol) | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+| ValidationModuleRuleEngine | Extensions | Set and call the ruleEngine to check transfer. | [ValidationModuleRuleEngine.sol](../contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol) | ✔ | ✔ | ✔ | ✔ | ✘ | ✘ |
+| ValidationModuleERC1404 | Extensions | Implements ERC-1404 | [ValidationModuleERC1404.sol](../contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol) | ✔ | ✔ | ✔ | ✘ | ✘ | ✘ |
+
+
+
+**Controllers**
+
+- ValidationModule
+
+
+
+- ValidationModuleAllowlist
+
+
+
+**Internal**
+
+- ValidationModuleRuleEngineInternal
+
+
+
+
+
+**Core**
+
+- ValidationModuleCore
+
+
+
+
+
+**Extensions**
+
+- ValidationModuleRuleEngine
+
+
+
+- ValidationModuleERC1404
+
+
+
+
+
+##### Core modules
+
+Generally, these modules are required to be compliant with the CMTA specification.
+
+| Modules | Description | File | CMTAT 1.0 | CMTAT 2.30 | CMTAT >= 3.0.0 |
+| ------------------------------------------------------------ | ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [VersionModule](./modules/core/Version/version.md) | Contract version | [VersionModule.sol](../contracts/modules/wrapper/core/VersionModule.sol) | ✔ | ✔ (Add two fields: flag and information) | ✔ Remove field flag (not used) Keep only the field VERSION and move the rest (tokenId, information,..) to an extension module `ExtraInformation` CMTAT 3.0.1: update name baseModule -> VersionModule |
+| [ERC20 Burn](./modules/core/ERC20Burn/ERC20Burn.md) (Prev. BurnModule) | Burn functions | [ERC20BurnModule.sol](../contracts/modules/wrapper/core/ERC20BurnModule.sol) | ✔ | ✔ Replace fn `burnFrom` by fn `forcedBurn` | Add fn `burnBatch` Rename `forceBurn` in `burn` `burnFrom` is moved to the option module `ERC20CrossChain`(v3.1.0) |
+| [Enforcement](./modules/core/Enforcement/enforcement.md) | Freeze/unfreeze address | [EnforcementModule.sol](../contracts/modules/wrapper/core/EnforcementModule.sol) | ✔ | ✔ | ✔ |
+| [ERC20Base](./modules/core/ERC20Base/ERC20base.md) | decimals, set name & symbol | [ERC20BaseModule.sol](../contracts/modules/wrapper/core/ERC20BaseModule.sol) | ✔ | ✔ Remove fn `forceTransfer` (replaced by `burn`and `mint`) | Add fn `balanceInfo` (useful to distribute dividends) Add fn `forcedTransfer` Add fn `setName`and `setSymbol` Remove custom fn `approve`(keep only ERC-20 approve) |
+| [ERC20 Mint](./modules/core/ERC20Mint/ERC20Mint.md) | Mint functions + BatchTransfer | [ERC20MintModule.sol](../contracts/modules/wrapper/core/ERC20MintModule.sol) | ✔ | ✔ | Add fn `mintBatch` Add fn `transferBatch` |
+| [Pause Module](./modules/core/Pause/pause.md) | Pause and deactivate contract | [PauseModule.sol](../contracts/modules/wrapper/core/PauseModule.sol) | ✔ | ✔ | Replace fn `kill` by fn `deactivateContract` |
+
+
+
+
+
+##### Extension modules
+
+Generally, these modules are not required to be compliant with the CMTA specification.
+
+| Modules | Description | File | CMTAT 1.0 | CMTAT 2.30 | CMTAT >= 3.0.0 |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [ExtraInformation](./modules/extensions/ExtraInformation/extraInformation.md) | Set extra information (tokenId, terms, metadata) | [ExtraInformationModule.sol](../contracts/modules/wrapper/extensions/ExtraInformationModule.sol) | ✔ (BaseModule) | ✔ (BaseModule) | ✔ |
+| [SnapshotEngineModule](./modules/extensions/snapshotEngine/Snapshot.md) (Prev. SnapshotModule) | Set snapshotEngine | [SnapshotEngineModule.sol](../contracts/modules/wrapper/extensions/SnapshotEngineModule.sol) | ✔ | Partial (Not included by default because unaudited) | ✔ (require an external SnapshotEngine) |
+| [DocumentEngineModule](./modules/extensions/documentEngine/document.md) | Set additional document (ERC1643) through a DocumentEngine | [DocumentEngineModule.sol](../contracts/modules/wrapper/options/DocumentEngineModule.sol) | ✘ | ✘ | ✔ |
+| [ERC20EnforcementModule](./modules/extensions/ERC20Enforcement/erc20enforcement.md) | The admin (or a third party appointed by it) can partially freeze a part of the balance of a token holder. | [ERC20EnforcementModule.sol](../contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol) | ✘ | ✘ | ✔ |
+
+> Note: `DocumentEngineModule` exists as an optional module but is currently not included in any deployment version. It is validated through dedicated test mocks.
+
+##### Option modules
+
+| Modules | Description | File | CMTAT 1.0 | CMTAT 2.3.0 | CMTAT >= 3.2.0 | | | |
+| ------------------------------------------------------------ | ---------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Deployment version | | | | | Standalone & Upgradeable (including Snapshot) | Allowlist | Debt | ERC7551 |
+| [DebtModule](./modules/options/debt/debt.md) | Set Debt and CreditEvent Info | [DebtModule.sol](../contracts/modules/wrapper/options/DebtModule.sol) | ✘ | ✔ | ✘ | ✘ | ✔ | ✘ |
+| [DebtEngineModule](./modules/options/debtEngine/debtEngine.md) | Add a DebtEngine module | [DebtEngineModule.sol](../contracts/modules/wrapper/options/DebtEngineModule.sol) | ✘ | ✘ | ✘ | ✘ | ✔ | ✘ |
+| [ERC2771Module](./modules/options/erc2771/erc2771.md) | ERC-2771 support | [ERC2771Module.sol](../contracts/modules/wrapper/options/ERC2771Module.sol) | ✔ | ✔ (forwarder immutable) | ✔ | ✔ | ✘ | ✔ |
+| [Allowlist](./modules/options/allowlist/allowlist.md) | Add integrated allowlist support | [AllowlistModule.sol](../contracts/modules/wrapper/options/AllowlistModule.sol) | ✘ | ✘ | ✘ | ✔ | ✘ | ✘ |
+| [ERC7551Module](./modules/options/erc7551/erc7551.md) | Add specific ERC-7551 functions | [ERC7551Module.sol](../contracts/modules/wrapper/options/ERC7551Module.sol) | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ |
+| [ERC20CrossChainModule](./modules/options/erc20crosschain/ERC20CrossChain.md) | Add cross-chain functionalities (ERC-7802, burn, burnFrom) | [ERC20CrossChainModule.sol](../contracts/modules/wrapper/options/ERC20CrossChainModule.sol) | ✘ | ✘ | ✔ | ✘ | ✘ | ✔ |
+| [CCIPModule](./modules/options/ccip/ccip.md) | Add CCIP specific function | [CCIPModule.sol](../contracts/modules/wrapper/options/CCIPModule.sol) | ✘ | ✘ | ✔ | ✘ | ✘ | ✔ |
+
+
+
+##### Security
+
+| | Description | File | CMTAT 1.0 | CMTAT 2.30 | CMTAT >= 3.0.0 |
+| ----------------------------------------------------- | -------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| [AccessControlModule](./modules/security/access.md) | Access Control | [AccessControlModule.sol](../contracts/modules/wrapper/security/AccessControlModule.sol) | ✔ | ✔ (Admin has all the roles by default) | ✔ |
+
+
+
+### Access Control (RBAC)
+
+See also [technical/access-control.md](./technical/access-control.md)
+
+CMTAT access control is also modular and flexible.
+
+**Wrapper modules**
+
+Firstly, wrapper modules will separately:
+
+- define the roles useful to restrict its own functions
+- define virtual functions `authorize` which require to be overridden in CMTAT base module to add access control check.
+
+To allow flexibility and customisation, wrapper modules do not implement the access control themselves. Access control is defined in CMTAT base modules. Therefore, it is possible to create a new base module to use a different access control.
+
+**CMTAT base module**
+
+Current CMTAT base module use the standard RBAC access control by using the contract `AccessControl`from OpenZeppelin.
+
+This is defined in the CMTAT base contract `CMTATBaseAccessControl`(level 1)
+
+The `AccessControlModule` which is used by the different CMTAT base module and deployment contracts override the OpenZeppelin function `hasRole` to give by default all the roles to the `admin`.
+
+See also [docs.openzeppelin.com - AccessControl](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl)
+
+#### Key management
+
+As with any token contract, access to the admin key must be adequately restricted.
+
+Likewise, access to the proxy contract must be restricted and segregated from the token contract.
+
+##### UUPS Proxy
+
+For the deployment version for **UUPS proxies**, unfortunately there is no segregation between contract rights (admin) and the proxy. A possible improvement would be to add an owner who would only have the rights to update the proxy.
+
+Any compromise to the DEFAULT_ADMIN_ROLE account may allow a hacker to take advantage of this authority and change the implementation contract which is pointed by proxy and therefore execute potential malicious functionality in the implementation contract.
+
+##### Role interaction notes
+
+- `ENFORCER_ROLE` can block mint operations by freezing the minter/operator address via `setAddressFrozen(address, true)`.
+ In spender-aware compliance paths, mint uses the effective operator as spender, so a frozen operator reverts with `ERC7943CannotSend`.
+- `SNAPSHOOTER_ROLE` can trigger a **transfer-liveness halt** (pause-like effect) if it configures a snapshot engine that always reverts, because snapshot hooks run inside `_update` on state-changing token operations.
+
+#### Role list
+
+Here is the list of roles and their 32 bytes identifier.
+
+| | Defined in | 32 bytes identifier |
+| ---------------------- | --------------------------------------------------------- | ------------------------------------------------------------ |
+| DEFAULT_ADMIN_ROLE | OpenZeppelin AccessControl | 0x0000000000000000000000000000000000000000000000000000000000000000 |
+| **Core Modules** | | |
+| BURNER_ROLE | BurnModule | 0x3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848 |
+| MINTER_ROLE | MintModule | 0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6 |
+| ENFORCER_ROLE | EnforcementModule | 0x973ef39d76cc2c6090feab1c030bec6ab5db557f64df047a4c4f9b5953cf1df3 |
+| PAUSER_ROLE | PauseModule | 0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a |
+| **Extension Modules** | | |
+| SNAPSHOOTER_ROLE | SnashotModule | 0x809a0fc49fc0600540f1d39e23454e1f6f215bc7505fa22b17c154616570ddef |
+| DOCUMENT_ROLE | DocumentModule | 0xdd7c9aafbb91d54fb2041db1d5b172ea665309b32f5fffdbddf452802a1e3b20 |
+| EXTRA_INFORMATION_ROLE | ExtraInformationModule (Also used by ERC7551 module) | 0x921df7a58eb4ea112afa962b8186161404ecda2e8fe97f8246026d02ad1a74b7 |
+| ERC20ENFORCER_ROLE | ERC20EnforcementModule | 0xd62f75bf68b069bc8e2abd495a949fafec67a4e5a5b7cb36aedf0dd51eec7e72 |
+| **Option Modules** | | |
+| ALLOWLIST_ROLE | AllowlistModule | 0x26a560d834a19637eccba4611bbc09fb32970bb627da0a70f14f83fdc9822cbc |
+| DEBT_ROLE | DebtModule | 0xc6f3350ab30f55ce45863160fc345c1663d4633fe7cacfd3b9bbb6420a9147f8 |
+| DEBT_ENGINE_ROLE | DebtEngineModule | 0x516b2a17ebe2d0badac282ee8b39b7f1c94deb40fe902ce0db99741f01cae093 |
+| CROSS_CHAIN_ROLE | ERC20CrossChainModule | 0x620d362b92b6ef580d4e86c5675d679fe08d31dff47b72f281959a4eecdd036a |
+| BURNER_FROM_ROLE | ERC20CrossChainModule | 0x5bfe08abba057c54e6a28bce27ce8c53eb21d7a94376a70d475b5dee60b6c4e2 |
+| BURNER_SELF_ROLE | ERC20CrossChainModule | 0x13d9f3ea33477b975af6cd01437366c28412d5bd9b872fa0fc25bd3a160683af |
+
+
+
+#### Role by modules
+
+Here is a summary tab for each restricted functions defined in a module
+For function signatures, struct arguments are represented with their corresponding native type.
+
+Roles are defined in their specific modules but enforced in CMTAT Base module.
+
+Thus, you are free to use a module, for example `PauseModule` and apply a different access control to restrict the function.
+
+| | Function signature | Visibility [public/external] | Input variables (Function arguments) | Output variables (return value) | Role Required |
+| --------------------------------------------- | ------------------------------------------------------------ | ---------------------------- | ------------------------------------------------------------ | ------------------------------------ | ------------------------------------------------------------ |
+| **Core Modules** | | | | | |
+| ERC20BaseModule | | | | | |
+| | `setName(string name_)` | public | `string name_` | - | DEFAULT_ADMIN_ROLE |
+| | `setSymbol(string symbol_)` | public | `string symbol_` | - | DEFAULT_ADMIN_ROLE |
+| ERC20BurnModule | | | | | |
+| | `burn(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | BURNER_ROLE |
+| | `burn(address account, uint256 value)` | public | `address account, uint256 value` | - | BURNER_ROLE |
+| | `batchBurn(address[] accounts, uint256[] values, bytes data)` | public | `address[] accounts, uint256[] values, bytes data` | - | BURNER_ROLE |
+| | `batchBurn(address[] accounts, uint256[] values)` | public | `address[] accounts, uint256[] values` | - | BURNER_ROLE |
+| ERC20MintModule | | | | | |
+| | `mint(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | MINTER_ROLE |
+| | `mint(address account, uint256 value)` | public | `address account, uint256 value` | - | MINTER_ROLE |
+| | `batchMint(address[] accounts, uint256[] values)` | public | `address[] accounts, uint256[] values` | - | MINTER_ROLE |
+| | `batchTransfer( address[] tos, uint256[] values)` | public | `address[] tos, uint256[] values` | bool | MINTER_ROLE |
+| EnforcementModule | | | | | |
+| | `setAddressFrozen(address account, bool freeze)` | public | `address account, bool freeze` | - | ENFORCER_ROLE |
+| | `setAddressFrozen(address account, bool freeze, bytes data)` | public | `address account, bool freeze, bytes data` | - | ENFORCER_ROLE |
+| | `batchSetAddressFrozen( address[] accounts, bool[] freezes)` | public | `address[] accounts, bool[] freezes` | - | ENFORCER_ROLE |
+| PauseModule | | | | | |
+| | `pause()` | public | - | - | PAUSER_ROLE |
+| | `unpause()` | public | - | - | PAUSER_ROLE |
+| | `deactivateContract()` | public | - | - | DEFAULT_ADMIN_ROLE |
+| **Extension Modules** | | | | | |
+| DocumentEngineModule | | | | | |
+| | `setDocumentEngine(address documentEngine_ )` | public | `IERC1643 documentEngine_` | - | DOCUMENT_ROLE |
+| ERC20EnforcementModule | | | | | |
+| | `forcedTransfer(address from, address to, uint256 value, bytes data)` | public | `address from, address to, uint256 value, bytes data` | bool | DEFAULT_ADMIN_ROLE |
+| | `forcedTransfer(address from, address to, uint256 value)` | public | `address from, address to, uint256 value` | bool | DEFAULT_ADMIN_ROLE |
+| | `freezePartialTokens(address account, uint256 value)` | public | `address account, uint256 value` | - | ERC20ENFORCER_ROLE |
+| | `unfreezePartialTokens(address account, uint256 value)` | public | `address account, uint256 value` | - | ERC20ENFORCER_ROLE |
+| | `freezePartialTokens(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | ERC20ENFORCER_ROLE |
+| | `unfreezePartialTokens(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | ERC20ENFORCER_ROLE |
+| ExtraInformationModule | | | | | |
+| | `setTokenId(string tokenId_ )` | public | | | EXTRA_INFORMATION_ROLE |
+| | `setTerms((string,string,bytes32) terms_)` | public | `IERC1643CMTAT.DocumentInfo terms_` | | |
+| | `setInformation(string information_)` | public | `string information_` | | |
+| SnapshotEngineModule | | | | | ERC20ENFORCER_ROLE |
+| | `setSnapshotEngine(address snapshotEngine_)` | public | `ISnapshotEngine snapshotEngine_` | | SNAPSHOOTER_ROLE |
+| **Option Modules** | | | | | |
+| AllowlistModule | | | | | |
+| | `setAddressAllowlist(address account, bool status)` | public | `address account, bool status` | - | ALLOWLIST_ROLE |
+| | `setAddressAllowlist(address account, bool status, bytes data)` | public | `address account, bool status, bytes data` | - | ALLOWLIST_ROLE |
+| | `batchSetAddressAllowlist(address[] accounts, bool[] status)` | public | `address[] accounts, bool[] status` | - | ALLOWLIST_ROLE |
+| DebtEngineModule | | | | | BURNER_FROM_ROLE |
+| | `setDebtEngine(address debtEngine_)` | public | `IDebtEngine debtEngine_` | - | DEBT_ENGINE_ROLE |
+| DebtModule | | | | | |
+| | `setCreditEvents( (bool,bool,string) creditEvents_)` | public | `CreditEvents creditEvents_` | - | DEBT_ROLE |
+| | `setDebt((string,string,string,string),(uint256,uint256,uint256,string,string,string,string,string,string,string,string,address) debt_)` | public | `ICMTATDebt.DebtInformation debt_` | - | DEBT_ROLE |
+| ERC7551Module | | | | | |
+| | `setMetaData(string metadata_)` | public | `string metadata_` | - | EXTRA_INFORMATION_ROLE |
+| | `setTerms(bytes32 hash, string uri)` | public | `bytes32 hash, string uri` | - | EXTRA_INFORMATION_ROLE |
+| ERC20CrossChain | | | | | |
+| | `crosschainMint(address to, uint256 value)` | public | `address to, uint256 value` | - | CROSS_CHAIN_ROLE |
+| | `crosschainBurn(address from, uint256 value)` | public | `address from, uint256 value` | - | CROSS_CHAIN_ROLE |
+| | `burnFrom(address account, uint256 value)` | public | `address account, uint256 value` | - | BURNER_FROM_ROLE |
+| | `burn(uint256 value)` | public | `uint256 value` | - | BURNER_SELF_ROLE |
+| CCIPModule | | | | | |
+| | `setCCIPAdmin(address newAdmin)` | public | `address newAdmin` | - | DEFAULT_ADMIN_ROLE |
+| **Base contract** | | | | | |
+| BaseCommon | | | | | |
+| | `burnAndMint(address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes data)` | public | `address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes data` | - | Same role requirement as `burn`and `mint`, so BURNER_ROLE and MINTER_ROLE |
+| CMTATBaseCore (only CMTAT light version) | | | | | |
+| | `burnAndMint(address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes data)` | public | `address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes data` | - | Same role requirement as `burn`and `mint`, so BURNER_ROLE and MINTER_ROLE |
+| | `forcedBurn(address account, uint256 value, bytes data)` | public | `address account, uint256 value, bytes data` | - | DEFAULT_ADMIN_ROLE |
+
+
+
+
+
+#### Schema
+
+This schema contains the different roles and their restricted functions.
+
+
+
+
+
+The OpenZepplin functions `grantRole`and `revokeRole` can be used by the admin to grant and revoke role to an address.
+
+#### Transfer adminship
+
+To transfer the adminship to a new admin, the current admin must call two functions:
+
+1) `grantRole()` by specifying the DEFAULT_ADMIN_ROLE identifier and the new admin address
+2) `renounceRole()` to revoke the DEFAULT_ADMIN_ROLE from its own account.
+
+The new admin can also revoke a role from the current/old admin by calling `revokeRole`.
+
+It is also possible to have several different admins.
+
+### Engines
+
+Engines are external smart contracts called by CMTAT modules.
+
+These engines are **optional** and their addresses can be left to zero.
+
+#### Schema
+
+Here is a schema with the different modules and the associated engines.
+
+
+
+#### RuleEngine (IERC-1404)
+
+The `RuleEngine` is an external contract used to apply transfer restrictions to the CMTAT through whitelisting, blacklisting,...
+
+This contract is defined in the module `ValidationModuleRuleEngine` with the following interface `IRuleEngine`.
+
+##### Requirement
+
+Since the version v3.2.0, the requirements to use a RuleEngine are the following:
+
+> To be used with a deployment version including the module `ValidationModuleRuleEngine`:
+>
+> The `RuleEngine` must import and implement the interface `IRuleEngine` which declares the ERC-3643 functions `transferred`(read-write) and `canTransfer`(ready-only) with several other functions related to [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg/16416) and [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643).
+>
+> To be used with a deployment version including the module `ValidationModuleERC1404`:
+>
+> The `RuleEngine` must import and implement the interface `IRuleEngineERC1404` which extends the interface `IRuleEngine`and defines functions related to [ERC-1404](https://github.com/ethereum/eips/issues/1404).
+>
+> Currently, all deployed version supporting a RuleEngine used the ERC-1404 version `ValidationModuleERC1404`
+
+The two interfaces (`IRuleEngine`and `IRuleEngineERC1404`) can be found in [IRuleEngine.sol](../contracts/interfaces/engine/IRuleEngine.sol).
+
+Warning:
+
+- The `RuleEngine` has to restrict the access of the function `transferred` to only the `CMTAT token contract`.
+- To stay flexible, the `ValidationModule` stores the RuleEngine with the the following engine: `IRuleEngine`. If you want to implement the standard ERC-1404, you have to use an engine implementing the interface `IRuleEngineERC1404`.
+
+##### How it works
+
+Before each transfer (standard transfer/mint/burn), the CMTAT calls the ERC-3643 function `transferred` which is the entrypoint for the RuleEngine.
+
+```solidity
+function transferred(address from, address to, uint256 value) external;
+```
+
+CMTAT defines the interaction with the RuleEngine inside a specific module, [ValidationModuleRuleEngine](../contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol) and [CMTATBaseRuleEngine](../contracts/modules/3_CMTATBaseRuleEngine.sol).
+
+- ValidationModuleRuleEngine
+
+
+
+- CMTATBaseRuleEngine
+
+
+
+This function `_transferred` is called before each transfer/burn/mint through the internal function `_checkTransferred` defined in [CMTAT_BASE](https://github.com/CMTA/CMTAT/blob/23a1e59f913d079d0c09d32fafbd95ab2d426093/contracts/modules/CMTAT_BASE.sol#L198).
+
+Here is a schema to show how it works:
+
+
+
+1. The token holders initiate a transfer transaction on CMTAT contract.
+2. The validation module inside the CMTAT calls the ERC-3643 function `transferred` from the RuleEngine if set with the following parameters inside: `from, to, value`.
+3. The Rule Engine performs the restriction check and revert if the transfer is not authorised.
+
+###### TransferFrom - Spender restriction
+
+The `RuleEngine`is also called with the function `transferFrom`.
+
+In this case, the `transferred`function called contains an additional `spender`argument:
+
+```solidity
+function transferred(address spender, address from, address to, uint256 value) external;
+```
+
+This allows the `RuleEngine`to also apply restriction on the spender.
+
+###### BurnFrom / CrosschainBurn - Operator restriction
+
+The same spender-aware model now applies to delegated/operator burn flows:
+
+- `burnFrom(account, value)` (allowance-based) propagates the effective operator (`_msgSender()`) to the RuleEngine hook.
+- `crosschainBurn(from, value)` also propagates the bridge operator (`_msgSender()`) for consistency with `burnFrom`.
+
+`crosschainMint(to, value)` now also propagates the bridge operator (`_msgSender()`) in the compliance path, so RuleEngine spender-aware checks can be applied consistently across delegated/cross-chain burn and mint flows.
+
+For these flows, CMTAT treats the effective operator as the `spender` parameter in RuleEngine hooks.
+
+`burnFrom` is access-controlled (`BURNER_FROM_ROLE`) and is not treated as a classic `transferFrom` path in CMTAT policy modeling. In RuleEngine hooks, both `burn` and `burnFrom` resolve to a burn-like tuple (`to == address(0)`) with operator-as-spender semantics, so the hook itself cannot intrinsically distinguish between them. To enforce `burnFrom`-specific policies, RuleEngine rules must target the operator addresses authorized to execute `burnFrom` (addresses granted `BURNER_FROM_ROLE`).
+
+##### Interface
+
+###### IRuleEngine
+
+Here the list of functions defined by the RuleEngine interface through inheritance
+
+```solidity
+// IRuleEngine
+function transferred(address spender, address from, address to, uint256 value)
+external;
+
+// IERC3643IComplianceContract
+function transferred(address from, address to, uint256 value)
+external;
+
+// IERC7551Compliance
+function canTransferFrom(address spender,address from,address to,uint256 value)
+external view returns (bool);
+
+
+// IER3643ComplianceRead
+function canTransfer(address from,address to,uint256 value)
+external view returns (bool isValid);
+
+// ERC-165
+// Should not be used to compute the IRuleEngine ERC-165 interface ID
+ function supportsInterface(bytes4 interfaceId)
+ public view override returns (bool)
+```
+
+For RuleEngine implementations, this also applies to mint/burn operator flows:
+- mint path: `from == address(0)`, `spender == operator`
+- burn path: `to == address(0)`, `spender == operator`
+
+RuleEngine policies should explicitly handle these cases when applying spender-based restrictions.
+
+If a RuleEngine restriction is intended to target only classic `transferFrom` spender scenarios, it should explicitly exclude mint/burn operator flows:
+- exclude mint path with `from != address(0)`
+- exclude burn path with `to != address(0)`
+
+The ERC-165 interface id for the `IRuleEngine` interface is `0x20c49ce7`
+
+###### IRuleEngineERC1404
+
+Here the list of functions defined by the RuleEngineERC1404 interface through the supplementary ERC-1404 inheritance `IERC1404Extend`
+
+```solidity
+// IERC-1404
+function detectTransferRestriction(address from,address to,uint256 value)
+external view returns (uint8);
+
+function messageForTransferRestriction(uint8 restrictionCode)
+external view returns (string memory);
+
+// IERC-1404Extend
+enum REJECTED_CODE_BASE {
+ TRANSFER_OK,
+ TRANSFER_REJECTED_DEACTIVATED,
+ TRANSFER_REJECTED_PAUSED,
+ TRANSFER_REJECTED_FROM_FROZEN,
+ TRANSFER_REJECTED_TO_FROZEN,
+ TRANSFER_REJECTED_SPENDER_FROZEN,
+ TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE
+}
+
+function detectTransferRestrictionFrom(address spender,address from,address to,uint256 value)
+external view returns (uint8);
+```
+
+The ERC-165 interface id for the `IERC1404Extend` interface is `0x78a8de7d`
+
+##### Interface details
+
+###### IRuleEngine
+
+`IRuleEngine` is the main interface which inherits from all other interfaces: `IERC1404Extend`, `IERC7551Compliance` and `IERC3643IComplianceContract`.
+
+```solidity
+interface IRuleEngine is IERC1404Extend, IERC7551Compliance, IERC3643IComplianceContract {
+ /**
+ * @notice
+ * Function called whenever tokens are transferred from one wallet to another
+ * @dev
+ * Must revert if the transfer is invalid
+ * Same name as ERC-3643 but with one supplementary argument `spender`
+ * This function can be used to update state variables of the RuleEngine contract
+ * This function can be called ONLY by the token contract bound to the RuleEngine
+ * @param spender spender address (sender)
+ * @param from token holder address
+ * @param to receiver address
+ * @param value value of tokens involved in the transfer
+ */
+ function transferred(address spender, address from, address to, uint256 value) external;
+}
+```
+
+###### IERC7551 & ERC-3643 Compliance
+
+A RuleEngine must implement the ERC-7551 function `canTransferFrom`& ERC-3643 compliance function `canTransfer`.
+
+```solidity
+interface IERC7551Compliance is IERC3643ComplianceRead {
+ /*
+ * @notice This function return true if the message sender is able to transfer amount tokens to to respecting all compliance.
+ * @dev Don't check the balance and the user's right (access control)
+ */
+ function canTransferFrom(
+ address spender,
+ address from,
+ address to,
+ uint256 value
+ ) external view returns (bool);
+}
+interface IERC3643ComplianceRead {
+ /**
+ * @notice Returns true if the transfer is valid, and false otherwise.
+ * @dev Don't check the balance and the user's right (access control)
+ */
+ function canTransfer(
+ address from,
+ address to,
+ uint256 value
+ ) external view returns (bool isValid);
+}
+```
+
+
+
+###### ERC-1404 & ERC1404Extend
+
+A RuleEngine must implement the `ERC1404Extend` interface which inherits from `IERC1404`
+
+- IERC1404
+
+```solidity
+interface IERC1404 {
+
+ /**
+ * @notice Returns a uint8 code to indicate if a transfer is restricted or not
+ * @dev
+ * See {ERC-1404}
+ * This function is where an issuer enforces the restriction logic of their token transfers.
+ * Some examples of this might include:
+ * - checking if the token recipient is whitelisted,
+ * - checking if a sender's tokens are frozen in a lock-up period, etc.
+ * @return uint8 restricted code, 0 means the transfer is authorized
+ *
+ */
+ function detectTransferRestriction(
+ address from,
+ address to,
+ uint256 value
+ ) external view returns (uint8);
+
+
+ /**
+ * @dev See {ERC-1404}
+ * This function is effectively an accessor for the "message",
+ * a human-readable explanation as to why a transaction is restricted.
+ *
+ */
+ function messageForTransferRestriction(
+ uint8 restrictionCode
+ ) external view returns (string memory);
+}
+```
+
+
+
+- IERC1404Extend
+
+```solidity
+/**
+* @title IERC1404 with custom related extensions
+*/
+interface IERC1404Extend is IERC1404{
+ /*
+ * @dev leave the code 6-9 free/unused for further CMTAT additions in your ruleEngine implementation
+ */
+ enum REJECTED_CODE_BASE {
+ TRANSFER_OK,
+ TRANSFER_REJECTED_PAUSED,
+ TRANSFER_REJECTED_FROM_FROZEN,
+ TRANSFER_REJECTED_TO_FROZEN,
+ TRANSFER_REJECTED_SPENDER_FROZEN,
+ TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE
+ }
+
+ /**
+ * @notice Returns a uint8 code to indicate if a transfer is restricted or not
+ * @dev
+ * See {ERC-1404}
+ * Add an additionnal argument `spender`
+ * This function is where an issuer enforces the restriction logic of their token transfers.
+ * Some examples of this might include:
+ * - checking if the token recipient is whitelisted,
+ * - checking if a sender's tokens are frozen in a lock-up period, etc.
+ * @return uint8 restricted code, 0 means the transfer is authorized
+ *
+ */
+ function detectTransferRestrictionFrom(
+ address spender,
+ address from,
+ address to,
+ uint256 value
+ ) external view returns (uint8);
+}
+```
+
+##### RuleEngine CMTA implementation
+
+CMTA provides an implementation of a [RuleEngine](https://github.com/CMTA/RuleEngine) compatible with CMTAT. This RuleEngine is also compatible with ERC-3643 tokens.
+
+In this implementation, the token holder calls the ERC-20 function `transfer` which triggers a call to the `RuleEngine` (ERC-3643 `transferred`) and the different rules associated.
+
+The different rules are not included in the RuleEngine interface and you are free to build a different RuleEngine.
+
+###### Schema
+
+
+
+###### Version
+
+Here is the list of the different versions available for each CMTAT version.
+
+| CMTAT version | RuleEngine |
+| ----------------------- | ------------------------------------------------------------ |
+| CMTAT v3.0.0 | [RuleEngine v3.0.0-rc0](https://github.com/CMTA/RuleEngine/releases/tag/v3.0.0-rc0) (unaudited) |
+| CMTAT 2.5.0 (unaudited) | RuleEngine >= [v2.0.3](https://github.com/CMTA/RuleEngine/releases/tag/v2.0.3) (unaudited) |
+| CMTAT 2.4.0 (unaudited) | RuleEngine >=v2.0.0 Last version: [v2.0.2](https://github.com/CMTA/RuleEngine/releases/tag/v2.0.2)(unaudited) |
+| CMTAT 2.3.0 | [RuleEngine v1.0.2](https://github.com/CMTA/RuleEngine/releases/tag/v1.0.2) |
+| CMTAT 2.0 (unaudited) | [RuleEngine 1.0](https://github.com/CMTA/RuleEngine/releases/tag/1.0) (unaudited) |
+| CMTAT 1.0 | No ruleEngine available |
+
+This contract acts as a controller and can call different contract rules to apply rules on each transfer.
+
+###### Rules
+
+Rules have their own dedicated repository: [github.com/CMTA/Rules](https://github.com/CMTA/Rules) and they can be used through a RuleEngine or directly with CMTAT.
+
+Here are the list of rules in development:
+
+| Rule | Type [ready-only / read-write] | Security Audit planned in the roadmap | Description |
+| ---------------------------- | ------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| RuleWhitelist | Ready-only | ☑ | This rule can be used to restrict transfers from/to only addresses inside a whitelist. |
+| RuleWhitelistWrapper | Ready-only | ☑ | This rule can be used to restrict transfers from/to only addresses inside a group of whitelist rules managed by different operators. |
+| RuleBlacklist | Ready-only | ☑ | This rule can be used to forbid transfer from/to addresses in the blacklist |
+| RuleSanctionList | Ready-only | ☑ | The purpose of this contract is to use the oracle contract from Chainalysis to forbid transfer from/to an address included in a sanctions designation (US, EU, or UN). |
+| RuleConditionalTransferLight | Ready-Write | In development | This rule requires that transfers have to be approved before being executed by the token |
+| RuleConditionalTransfer | Ready-Write | ✘ (experimental rule) | Same principle as the light version (see above) but with more options such as a time limit for approving a request as well as for carrying out the transfer |
+
+#### SnapshotEngine
+
+See also [technical/snapshot.md](./technical/snapshot.md)
+
+This Engine allows to perform snapshot on-chain.
+
+- This engine is defined in the module `SnapshotModule`.
+- CMTAT implements only one function defined in the interface [ISnapshotEngine](../contracts/interfaces/engine/ISnapshotEngine.sol)
+
+**Before** each transfer, the CMTAT calls the function `operateOnTransfer` which is the entrypoint for the SnapshotEngine.
+
+```solidity
+/*
+* @dev minimum interface to define a SnapshotEngine
+*/
+interface ISnapshotEngine {
+ /**
+ * @notice Records balance and total supply snapshots before any token transfer occurs.
+ * @dev This function should be called inside the {_update} hook so that
+ * snapshots are updated prior to any state changes from {_mint}, {_burn}, or {_transfer}.
+ * It ensures historical balances and total supply remain accurate for snapshot queries.
+ *
+ * @param from The address tokens are being transferred from (zero address if minting).
+ * @param to The address tokens are being transferred to (zero address if burning).
+ * @param balanceFrom The current balance of `from` before the transfer (used to update snapshot).
+ * @param balanceTo The current balance of `to` before the transfer (used to update snapshot).
+ * @param totalSupply The current total supply before the transfer (used to update snapshot).
+ */
+ function operateOnTransfer(address from, address to, uint256 balanceFrom, uint256 balanceTo, uint256 totalSupply) external;
+}
+```
+
+##### SnapshotEngine CMTA implementation
+
+CMTA provides an implementation of a [SnapshotEngine](https://github.com/CMTA/SnapshotEngine) compatible with CMTAT.
+
+| CMTAT | SnapshotEngine |
+| -------------------------------- | ------------------------------------------------------------ |
+| CMTAT v3.0.0 | [v0.3.0](https://github.com/CMTA/SnapshotEngine/releases/tag/v0.3.0) (unaudited) |
+| CMTAT v2.3.0 | SnapshotEngine v0.1.0 (unaudited) |
+| CMTAT v2.4.0, v2.5.0 (unaudited) | Include inside SnapshotModule (unaudited) |
+| CMTAT v2.3.0 | Include inside SnapshotModule (unaudited) |
+| CMTAT v1.0.0 | Include inside SnapshotModule, but not gas efficient (audited) |
+
+##### CMTAT Snapshot - Deployment version
+
+Instead of an external contract, it is also possible to extend CMTAT to include the logic to perform snapshots.
+
+The [SnapshotEngine](https://github.com/CMTA/SnapshotEngine) repository provides also a specific deployment version which extends CMTAT to include a part of the SnapshotEngine codebase to perform snapshot on-chain.
+
+#### DebtEngine
+
+This engine can be used to configure Debt and Credits Events information
+
+- It is defined in the `DebtEngineModule` (option module)
+- It allows to set Credit Events and Debt info through an external contract called `DebtEngine`.
+
+This module only implements two functions, available in the interface [IDebtEngine](../contracts/interfaces/engine/IDebtEngine.sol) to get information from the `DebtEngine`.
+
+```solidity
+interface IDebtEngine is ICMTATDebt, ICMTATCreditEvents {
+ // nothing more
+}
+interface ICMTATDebt {
+ /**
+ * @notice Returns debt information
+ */
+ function debt() external view returns(DebtInformation memory);
+}
+interface ICMTATCreditEvents {
+ /**
+ * @notice Returns credit events
+ */
+ function creditEvents() external view returns(CreditEvents memory);
+}
+```
+
+Using an external contract provides two advantages:
+
+- Reduces code size of CMTAT, which is near of the maximal size limit
+- Allow to manage this information for several different tokens (CMTAT or not).
+
+Here is the list of the different version available for each CMTAT version.
+
+| CMTAT version | DebtEngine |
+| ------------------------ | ------------------------------------------------------------ |
+| CMTAT v3.0.0 | Under development |
+| CMTAT v2.5.0 (unaudited) | [DebtEngine v0.2.0](https://github.com/CMTA/DebtEngine/releases/tag/v0.2.0) (unaudited) |
+
+#### DocumentEngine (IERC-1643)
+
+See also [technical/document.md](./technical/document.md)
+
+The `DocumentEngine` is an external contract to support [*ERC-1643*](https://github.com/ethereum/EIPs/issues/1643) inside CMTAT, a standard proposition to manage documents on-chain. This standard is notably used by [ERC-1400](https://github.com/ethereum/eips/issues/1411) from Polymath.
+
+This engine is defined in the module `DocumentModule`
+
+This EIP defines a document with three attributes:
+
+- A short name (represented as a `bytes32`)
+
+- A generic URI (represented as a `string`) that could point to a website or other document portal.
+- The hash of the document contents associated with it on-chain.
+
+CMTAT only implements two functions from this standard, available in the interface [IERC1643](../contracts/interfaces/tokenization/draft-IERC1643.sol) to get the documents from the DocumentEngine.
+
+```solidity
+interface IERC1643 {
+ struct Document {
+ string uri;
+ bytes32 documentHash;
+ uint256 lastModified;
+ }
+ /**
+ * @notice return a document identified by its name
+ */
+ function getDocument(bytes32 name) external view returns (Document memory document);
+ /**
+ * @notice return all documents
+ */
+ function getAllDocuments() external view returns (bytes32[] memory);
+}
+```
+
+Compatibility note:
+- ERC-1643 identifiers are `bytes32` in `IERC1643`.
+- CMTAT terms metadata `IERC1643CMTAT.DocumentInfo.name` remains a `string`.
+
+The `DocumentEngine` has to import and implement this interface. To manage the documents, the engine is completely free on how to do it.
+
+Using an external contract provides two advantages:
+
+- Reduce code size of CMTAT, which is near the maximal size limit
+- Allow documents management for several different tokens (CMTAT or not).
+
+Here is the list of the different versions available for each CMTAT version.
+
+| CMTAT version | DocumentEngine |
+| ------------------------ | ------------------------------------------------------------ |
+| CMTAT v3.0.0 | Under development |
+| CMTAT v2.5.0 (unaudited) | [DocumentEngine v0.3.0](https://github.com/CMTA/DocumentEngine/releases/tag/v0.3.0) (unaudited) |
+
+#### AuthorizationEngine (Deprecated)
+
+> Warning: this engine has been removed since CMTAT v3.0.0
+
+The `AuthorizationEngine` was an external contract to add supplementary checks on AccessControl (functions `grantRole` and `revokeRole`) from the CMTAT. Since delegating access rights to an external contract is complicated and it is better to manage access control directly in CMTAT, we removed it in version 3.0.0.
+
+There was only one prototype available: [CMTA/AuthorizationEngine](https://github.com/CMTA/AuthorizationEngine)
+
+| CMTAT version | AuthorizationEngine |
+| -------------------------------------- | -------------------------------------- |
+| CMTAT v3.0.0 | Removed |
+| CMTAT v2.4.0, 2.5.0, 2.5.1 (unaudited) | AuthorizationEngine v1.0.0 (unaudited) |
+| CMTAT 2.3.0 (audited) | Not available |
+| CMTAT 1.0 (audited) | Not available |
+
+----
+
+## Enforcement / Transfer restriction
+
+There are several ways to restrict transfers as well as burn/mint operations
+
+### Pre-Check
+
+CMTAT provides **pre-check functions** to verify if a transfer will succeed before executing it.
+These functions are useful to avoid failed transactions due to compliance rules.
+
+| Function | ERC | Purpose | Module |
+| ------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------- | -------------------- |
+| `canTransfer(from, to, value)` | [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943), [ERC-7551](https://github.com/ethereum/ERCs/blob/60a282eb3c867af2dbed8eff12e7549b548cf1bf/ERCS/erc-7551.md) | Check if a direct transfer is allowed | ValidationModuleCore |
+| `canTransferFrom(spender, from, to, value)` | [ERC-7551](https://github.com/ethereum/ERCs/blob/60a282eb3c867af2dbed8eff12e7549b548cf1bf/ERCS/erc-7551.md) | Check if a delegated transfer is allowed | ValidationModuleCore |
+| `canSend(account)` | [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) | Check if an account is allowed to send | ValidationModule |
+| `canReceive(account)` | [ERC-7943](https://eips.ethereum.org/EIPS/eip-7943) | Check if an account is allowed to receive | ValidationModule |
+
+### Enforcement Module
+
+Specific addresses can be frozen with the following ERC-3643 functions `setAddressFrozen`and `batchSetAddressFrozen`
+
+```solidity
+interface IERC3643Enforcement {
+ function isFrozen(address account) external view returns (bool);
+ function setAddressFrozen(address account, bool freeze) external;
+ function batchSetAddressFrozen(address[] calldata accounts, bool[] calldata freeze) external;
+}
+```
+
+Additionally, a `data`parameter can be also used, which will be emitted inside the smart contract
+
+```solidity
+function setAddressFrozen(address account, bool freeze, bytes calldata data)
+```
+
+Due to a limited contract size, there is no batch version with a data parameter available.
+`setAddressFrozen` and `batchSetAddressFrozen` reject `address(0)`.
+
+When an address is frozen, it is not possible to mint tokens to this address or burn its tokens. To move tokens from a frozen address, the issuer must use the function `forcedTransfer`.
+
+### ERC20EnforcementModule
+
+- A part of the balance of a specific address can be frozen with the following ERC3643 function `freezePartialTokens` and `unfreezePartialTokens`
+- Transfer/burn can be forced by the admin (ERC20EnforcementModule) with the following ERC3643 function `forcedTransfer`.
+ - In this case, if a part of the balance is frozen, the tokens are unfrozen before being burnt or transferred.
+- `freezePartialTokens` and `unfreezePartialTokens` reject `address(0)`.
+
+```solidity
+interface IERC3643ERC20Enforcement {
+ /**
+ * @notice Returns the amount of tokens that are partially frozen on a wallet
+ */
+ function getFrozenTokens(address account) external view returns (uint256);
+
+ /**
+ * @notice freezes token amount specified for given address.
+ */
+ function freezePartialTokens(address account, uint256 value) external;
+ /**
+ * @notice unfreezes token amount specified for given address
+ */
+ function unfreezePartialTokens(address account, uint256 value) external;
+ /**
+ *
+ * @notice Triggers a forced transfer.
+ */
+ function forcedTransfer(address from, address to, uint256 value) external returns (bool);
+}
+```
+
+### Pause & Deactivate contract (PauseModule)
+
+#### Pause
+
+- Standard transfers can be put in pause with the following ERC3643 function `pause`and `unpause`
+
+- From ERC-3643
+
+```solidity
+interface IERC3643Pause {
+ /**
+ * @notice Returns true if the contract is paused, and false otherwise.
+ */
+ function paused() external view returns (bool);
+ /**
+ * @notice pauses the token contract,
+ * @dev When contract is paused token holders cannot transfer tokens anymore
+ *
+ */
+ function pause() external;
+
+ /**
+ * @notice unpauses the token contract,
+ * @dev When contract is unpaused token holders can transfer tokens
+ *
+ */
+ function unpause() external;
+}
+```
+
+#### Note
+
+The pause function does not affect burn and mint operations implemented in the contracts `ERC20MintModule` and `ERC20BurnModule`.
+
+By separating burn/mint from standard transfer, the admin can re-adjust the supply while the standard transfers are paused. The alternative in this case to block mint and burn operations is to remove the MINTER and BURNER roles from the addresses concerned.
+
+On the other hand, specific function for cross-chain bridge (`5_CMTATBaseERC20CrossChain.sol`) will revert if contract is paused because they are not intended to be used by the issuer to manage the supply.
+
+#### Future possible improvement
+
+An alternative solution would be to provide an additional function `pauseAllTransfers` which would pause standard transfers, as well as all burn and mint operations.
+However, due to the architecture of current contracts, it is not possible to add this functionality without exceeding the maximum contract size on Ethereum.
+Consideration will be given to how this can be achieved in a future release.
+
+#### Deactivate contracts
+
+```solidity
+interface ICMTATDeactivate {
+ event Deactivated(address indexed account);
+ error AlreadyDeactivated();
+ /**
+ * @notice deactivate the contract
+ * Warning: the operation is irreversible, be careful
+ */
+ function deactivateContract() external;
+
+ /**
+ * @notice Returns true if the contract is deactivated, and false otherwise.
+ */
+ function deactivated() external view returns (bool) ;
+}
+```
+
+Since the version v2.3.1, a function `deactivateContract` is implemented in the PauseModule to deactivate the contract.
+
+If a contract is deactivated, it is no longer possible to perform transfer and burn/mint operations.
+
+##### Kill (previous version)
+
+CMTAT initially supported a `kill()` function relying on the SELFDESTRUCT opcode (which effectively destroyed the contract's storage and code).
+However, Ethereum's [Cancun upgrade](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md) (rolled out in Q1 of 2024) has removed support for SELFDESTRUCT (see [EIP-6780](https://eips.ethereum.org/EIPS/eip-6780)).
+
+From then on, the `kill` function no longer worked as expected, and we have replaced it by the function `deactivateContract` .
+
+##### How it works
+
+Firstly, the contract must be in `pause`state, by calling the function `pause`, otherwise the function reverts.
+If `deactivateContract()` is called again after deactivation, it reverts with `AlreadyDeactivated()`.
+
+This function sets a boolean state variable `isDeactivated` to true.
+The function `unpause `is updated to revert if the previous variable is set to true, thus the contract is in the pause state "forever".
+
+The consequences are the following:
+
+- In standalone deployment, this operation is irreversible, it is not possible to rollback.
+- In upgradeable deployment (with a proxy), it is still possible to rollback by deploying a new implementation which sets the variable `isDeactivated`to false.
+
+##### Post-deactivation privileged operations
+
+After deactivation, holder-initiated operations remain blocked by permanent pause/deactivation checks.
+The following privileged operations are intentionally post-deactivation-enabled:
+
+- `setAddressFrozen` / `batchSetAddressFrozen` (`EnforcementModule`)
+- `freezePartialTokens` / `unfreezePartialTokens` (`ERC20EnforcementModule`)
+- `forcedTransfer` and related privileged enforcement paths (`ERC20EnforcementModule` / `ERC20EnforcementERC7551Module`)
+
+### Supply management (burn & mint)
+
+ Minting and burning follow a simpler path:
+ 1. Check if contract is deactivated (permanent pause)
+ 2. Check if target address is frozen
+
+These behaviour are enforced in the different `ValidationModule`
+
+Frozen accounts can only have tokens removed via `forcedBurn()` or `forcedTransfer()` by admins.
+
+#### Summary tab
+
+This tab summarises the different behaviour of burn/mint functions if:
+
+- The target address is frozen (EnforcementModule)
+- The target address does not have enough active balance (ERC20EnforcementModule)
+- If a `ruleEngine` is configured (ValidationModuleInternal)
+- If the contract is in pause state
+- If the contract is deactivated
+
+| | burn | batchBurn | burnFrom | burnAndMint | mint | batchMint | batchTransfer | crosschain burn | Crosschain mint | forcedTransfer |
+| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Module | ERC20Burn | ERC20Burn | CMTATBaseERC20CrossChain | CMTATBaseCommon | ERC20Mint | ERC20Mint | ERC20Mint | CMTATBaseERC20CrossChain | CMTATBaseERC20CrossChain | ERC20Enforcement |
+| Module type | Core | Core | Options | Base module | Core | Core | Core | Options | Options | Extensions |
+| Allow operation on a frozen address | ✘ | ✘ | ✘ | Same as burn & mint | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ |
+| Unfreeze missing funds if active balance is not enough (`ERC20EnforcementModule`) | ✘ | ✘ | ✘ | Same as burn & mint | - | - | ✘ | ✘ | - | ✔ |
+| Call the `RuleEngine` | ✔ | ✔ | ✔ | Same as burn & mint | ✔ | ✔ | ✔ | ✔ | ✔ | ✘ |
+| Authorised if contract is in pause state | ✔ | ✔ | ✘ | Same as burn & mint | ✔ | ✔ | ✘ | ✘ | ✘ | ✔ |
+| Authorised if the contract is deactivated | ✘ | ✘ | ✘ | Same as burn & mint | ✘ | ✘ | ✘ | ✘ | ✘ | ✔ |
+
+
+
+##### Note
+
+Contrary to a `mint`operation, the function `batchTransfer` will perform the compliance check on the `from` address, which will be an address with the minter role. Another difference is the function will revert if the contract is in pause state.
+
+
+
+### Allowlist (whitelist) module
+
+With the `Allowlist` module and the associated `ValidationModuleAllowlist`, a supplementary check will be performed on the relevant address to determine if they are in the allowlist.
+
+#### Interface
+
+```solidity
+interface IAllowlistModule {
+ /* ============ Events ============ */
+ /**
+ * @notice Emitted when an address is added to or removed from the allowlist
+ */
+ event AddressAddedToAllowlist(address indexed account, bool indexed status, address indexed enforcer, bytes data);
+ /**
+ * @notice Emitted when the allowlist is enabled or disabled
+ */
+ event AllowlistEnableStatus(address indexed operator, bool status);
+ /* ============ Functions ============ */
+ /**
+ * @notice Checks if an account is allowlisted
+ */
+ function isAllowlisted(address account) external view returns (bool);
+ /**
+ * @notice Adds or removes an address from the allowlist
+ */
+ function setAddressAllowlist(address account, bool status) external;
+
+ /**
+ * @notice Adds or removes an address from the allowlist with additional data
+ */
+ function setAddressAllowlist(address account, bool status, bytes calldata data) external;
+ /**
+ * @notice Batch version of {setAddressAllowlist}
+ */
+ function batchSetAddressAllowlist(address[] calldata accounts, bool[] calldata status) external;
+ /**
+ * @notice Enables or disables the allowlist
+ */
+ function enableAllowlist(bool status) external;
+
+ /**
+ * @notice Returns whether the allowlist is currently enabled
+ */
+ function isAllowlistEnabled() external view returns (bool);
+}
+
+```
+
+#### Schema
+
+
+
+
+
+### Schema
+
+Here is a schema describing the different check performed during:
+
+- `transfer`, `transferFrom` and `batchTransfer`
+- `burn` / `mint` (supply management)
+- `burn` / `mint` for crosschain transfers
+
+
+
+### ERC-20 approve
+
+The ERC-20 `approve` function reverts when the contract is paused.
+
+This behaviour is enforced in the CMTAT base modules and applies to the standard deployment versions, including Permit, ERC-1363, ERC-7551, Debt, DebtEngine, UUPS and Allowlist.
+
+The `approve` function also validates the allowance authorization domain:
+
+- the owner (`msg.sender`) must be allowed to transact
+- the spender must be allowed to transact
+
+As a consequence:
+
+- if an address is frozen, it cannot grant or receive an ERC-20 allowance
+- in the Allowlist deployment version, if the allowlist is enabled, the owner and the spender must both be allowlisted for `approve` to succeed
+
+The `Light` deployment version follows the same pause and allowance-authorization checks for `approve`.
+
+For the Permit deployment version, the same allowance-authorization checks are also applied to `permit`, using the signed `owner` and `spender` addresses.
+
+
+
+## Functionality details
+
+### ERC-20 properties
+
+All ERC-20 properties (`name`, `symbol`and `decimals`) can be set at deployment or initialization if a proxy is used.
+
+Once the contract is deployed, the core module `ERC20BaseModule` offers two ERC-3643 functions which allow to update the name and the symbol (but not the decimals).
+
+```solidity
+interface IERC3643ERC20Base {
+ /**
+ * @notice sets the token name
+ */
+ function setName(string calldata name) external;
+ /**
+ * @notice sets the token symbol
+ */
+ function setSymbol(string calldata symbol) external;
+}
+```
+
+
+
+### MetaTx/Gasless support (ERC-2771 module)
+
+The CMTAT supports client-side gasless transactions using the standard [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771).
+
+The contract uses the OpenZeppelin contract `ERC2771ContextUpgradeable`, which allows a contract to get the original client with `_msgSender()` instead of the feepayer given by `msg.sender`.
+
+At deployment, the parameter `forwarder` inside the CMTAT contract constructor has to be set with the defined address of the forwarder.
+
+After deployment:
+
+- In standalone deployment, the forwarder is immutable and can not be changed after deployment.
+
+- In upgradeable deployment (with a proxy), it is possible to change the forwarder by deploying a new implementation. This is possible because the forwarder is stored inside the implementation contract bytecode instead of the proxy's storage.
+
+References:
+
+- [OpenZeppelin Meta Transactions](https://docs.openzeppelin.com/contracts/5.x/api/metatx)
+
+- OpenGSN has deployed several forwarders, see their [documentation](https://docs.opengsn.org/contracts/#receiving-a-relayed-call) to see some examples.
+
+### Supply management (mint/burn)
+
+#### Event
+
+Here is the list of events emitted by functions, which modify the total supply.
+
+If you want to track all operations which burn or mint tokens, you can track the ERC-20 standard Transfer event with the address zero as the origin address (from) for a mint and the same address zero as the receiver address for a burn.
+
+##### Summary tab
+
+| Name | Defined | Standard | Concerned functions |
+| ------------------------------------------------------------ | ----------------------------- | --------------------- | ------------------------------------------------------------ |
+| `Transfer(address indexed from, address indexed to, uint256 value)` | IERC20 (OpenZeppelin) | ERC-20 | All functions which impact the supply because a burn/mint is a transfer |
+| `Mint(address indexed account, uint256 value, bytes data)` | IERC7551Mint | ERC-7551 (draft) | `mint` (ERC20MintModule) |
+| `BatchMint( address indexed minter, address[] accounts, uint256[] values` | | - | `batchMint` (ERC20MintModule) |
+| `Burn(address indexed account, uint256 value, bytes data)` | IERC7551Burn | ERC-7551 (draft) | `burn` (ERC20BurnModule) |
+| `BatchBurn(address indexed burner, address[] accounts, uint256[] values)` | | - | `batchMint` (ERC20BurnModule) |
+| `BurnFrom(address indexed burner, address indexed account, address indexed spender, uint256 value)` | IBurnERC20 | - | `burnFrom(address account, uint256 value)`
`burn(uint256 value)` (ERC20CrossChain) |
+| `CrosschainMint(address indexed to, uint256 value, address indexed sender)` | IERC7551 | ERC-7802 | `crosschainMint` (ERC20CrossChain) |
+| `CrosschainBurn(address indexed from, uint256 value, address indexed sender)` | IERC7551 | ERC-7802 | `crosschainMint` (ERC20CrossChain) |
+| `ForcedTransfer(address indexed operator, address indexed from, address indexed to, uint256 value, bytes data)` | IERC7551ERC20EnforcementEvent | ERC-7551 (draft) | `forcedTransfer` (ERC20EnforcementERC7551Module) `forcedBurn` (CMTATBaseCore) |
+| `Spend(address indexed account, address indexed spender, uint256 value)` | IERC20Allowance | - | `transferFrom` (ERC20BaseModule) `transferFrom`don't change the supply `burnFrom(address account, uint256 value)` |
+
+
+
+#### Burn (ERC20BurnModule)
+
+Core modue
+
+##### ERC-3643
+
+```solidity
+interface IERC3643Burn{
+ /**
+ * @notice Burns tokens from a given address, by transferring them to address(0)
+ */
+ function burn(address account,uint256 value) external;
+ /**
+ * @notice Batch version of {burn}
+ */
+ function batchBurn(address[] calldata accounts,uint256[] calldata values) external;
+}
+```
+
+##### ERC-7551
+
+```solidity
+interface IERC7551Burn {
+ /**
+ * @notice Emitted when the specified `value` amount of tokens owned by `owner`are destroyed with the given `data`
+ */
+ event Burn(address indexed burner, address indexed account, uint256 value, bytes data);
+ /**
+ * @notice Burns tokens from a given address, by transferring them to address(0)
+ */
+ function burn(address account, uint256 amount, bytes calldata data) external;
+}
+```
+
+
+
+#### Mint (ERC20MintModule)
+
+Core module
+
+##### ERC-3643
+
+```solidity
+interface IERC3643Mint{
+ /**
+ * @notice Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0)
+ */
+ function mint(address account, uint256 value) external;
+ /**
+ * @notice batch version of {mint}
+ */
+ function batchMint( address[] calldata accounts,uint256[] calldata values) external;
+}
+```
+
+##### ERC7551
+
+```solidity
+interface IERC7551Mint {
+ /**
+ * @notice Emitted when the specified `value` amount of new tokens are created and
+ * allocated to the specified `account`.
+ */
+ event Mint(address indexed minter, address indexed account, uint256 value, bytes data);
+ /**
+ * @notice Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0)
+ */
+ function mint(address account, uint256 value, bytes calldata data) external;
+}
+```
+
+
+
+#### Cross-chain (ERC20Crosschain)
+
+This part is implemented in the option module `ERC20CrossChain`
+
+##### BurnFrom / burn
+
+```solidity
+/**
+ * @notice Standard interface for token burning operations with allowance.
+ */
+interface IBurnFromERC20 {
+ /** ============ Events ============ **/
+ /**
+ * @notice Emitted when a spender burns tokens on behalf of an account, reducing the spender's allowance.
+ */
+ event BurnFrom(address indexed burner, address indexed account, address indexed spender, uint256 value);
+
+ /** ============ Functions ============ **/
+ /**
+ * @notice Burns a specified amount of tokens from a given account, deducting from the caller's allowance.
+ */
+ function burnFrom(address account, uint256 value) external;
+
+ /**
+ * @notice Burns a specified amount of tokens from the caller's own balance.
+ * @param value The number of tokens to burn.
+ * @dev This function is restricted to authorized roles.
+ */
+ function burn(uint256 value) external;
+}
+```
+
+##### ERC-7802
+
+See the dedicated section (at the beginning of this document)
+
+##### Access control
+
+in the different `CMTATBase`modules, the function responsible to manage the access control are overridden to forbid `self burn`.
+
+It means that a token holder can not burn its own tokens.
+
+Example (ERC20CrossChainModule):
+
+```solidity
+function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{}
+```
+
+**Reason**
+
+It's deliberate that only the issuer (and not the tokenholder) can cancel a token, and that this corresponds to a legal requirement in several countries.
+
+Indeed, once issued, a security can only be cancelled by its issuer, not by its holder. Since the token serves as a vehicle for the security, the same must apply to the token itself. An investor wishing to "get rid of" a token must transfer it to the issuer, who can then cancel it when the law allows.
+
+**Alternative**
+
+You can still allow `self burn` by creating a new function or by overriding the corresponding functions.
+
+### Manage on-chain document
+
+#### Terms
+
+Tokenization terms are defined by the extension module `ExtraInformationModule `
+
+The term is made of:
+
+- A name (string)
+- An `IERC1643.Document`document, which means:
+ - A string uri (optional)
+ - The document hash (optional)
+ - The last on-chain modification date (set by the smart contract)
+
+```solidity
+interface IERC1643 {
+ struct Document {
+ string uri;
+ bytes32 documentHash;
+ uint256 lastModified;
+ }
+ // rest of the interface
+}
+interface ICMTATBase {
+ /*
+ * @dev A reference to (e.g. in the form of an Internet address) or a hash of the tokenization terms
+ */
+ struct Terms {
+ string name;
+ IERC1643.Document doc;
+ }
+ event Term(Terms newTerm);
+ /*
+ * @notice returns tokenization terms
+ */
+ function terms() external view returns (Terms memory);
+ /*
+ * @notice set tokenization terms
+ */
+ function setTerms(IERC1643CMTAT.DocumentInfo calldata terms_) external;
+}
+```
+
+#### Additional documents through ERC1643 and DocumentEngine
+
+Additional documents can be added through the `DocumentEngine`
+
+For more information, see the section dedicated to the `DocumentEngine`
+
+### Cross-chain transfers (ERC-7802, CCIP-CCT, LayerZero)
+
+See also [technical/cross-chain-bridge-integration.md](./technical/cross-chain-bridge-integration.md)
+
+#### Chainlink CCIP - CCT
+
+CMTAT implements the required function of the [Cross-Chain Token Standard](https://docs.chain.link/ccip/concepts/cross-chain-token) (CCT) which means:
+
+- CMTAT CCIP admin can enable the token in CCIP, without the need of requesting assistance to [Chainlink](https://chain.link).
+- Chainlink CCIP pool can perform the relevant mint and burn operations on CMTAT tokens.
+
+See also [docs.chain.link - Cross Chain Token (EVM)](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#overview)
+
+##### [Registration functions](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#registration-functions)
+
+CMTAT implements the following function `getCCIPAdmin()` to return the address authorized to register the token in CCIP.
+
+The alternative function proposed by CCIP, `owner`, is not implemented by CMTAT but this could be done easily. Note that `getCCIPAdmin` is the recommended function to use in the CCIP documentation.
+
+##### [Transfer functions](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#transfer-functions)
+
+Here is the list of functions required to implement CCT and be compatible with CCIP.
+
+| | | Implemented | CCIP Pool [BurnMint Requirements](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#burnmint-requirements) | CCIP Pool [Lock-Release requirements](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#lockrelease-requirements) | Pausable | CMTAT Module | Role |
+| -------------------------- | ------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ---------------------------------- | ---------------- |
+| Register CCIP token | | | | | | | |
+| | `owner()` | ✘ | - | - | | - | |
+| | `getCCIPAdmin()` | ✔ | - | - | | CCIPModule | - |
+| Burn and Mint Requirements | | | | | | | |
+| | `mint(address account, uint256 amount)` | ✔ | ✔ | ✘ | ✘ | MintModule (Core module) | MINTER_ROLE |
+| | `burn(uint256 amount)` | ✔ | ✔ | ✘ | ✘ | ERC20CrossChain | BURNER_FROM_ROLE |
+| | ERC-20 `decimals()` | ✔ | ✔ | ✔ | - | ERC20BaseModule (Core module) | |
+| | ERC-20 `balanceOf(address account)` | ✔ | ✔ | ✔ | - | OpenZeppelin inheritance | |
+| | `burnFrom(address account, uint256 amount)` | ✔ | ✔ | ✘ | ✔ | ERC20CrossChain | BURNER_FROM_ROLE |
+
+Note:
+
+- `Lock and Mint` and `Burn and Unlock` models are also compatible with CMTAT through the implementation of `Burn and Mint`requirements.
+- `Lock and Unlock`model does not need specific requirement from the token contract.
+- The admin must grant the required permissions to mint/burn to the CCIP token pool.
+- Pausing the contract through the PauseModule will not affect the mint and burn functions of the MintModule and BurnModule. The alternative solution in this case is to revoke the MINTER_ROLE and BURNER_ROLE from the relevant addresses to prevent minting and burning.
+
+##### CMTAT implementation
+
+Here is the list of implemented functions and their respective modules.
+
+```solidity
+// ERC20BaseModule
+function decimals() public view virtual override(ERC20Upgradeable) returns (uint8)
+// OpenZeppelin ERC20Upgrdeable
+function balanceOf(address account) public view virtual returns (uint256)
+// CCIPModule
+function setCCIPAdmin(address newAdmin) public virtual onlyCCIPSetAdmin
+function getCCIPAdmin() public view virtual returns (address)
+// MintModule
+function mint(address account, uint256 value) public virtual override(IERC5679Mint) onlyMinter
+// ERC20CrossChain
+function burnFrom(address account, uint256 value) public virtual override(IBurnFromERC20) onlyBurnerFrom
+function burn(uint256 value) public virtual onlyBurnerFrom
+```
+
+##### Example
+
+[CMTAT-CCIP](https://github.com/CMTA/CMTAT-CCIP) repository contains a collection of Foundry scripts designed to simplify and show deployment of a CMTAT token (v3.1.0) with CCIP contracts.
+
+It was built by [Nox Labs](https://github.com/Nox-Labs) in collaboration with CMTA and [Taurus](https://www.taurushq.com).
+
+#### Optimism superchain ERC-20 (ERC-7802)
+
+> CMTAT implements ERC-7802 in the option module `ERC20CrossChain`
+
+The [`SuperchainTokenBridge`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol) uses [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) to enable asset interoperability within the Superchain.
+
+- Asset interoperability allows tokens to move across the Superchain by burning tokens on the source chain and minting an equivalent amount on the destination chain.
+- Instead of wrapping assets, this mechanism effectively "teleports" tokens between chains in the Superchain.
+
+Reference: [docs.optimism.io/interop/superchain-erc20](https://docs.optimism.io/interop/superchain-erc20)
+
+##### Initiating message (source chain)
+
+> Example of use
+
+1. The user (or a contract) calls [`SuperchainTokenBridge.sendERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol#L52-L78).
+2. The token bridge calls the function [`CMTAT.crosschainBurn`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainERC20.sol#L37-L46) to burn those tokens on the source chain.
+3. The source token bridge calls [`SuperchainTokenBridge.relayERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol#L80-L97) on the destination token bridge. This call is relayed using [`L2ToL2CrossDomainMessenger`](https://docs.optimism.io/interop/message-passing). The call is *initiated* here, by emitting an initiating message. It will be executed later, after the destination chain receives an executing message to [`L2ToL2CrossDomainMessenger`](https://docs.optimism.io/interop/message-passing).
+
+##### Executing message (destination chain)
+
+1. The autorelayer (or the user, or any offchain entity) sends an executing message to [`L2ToL2CrossDomainMessenger`](https://docs.optimism.io/interop/message-passing) to relay the message.
+2. The destination token bridge calls [`CMTAT.crosschainMint`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainERC20.sol#L26-L35) to mint tokens for the user/contract that called `SuperchainTokenBridge.sendERC20` originally.
+
+##### Requirement
+
+- You must allow the `SuperchainTokenBridge` to call `crosschainMint` and `crosschainBurn`. No additional permission or role setup is required.
+
+- Deploy the `CMTAT` at the same address on every chain in the Superchain where you want your token to be available. If you do not deploy the contract to a specific destination chain, users will be unable to successfully move their tokens to that chain.
+
+#### LayerZero
+
+Two OFT adapters (ERC-3643/ERC-7802) working with CMTAT are available here: [CMTAT-LayerZero](https://github.com/CMTA/CMTAT-LayerZero).
+
+It was built by [Nox Labs](https://github.com/Nox-Labs) in collaboration with CMTA and [Taurus](https://www.taurushq.com).
+
+CMTAT provides two main methods to burn and mint tokens.
+
+- Standard burn/mint with the same interface as ERC-3643
+- Cross-chain burn/mint through ERC-7802
+
+To bridge tokens through LayerZero, you can use an adapter which implements one of these two methods.
+
+## Deployment model
+
+See also [technical/deployment.md](./technical/deployment.md)
+
+Contracts for deployment are available in the directory [contracts/deployment](../contracts/deployment).
+A dedicated Permit deployment version is available: `CMTATStandalonePermit` and `CMTATUpgradeablePermit`.
+
+### Summary tab
+
+| CMTAT Model | Description | Standalone/Proxy | Contract | Note |
+| -------------------- | ------------------------------------------------------------ | ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| CMTAT Standard | Deployment without proxy (immutable) | Standalone | [CMTATStandardStandalone](../contracts/deployment/CMTATStandardStandalone.sol) | Core & extension module without Debt, Allowlist, ERC-3643, UUPS and snapshot engine Include also the option module `ERC2771`, `ERC20CrossChain` support, and ERC-7551 enforcement functions (`ERC20EnforcementERC7551Module`) |
+| | Deployment with a standard proxy (Transparent or Beacon Proxy) | Upgradeable | [CMTATStandardUpgradeable](../contracts/deployment/CMTATStandardUpgradeable.sol) | - |
+| Upgradeable UUPS | Deployment with a UUPS proxy | Only upgradeable | [CMTATUpgradeableUUPS](../contracts/deployment/CMTATUpgradeableUUPS.sol) | Same as standard version, but adds UUPS proxy support and does not include the Standard-only ERC-7551 enforcement base (`CMTATBaseERC7551Enforcement`) |
+| ERC-1363 | Implements [ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) | Standalone | [CMTATStandaloneERC1363](../contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol) | Same as standard version, but adds also the support of `ERC-1363` |
+| | - | Upgradeable | [CMTATUpgradeableERC1363](../contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol) | - |
+| Permit | Adds [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) + [ERC-6357 Multicall](https://eips.ethereum.org/EIPS/eip-6357) | Standalone | [CMTATStandalonePermit](../contracts/deployment/permit/CMTATStandalonePermit.sol) | Same as standard version, but without `ERC2771` to keep bytecode lean |
+| | - | Upgradeable | [CMTATUpgradeablePermit](../contracts/deployment/permit/CMTATUpgradeablePermit.sol) | - |
+| Light | Only core modules | Standalone | [CMTATStandaloneLight](../contracts/deployment/light/CMTATStandaloneLight.sol) | The core features (i.e., minting, burning,address freeze / blacklisting, pause) without additional functions required by equities and debt instruments (e.g., document management, snapshot, partial freeze of balances). |
+| | | Upgradeable | [CMTATUpgradeableLight](../contracts/deployment/light/CMTATUpgradeableLight.sol) | - |
+| Debt | Set Debt information and Credit Events | Standalone | [CMTATStandaloneDebt](../contracts/deployment/debt/CMTATStandaloneDebt.sol) | Add the debt support. Contrary to the standard version, it does not include the module `ERC2771Module` and the support of `ERC20CrossChain` |
+| | | Upgradeable | [CMTATUpgradeableDebt](../contracts/deployment/debt/CMTATUpgradeableDebt.sol) | - |
+| DebtEngine | Set Debt information and Credit Events through an external contract `DebtEngine` | Standalone | [CMTATStandaloneDebtEngine](../contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol) | Add the debt engine support. Contrary to the standard version, it does not include the module `ERC2771Module`. Contrary to the Debt version, it includes `ERC20CrossChain` module and ERC-1404 functionality. |
+| | | Upgradeable | [CMTATUpgradeableDebtEngine](../contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol) | - |
+| Allowlist | Restrict transfer to an allowlist (whitelist) | Standalone | [CMTATStandaloneAllowlist](../contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol) | Contrary to the standard version, it does not include the `RuleEng`ERC-1404` support (ValidationModuleERC1404) & ERC20Crosschain. Includes ERC-7551 enforcement functions via `ERC20EnforcementERC7551Module`. |
+| | | Upgradeable | [CMTATUpgradeableAllowlist](../contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol) | - |
+| ERC7551 | Deployment specific for ERC-7551 | Standalone | [CMTATStandaloneERC7551](../contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol) | Add support of `ERC7551Module` |
+| | | Upgradeable | [CMTATUpgradeableERC7551](../contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol) | - |
+| Snapshot | Same as standard version, but with snapshot engine support | Standalone | [CMTATStandaloneSnapshot](../contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol) | Extends CMTATStandardStandalone with `SnapshotEngine` support via CMTATBaseERC2771Snapshot |
+| | | Upgradeable | [CMTATUpgradeableSnapshot](../contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol) | - |
+
+### Standard Standalone
+
+To deploy CMTAT without a proxy, in standalone mode, you need to use the contract version `CMTATStandardStandalone`.
+
+Here is the surya inheritance schema:
+
+
+
+### Upgradeable (with a proxy)
+
+See also [technical/upgradeable.md](./technical/upgradeable.md)
+
+The CMTAT supports deployment via a proxy contract. Furthermore, using a proxy permits to upgrade the contract, using a standard proxy upgrade pattern.
+
+- The implementation contract to use with a TransparentProxy is the `CMTATStandardUpgradeable`.
+- The implementation contract to use with a UUPSProxy is the `CMTATUpgradeableUUPS`.
+
+Please see the OpenZeppelin [upgradeable contracts documentation](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable) for more information about the proxy requirements applied to the contract.
+
+See the OpenZeppelin [Upgrades plugins](https://docs.openzeppelin.com/upgrades-plugins/1.x/) for more information about plugin upgrades in general.
+
+#### Inheritance
+
+- UUPS
+
+
+
+- Proxy standard
+
+
+
+
+
+#### Implementation details
+
+##### Storage
+
+CMTAT also implements the standard [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) to manage the storage location. See [this article](https://www.rareskills.io/post/erc-7201) by RareSkills for more information.
+
+| Modules | Variable | bytes32 Value |
+| ------------------------------ | ----------------------------------------- | ------------------------------------------------------------ |
+| **Internal** | | |
+| AllowlistModuleInternal | AllowlistModuleInternalStorageLocation | 0x53076eaf2d1e2f915f2e0487c9f92cca686c37fd47bf11f95f0da313b2809800 |
+| EnforcementModuleInternal | EnforcementModuleInternalStorageLocatio | 0x0c7bc8a17be064111d299d7669f49519cb26c58611b72d9f6ccc40a1e1184e00 |
+| ERC20EnforcementModuleInternal | ERC20EnforcementModuleStorageLocation | 0x9d8059a24cb596f1948a937c2c163cf14465c2a24abfd3cd009eec4ac4c39800 |
+| | ValidationModuleRuleEngineStorageLocation | 0x77c8cc897d160e7bf5b10921804e357da17ae27460d4a6b5d9b27ffddf159d00 |
+| **Core** | | |
+| ERC20BaseModule | ERC20BaseModuleStorageLocation | 0x9bd8d607565c0370ae5f91651ca67fd26d4438022bf72037316600e29e6a3a00 |
+| PauseModule | | 0xab1527b6135145d8da1edcbd6b7b270624e17f2b41c74a8c746ff388ad454700 |
+| **Extension** | | |
+| DocumentEngineModule | DocumentEngineModuleStorageLocation | 0xbd0905600c85d707dc53eba2e146c1c2527cd32ac3ff6b86846155151b3e2700 |
+| ExtraInformationModule | ExtraInformationModuleStorageLocation | 0xd2d5d34c4a4dea00599692d3257c0aebc5e0359176118cd2364ab9b008c2d100 |
+| SnapshotEngineModule | SnapshotEngineModuleStorageLocation | 0x1387b97dfab601d3023cb57858a6be29329babb05c85597ddbe4926c1193a900 |
+| **Options** | | |
+| CCIPModule | CCIPModuleStorageLocation | 0x364fbfd89c0eee55bbc8dd10b1a9bf3e04fba9f3ee606f4c79a82f9941ad7a00 |
+| DebtModule | DebtModuleStorageLocation | 0xf8a315cc5f2213f6481729acd86e55db7ccc930120ccf9fb78b53dcce75f7c00 |
+| ERC7551Module | ERC7551ModuleStorageLocation | 0x2727314c926b592b6f70e7d6d2e4677ebcac070f293306927f71fe77858eec00 |
+
+
+
+##### Initialize functions
+
+Inside the public initializer function to initialize your proxy, you have to call the different functions `__{ContractName}_init_unchained`.
+
+Do not forget to call the functions `init_unchained` from the parent initializer if you create your own contract from the different modules.
+
+For wrapper modules, we have removed the public function `{ContractName}_init` when they are not useful to reduce the size of the contracts.
+
+As indicated in the [OpenZeppelin documentation](https://docs.openzeppelin.com/contracts/5.x/upgradeable#multiple-inheritance):
+
+> Initializer functions are not linearized by the compiler like constructors. Because of this, each `__{ContractName}_init` function embeds the linearized calls to all parent initializers. As a consequence, calling two of these `init` functions can potentially initialize the same contract twice.
+>
+> The function `__{ContractName}_init_unchained` found in every contract is the initializer function minus the calls to parent initializers, and can be used to avoid the double initialization problem, but doing this manually is not recommended. We hope to be able to implement safety checks for this in future versions of the Upgrades Plugins.
+
+### ERC-1363
+
+[ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) is an extension interface for ERC-20 tokens that supports executing code on a recipient contract after transfers, or code on a spender contract after approvals, in a single transaction.
+
+Two dedicated versions (proxy and standalone) implementing this standard are available.
+
+More information on this standard here: [erc1363.org](https://erc1363.org), [RareSkills - ERC-1363](https://www.rareskills.io/post/erc-1363)
+
+#### Inheritance
+
+- CMTAT ERC-1363 Base
+
+
+
+
+
+
+
+
+
+- CMTAT Upgradeable ERC-1363
+
+
+
+
+
+- CMTAT Standalone ERC-1363
+
+
+
+### Light version
+
+The light version only includes core modules.
+
+It also includes a function `forceBurn`to allow the admin to burn a token from a frozen address. This function is not required for deployment versions which include the extension module `ERC20EnforcementModule` because this module contains a function `forcedTransfer`which can be used instead.
+
+If the address is not frozen, it is also possible to perform a burn-and-mint atomically through the function `burnAndMint` like the deployment standard versions
+
+- CMTAT Upgradeable Light
+
+
+
+- CMTAT Standalone Light
+
+
+
+- CMTATBaseCore
+
+
+
+### Debt version
+
+See also [technical/debt.md](./technical/debt.md)
+
+Two deployment version are available to represent Debt and Credit Events information on-chain: `Debt` and `DebtEngine`
+
+The first one `Debt` includes the `DebtModule` and allows to set these information directly in the main token contract.
+
+The second `DebtEngine` includes the `DebtEngineModule` to set these information through an external contract called by the CMTAT token contract.
+
+See also [CMTAT - Standard for the tokenization of debt instruments using distributed ledger technology](https://cmta.ch/standards/standard-for-the-tokenization-of-debt-instruments-using-distributed-ledger-technology)
+
+#### Struct
+
+The debt information are defined by the struct `ICMTATDebt` in [ICMTAT.sol](../contracts/interfaces/tokenization/ICMTAT.sol)
+
+```solidity
+interface ICMTATDebt {
+ struct DebtInformation {
+ DebtIdentifier debtIdentifier;
+ DebtInstrument debtInstrument;
+ }
+ struct DebtIdentifier {
+ string issuerName;
+ string issuerDescription;
+ string guarantor;
+ string debtHolder;
+ }
+ struct DebtInstrument {
+ // uint256
+ uint256 interestRate;
+ uint256 parValue;
+ uint256 minimumDenomination;
+ // string
+ string issuanceDate;
+ string maturityDate;
+ string couponPaymentFrequency;
+ string interestScheduleFormat;
+ string interestPaymentDate;
+ string dayCountConvention;
+ string businessDayConvention;
+ string currency;
+ // address
+ address currencyContract;
+ }
+ function debt() external view returns(DebtInformation memory);
+}
+```
+
+
+
+##### Debt Identifier
+
+Information on the issuer and other persons involved.
+
+Defined by the struct `DebtIdentifier` in [ICMTAT.sol](../contracts/interfaces/tokenization/ICMTAT.sol)
+
+| Field name | Type | Description |
+| ----------------- | ------ | ------------------------------------------------------------ |
+| issuerName | string | Issuer identifier (legal entity identifier [LEI] or, if unavailable, Swiss entity identification number [UID] or equivalent) |
+| issuerDescription | string | - |
+| guarantor | string | Guarantor identifier (legal entity identifier [LEI] or, if unavailable, Swiss entity identification number [UID] or equivalent), if applicable |
+| debtHolder | string | Debtholders representative identifier (legal entity identifier [LEI] or, if unavailable, Swiss entity identification number [UID] or equivalent), if applicable |
+
+##### Debt Instrument
+
+Information on the Instruments.
+
+Defined by the struct `DebtInstrument` in [ICMTAT.sol](../contracts/interfaces/tokenization/ICMTAT.sol)
+
+| Field name | Type | Description |
+| ---------------------- | ------- | ------------------------------------------------------------ |
+| interestRate | uint256 | - |
+| parValue | uint256 | - |
+| minimumDenomination | uint256 | - |
+| issuanceDate | string | - |
+| maturityDate | string | - |
+| couponPaymentFrequency | string | - |
+| interestScheduleFormat | string | The purpose of the interest schedule is to set, within the parameters of the smart contract, the dates on which the interest payments accrue. Format A: start date/end date/period Format B: start date/end date/day of period (e.g., quarter or year) Format C: date 1/date 2/date 3/…. |
+| interestPaymentDate | string | Interest payment date (if different from the date on which the interest payment accrues): Format A: period (indicating the period between the accrual date for the interest payment and the date on which the payment is scheduled to be made) Format B: specific date |
+| dayCountConvention | string | - |
+| businessDayConvention | string | - |
+| currency | string | - |
+| currencyContract | address | - |
+
+##### Credit Events
+
+Defined by the struct `CreditEvents`in [ICMTAT.sol](../contracts/interfaces/tokenization/ICMTAT.sol).
+
+Similar to the debt information, Credit Events can be set directly inside the smart contract (`DebtModule`) or through the external contract `DebtEngine`(`DebtEngineModule`).
+
+```solidity
+interface ICMTATCreditEvents {
+ function creditEvents() external view returns(CreditEvents memory);
+ struct CreditEvents {
+ bool flagDefault;
+ bool flagRedeemed;
+ string rating;
+ }
+}
+```
+
+
+
+| Field name | Type |
+| ------------ | ------ |
+| flagDefault | bool |
+| flagRedeemed | bool |
+| rating | string |
+
+#### Specification
+
+Here are the different fields and functions to read and store the related debt information and Credit Events.
+
+| | Module | Function | Type [Read/Write] | Internal field |
+| --------------- | -------------------------------- | ---------------------------------------- | ---------------------- | --------------- |
+| Debt Identifier | | | | |
+| | DebtModule DebtEngineModule | debt() | Read | `_debt` |
+| | DebtModule | setDebt(...) | Write | `_debt` |
+| Debt Instrument | | | | |
+| | DebtModule DebtEngineModule | debt() | Read | `_debt` |
+| | DebtModule | setDebt(...) setDebtInstrument(...) | Write | `_debt` |
+| Credit Events | DebtEngineModule | creditEvents() | Read | `_creditEvents` |
+| | DebtModule | setCreditEvents(...) | Write | `_creditEvents` |
+
+#### Schema
+
+##### Debt
+
+- CMTAT Standalone Debt
+
+
+
+- CMTAT Upgradeable Debt
+
+
+
+- CMTAT Base Debt
+
+
+
+
+
+##### DebtEngine
+
+- CMTAT Standalone DebtEngine
+
+
+
+- CMTAT Upgradeable DebtEngine
+
+
+
+- CMTAT Base DebtEngine
+
+
+
+
+
+
+
+### Permit + ERC-6357 Multicall
+
+See also [technical/permit-multicall.md](./technical/permit-multicall.md)
+
+The Permit deployment version adds support for [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) and [ERC-6357 single-contract Multicall](https://eips.ethereum.org/EIPS/eip-6357).
+
+It is available through the dedicated deployment contracts:
+
+- `CMTATStandalonePermit`
+- `CMTATUpgradeablePermit`
+
+Compared with the standard deployment version:
+
+- it supports signature-based approvals through `permit`
+- it supports batching several calls in a single transaction through `multicall`
+- it does not include `ERC2771` support, in order to keep bytecode lean
+
+The same allowance authorization checks apply to both `approve` and `permit`:
+
+- the contract must not be paused
+- the owner must be allowed to transact
+- the spender must be allowed to transact
+
+#### How to use it ?
+
+1) Select the deployment version you want: `CMTATStandalonePermit` or `CMTATUpgradeablePermit`
+2) Use `permit(owner, spender, value, deadline, v, r, s)` to create or update an allowance from an off-chain signature
+3) Use `multicall(bytes[] calldata data)` to batch several operations in a single transaction
+
+This deployment version is useful when a workflow needs gas-sponsored approvals, signature-based UX, or atomic batching of several token operations.
+
+### Allowlist
+
+The Allowlist deployment version allows to restrict transfer to token holders present inside an allowlist (whitelist) maintained inside the smart contract.
+
+For this purpose, a specific Validation controller is used called `ValidationModuleAllowlist`as well as a specific option module `AllowlistModule`.
+
+As a result, with this deployment version, it is not possible to set a `RuleEngine` and the contract does not implement the standard `ERC-1404`.
+
+More information regarding the Ethereum API available in the [Allowlist module documentation ](./modules/options/allowlist/allowlist.md)
+
+#### How to use it ?
+
+1) Select the deployment version you want: `CMTATStandaloneAllowlist` or `CMTATUpgradeableAllowlist`
+2) Once the contract is deployed, with an authorized user (default admin or an address with the `ALLOWLIST_ROLE`) enables the `allowlist`by calling the function `enableAllowlist` with true as status.
+ - Once this is done, all transfers (including `mint` and `burn`) will be rejected if the origin or target address is not in the `allowlist`
+ - For a mint operation, the contract authorized the origin address zero by default.
+ - For a burn operation, the operation will be rejected if the target account is not in the `allowlist`. In this case, the issuer must use the function `forcedTransfer`to burn the tokens.
+ - It is possible to disable the use of the allowlist by calling the same function `enableAllowlist` with false as status.
+3) Add the different addresses in the `allowlist` by calling the functions `setAddressAllowlist` and `batchSetAddressAllowlist`. It is possible to call theses functions even if the `allowlist` is not enabled.
+
+
+
+#### Inheritance
+
+- CMTAT Standalone Allowlist
+
+
+
+- CMTAT Upgradeable Allowlist
+
+
+
+- CMAT base Allowlist
+
+
+
+
+
+### Factory
+
+Factory contracts are available to deploy the CMTAT with a beacon proxy, a transparent proxy or an UUPS proxy.
+
+These contracts have now their own GitHub project: [CMTAT Factory](https://github.com/CMTA/CMTATFactory)
+
+| CMTAT version | CMTAT Factory |
+| --------------------------------- | ------------------------------------------------------------ |
+| CMTAT v3.0.0 | CMTAT Factory [v0.2.0](https://github.com/CMTA/CMTATFactory/releases/tag/v0.2.0) (unaudited) |
+| CMTAT v2.5.0 / v2.5.1 (unaudited) | Available within CMTAT see contracts/deployment (unaudited) |
+| CMTAT 2.3.0 (audited) | Not available |
+| CMTAT 1.0 (audited) | Not available |
+
+Further reading: [Taurus - Making CMTAT Tokenization More Scalable and Cost-Effective with Proxy and Factory Contracts](https://www.taurushq.com/blog/cmtat-tokenization-deployment-with-proxy-and-factory/) (version used CMTAT v2.5.1)
+
+### Deployment for other types of tokens (ERC-721, ERC-1155, ...)
+
+Deployment version using another type of token than ERC-20 (e.g ERC-721) or with a different logic (e.g [ZamaFHE - EncryptedERC20](https://www.zama.ai/post/confidential-erc-20-tokens-using-homomorphic-encryption)) can be built by using the base contract `CMTATBaseGeneric`. This base contract inherits from several non-ERC-20 modules
+
+Currently, there is no available version but a mock contract which implements ERC-721 with `CMTATBaseGeneric`is available in the mock directory: [EC721MockUpgradeable.sol](../contracts/mocks/ERC721MockUpgradeable.sol)
+
+- ERC721MockUpgradeable
+
+
+
+- CMTATBaseGeneric
+
+
+
+
+
+----
+
+## Documentation
+
+The documentation is available in the directory `doc`
+
+Here a summary of the main documents
+
+| Document | Files |
+| ----------------------------------- | ------------------------------------------------------------ |
+| Documentation of the modules API. | [modules](./modules) |
+| How to use the project + toolchains | [USAGE.md](./USAGE.md) |
+| FAQ | [FAQ.md](./general/FAQ.md) |
+| Crosschain transfers | [crosschain-bridge-support.md](./general/crosschain-bridge-support.md) |
+
+CMTA provides further documentation describing the CMTAT framework in a platform-agnostic way, and covering legal aspects, see
+
+- [CMTA Token (CMTAT)](https://cmta.ch/standards/cmta-token-cmtat)
+- [Standard for the tokenization of shares of Swiss corporations using the distributed ledger technology](https://cmta.ch/standards/standard-for-the-tokenization-of-shares-of-swiss-corporations-using-the-distributed-ledger-technology)
+- [Standard for the tokenization of debt instruments using distributed ledger technology](https://cmta.ch/standards/standard-for-the-tokenization-of-debt-instruments-using-distributed-ledger-technology)
+
+### Further reading
+
+- CMTA official publication
+ - [CMTA - A comparison of different security token standards](https://cmta.ch/news-articles/a-comparison-of-different-security-token-standards)
+
+- Solidity (EVM version)
+ - [Taurus - Security Token Standards: A Closer Look at CMTAT](https://www.taurushq.com/blog/security-token-standards-a-closer-look-at-cmtat/)
+ - [Taurus - Equity Tokenization: How to Pay Dividend On-Chain Using CMTAT](https://www.taurushq.com/blog/equity-tokenization-how-to-pay-dividend-on-chain-using-cmtat/) (CMTAT v2.4.0)
+ - [Taurus - Token Transfer Management: How to Apply Restrictions with CMTAT and ERC-1404](https://www.taurushq.com/blog/token-transfer-management-how-to-apply-restrictions-with-cmtat-and-erc-1404/) (CMTAT v2.4.0)
+ - [Taurus - Making CMTAT Tokenization More Scalable and Cost-Effective with Proxy and Factory Contracts](https://www.taurushq.com/blog/cmtat-tokenization-deployment-with-proxy-and-factory/) (CMTAT v2.5.1)
+ - [Taurus - Conditional Transfers with CMTAT & Taurus-CAPITAL: A Step-by-Step Guide](https://www.taurushq.com/blog/tokenization-conditionaltransfer-with-cmtat/) (CMTAT v2.5.0)
+
+- Aztec
+ - [Taurus - Addressing the Privacy and Compliance Challenge in Public Blockchain Token Transactions](https://www.taurushq.com/blog/enhancing-token-transaction-privacy-on-public-blockchains-while-ensuring-compliance/) (Aztec)
+ - [Taurus Deploys the First Private Stablecoin Contract](https://www.taurushq.com/blog/taurus-deploys-the-first-private-stablecoin-contract/)
+- Tezos
+ - [QuillAudits - TEZOS CMTAT](https://www.quillaudits.com/research/rwa-development/non-evm-standards/tozos-cmtat)
+
+
+
+------
+
+## Security
+
+### Vulnerability disclosure
+
+Please see [SECURITY.md](../SECURITY.md).
+
+
+### Module
+
+Access control is managed thanks to the module `AccessControlModule`.
+
+See [AccessControlModule.sol](../contracts/modules/wrapper/security/AccessControlModule.sol)
+
+### Audit
+
+CMTAT is regularly audited by globally recognised firm specialised in smart contracts security.
+
+Only the audited version should be used in production.
+
+| Version | Security Audit Firm |
+| ------------------------------------------------------------ | ---------------------------------------------- |
+| [CMTAT v3.0.0](https://github.com/CMTA/CMTAT/releases/tag/v3.0.0) | [Halborn](https://www.halborn.com) |
+| CMTAT v2.3.0 | [ABDKConsulting](https://www.abdk.consulting/) |
+| CMTAT v1.0.0 | [ABDKConsulting](https://www.abdk.consulting/) |
+
+
+
+#### Out of scope
+
+Mocks contracts in the directory [contracts/mocks](../contracts/mocks) are not audited and are not intended for use in production.
+
+They are only used for testing.
+
+#### First audit - September 2021 [ABDK]
+
+Fixed version: [1.0](https://github.com/CMTA/CMTAT/releases/tag/1.0)
+
+Fixes of security issues discovered by the initial audit were reviewed by ABDK and confirmed to be effective, as certified by the [report released](./security/audit/ABDK-CMTAT-audit-20210910/ABDK-CMTAT-audit-20210910.pdf) on September 10, 2021, covering [version c3afd7b](https://github.com/CMTA/CMTAT/tree/c3afd7b4a2ade160c9b581adb7a44896bfc7aaea) of the contracts.
+Version [1.0](https://github.com/CMTA/CMTAT/releases/tag/1.0) includes additional fixes of minor issues, compared to the version retested.
+
+A summary of all fixes and decisions taken is available in the file [CMTAT-Audit-20210910-summary.pdf](./security/audit/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.pdf)
+
+#### Second audit - March 2023 [ABDK]
+
+Fixed version: [v2.3.0](https://github.com/CMTA/CMTAT/releases/tag/v2.3.0)
+
+The second audit covered version [2.2](https://github.com/CMTA/CMTAT/releases/tag/2.2).
+
+Version v2.3.0 contains the different fixes and improvements related to this audit.
+
+The report is available in [ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf](./security/audit/ABDK_CMTA_CMTATRuleEngine_v_1_0/ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf).
+
+#### Third audit - July 2025 [Halborn]
+
+This audit has been made by [Halborn](https://www.halborn.com).
+
+Fixed version: [v3.0.0](https://github.com/CMTA/CMTAT/releases/tag/v3.0.0)
+
+The third audit covered version [v3.0.0-rc5](https://github.com/CMTA/CMTAT/tree/v3.0.0-rc5).
+
+Version v3.0.0 contains the different fixes and improvements related to this audit.
+
+The report is available in [Taurus_CMTAT_Smart_Contract_Security_Assessment_Report_Halborn.pdf](./security/audit/Halborn-CMTATv3.0.0-2025/Taurus_CMTAT_Smart_Contract_Security_Assessment_Report_Halborn.pdf).
+
+> After the 1st audit phase, we made another fix to perform compliance check with all batch functions. See [commits - 198d0194a0eef526b0a33cb625f6227da07608d4](https://github.com/CMTA/CMTAT/pull/313/commits/198d0194a0eef526b0a33cb625f6227da07608d4). This fix was also reviewed by Halborn.
+
+#### Pre-review - April 2026 [Sequent]
+
+The pre-verification report is available in [sequent-report-CMTAT.pdf](./security/pre-review/sequent-report-CMTAT.pdf).
+
+A detailed maintainer feedback is available in [SequentReport-feedback.md](./security/pre-review/SequentReport-feedback.md).
+
+### Tools
+
+> More details are available in the file [USAGE.md](./USAGE.md)
+
+#### [Aderyn](https://github.com/Cyfrin/aderyn)
+
+Here are the reports produced by [Aderyn](https://github.com/Cyfrin/aderyn):
+
+| Version | File |
+| ------- | ------------------------------------------------------------ |
+| v3.3.0 | [v3.3.0-aderyn-report.md](./security/tools/aderyn/v3.3.0-aderyn-report.md) [v3.3.0-aderyn-feedback.md](./security/tools/aderyn/v3.3.0-aderyn-feedback.md) |
+| v3.0.0 | [v3.0.0-aderyn-report.md](./security/tools/aderyn/archive/v3.0.0-aderyn-report.md) |
+
+Summary (v3.3.0):
+
+| Category | Tool Severity | Count | CMTAT Maintainer Assessment | Status |
+| ------- | ------------- | ----- | --------------------------- | ------ |
+| H-1..H-2 | High | 2 | Mixed (false positives + design choice) | Reviewed |
+| L-1..L-10 | Low | 10 | Mixed (valid, design choices, style/tooling) | Reviewed |
+
+#### [Slither](https://github.com/crytic/slither)
+
+Here are the reports produced by [Slither](https://github.com/crytic/slither):
+
+| Version | File |
+| ------- | ------------------------------------------------------------ |
+| v3.3.0 | [v3.3.0-slither-report.md](./security/tools/slither/v3.3.0-slither-report.md) [v3.3.0-slither-feedback.md](./security/tools/slither/v3.3.0-slither-feedback.md) |
+| v3.0.0 | [v3.0.0-slither-report.md](./security/tools/slither/archive/v3.0.0-slither-report.md) |
+| v2.3.0 | [v2.3.0-slither-report.md](./security/tools/slither/archive/v2.3.0-slither-report.md) |
+
+Summary (v3.3.0):
+
+| Detector | Tool Severity | Count | CMTAT Maintainer Assessment | Status |
+| ------- | ------------- | ----- | --------------------------- | ------ |
+| `uninitialized-local` | Medium | 1 | Under review (potential correctness) | Open |
+| `calls-loop` | Low | 28 | Design choice / context dependent | Accepted |
+| `assembly` | Informational | 13 | Expected pattern (ERC-7201-style slots) | Accepted |
+| `dead-code` | Informational | 2 | Cleanup candidate, no direct security impact | Open |
+| `naming-convention` | Informational | 56 | Style-only | Closed |
+| `unindexed-event-address` | Informational | 1 | Minor optimization item | Accepted |
+
+#### [Mythril](https://github.com/Consensys/mythril)
+
+Here are the reports produced by Mythril
+
+| Version | File |
+| ------- | ------------------------------------------------------------ |
+| v3.0.0 | Mythril currently generates a fatal error, impossible to run the tool |
+| v2.5.0 | [mythril-report-standalone.md](./security/tools/mythril/v2.5.0/myth_standalone_report.md) [mythril-report-proxy.md](./security/tools/mythril/v2.5.0/myth_proxy_report.md) |
+
+#### [Nethermind Audit Agent](https://auditagent.nethermind.io)
+
+Here are the reports produced by [Nethermind Audit Agent](https://auditagent.nethermind.io):
+
+| Version | File |
+| ---------- | ------------------------------------------------------------ |
+| v3.1.0 | [nethermind-audit-agent/v3.1.0](./security/tools/nethermind-audit-agent/v3.1.0) |
+| v3.0.0-rc5 | [nethermind-audit-agent/v3.0.0-rc5](./security/tools/nethermind-audit-agent/v3.0.0-rc5) |
+
+The v3.1.0 report identified **14 findings** (2 high, 2 medium, 10 low). All findings were reviewed by CMTA maintainers; 7 were assessed as invalid and 7 were acknowledged as design choices. No finding required a code fix.
+
+| N° | Title | Severity | Validity |
+|----|-------|----------|----------|
+| 1 | Partial-freeze not enforced on transfer path | High | Invalid |
+| 2 | Unprotected `initialize()` allows front-running of proxy initialization | High | Invalid |
+| 3 | Missing spender validation in transfer check function | Medium | Design choice |
+| 4 | Missing contract validation for RuleEngine address | Medium | Design choice |
+| 5 | Transfers ignore pause/deactivation in `CMTATBaseCommon` | Low | Design choice |
+| 6 | Transfers to frozen recipients possible in `CMTATBaseCommon.transfer()` | Low | Design choice |
+| 7 | Reentrancy window between unfreeze and balance update | Low | Invalid |
+| 8 | `canTransfer`/`canTransferFrom` can return `true` when transfer would revert | Low | Design choice |
+| 9 | SnapshotEngine hook bypassed in `_update` | Low | Design choice |
+| 10 | RuleEngine spender hardcoded to `address(0)` for minter-initiated transfers | Low | Invalid |
+| 11 | Forced transfers still enforced by standard validation | Low | Invalid |
+| 12 | Inconsistent deactivation handling between `canTransfer()` and `detectTransferRestriction()` | Low | Invalid |
+| 13 | `approve` not protected by pause modifier | Low | Design choice |
+| 14 | ERC2771 forwarder set via constructor in upgradeable deployments | Low | Invalid |
+
+A detailed response to each finding is available in [CMTAT_AuditAgent_Report_Comment_v3.1.0.md](./security/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.md).
+
+#### [Wake Arena](https://ackee.xyz) (Ackee Blockchain Security)
+
+Here are the reports produced by [Wake Arena](https://ackee.xyz), an automated AI vulnerability analysis tool developed by Ackee Blockchain Security:
+
+| Version | File |
+| ------------ | ------------------------------------------------------------ |
+| v3.2.0-rc2 | [Wake Arena Report - CMTA: CMTAT-v3.2.0-rc2](./security/tools/ackee-wake-arena/Wake Arena Report - CMTA_ CMTAT-v3.2.0-rc2.pdf) |
+
+> Ackee Blockchain Security, Wake Arena AI Report \| CMTA: CMTAT, February 10, 2026 12:24 UTC.
+
+The report (v3.2.0-rc2, February 10, 2026) identified **6 findings** (0 critical, 0 high, 3 medium, 2 low, 1 info):
+
+| ID | Title | Impact | Status |
+|----|-------|--------|--------|
+| M1 | Double invocation of compliance hook in `_minterTransferOverride` | Medium | Fixed |
+| M2 | Double invocation of compliance hook in `_burnOverride` | Medium | Fixed |
+| M3 | Double invocation of compliance hook in `_mintOverride` | Medium | Fixed |
+| L1 | Misleading `Spend` event emitted on `transferFrom` when allowance is infinite | Low | Acknowledged (comment added) |
+| L2 | Unmitigated ERC20 `approve` allowance change race condition | Low | Acknowledged – won't fix |
+| I1 | Documentation mismatch: `_authorizeSelfBurn` comment referenced wrong role | Info | Fixed |
+
+A detailed feedback and response to each finding is available in [CMTAT-wake-arena-feedback.md](./security/tools/ackee-wake-arena/CMTAT-wake-arena-feedback.md).
+
+#### [Sequent](https://www.sequent.inc) (Pre-verification Review)
+
+Here are the reports produced by Sequent:
+
+| Version | File |
+| ------- | ---- |
+| v3.3.0-pre | [sequent-report-CMTAT.pdf](./security/pre-review/sequent-report-CMTAT.pdf) [SequentReport-feedback.md](./security/pre-review/SequentReport-feedback.md) |
+
+### Test
+
+A code coverage is available in [index.html](./test/coverage/index.html).
+
+
+
+## Usage
+
+More details are available in the file [USAGE.md](./USAGE.md)
+
+### Use CMTAT in Your Project
+
+f you want to use CMTAT, we recommend including it as a library via a [GitHub submodule](https://www.atlassian.com/git/tutorials/git-submodule) rather than creating a fork.
+
+This approach keeps your changes separate from the upstream CMTAT codebase and makes it easier to upgrade to newer versions. Updating a submodule is generally cleaner and more straightforward than maintaining a fork.
+
+### Solidity style guideline
+
+CMTAT follows the solidity style guideline present here: [docs.soliditylang.org/en/latest/style-guide.html](https://docs.soliditylang.org/en/latest/style-guide.html)
+
+- Orders of Functions
+
+Functions are grouped according to their visibility and ordered:
+
+```
+1. constructor
+
+2. receive function (if exists)
+
+3. fallback function (if exists)
+
+4. external
+
+5. public
+
+6. internal
+
+7. private
+```
+
+Within a grouping, place the `view` and `pure` functions last
+
+- Function declaration
+
+```
+1. Visibility
+2. Mutability
+3. Virtual
+4. Override
+5. Custom modifiers
+```
+
+Inside each contract, library or interface, use the following order:
+
+```
+1. Type declarations
+2. State variables
+3. Events
+4. Errors
+5. Modifiers
+6. Functions
+```
+
+
+
+### Configuration & toolchain
+
+#### Details
+
+The project is built with [Hardhat](https://v2.hardhat.org) and uses [OpenZeppelin](https://www.openzeppelin.com/solidity-contracts)
+
+[Hardhat](https://v2.hardhat.org) is the main development toolchain for this repository and for CMTAT. [Forge (Foundry)](https://www.getfoundry.sh) is also installed and can compile contracts here, but Foundry-specific deployment scripts and Foundry-native tests are maintained in a dedicated repository: [CMTAT-Foundry](https://github.com/CMTA/CMTAT-Foundry).
+
+- hardhat.config.js
+ - Solidity [v0.8.34](https://docs.soliditylang.org/en/v0.8.34/)
+ - EVM version: Prague (Pectra upgrade)
+ - Optimizer: true, 200 runs
+
+- Package.json
+ - OpenZeppelin Contracts (Node.js module): [v5.6.1](https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v5.6.1)
+ - OpenZeppelin Contracts Upgradeable (Node.js module): [v5.6.1](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.6.1)
+
+#### Installation & Compilation
+
+- Clone the repository
+
+Clone the git repository, with the option `--recurse-submodules` to fetch the submodules:
+
+`git clone git@github.com:CMTA/CMTAT.git --recurse-submodules`
+
+- Install node modules
+
+`npm install`
+
+- Run test
+
+`npx hardhat test`
+
+### Hardhat
+
+> Since the [sunset of Truffle](https://consensys.io/blog/consensys-announces-the-sunset-of-truffle-and-ganache-and-new-hardhat) by Consensys, [Hardhat](https://v2.hardhat.org) is our main development environment.
+
+To use Hardhat, the recommended way is to use the version installed as
+part of the node modules, via the `npx` command:
+
+`npx hardhat`
+
+Alternatively, you can install Hardhat [globally](https://v2.hardhat.org/hardhat-runner/docs/getting-started):
+
+`npm install -g hardhat`
+
+### Contract size
+
+```bash
+npm run-script size
+```
+
+Measured with `solc 0.8.34`, optimizer enabled (200 runs). EVM deployed bytecode limit: **24.576 KiB**.
+
+The deployed size is identical between standalone and upgradeable for the same variant; the initcode is larger for standalone contracts since it embeds the full constructor logic rather than a proxy initializer.
+
+| Deployment version | Deployed (KiB) | Initcode standalone (KiB) | Initcode upgradeable (KiB) |
+| ------------------ | -------------- | ------------------------- | -------------------------- |
+| CMTAT Standard | 22.243 | 25.635 | 22.569 |
+| CMTAT Snapshot | 22.067 | 25.459 | 22.394 |
+| CMTAT Light | 11.298 | 13.048 | 11.507 |
+| CMTAT Allowlist | 19.879 | 23.056 | 20.205 |
+| CMTAT Debt | 23.187 | 26.301 | 23.396 |
+| CMTAT DebtEngine | 23.791 | 26.905 | 24.000 |
+| CMTAT ERC-7551 | 22.807 | 26.198 | 23.133 |
+| CMTAT ERC-1363 | 23.805 | 27.238 | 24.131 |
+| CMTAT Permit | 23.268 | 26.557 | 23.477 |
+| CMTAT UUPS | 23.544 | — | 23.896 |
+
+All variants are within the deployed bytecode limit.
+
+---
+
+## CMTAT Implementations
+
+This section provides an overview of CMTAT-related projects, both official implementations managed by CMTA and community-driven projects. Some community projects may have received feedback from CMTA.
+
+### Official / CMTA-Managed Implementations
+
+#### Solana
+
+Specifications to deploy CMTAT-compliant tokens on Solana are available in the repository [CMTAT-Solana](https://github.com/CMTA/CMTAT-Solana), developed by [Taurus](https://www.taurushq.com) as an internal CMTA project in collaboration with the Solana Foundation.
+
+#### Tezos
+
+[CMTAT FA2](https://github.com/CMTA/CMTAT-Tezos-FA2): Official version written in SmartPy, developed by [AirGap](https://airgap.it) in collaboration with CMTA.
+
+A second unofficial version is available in the community section.
+
+### Unofficial Implementations
+
+#### Aztec (Noir)
+
+A specific version is available for [Aztec](https://aztec.network/): [Aztec Private CMTAT](https://github.com/CMTA/private-CMTAT-aztec), developed by [Taurus](https://www.taurushq.com) in collaboration with CMTA.
+
+- This version is **not officially approved** by CMTA.
+- See also [Taurus - Addressing the Privacy and Compliance Challenge](https://www.taurushq.com/blog/enhancing-token-transaction-privacy-on-public-blockchains-while-ensuring-compliance/)
+
+#### Starknet (Cairo)
+
+A version for [Starknet](https://www.starknet.io/) written in Cairo is under development by [Sereel](https://www.sereel.com/) in collaboration with CMTA: [0xsereel/cairo-cmtat](https://github.com/0xsereel/cairo-cmtat)
+
+#### Tezos (Ligo)
+
+- [@ligo/cmtat](https://github.com/CMTA/CMTAT-Ligo): Unofficial version written in Ligo by Frank Hillard.
+ - See also [Tokenization of securities on Tezos by Frank Hillard](https://medium.com/@frank.hillard_62931/tokenization-of-securities-on-tezos-2e3c3e90fc5a)
+
+### Community projects
+
+- [swapnilraj - fix-engine](https://github.com/swapnilraj/CMTAT/tree/swp/fix-engine)
+
+Add FIX Asset Descriptors to CMTAT. See also [ERC-FIX](https://www.erc-fix.com/spec)
+
+- [siva-sub - cmtat-icma-tokenized-bonds](https://github.com/siva-sub/cmtat-icma-tokenized-bonds)
+
+ Integration of CMTATv3.0 framework with ICMA Bond Data Taxonomy v1.2
+
+### Guideline
+
+If you create a version for another blockchain, feel free to use this summary tab to build a correspondence table between CMTAT framework, CMTAT Solidity version and your implementation.
+
+#### CMTAT framework
+
+In the below table, the CMTAT framework required features are mapped to Solidity features.
+
+| **CMTAT framework mandatory functionalities** | **CMTAT Solidity corresponding features** |
+| --------------------------------------------- | ------------------------------------------------------------ |
+| Know total supply | ERC20 `totalSupply` |
+| Know balance | ERC20 `balanceOf` |
+| Transfer tokens | ERC20 `transfer` |
+| Create tokens (mint) | `Mint/batchMint` |
+| Cancel tokens (force burn) | `burn/batchBurn` *(Nb. we recommend to have a dedicated function to burn tokens without the token holder consent or from a frozen address*) |
+| Pause tokens | Pause (*Nb. With CMTAT Solidity it is still possible to burn and mint while transfers are paused.)* |
+| Unpause tokens | `unpause` |
+| Deactivate contract | `deactivateContract` |
+| Freeze | `setAddressFrozen` (previously `freeze`) |
+| Unfreeze | `setAddressFrozen` (previously `unfreeze`) |
+| Name attribute | ERC20 `name` attribute |
+| Ticker symbol attribute | ERC20 `symbol` attribute |
+| Token ID attribute | `tokenId` |
+| Reference to legally required documentation | `terms` (document name, hash and uri with at least the uri) |
+
+**Freeze**
+
+To be compatible with [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), the freeze functionality is implemented with only one function: `setAddressFrozen` which takes the target address and the frozen status (true/false).
+
+However, for non-EVM blockchains, it could be clearer and make more sense to separate the freeze and unfreeze (or `thaw`) functionality with two separate and distinct functions, such as:
+
+```solidity
+freeze(address targetAddress)
+unfreeze(address targetAddress)
+```
+
+#### CMTAT extended
+
+In the below table, the CMTAT framework extendedfeatures are mapped to Solidity features.
+
+| CMTAT Functionalities | **CMTAT Solidity corresponding features** | CMTAT Allowlist | CMTAT Light | CMTAT Debt | CMTAT Standard | CMTAT Snapshot |
+| ------------------------------------ | ---------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| On-chain snapshot | `snapshotModule & snapshotEngine` | ✘ | ✘ | ✔ | ✘ | ✔ |
+| Forced Transfer | `forcedTransfer` | ✔ | ✘ | ✔ | ✔ | ✔ |
+| Forced burn | `forcedBurn` | ✘ | ✔ | ✘ | ✘ | ✘ |
+| Freeze partial token | `freezePartialTokens`/ `unfreezePartialTokens` | ✔ | ✘ | ✔ | ✔ | ✔ |
+| Integrated whitelisting/allowlisting | CMTAT Allowlist | ✔ | ✘ | ✘ | ✘ | ✘ |
+| External Whitelisting/allowlisting | CMTAT with rule whitelist | ✘ | ✘ | ✔ | ✔ | ✔ |
+| RuleEngine / transfer hook | CMTAT with RuleEngine | ✘ | ✘ | ✔ | ✔ | ✔ |
+| Upgradibility | CMTAT Upgradeable version | ✔ | ✔ | ✔ | ✔ | ✔ |
+| Feepayer/gasless | CMTAT with ERC-2771 module | ✔ | ✘ | ✘ | ✔ | ✔ |
+
+**ForcedBurn/forcedTransfer:**
+
+In the standard burn function, it is not possible to burn token from a frozen wallet. CMTAT offers a dedicated function `forcedTransfer`which allows to force a transfer or a burn. If the `forcedTransfer` function is not available, the alternative is to implement only the function `forcedBurn`.
+
+This is what is done for the CMTAT light version which does not include `forcedTransfer`. You can also decide to implement both. In this case, we suggest that only `forcedBurn`can burn tokens and not `forcedTransfer`. With the CMTAT Solidity version, when `forcedTransfer` is available, we do not implement `forcedBurn` to reduce smart contract code size, but this limitation is not necessarily present with other blockchains.
+
+#### Implementation details
+
+| Functionalities | **CMTAT Solidity** | Note |
+| ---------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Mint while pause | ✔ | Dedicated crosschain mint (e.g. `crosschainMint`) cannot be performed while the contract is in the pause state. |
+| Burn while pause | ✔ | Dedicated crosschain burn (e.g.`crosschainBurn`) cannot be performed while the contract is in the pause state. |
+| Self-Burn for everyone | ✘ | Token holder can not burn their own tokens. Only authorized addresses are allowed to burn tokens. |
+| Self-Burn for authorized addresses | ✔ | |
+| Standard burn on a frozen address | ✘ | Required to use `forcedTransfer` or `forcedBurn` |
+| Burn tokens with the function `forcedTransfer` | ✔ | See note above |
+
+**Self burn**
+
+It's deliberate that only the issuer and authorized addresses (and not the tokenholder) can burn a token, and that this corresponds to a legal requirement in several countries.
+
+Indeed, once issued, a security can only be cancelled by its issuer, not by its holder. Since the token serves as a vehicle for the security, the same must apply to the token itself. An investor wishing to "get rid of" a token must transfer it to the issuer, who can then cancel it when the law allows.
+
+However, feel free to add it in your CMTAT version if this makes sense for you from a legal or business perspective.
+
+## Intellectual property
+
+The code is copyright (c) Capital Market and Technology Association, 2018-2026, and is released under [Mozilla Public License 2.0](../LICENSE.md).
diff --git a/doc/SUMMARY.md b/doc/SUMMARY.md
new file mode 100644
index 00000000..f966ff6d
--- /dev/null
+++ b/doc/SUMMARY.md
@@ -0,0 +1,65 @@
+## Deployment Variants
+
+- **Standard** (`CMTATStandardStandalone` / `CMTATStandardUpgradeable`) - Core features, no snapshot engine
+- **Snapshot** (`CMTATStandaloneSnapshot` / `CMTATUpgradeableSnapshot`) - Same as standard + SnapshotEngine support
+- **Light** - Minimal for stablecoins
+- **Allowlist** - Whitelist-based transfers (KYC)
+- **Debt** - Bond-specific fields (maturity, coupon) + SnapshotEngine support
+- **DebtEngine** - Debt with external engine + SnapshotEngine support
+- **ERC-7551** - German eWpG compliance
+- **ERC-1363** - transferAndCall support
+- **Permit** - ERC-2612 gasless approvals + ERC-6357 multicall
+- **UUPS** - Same as standard with UUPS proxy support
+
+---
+
+## Architecture Highlights
+
+1. **Modular composition** - Mix-and-match features via inheritance
+2. **Engine pattern** - External contracts for complex logic (RuleEngine, SnapshotEngine, DocumentEngine, DebtEngine)
+3. **ERC-7201 storage** - Namespaced storage for safe upgrades
+4. **Role-based access control** - Granular permissions (not single owner)
+5. **10+ standard compliance** - ERC-20, ERC-3643, ERC-7551, ERC-2771, ERC-7802, etc.
+
+---
+
+## Contract Inheritance Hierarchy
+
+```
+Level 0 (independent mixins):
+ CMTATBaseCommon - Core ERC20 + Mint + Burn + ERC20Enforcement (partial freeze) + ExtraInformation (no RBAC, no pause, no address freeze, no transfer validation)
+ CMTATBaseCore - Core modules only (light variant)
+ CMTATBaseGeneric - Non-ERC20 modules only
+ CMTATBaseSnapshot - Pure mixin: ERC20Upgradeable + SnapshotEngineModule (_update hook)
+
+Standard chain:
+ CMTATBaseCommon (0)
+ ↓
+ CMTATBaseDocument (1) - ERC-1643 document primitives
+ ↓
+ CMTATBaseAccessControl (2) - RBAC roles management
+ ↓
+ CMTATBaseRuleEngine / CMTATBaseAllowlist (3) - Transfer validation rules
+ ├── CMTATBaseDebt (4) - DebtModule + CMTATBaseSnapshot [Debt variant — terminal]
+ ↓
+ CMTATBaseERC1404 (4) - ERC-1404 compliance (restrictedTransfer)
+ ↓
+ CMTATBaseERC20CrossChain (5) - CCIP & ERC-7802 support
+ ├── CMTATBaseERC2612 (6) - ERC-2612 Permit + ERC-6357 Multicall [Permit variant]
+ ├── CMTATBaseDebtEngine (6) - + CMTATBaseSnapshot + DebtEngineModule [DebtEngine variant]
+ └── CMTATBaseERC2771 (6) - Gasless meta-transactions [Standard / UUPS]
+ ├── CMTATBaseERC2771Snapshot (7) - + CMTATBaseSnapshot [Snapshot variant]
+ └── CMTATBaseERC7551Enforcement (7) - ERC-7551 enforcement overrides
+ ├── CMTATBaseERC1363 (8) - ERC-1363 transferAndCall [ERC-1363 variant]
+ └── CMTATBaseERC7551 (8) - ERC-7551 (eWpG) [ERC-7551 variant]
+```
+
+---
+
+## Key Roles (Access Control)
+
+- `DEFAULT_ADMIN_ROLE` - Admin access (can grant/revoke roles)
+- `MINTER_ROLE` - Can mint tokens
+- `BURNER_ROLE` - Can burn tokens
+- `PAUSER_ROLE` - Can pause/unpause contract
+- `ENFORCER_ROLE` - Can freeze/unfreeze addresses
diff --git a/doc/USAGE.md b/doc/USAGE.md
index d8a7dc51..d08dd0f2 100644
--- a/doc/USAGE.md
+++ b/doc/USAGE.md
@@ -16,15 +16,15 @@ are the latest ones that we tested:
- EVM version: Prague (Pectra upgrade)
- Package.json
- - OpenZeppelin Contracts (Node.js module): [v5.5.0](https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v5.5.0)
- - OpenZeppelin Contracts Upgradeable (Node.js module): [v5.5.0](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.5.0)
+ - OpenZeppelin Contracts (Node.js module): [v5.6.1](https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v5.6.1)
+ - OpenZeppelin Contracts Upgradeable (Node.js module): [v5.6.1](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.6.1)
### Tools
- Node v24.12.0
-- npm 10.2.5
+- npm 11.11.0
- Nomiclabs - Hardhat: ^2.24.0
- **[hardhat-ethers](https://www.npmjs.com/package/@nomicfoundation/hardhat-ethers)**
- [Hardhat](https://hardhat.org/) plugin for integration with [ethers.js](https://github.com/ethers-io/ethers.js/)
@@ -35,12 +35,14 @@ are the latest ones that we tested:
#### Submodule
-Use inside Javascript tests
+Used inside JavaScript Hardhat tests (test helper imports).
-OpenZeppelin Contracts Upgradeable (submodule) [v5.2.0](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.2.0)
+OpenZeppelin Contracts Upgradeable (submodule in `lib/openzeppelin-contracts-upgradeable`) [v5.6.1](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.6.1)
Upgradeable variant of OpenZeppelin Contracts, meant for use in upgradeable contracts.
The version of the library used is available in the file [USAGE.md](./USAGE.md)
+Current explicit usage in this repository is for Hardhat test helpers (e.g. EIP-712 helpers in `test/common`).
+
Warning:
- Submodules are not automatically updated when the host repository is updated.
@@ -57,7 +59,7 @@ Clone the git repository, with the option `--recurse-submodules` to fetch the su
- Node.js version
-We recommend to install the [Node Version Manager `nvm`](https://github.com/nvm-sh/nvm) to manage multiple versions of Node.js on your machine. You can then, for example, install the version 20.5.0 of Node.js with the following command: `nvm install 20.5.0`
+We recommend to install the [Node Version Manager `nvm`](https://github.com/nvm-sh/nvm) to manage multiple versions of Node.js on your machine. You can then, for example, install the version 24.12.0 of Node.js with the following command: `nvm install 24.12.0`
The file [.nvmrc](../.nvmrc) at the root of the project set the Node.js version. `nvm use`will automatically use this version if no version is supplied on the command line.
@@ -229,7 +231,7 @@ npm run-script coverage
Slither is a Solidity static analysis framework written in Python3
```bash
-slither . --checklist --filter-paths "mocks|openzeppelin-contracts-upgradeable|openzeppelin-contracts|@openzeppelin|test" > slither-report.md
+slither . --checklist --filter-paths "mocks|lib/openzeppelin-contracts-upgradeable|openzeppelin-contracts|@openzeppelin|test" > slither-report.md
```
### [Mythril](https://github.com/Consensys/mythril)
@@ -253,13 +255,13 @@ Note: Candidate: function require(bool, string memory)
- Standalone
```bash
-myth analyze contracts/deployment/CMTATStandalone.sol --solc-json solc_setting.json > myth_standalone_report.md
+myth analyze contracts/deployment/CMTATStandardStandalone.sol --solc-json solc_setting.json > myth_standalone_report.md
```
- With proxy
```bash
-myth analyze contracts/deployment/CMTATUpgradeable.sol --solc-json solc_setting.json > myth_proxy_report.md
+myth analyze contracts/deployment/CMTATStandardUpgradeable.sol --solc-json solc_setting.json > myth_proxy_report.md
```
File path for `solc` is configured in `solc_setting.json`
diff --git a/doc/modules/base/0_CMTATBaseCore.md b/doc/modules/base/0_CMTATBaseCore.md
index bce0d5d9..5281dbec 100644
--- a/doc/modules/base/0_CMTATBaseCore.md
+++ b/doc/modules/base/0_CMTATBaseCore.md
@@ -4,6 +4,23 @@ This document defines the CMTAT Base Core Module for the CMTA Token specificatio
[TOC]
+## Hierarchy Context
+
+`CMTATBaseCore` sits at **level 0** in the CMTAT inheritance hierarchy. It is the self-contained base used exclusively by the **Light** deployment variants (`CMTATStandaloneLight`, `CMTATUpgradeableLight`).
+
+Unlike `CMTATBaseCommon` (also level 0), `CMTATBaseCore` bundles access control, pause, full validation (`ValidationModule`, `ValidationModuleAllowance`), and enforcement into a single compact base:
+
+| Feature | `CMTATBaseCore` | `CMTATBaseCommon` |
+|---|---|---|
+| ERC-20 (mint, burn, base) | ✓ | ✓ |
+| `AccessControlModule` (RBAC, concrete `_authorize*` overrides) | ✓ | — |
+| `PauseModule` + `EnforcementModule` + `ValidationModule` | ✓ | — |
+| `ValidationModuleAllowance` (approve/permit checks) | ✓ | — |
+| `ERC20EnforcementModule` (partial freeze, forced transfer) | — | ✓ |
+| `ExtraInformationModule` | — | ✓ |
+
+`CMTATBaseCommon` is intended to be composed further up the hierarchy (through `CMTATBaseAccessControl` at level 2), where RBAC, enforcement, and extension modules are layered on separately. `CMTATBaseCore` collapses that into one level for the Light case, where only core operations (mint, burn, pause, freeze, `forcedBurn`) are needed.
+
## Schema

@@ -48,13 +65,14 @@ Only authorized users (*DEFAULT_ADMIN_ROLE*) are allowed to call this function.
##### Events
-###### `Enforcement (address,address, uint256, bytes)`
+###### `ForcedTransfer (address,address,address,uint256,bytes)`
```solidity
-event Enforcement (address indexed enforcer, address indexed account, uint256 amount, bytes data);
+event ForcedTransfer(address indexed operator, address indexed from, address indexed to, uint256 value, bytes data);
```
-Emitted when the specified `value` amount of tokens owned by `owner`are destroyed with the given `data`
+Emitted when the specified `value` amount of tokens are force-moved by `operator`.
+In `forcedBurn`, this is emitted with `to = address(0)` to represent a forced burn with `data`.
diff --git a/doc/modules/base/surya_report/surya_report_0_CMTATBaseCommon.sol.md b/doc/modules/base/surya_report/surya_report_0_CMTATBaseCommon.sol.md
index a1b0f5f0..9e890052 100644
--- a/doc/modules/base/surya_report/surya_report_0_CMTATBaseCommon.sol.md
+++ b/doc/modules/base/surya_report/surya_report_0_CMTATBaseCommon.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/0_CMTATBaseCommon.sol | 07c0f430a12b113d1a6ead1e9a4918e10a105662 |
+| ./modules/0_CMTATBaseCommon.sol | ef3159d406b8c61dbc2520fb37c0c29c5827d2bc |
### Contracts Description Table
@@ -15,28 +15,17 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseCommon** | Implementation | VersionModule, ERC20MintModule, ERC20BurnModule, ERC20BaseModule, SnapshotEngineModule, ERC20EnforcementModule, DocumentEngineModule, ExtraInformationModule, AccessControlModule, IBurnMintERC20, IERC5679 |||
-| └ | __CMTAT_commonModules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
+| **CMTATBaseCommon** | Implementation | VersionModule, ERC20MintModule, ERC20BurnModule, ERC20BaseModule, ERC20EnforcementModule, ExtraInformationModule, IBurnMintERC20, IERC5679 |||
| └ | decimals | Public ❗️ | |NO❗️ |
| └ | name | Public ❗️ | |NO❗️ |
| └ | symbol | Public ❗️ | |NO❗️ |
-| └ | supportsInterface | Public ❗️ | |NO❗️ |
| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
| └ | burnAndMint | Public ❗️ | 🛑 |NO❗️ |
| └ | _checkTransferred | Internal 🔒 | 🛑 | |
-| └ | _update | Internal 🔒 | 🛑 | |
| └ | _mintOverride | Internal 🔒 | 🛑 | |
| └ | _burnOverride | Internal 🔒 | 🛑 | |
| └ | _minterTransferOverride | Internal 🔒 | 🛑 | |
-| └ | _authorizeERC20AttributeManagement | Internal 🔒 | 🛑 | onlyRole |
-| └ | _authorizeMint | Internal 🔒 | 🛑 | onlyRole |
-| └ | _authorizeBurn | Internal 🔒 | 🛑 | onlyRole |
-| └ | _authorizeDocumentManagement | Internal 🔒 | 🛑 | onlyRole |
-| └ | _authorizeExtraInfoManagement | Internal 🔒 | 🛑 | onlyRole |
-| └ | _authorizeERC20Enforcer | Internal 🔒 | 🛑 | onlyRole |
-| └ | _authorizeForcedTransfer | Internal 🔒 | 🛑 | onlyRole |
-| └ | _authorizeSnapshots | Internal 🔒 | 🛑 | onlyRole |
### Legend
diff --git a/doc/modules/base/surya_report/surya_report_0_CMTATBaseCore.sol.md b/doc/modules/base/surya_report/surya_report_0_CMTATBaseCore.sol.md
index 41642b66..d85109f6 100644
--- a/doc/modules/base/surya_report/surya_report_0_CMTATBaseCore.sol.md
+++ b/doc/modules/base/surya_report/surya_report_0_CMTATBaseCore.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/0_CMTATBaseCore.sol | 8a4a5979a8c928967f5316539ff24ff15b509a4b |
+| ./modules/0_CMTATBaseCore.sol | 6e879243185b8c9f76fcedb367b2aee8b27ba60e |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseCore** | Implementation | Initializable, ContextUpgradeable, VersionModule, ERC20MintModule, ERC20BurnModule, ValidationModuleCore, ERC20BaseModule, AccessControlModule, IForcedBurnERC20, IBurnMintERC20, IERC7551ERC20EnforcementEvent, IERC5679 |||
+| **CMTATBaseCore** | Implementation | Initializable, ContextUpgradeable, VersionModule, ERC20MintModule, ERC20BurnModule, ValidationModuleAllowance, ERC20BaseModule, AccessControlModule, IForcedBurnERC20, IBurnMintERC20, IERC7551ERC20EnforcementEvent, IERC5679, IERC7943FungibleTransferError |||
| └ | initialize | Public ❗️ | 🛑 | initializer |
| └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
@@ -25,6 +25,7 @@
| └ | symbol | Public ❗️ | |NO❗️ |
| └ | supportsInterface | Public ❗️ | |NO❗️ |
| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
| └ | burnAndMint | Public ❗️ | 🛑 |NO❗️ |
| └ | forcedBurn | Public ❗️ | 🛑 | onlyERC20ForcedBurnManager |
diff --git a/doc/modules/base/surya_report/surya_report_0_CMTATBaseGeneric.sol.md b/doc/modules/base/surya_report/surya_report_0_CMTATBaseGeneric.sol.md
index 628be5f1..2484b42a 100644
--- a/doc/modules/base/surya_report/surya_report_0_CMTATBaseGeneric.sol.md
+++ b/doc/modules/base/surya_report/surya_report_0_CMTATBaseGeneric.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/0_CMTATBaseGeneric.sol | e6a7560e642a8d9cf0793b42515b73b9b767f5f5 |
+| ./modules/0_CMTATBaseGeneric.sol | 2db1ecb2c69ee4f60e17917ff565907e44da1daf |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseGeneric** | Implementation | Initializable, ContextUpgradeable, ValidationModule, VersionModule, DocumentEngineModule, ExtraInformationModule, AccessControlModule |||
+| **CMTATBaseGeneric** | Implementation | Initializable, ContextUpgradeable, ValidationModule, VersionModule, DocumentERC1643Module, ExtraInformationModule, AccessControlModule |||
| └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
diff --git a/doc/schema/surya_report/surya_report_3_CMTATBaseDebt.sol.md b/doc/modules/base/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md
similarity index 72%
rename from doc/schema/surya_report/surya_report_3_CMTATBaseDebt.sol.md
rename to doc/modules/base/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md
index ac2b89ac..0819ad75 100644
--- a/doc/schema/surya_report/surya_report_3_CMTATBaseDebt.sol.md
+++ b/doc/modules/base/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/3_CMTATBaseDebt.sol | 45147c1d823ef33047846c34f109dcbbd12849d6 |
+| ./modules/0_CMTATBaseSnapshot.sol | a6d54586c8a7ed63bffceed0c7bd1abe35b5e5cd |
### Contracts Description Table
@@ -15,8 +15,8 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseDebt** | Implementation | CMTATBaseRuleEngine, DebtModule |||
-| └ | _authorizeDebtManagement | Internal 🔒 | 🛑 | onlyRole |
+| **CMTATBaseSnapshot** | Implementation | ERC20Upgradeable, SnapshotEngineModule |||
+| └ | _update | Internal 🔒 | 🛑 | |
### Legend
diff --git a/doc/modules/base/surya_report/surya_report_1_CMTATBaseDocument.sol.md b/doc/modules/base/surya_report/surya_report_1_CMTATBaseDocument.sol.md
new file mode 100644
index 00000000..d85f71c1
--- /dev/null
+++ b/doc/modules/base/surya_report/surya_report_1_CMTATBaseDocument.sol.md
@@ -0,0 +1,26 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/1_CMTATBaseDocument.sol | 6d9a534014f54d5736d99d1dc3f7e6d4ba7cb93d |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseDocument** | Implementation | DocumentERC1643Module |||
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_1_CMTATBaseAccessControl.sol.md b/doc/modules/base/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md
similarity index 88%
rename from doc/schema/surya_report/surya_report_1_CMTATBaseAccessControl.sol.md
rename to doc/modules/base/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md
index 8f7c8b57..6e38fe59 100644
--- a/doc/schema/surya_report/surya_report_1_CMTATBaseAccessControl.sol.md
+++ b/doc/modules/base/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/1_CMTATBaseAccessControl.sol | 4d3786f9e7a74fae5e3f5d5d8c24e1769e92b7fc |
+| ./modules/2_CMTATBaseAccessControl.sol | cf934aa8b26c9bdc2aeb336391b3c4098da70c18 |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseAccessControl** | Implementation | AccessControlModule, CMTATBaseCommon |||
+| **CMTATBaseAccessControl** | Implementation | AccessControlModule, CMTATBaseCommon, CMTATBaseDocument |||
| └ | __CMTAT_commonModules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | supportsInterface | Public ❗️ | |NO❗️ |
| └ | _authorizeERC20AttributeManagement | Internal 🔒 | 🛑 | onlyRole |
@@ -25,7 +25,6 @@
| └ | _authorizeExtraInfoManagement | Internal 🔒 | 🛑 | onlyRole |
| └ | _authorizeERC20Enforcer | Internal 🔒 | 🛑 | onlyRole |
| └ | _authorizeForcedTransfer | Internal 🔒 | 🛑 | onlyRole |
-| └ | _authorizeSnapshots | Internal 🔒 | 🛑 | onlyRole |
### Legend
diff --git a/doc/schema/surya_report/surya_report_2_CMTATBaseAllowlist.sol.md b/doc/modules/base/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md
similarity index 68%
rename from doc/schema/surya_report/surya_report_2_CMTATBaseAllowlist.sol.md
rename to doc/modules/base/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md
index 5e5c0622..93574cec 100644
--- a/doc/schema/surya_report/surya_report_2_CMTATBaseAllowlist.sol.md
+++ b/doc/modules/base/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/2_CMTATBaseAllowlist.sol | d2f26a3723557900754a1d49f3bc32e6de5d6b8a |
+| ./modules/3_CMTATBaseAllowlist.sol | 517b746b223a533ad42e9dad2a49520c1fd14d1f |
### Contracts Description Table
@@ -15,24 +15,34 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseAllowlist** | Implementation | Initializable, ContextUpgradeable, CMTATBaseAccessControl, ValidationModuleAllowlist, ValidationModuleCore, ERC2771Module, IERC7943FungibleTransferError |||
+| **CMTATBaseAllowlist** | Implementation | Initializable, ContextUpgradeable, CMTATBaseAccessControl, ValidationModuleAllowlist, ValidationModuleAllowance, ERC2771Module, ERC20EnforcementERC7551Module, IERC7943FungibleTransferError |||
| └ | initialize | Public ❗️ | 🛑 | initializer |
| └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | approve | Public ❗️ | 🛑 | whenNotPaused |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
| └ | canTransfer | Public ❗️ | |NO❗️ |
| └ | canTransferFrom | Public ❗️ | |NO❗️ |
| └ | _authorizePause | Internal 🔒 | 🛑 | onlyRole |
| └ | _authorizeDeactivate | Internal 🔒 | 🛑 | onlyRole |
| └ | _authorizeFreeze | Internal 🔒 | 🛑 | onlyRole |
| └ | _authorizeAllowlistManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeERC20Enforcer | Internal 🔒 | 🛑 | |
+| └ | _authorizeForcedTransfer | Internal 🔒 | 🛑 | |
| └ | _canMintBurnByModule | Internal 🔒 | | |
-| └ | _canMintBurnByModuleAndRevert | Internal 🔒 | | |
-| └ | _canTransact | Internal 🔒 | | |
+| └ | _canMintByModuleAndRevert | Internal 🔒 | | |
+| └ | _canBurnByModuleAndRevert | Internal 🔒 | | |
+| └ | _canSend | Internal 🔒 | | |
+| └ | _canReceive | Internal 🔒 | | |
| └ | _canTransferStandardByModule | Internal 🔒 | | |
| └ | _canTransferStandardByModuleAndRevert | Internal 🔒 | | |
| └ | _checkTransferred | Internal 🔒 | 🛑 | |
+| └ | getFrozenTokens | Public ❗️ | |NO❗️ |
| └ | _msgSender | Internal 🔒 | | |
| └ | _contextSuffixLength | Internal 🔒 | | |
| └ | _msgData | Internal 🔒 | | |
diff --git a/doc/schema/surya_report/surya_report_2_CMTATBaseRuleEngine.sol.md b/doc/modules/base/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md
similarity index 95%
rename from doc/schema/surya_report/surya_report_2_CMTATBaseRuleEngine.sol.md
rename to doc/modules/base/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md
index 945d9033..bc23215b 100644
--- a/doc/schema/surya_report/surya_report_2_CMTATBaseRuleEngine.sol.md
+++ b/doc/modules/base/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/2_CMTATBaseRuleEngine.sol | 9f24fd10583b2933a154bd6ad685fff24bd2570c |
+| ./modules/3_CMTATBaseRuleEngine.sol | b9bc5276aceceae7c6224027123f31f4ed47c61b |
### Contracts Description Table
diff --git a/doc/modules/base/surya_report/surya_report_4_CMTATBaseDebt.sol.md b/doc/modules/base/surya_report/surya_report_4_CMTATBaseDebt.sol.md
new file mode 100644
index 00000000..8f161dd7
--- /dev/null
+++ b/doc/modules/base/surya_report/surya_report_4_CMTATBaseDebt.sol.md
@@ -0,0 +1,35 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/4_CMTATBaseDebt.sol | 593ad8bf57d7bbd52a5ee426a3e0f11d2e2d49c6 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseDebt** | Implementation | CMTATBaseRuleEngine, DebtModule, CMTATBaseSnapshot |||
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+| └ | _update | Internal 🔒 | 🛑 | |
+| └ | _authorizeDebtManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeSnapshots | Internal 🔒 | 🛑 | onlyRole |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/modules/base/surya_report/surya_report_2_CMTATBaseERC1404.sol.md b/doc/modules/base/surya_report/surya_report_4_CMTATBaseERC1404.sol.md
similarity index 92%
rename from doc/modules/base/surya_report/surya_report_2_CMTATBaseERC1404.sol.md
rename to doc/modules/base/surya_report/surya_report_4_CMTATBaseERC1404.sol.md
index a84c376c..109c43e4 100644
--- a/doc/modules/base/surya_report/surya_report_2_CMTATBaseERC1404.sol.md
+++ b/doc/modules/base/surya_report/surya_report_4_CMTATBaseERC1404.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/2_CMTATBaseERC1404.sol | 8769828373a6eb13fa46ead7e2ff0e5978ad2d85 |
+| ./modules/4_CMTATBaseERC1404.sol | 2f40fd05006c12aae809d94f8db9f500fc0d6eba |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_4_CMTATBaseERC20CrossChain.sol.md b/doc/modules/base/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md
similarity index 91%
rename from doc/schema/surya_report/surya_report_4_CMTATBaseERC20CrossChain.sol.md
rename to doc/modules/base/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md
index de089895..989d2adc 100644
--- a/doc/schema/surya_report/surya_report_4_CMTATBaseERC20CrossChain.sol.md
+++ b/doc/modules/base/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/4_CMTATBaseERC20CrossChain.sol | 2eeb3b1423304a8a6117d1ed6386ba562b43315c |
+| ./modules/5_CMTATBaseERC20CrossChain.sol | 5900451fe62bc9ac7ae8d5ba8b03c8851206fb60 |
### Contracts Description Table
@@ -30,7 +30,6 @@
| └ | _checkTokenBridge | Internal 🔒 | 🛑 | whenNotPaused |
| └ | _authorizeBurnFrom | Internal 🔒 | 🛑 | onlyRole whenNotPaused |
| └ | _authorizeSelfBurn | Internal 🔒 | 🛑 | onlyRole whenNotPaused |
-| └ | _update | Internal 🔒 | 🛑 | |
### Legend
diff --git a/doc/modules/base/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md b/doc/modules/base/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md
new file mode 100644
index 00000000..0ad6c074
--- /dev/null
+++ b/doc/modules/base/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md
@@ -0,0 +1,35 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/6_CMTATBaseDebtEngine.sol | bfeb152012d9b39da44296cc36fa90eb0f2b8035 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseDebtEngine** | Implementation | DebtEngineModule, CMTATBaseERC20CrossChain, CMTATBaseSnapshot |||
+| └ | _update | Internal 🔒 | 🛑 | |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+| └ | _authorizeDebtEngineManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeSnapshots | Internal 🔒 | 🛑 | onlyRole |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2612.sol.md b/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2612.sol.md
new file mode 100644
index 00000000..80d81a3c
--- /dev/null
+++ b/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2612.sol.md
@@ -0,0 +1,34 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/6_CMTATBaseERC2612.sol | 45670849fccf2fa62ef778ee4800b8a0ff0040d9 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseERC2612** | Implementation | CMTATBaseERC20CrossChain, ERC20PermitUpgradeable, MulticallUpgradeable |||
+| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
+| └ | permit | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_5_CMTATBaseERC2771.sol.md b/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2771.sol.md
similarity index 91%
rename from doc/schema/surya_report/surya_report_5_CMTATBaseERC2771.sol.md
rename to doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2771.sol.md
index 2c3bba37..a0e88367 100644
--- a/doc/schema/surya_report/surya_report_5_CMTATBaseERC2771.sol.md
+++ b/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2771.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/5_CMTATBaseERC2771.sol | 1bfc46328036cec1ea2cb5d9f64fac48c0ba86b9 |
+| ./modules/6_CMTATBaseERC2771.sol | f10975c79346dd77a446db967bf938e9de46af36 |
### Contracts Description Table
diff --git a/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md b/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md
new file mode 100644
index 00000000..b0b2ff7d
--- /dev/null
+++ b/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md
@@ -0,0 +1,37 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/7_CMTATBaseERC2771Snapshot.sol | 73abac918adab1aa31671e98a0cecb7e6435cd73 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseERC2771Snapshot** | Implementation | CMTATBaseERC2771, CMTATBaseSnapshot |||
+| └ | _update | Internal 🔒 | 🛑 | |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+| └ | _msgSender | Internal 🔒 | | |
+| └ | _msgData | Internal 🔒 | | |
+| └ | _contextSuffixLength | Internal 🔒 | | |
+| └ | _authorizeSnapshots | Internal 🔒 | 🛑 | onlyRole |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md b/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md
new file mode 100644
index 00000000..cebd5a77
--- /dev/null
+++ b/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md
@@ -0,0 +1,38 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/7_CMTATBaseERC7551Enforcement.sol | 56d471f72113e2f281ea95c65ff066fd8bd44f7c |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseERC7551Enforcement** | Implementation | CMTATBaseERC2771, ERC20EnforcementERC7551Module |||
+| └ | _authorizeERC20Enforcer | Internal 🔒 | 🛑 | |
+| └ | _authorizeForcedTransfer | Internal 🔒 | 🛑 | |
+| └ | _msgSender | Internal 🔒 | | |
+| └ | _msgData | Internal 🔒 | | |
+| └ | _contextSuffixLength | Internal 🔒 | | |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | getFrozenTokens | Public ❗️ | |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_6_CMTATBaseERC1363.sol.md b/doc/modules/base/surya_report/surya_report_8_CMTATBaseERC1363.sol.md
similarity index 89%
rename from doc/schema/surya_report/surya_report_6_CMTATBaseERC1363.sol.md
rename to doc/modules/base/surya_report/surya_report_8_CMTATBaseERC1363.sol.md
index 22a56a86..c291424e 100644
--- a/doc/schema/surya_report/surya_report_6_CMTATBaseERC1363.sol.md
+++ b/doc/modules/base/surya_report/surya_report_8_CMTATBaseERC1363.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/6_CMTATBaseERC1363.sol | e5e88fe2769f84d8e6b47136f1efd8bf57de003b |
+| ./modules/8_CMTATBaseERC1363.sol | 55f464bf7e8bc8fb2ed679b564f13727f61bbf96 |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseERC1363** | Implementation | ERC1363Upgradeable, CMTATBaseERC2771 |||
+| **CMTATBaseERC1363** | Implementation | ERC1363Upgradeable, CMTATBaseERC7551Enforcement |||
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | approve | Public ❗️ | 🛑 |NO❗️ |
| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
@@ -24,7 +24,6 @@
| └ | decimals | Public ❗️ | |NO❗️ |
| └ | name | Public ❗️ | |NO❗️ |
| └ | symbol | Public ❗️ | |NO❗️ |
-| └ | _update | Internal 🔒 | 🛑 | |
| └ | _msgSender | Internal 🔒 | | |
| └ | _contextSuffixLength | Internal 🔒 | | |
| └ | _msgData | Internal 🔒 | | |
diff --git a/doc/modules/base/surya_report/surya_report_5_CMTATBaseERC7551.sol.md b/doc/modules/base/surya_report/surya_report_8_CMTATBaseERC7551.sol.md
similarity index 79%
rename from doc/modules/base/surya_report/surya_report_5_CMTATBaseERC7551.sol.md
rename to doc/modules/base/surya_report/surya_report_8_CMTATBaseERC7551.sol.md
index a9622910..83be16aa 100644
--- a/doc/modules/base/surya_report/surya_report_5_CMTATBaseERC7551.sol.md
+++ b/doc/modules/base/surya_report/surya_report_8_CMTATBaseERC7551.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/5_CMTATBaseERC7551.sol | 6fb7d71399fbf4f0135697c09f928ee646074e05 |
+| ./modules/8_CMTATBaseERC7551.sol | ea759e98774152ca4f29fcd2b45e77f401fc6103 |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseERC7551** | Implementation | CMTATBaseERC2771, ERC7551Module |||
+| **CMTATBaseERC7551** | Implementation | CMTATBaseERC7551Enforcement, ERC7551Module |||
| └ | _authorizeExtraInfoManagement | Internal 🔒 | 🛑 | |
diff --git a/doc/modules/controllers/validation.md b/doc/modules/controllers/validation.md
index 3ace40b6..a570f7b9 100644
--- a/doc/modules/controllers/validation.md
+++ b/doc/modules/controllers/validation.md
@@ -22,10 +22,105 @@ This document defines the Validation Module for the CMTA Token specification. Th
+## Architecture
+
+`ValidationModule` is the base transfer-check coordinator. It is extended by:
+
+- `ValidationModuleCore` — adds `canTransfer` and `canTransferFrom` (used by all standard deployment variants)
+- `ValidationModuleRuleEngine` — chains an external `RuleEngine` into the transfer path
+- `ValidationModuleAllowlist` — overrides `_canSend` / `_canReceive` with allowlist membership checks (used by the Allowlist deployment variant)
+- `ValidationModuleAllowance` — enforces pause and freeze checks on `approve` / `permit` (used by the Permit deployment variant)
+
+## Check Composition
+
+A transfer is permitted only when all of the following pass:
+
+1. **Not paused** — `PauseModule.paused()` must be false (standard transfers) or not deactivated (mint/burn).
+2. **Not frozen** — `spender`, `from`, and `to` must each pass `EnforcementModule.isFrozen`.
+3. **Not RuleEngine-blocked** — if a `RuleEngine` is set, `operateOnTransfer` must return a passing code.
+4. **Allowlist (Allowlist variant only)** — if allowlist is enabled, `from`, `to`, and `spender` must each be allowlisted.
+
+Mint and burn paths skip the spender freeze check and instead check whether the recipient (`mint`) or source (`burn`) address is frozen and whether the contract is deactivated.
+
## API for Ethereum
-> This section describes the Ethereum API of the Validation Module.
+### `ValidationModule`
+
+#### `canSend(address) → bool`
+
+```solidity
+function canSend(address account) public view virtual returns (bool allowed)
+```
+
+Returns `true` if `account` is currently permitted to send tokens (i.e., act as a sender, spender, or burn source). Base implementation returns `!isFrozen(account)`. Overridden by `ValidationModuleAllowlist` to also require allowlist membership when the allowlist is enabled.
+
+Implements `IERC7943FungibleSendReceiveCheck`.
+
+| Parameter | Type | Description |
+|-----------|---------|------------------------|
+| `account` | address | Address to check. |
+
+---
+
+#### `canReceive(address) → bool`
+
+```solidity
+function canReceive(address account) public view virtual returns (bool allowed)
+```
+
+Returns `true` if `account` is currently permitted to receive tokens (i.e., act as a recipient or mint target). Base implementation returns `!isFrozen(account)`. Overridden by `ValidationModuleAllowlist` to also require allowlist membership when the allowlist is enabled.
+
+Implements `IERC7943FungibleSendReceiveCheck`.
+
+| Parameter | Type | Description |
+|-----------|---------|------------------------|
+| `account` | address | Address to check. |
+
+---
+
+### `ValidationModuleCore`
+
+#### `canTransfer(address, address, uint256) → bool`
+
+```solidity
+function canTransfer(address from, address to, uint256 value) public view virtual returns (bool)
+```
+
+Full pre-check for a direct transfer (`msg.sender == from`). Returns `false` if the contract is paused, or if `from` or `to` is frozen (or not allowlisted when allowlist is enabled). If a `RuleEngine` is set it is also consulted.
+
+Implements ERC-3643 `IERC3643ComplianceRead`.
+
+| Parameter | Type | Description |
+|-----------|---------|---------------------------------|
+| `from` | address | Token sender. |
+| `to` | address | Token recipient. |
+| `value` | uint256 | Amount (ignored in base check). |
+
+---
+
+#### `canTransferFrom(address, address, address, uint256) → bool`
+
+```solidity
+function canTransferFrom(address spender, address from, address to, uint256 value) public view virtual returns (bool)
+```
+
+Full pre-check for a delegated transfer (`spender != from`). Extends `canTransfer` by also checking that `spender` is not frozen (or blocked by allowlist/RuleEngine).
+
+Implements ERC-7551 `IERC7551Compliance`.
+
+| Parameter | Type | Description |
+|-----------|---------|---------------------------------|
+| `spender` | address | Address executing the transfer. |
+| `from` | address | Token source. |
+| `to` | address | Token recipient. |
+| `value` | uint256 | Amount (ignored in base check). |
+
+---
+
+### Runtime Path: `_canTransferGenericByModuleAndRevert`
-This module does not provide directly public functions.
+```solidity
+function _canTransferGenericByModuleAndRevert(address spender, address from, address to) internal view virtual
+```
-
+The internal entry point called on every token movement (`_update`). Routes to the appropriate check depending on whether the operation is a mint (`from == address(0)`), burn (`to == address(0)`), or standard transfer, then reverts with `ERC7943CannotSend` or `ERC7943CannotReceive` if the check fails.
diff --git a/doc/modules/controllers/validationAllowlist.md b/doc/modules/controllers/validationAllowlist.md
index 4b5796fd..819f03a8 100644
--- a/doc/modules/controllers/validationAllowlist.md
+++ b/doc/modules/controllers/validationAllowlist.md
@@ -1,11 +1,9 @@
-# Validation RuleEngine Module
+# Validation Allowlist Module
-This document defines the Validation RuleEngine Module for the CMTA Token specification. The goal of this module is to use an external contract (`RuleEngine`) to check the validity of a transfer.
+This document defines the Validation Allowlist Module for the CMTA Token specification. It restricts token transfers so that only addresses on an administrator-managed allowlist can send or receive tokens.
[TOC]
-
-
## Schema
### Inheritance
@@ -16,12 +14,60 @@ This document defines the Validation RuleEngine Module for the CMTA Token specif

+## Architecture
+
+Two contracts together provide the allowlist enforcement layer used in the Allowlist deployment variant:
+
+| Contract | Role |
+|---|---|
+| `ValidationModuleAllowlist` | Overrides `_canSend` / `_canReceive` to add allowlist checks on top of the standard frozen-address checks for transfers, mint, and burn |
+| `ValidationModuleAllowance` | Overrides the allowance authorization path (`approve` / `permit`) to require that both `owner` and `spender` pass `_canSend` |
+
+Both extend `ValidationModule` / `ValidationModuleCore` and work alongside the existing pause and freeze checks — the allowlist check is an additional gate, not a replacement.
+
+## Transfer Enforcement (`ValidationModuleAllowlist`)
+
+### `_canSend(address account) → bool`
+
+Returns `false` (blocking the operation) when **both** conditions hold:
+1. The allowlist is enabled (`_isAllowlistEnabled()` returns true).
+2. `account` is not in the allowlist (`!isAllowlisted(account)`).
+
+When the allowlist is disabled, this falls through to the base `ValidationModule._canSend`, which returns `!isFrozen(account)`.
+
+This check applies to senders, spenders, and burn sources.
+
+### `_canReceive(address account) → bool`
+
+Identical logic applied to the recipient side (mint targets and transfer recipients).
+
+### Effect of `enableAllowlist(bool status)`
+
+| `status` | `_canSend` / `_canReceive` behaviour |
+|---|---|
+| `true` | Allowlist membership required on top of the frozen-address check |
+| `false` | Only the frozen-address check applies (allowlist is ignored) |
+
+Disabling the allowlist does **not** clear the stored membership list — re-enabling it restores the previous state.
+
+### Mint and Burn
+
+Allowlist enforcement also applies to mint and burn paths:
+- **Mint** — the recipient must pass `_canReceive` (reverts with `ERC7943CannotReceive` if not allowlisted when enabled).
+- **Burn** — the token holder must pass `_canSend` (reverts with `ERC7943CannotSend` if not allowlisted when enabled).
+
+Use `forcedTransfer` or `forcedBurn` to move tokens out of a non-allowlisted address when required.
+
+## Allowance Authorization (`ValidationModuleAllowance`)
+`ValidationModuleAllowance` guards `approve` and `permit` calls. Before an allowance is set, `_canAuthorizeAllowanceByModuleAndRevert` checks:
-## API for Ethereum
+1. The contract must not be paused.
+2. The `owner` must pass `_canSend` (not frozen; allowlisted if allowlist enabled).
+3. The `spender` must pass `_canSend` (not frozen; allowlisted if allowlist enabled).
-> This section describes the Ethereum API of the Validation Module.
+Note that the spender check here is a pre-authorization gate, not a transfer check. A spender that later becomes non-allowlisted or frozen will fail at the `transferFrom` call even if the allowance was set earlier.
-This module does not provide directly public functions.
+This module is also used by the Permit deployment variant to enforce the same checks on `permit` signatures.
-< To do>
+See also: [allowlist.md](../options/allowlist/allowlist.md) for the management API (`setAddressAllowlist`, `enableAllowlist`).
diff --git a/doc/modules/core/Enforcement/enforcement.md b/doc/modules/core/Enforcement/enforcement.md
index 4827d27e..35db285f 100644
--- a/doc/modules/core/Enforcement/enforcement.md
+++ b/doc/modules/core/Enforcement/enforcement.md
@@ -66,6 +66,7 @@ Updates the frozen status of a specific account, either freezing or unfreezing i
**Requirement**
Only authorized users (`ENFORCEMENT_ROLE`) are allowed to call this function.
+`account` cannot be the zero address (`address(0)`).
### IERC3643EnforcementEvent
@@ -160,6 +161,7 @@ Emits an `AddressFrozen` event.
**Requirement**
Only authorized users (`ENFORCEMENT_ROLE`) are allowed to call this function.
+`account` cannot be the zero address (`address(0)`).
------
@@ -187,4 +189,4 @@ Enables bulk freezing or unfreezing in a single call.
- `accounts.length` must match `freeze.length`.
- Only authorized users (`ENFORCEMENT_ROLE`) are allowed to call this function.
-
+- `account` entries cannot be the zero address (`address(0)`).
diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandalone.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandalone.sol.md
index 65debcd1..2b02b781 100644
--- a/doc/modules/deployment/surya_report/surya_report_CMTATStandalone.sol.md
+++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandalone.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/CMTATStandalone.sol | [object Promise] |
+| ./deployment/CMTATStandardStandalone.sol | [object Promise] |
### Contracts Description Table
diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeable.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeable.sol.md
index 3be489df..006636df 100644
--- a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeable.sol.md
+++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeable.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/CMTATUpgradeable.sol | [object Promise] |
+| ./deployment/CMTATStandardUpgradeable.sol | [object Promise] |
### Contracts Description Table
diff --git a/doc/modules/extensions/ERC20Enforcement/erc20enforcement.md b/doc/modules/extensions/ERC20Enforcement/erc20enforcement.md
index cf1f00f1..277015c2 100644
--- a/doc/modules/extensions/ERC20Enforcement/erc20enforcement.md
+++ b/doc/modules/extensions/ERC20Enforcement/erc20enforcement.md
@@ -1,6 +1,8 @@
# ERC20 Enforcement Module
-This document defines ERC20 Enforcement Module for the CMTA Token specification.
+This document defines the ERC20 Enforcement Module for the CMTA Token specification.
+
+> **Note:** ERC-7551 specific enforcement (bytes data overloads for `forcedTransfer`, `freezePartialTokens`, `unfreezePartialTokens`, and `getActiveBalanceOf`) is provided by `ERC20EnforcementERC7551Module`. See [ERC-7551 Module](../../options/erc7551/erc7551.md).
[TOC]
@@ -42,7 +44,8 @@ This module defines an interface for managing **token freezing** and **forced tr
#### Events
-*For event definitions, refer to the `IERC7551ERC20Enforcement` interface.*
+*This module emits ERC-3643/ERC-7943 enforcement events.
+ERC-7551 specific `ForcedTransfer(operator,from,to,value,data)` is emitted by `ERC20EnforcementERC7551Module`.*
------
@@ -56,7 +59,7 @@ function getFrozenTokens(address account) external view returns (uint256 frozenB
```solidity
function getFrozenTokens(address account)
-public override(IERC7551ERC20Enforcement, IERC3643ERC20Enforcement)
+public override(IERC3643ERC20Enforcement)
view virtual
returns (uint256)
```
@@ -109,6 +112,7 @@ Freezes a specific amount of tokens for a given address, making them non-transfe
**Requirements:**
- Only authorized users (*ERC20ENFORCER_ROLE*) are allowed to call this function.
+- `account` cannot be the zero address (`address(0)`), otherwise reverts with `CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed`.
------
@@ -139,6 +143,45 @@ Unfreezes a specific amount of tokens for a given address, making them transfera
**Requirements:**
+- Only authorized users (*ERC20ENFORCER_ROLE*) are allowed to call this function.
+- `account` cannot be the zero address (`address(0)`), otherwise reverts with `CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed`.
+
+------
+
+##### `setFrozenTokens(address,uint256)`
+
+```solidity
+function setFrozenTokens(address account, uint256 value) external returns (bool result)
+```
+
+```solidity
+function setFrozenTokens(address account, uint256 value)
+public virtual override(IERC7943FungibleEnforcementSpecific)
+onlyERC20Enforcer
+returns (bool result)
+```
+
+Sets the frozen token balance for a given address to exactly `value`. Unlike `freezePartialTokens` / `unfreezePartialTokens` (which add or subtract), this function replaces the current frozen amount directly.
+
+The frozen amount may exceed the account's current token balance (over-freezing is allowed). The effective non-transferable amount is `min(frozenTokens, balance)`.
+
+**Parameters**
+
+| Name | Type | Description |
+| --------- | ------- | --------------------------------------------------------- |
+| `account` | address | Address whose frozen token balance will be set. |
+| `value` | uint256 | The new absolute frozen token amount for the account. |
+
+**Returns**
+
+| Name | Type | Description |
+| --------- | ---- | ----------------- |
+| `result` | bool | Always `true`. |
+
+**Emits:** `Frozen` (ERC-7943 event — amount is the new frozen balance)
+
+**Requirements:**
+
- Only authorized users (*ERC20ENFORCER_ROLE*) are allowed to call this function.
------
@@ -187,9 +230,13 @@ If needed, frozen tokens are automatically unfrozen to fulfill the transfer.
- Only authorized users (*DEFAULT_ADMIN_ROLE*) are allowed to call this function.
-### Interface:`IERC7551ERC20Enforcement`
+---
+
+> **The functions below are defined in `ERC20EnforcementERC7551Module`, not in `ERC20EnforcementModule`.** They are documented here for reference. See [ERC-7551 Module](../../options/erc7551/erc7551.md#ERC20EnforcementERC7551Module) for full details.
+
+### Interface:`IERC7551ERC20Enforcement` (via `ERC20EnforcementERC7551Module`)
-> Defines token enforcement rules, including freezing/unfreezing tokens, tracking active balances, and allowing forced transfers.
+> Defines ERC-7551 token enforcement rules: freezing/unfreezing tokens with `bytes data`, tracking active balances, and forced transfers with audit data.
------
@@ -205,6 +252,7 @@ If needed, frozen tokens are automatically unfrozen to fulfill the transfer.
- `TokensFrozen(address account, uint256 amount, bytes data)`
- `TokensUnfrozen(address account, uint256 amount, bytes data)`
+- `ForcedTransfer(address operator, address from, address to, uint256 value, bytes data)`
- `Transfer(address from, address to, uint256 value)`
------
diff --git a/doc/modules/extensions/ExtraInformation/extraInformation.md b/doc/modules/extensions/ExtraInformation/extraInformation.md
index 0150f6e3..30f74356 100644
--- a/doc/modules/extensions/ExtraInformation/extraInformation.md
+++ b/doc/modules/extensions/ExtraInformation/extraInformation.md
@@ -23,10 +23,11 @@ The ExtraInformation Module set the basic properties common to the different CMT
| Field name | Type | Setter | Description |
| ------------- | ------------------------------------------------------------ | ---------------- | ------------------------------------------------------------ |
| `tokenId` | string | `setTokenId` | ISIN or other identifier |
-| `terms` | IERC1643Document (string name, string URI, bytes32 documentHash, uint256 lastModified) | `setTerms` | Reference to any legally required documentation about the distributed ledger or the smart contract, such as the tokenization terms, the terms of the instrument and other relevant documents (e.g. prospectus or key information document) |
-| `metaData` | string | `setMetaData` | Use case: a link towards a JSON file to describes metadata. See [ERC-7551](https://ethereum-magicians.org/t/erc-7551-crypto-security-token-smart-contract-interface-ewpg/16416) |
+| `terms` | `CMTATTerms` (`string name`, `IERC1643.Document doc`) — setter takes `IERC1643CMTAT.DocumentInfo` (`string name`, `string uri`, `bytes32 documentHash`) | `setTerms` | Reference to any legally required documentation about the distributed ledger or the smart contract, such as the tokenization terms, the terms of the instrument and other relevant documents (e.g. prospectus or key information document) |
| `information` | string | `setInformation` | Supplementary information related to the token |
+> **Note:** `metaData` / `setMetaData` are **not** part of `ExtraInformationModule`. They are defined in `ERC7551Module` and are only available in the ERC-7551 deployment variant.
+
## Schema
@@ -47,7 +48,7 @@ The ExtraInformation Module set the basic properties common to the different CMT
### Structs
-#### `Terms`
+#### `CMTATTerms`
Represents the tokenization terms, including a name and an associated document reference.
@@ -74,17 +75,17 @@ Emitted when the information field is updated (typically containing free-form me
| ---------------- | -------- | --------------------------------------- |
| `newInformation` | `string` | The new metadata or description string. |
-#### `Term(string,(string,bytes32,uint256))`
+#### `Terms(CMTATTerms)`
```solidity
-event Term(Terms newTerm)
+event Terms(CMTATTerms newTerm)
```
Emitted when new tokenization terms are set.
-| Name | Type | Description |
-| --------- | ------- | -------------------------------------- |
-| `newTerm` | `Terms` | The new terms structure being applied. |
+| Name | Type | Description |
+| --------- | ------------- | -------------------------------------- |
+| `newTerm` | `CMTATTerms` | The new terms structure being applied. |
diff --git a/doc/modules/extensions/documentEngine/document.md b/doc/modules/extensions/documentEngine/document.md
index 57421efe..d91c5b2a 100644
--- a/doc/modules/extensions/documentEngine/document.md
+++ b/doc/modules/extensions/documentEngine/document.md
@@ -5,6 +5,12 @@ This document defines Document Module for the CMTA Token specification.
> Interface for managing documents via delegation to an external document engine contract.
> Extends `IERC1643`, the standard for document management.
+> **Current status (v3.3.0):** `DocumentEngineModule` is available in the codebase but is **not** integrated in any shipped deployment contract (`CMTATStandard*`, `Permit`, `Snapshot`, `Debt`, `DebtEngine`, `Allowlist`, `ERC1363`, `ERC7551`, `Light`, `UUPS`). It is exercised through dedicated test mocks only (`CMTATDocumentEngineModuleMock`).
+>
+> All shipped deployment variants **except Light** integrate `DocumentERC1643Module` instead — the native in-contract ERC-1643 implementation that stores documents directly in the token contract and uses `DOCUMENT_ROLE` for write authorization. The Light variant (`CMTATBaseCore`) does not extend `CMTATBaseDocument` and therefore has no ERC-1643 document support. `DocumentEngineModule` uses the separate `DOCUMENT_ENGINE_ROLE` to authorize `setDocumentEngine`, `setDocument`, and `removeDocument` calls forwarded to the external engine.
+>
+> See [`doc/technical/document.md`](../../../../doc/technical/document.md) for a comparison of both patterns.
+
[TOC]
## Schema
@@ -127,14 +133,14 @@ A structure that stores metadata for a document.
#### Functions
-##### `getDocument(string)->((string,bytes32,uint256))`
+##### `getDocument(bytes32)->((string,bytes32,uint256))`
```public
-function getDocument(string name) external view returns (Document doc)
+function getDocument(bytes32 name) external view returns (Document doc)
```
```solidity
-function getDocument(string memory name)
+function getDocument(bytes32 name)
public view virtual override(IERC1643)
returns (Document memory document)
```
@@ -143,9 +149,9 @@ Retrieves a document by its name.
###### Parameters
-| Name | Type | Description |
-| ------ | -------- | -------------------------------------- |
-| `name` | `string` | The unique identifier of the document. |
+| Name | Type | Description |
+| ------ | --------- | -------------------------------------- |
+| `name` | `bytes32` | The unique identifier of the document. |
@@ -159,22 +165,72 @@ Retrieves a document by its name.
------
-##### `getAllDocuments()-> string[]`
+##### `getAllDocuments()-> bytes32[]`
```solidity
-function getAllDocuments() external view returns (string[] names)
+function getAllDocuments() external view returns (bytes32[] names)
```
```solidity
function getAllDocuments()
public view virtual override(IERC1643)
-returns (string[] memory documentNames_)
+returns (bytes32[] memory documentNames_)
```
Returns the list of all registered document names.
###### Returns
-| Name | Type | Description |
-| ---------------- | ---------- | ---------------------------------- |
-| `documentNames_` | `string[]` | Array of all document identifiers. |
+| Name | Type | Description |
+| ---------------- | ----------- | ---------------------------------- |
+| `documentNames_` | `bytes32[]` | Array of all document identifiers. |
+
+------
+
+##### `setDocument(bytes32,string,bytes32)`
+
+```solidity
+function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external
+```
+
+```solidity
+function setDocument(bytes32 name, string calldata uri, bytes32 documentHash)
+public virtual override(IERC1643)
+onlyDocumentManager
+```
+
+Forwards a document write to the external engine. Creates or updates the document identified by `name`.
+
+###### Parameters
+
+| Name | Type | Description |
+| -------------- | --------- | ---------------------------------------- |
+| `name` | `bytes32` | The unique identifier of the document. |
+| `uri` | `string` | URI pointing to the off-chain document. |
+| `documentHash` | `bytes32` | Cryptographic hash of the document. |
+
+**Requirements:** caller must have `DOCUMENT_ENGINE_ROLE`.
+
+------
+
+##### `removeDocument(bytes32)`
+
+```solidity
+function removeDocument(bytes32 name) external
+```
+
+```solidity
+function removeDocument(bytes32 name)
+public virtual override(IERC1643)
+onlyDocumentManager
+```
+
+Forwards a document removal to the external engine.
+
+###### Parameters
+
+| Name | Type | Description |
+| ------ | --------- | -------------------------------------- |
+| `name` | `bytes32` | The unique identifier of the document. |
+
+**Requirements:** caller must have `DOCUMENT_ENGINE_ROLE`.
diff --git a/doc/modules/extensions/documentEngine/surya_report_DocumentEngineModule.sol.md b/doc/modules/extensions/documentEngine/surya_report_DocumentEngineModule.sol.md
index 4e545d3f..85345961 100644
--- a/doc/modules/extensions/documentEngine/surya_report_DocumentEngineModule.sol.md
+++ b/doc/modules/extensions/documentEngine/surya_report_DocumentEngineModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/extensions/DocumentEngineModule.sol | 77cab3ff874781c726f136600388038af94ec5fc |
+| ./modules/wrapper/options/DocumentEngineModule.sol | 77cab3ff874781c726f136600388038af94ec5fc |
### Contracts Description Table
diff --git a/doc/modules/extensions/snapshotEngine/Snapshot.md b/doc/modules/extensions/snapshotEngine/Snapshot.md
index 2aa1614f..493ff0ea 100644
--- a/doc/modules/extensions/snapshotEngine/Snapshot.md
+++ b/doc/modules/extensions/snapshotEngine/Snapshot.md
@@ -90,3 +90,53 @@ Returns the currently active snapshot engine.
| Returns | Type | Description |
| ---------------- | ----------------- | --------------------------------------------- |
| `snapshotEngine` | `ISnapshotEngine` | Address of the currently set snapshot engine. |
+
+---
+
+## Base Mixins
+
+### `CMTATBaseSnapshot` (level 0)
+
+`contracts/modules/0_CMTATBaseSnapshot.sol`
+
+A pure mixin that composes `ERC20Upgradeable` and `SnapshotEngineModule`. Its sole role is to wire the ERC-20 `_update` hook into the snapshot engine:
+
+```solidity
+abstract contract CMTATBaseSnapshot is ERC20Upgradeable, SnapshotEngineModule {
+ function _update(address from, address to, uint256 amount) internal virtual override(ERC20Upgradeable) {
+ ISnapshotEngine snapshotEngineLocal = snapshotEngine();
+ if (address(snapshotEngineLocal) != address(0)) {
+ // snapshot balances before transfer, then call operateOnTransfer
+ ERC20Upgradeable._update(from, to, amount);
+ snapshotEngineLocal.operateOnTransfer(from, to, fromBalanceBefore, toBalanceBefore, totalSupplyBefore);
+ } else {
+ ERC20Upgradeable._update(from, to, amount);
+ }
+ }
+}
+```
+
+`CMTATBaseSnapshot` is intentionally access-control-free: the `_authorizeSnapshots()` hook is left `abstract` and is implemented by the consuming base contract (typically enforcing `SNAPSHOOTER_ROLE`).
+
+### `CMTATBaseERC2771Snapshot` (level 7)
+
+`contracts/modules/7_CMTATBaseERC2771Snapshot.sol`
+
+Combines `CMTATBaseERC2771` (gasless meta-transactions via ERC-2771 trusted forwarder) with `CMTATBaseSnapshot`. It resolves the `_update` diamond-inheritance ambiguity by delegating to `CMTATBaseSnapshot._update`, and similarly resolves `_msgSender` / `_msgData` / `_contextSuffixLength` in favour of `CMTATBaseERC2771`.
+
+This is the base contract used by the dedicated **Snapshot** deployment variants (`CMTATStandaloneSnapshot`, `CMTATUpgradeableSnapshot`).
+
+---
+
+## Deployment Variants
+
+| Variant | Base | Available snapshot support |
+|---|---|---|
+| `CMTATStandaloneSnapshot` | `CMTATBaseERC2771Snapshot` | Yes — dedicated variant |
+| `CMTATUpgradeableSnapshot` | `CMTATBaseERC2771Snapshot` | Yes — dedicated variant |
+| `CMTATStandaloneDebt` | `CMTATBaseDebt` (inherits `CMTATBaseSnapshot`) | Yes — included by default |
+| `CMTATUpgradeableDebt` | `CMTATBaseDebt` | Yes — included by default |
+| `CMTATStandaloneDebtEngine` | `CMTATBaseDebtEngine` (inherits `CMTATBaseSnapshot`) | Yes — included by default |
+| `CMTATUpgradeableDebtEngine` | `CMTATBaseDebtEngine` | Yes — included by default |
+
+Issuers using the `Debt` or `DebtEngine` deployment variants do **not** need to deploy the separate `Snapshot` variant to access SnapshotEngine support — it is already available through `CMTATBaseSnapshot` in those base contracts.
diff --git a/doc/modules/options/allowlist/allowlist.md b/doc/modules/options/allowlist/allowlist.md
index eb939a9d..57361b14 100644
--- a/doc/modules/options/allowlist/allowlist.md
+++ b/doc/modules/options/allowlist/allowlist.md
@@ -225,4 +225,21 @@ returns (bool)
| ---- | ------------------------------- |
| bool | `true` if allowlist is enabled. |
+---
+
+## Transfer Enforcement
+
+The allowlist management API above only controls *who is on the list*. The actual enforcement during transfers is performed by `ValidationModuleAllowlist`, which overrides `_canSend` and `_canReceive` from `ValidationModule`:
+
+- **`_canSend(account)`** — returns `false` when the allowlist is enabled and `account` is not allowlisted (in addition to the base frozen-address check).
+- **`_canReceive(account)`** — same logic applied to the recipient side.
+
+When the allowlist is disabled (`enableAllowlist(false)`), these checks are skipped and the standard frozen-address checks apply.
+
+The same allowlist check is applied to mint and burn targets. Minting to a non-allowlisted address or burning from a non-allowlisted address reverts with `ERC7943CannotReceive` / `ERC7943CannotSend` when the allowlist is enabled.
+
+Allowance authorization (`approve`, `permit`) is separately guarded by `ValidationModuleAllowance`: both `owner` and `spender` must pass `_canSend` (i.e., must be allowlisted when the allowlist is enabled and not frozen).
+
+See also: [validationAllowlist.md](../../controllers/validationAllowlist.md)
+
diff --git a/doc/modules/options/debtEngine/debtEngine.md b/doc/modules/options/debtEngine/debtEngine.md
index ceb31a32..4e1756b5 100644
--- a/doc/modules/options/debtEngine/debtEngine.md
+++ b/doc/modules/options/debtEngine/debtEngine.md
@@ -8,7 +8,7 @@ This module allows to set an external engine called `DebtEngine`to configure Deb
## Interface
-The interface and struct to represent Debt is available in [ICMTAT.sol](/contracts/interfaces/tokenization/ICMTAT.sol)
+The interface and struct to represent Debt is available in [ICMTAT.sol](../../../../contracts/interfaces/tokenization/ICMTAT.sol)
## Schema
diff --git a/doc/modules/options/erc20crosschain/ERC20CrossChain.md b/doc/modules/options/erc20crosschain/ERC20CrossChain.md
index 8b9ccd41..5cc6ae2e 100644
--- a/doc/modules/options/erc20crosschain/ERC20CrossChain.md
+++ b/doc/modules/options/erc20crosschain/ERC20CrossChain.md
@@ -93,6 +93,7 @@ Mints tokens as part of a crosschain transfer.
- The contract must not be paused
- error: `EnforcedPause()`
- Only authorized users (`CROSS_CHAIN_ROLE`) are allowed to call this function.
+- Compliance path note (CMTAT base integration): operator (`_msgSender()`) is propagated through transfer-compliance checks for spender-aware RuleEngine restriction support.
**Emits:**
@@ -129,6 +130,7 @@ Burns tokens in preparation for a crosschain transfer.
- The contract must not be paused
- error: `EnforcedPause()`
- Only authorized users (`CROSS_CHAIN_ROLE`) are allowed to call this function.
+- Compliance path note (CMTAT base integration): operator (`_msgSender()`) is propagated through transfer-compliance checks for spender-aware RuleEngine restriction support.
**Emits:**
@@ -164,6 +166,7 @@ Burns tokens from an account by using the caller’s allowance.
- The contract must not be paused
- error: `EnforcedPause()`
- Only authorized users (`BURNER_FROM_ROLE`) are allowed to call this function.
+- Compliance path note (CMTAT base integration): operator (`_msgSender()`) is propagated through transfer-compliance checks for spender-aware RuleEngine restriction support.
**Emits:**
diff --git a/doc/modules/options/erc2612/erc2612.md b/doc/modules/options/erc2612/erc2612.md
new file mode 100644
index 00000000..461e0245
--- /dev/null
+++ b/doc/modules/options/erc2612/erc2612.md
@@ -0,0 +1,122 @@
+# ERC-2612 Permit + ERC-6357 Multicall Module
+
+This document describes `CMTATBaseERC2612`, which extends CMTAT with ERC-2612 gasless approvals and ERC-6357 multicall batching.
+
+[TOC]
+
+## Rationale
+
+**ERC-2612 (Permit)** — Allows token holders to authorize allowances via an off-chain EIP-712 signature rather than an on-chain `approve` transaction. This eliminates the need for a separate approval step, reducing gas costs and improving UX for relayer flows.
+
+**ERC-6357 (Multicall)** — Allows multiple calls to the same contract to be batched into a single transaction via `delegatecall`. This saves gas when a user needs to perform several operations atomically (e.g., set terms and freeze in one tx).
+
+## Contract
+
+`contracts/modules/6_CMTATBaseERC2612.sol`
+
+Inherits from:
+- `CMTATBaseERC20CrossChain` — full CMTAT feature set including CCIP and ERC-7802
+- `ERC20PermitUpgradeable` (OpenZeppelin) — ERC-2612 implementation
+- `MulticallUpgradeable` (OpenZeppelin) — ERC-6357 implementation
+
+## Deployment Variants
+
+| Contract | Type |
+|---|---|
+| `contracts/deployment/permit/CMTATStandalonePermit.sol` | Immutable (no proxy) |
+| `contracts/deployment/permit/CMTATUpgradeablePermit.sol` | Transparent / Beacon proxy |
+
+## API for Ethereum
+
+### Functions
+
+#### `permit(address,address,uint256,uint256,uint8,bytes32,bytes32)`
+
+```solidity
+function permit(
+ address owner,
+ address spender,
+ uint256 value,
+ uint256 deadline,
+ uint8 v,
+ bytes32 r,
+ bytes32 s
+) public virtual override(ERC20PermitUpgradeable)
+```
+
+Sets `allowance[owner][spender]` to `value` using a signed EIP-712 message, without requiring an on-chain transaction from `owner`.
+
+CMTAT adds the following checks on top of the standard OpenZeppelin implementation:
+
+- Contract must not be paused.
+- `owner` must not be frozen (allowance validation via `ValidationModuleAllowance`).
+- `spender` must not be frozen.
+
+**Parameters**
+
+| Name | Type | Description |
+|------------|-----------|------------------------------------------|
+| `owner` | `address` | Account granting the allowance. |
+| `spender` | `address` | Account receiving the allowance. |
+| `value` | `uint256` | Allowance amount. |
+| `deadline` | `uint256` | Expiry timestamp for the signature. |
+| `v` | `uint8` | ECDSA recovery byte. |
+| `r` | `bytes32` | ECDSA signature half. |
+| `s` | `bytes32` | ECDSA signature half. |
+
+**Requirements**
+
+- `deadline >= block.timestamp`
+- Signature is valid for the given `owner`
+- Contract is not paused
+- `owner` and `spender` are not frozen
+
+---
+
+#### `multicall(bytes[])`
+
+```solidity
+function multicall(bytes[] calldata data) external returns (bytes[] memory results)
+```
+
+Executes multiple calls to this contract in a single transaction using `delegatecall`. Reverts atomically if any sub-call fails.
+
+Provided by OpenZeppelin `MulticallUpgradeable`. See [ERC-6357](../../../ERCSpecification/erc-6357-multicall.md).
+
+**Parameters**
+
+| Name | Type | Description |
+|--------|-----------|------------------------------------------|
+| `data` | `bytes[]` | Array of ABI-encoded function call data. |
+
+**Returns**
+
+| Name | Type | Description |
+|-----------|-----------|-------------------------------------|
+| `results` | `bytes[]` | ABI-encoded return values per call. |
+
+---
+
+#### `nonces(address)`
+
+```solidity
+function nonces(address owner) external view returns (uint256)
+```
+
+Returns the current permit nonce for `owner`. Incremented on each successful `permit` call.
+
+---
+
+#### `DOMAIN_SEPARATOR()`
+
+```solidity
+function DOMAIN_SEPARATOR() external view returns (bytes32)
+```
+
+Returns the EIP-712 domain separator used for permit signature verification.
+
+## Security Considerations
+
+- The `permit` function validates both pause state and freeze state before delegating to OpenZeppelin's implementation, consistent with how CMTAT validates standard `approve`.
+- `multicall` uses `delegatecall` — all sub-calls share `msg.sender` and contract storage. Do not use with ETH values unless the contract is designed for it.
+- Permit signatures are replayable across chains if the chain ID changes (e.g., after a fork). OpenZeppelin's implementation includes the chain ID in `DOMAIN_SEPARATOR`, mitigating this.
diff --git a/doc/modules/options/erc7551/erc7551.md b/doc/modules/options/erc7551/erc7551.md
index e30f597b..fbcb4bee 100644
--- a/doc/modules/options/erc7551/erc7551.md
+++ b/doc/modules/options/erc7551/erc7551.md
@@ -1,6 +1,17 @@
# ERC7551 Module (eWpG)
-This document defines the ERC7551 Module for the CMTA Token specification. The goal of this module is to implement specific function required by ERC-7551 authors.
+This document covers the ERC-7551 modules for the CMTA Token specification. Two contracts implement ERC-7551 support:
+
+| Contract | Purpose |
+|---|---|
+| `ERC7551Module` | Document and metadata functions (`metaData`, `setMetaData`, `terms`, `setTerms`, `termsHash`) |
+| `ERC20EnforcementERC7551Module` | Enforcement bytes overloads (`forcedTransfer`, `freezePartialTokens`, `unfreezePartialTokens`) and `getActiveBalanceOf` |
+
+`ERC7551Module` is composed in `CMTATBaseERC7551` (`contracts/modules/8_CMTATBaseERC7551.sol`), which is the base for the ERC-7551 deployment variants (`CMTATStandaloneERC7551`, `CMTATUpgradeableERC7551`).
+
+`ERC20EnforcementERC7551Module` is also composed in `CMTATBaseERC7551Enforcement` (`contracts/modules/7_CMTATBaseERC7551Enforcement.sol`), which is used by the Standard deployment variants (`CMTATStandardStandalone`, `CMTATStandardUpgradeable`).
+
+It is also composed in `CMTATBaseAllowlist` (`contracts/modules/3_CMTATBaseAllowlist.sol`), so Allowlist deployment variants expose the same ERC-7551 enforcement functions.
[TOC]
@@ -140,3 +151,78 @@ Sets a new metadata string (commonly a URL).
**Requirements:**
- Only authorized users (*EXTRA_INFORMATION_ROLE*) are allowed to call this function.
+
+---
+
+## ERC20EnforcementERC7551Module
+
+`contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol`
+
+Extends `ERC20EnforcementModule` with the ERC-7551 enforcement interface (`IERC7551ERC20Enforcement`). Adds `bytes data` overloads for enforcement functions (for audit trails and metadata), plus the `getActiveBalanceOf` view.
+
+See also: [ERC20 Enforcement Module](../../extensions/ERC20Enforcement/erc20enforcement.md)
+
+### Functions
+
+#### `getActiveBalanceOf(address)`
+
+```solidity
+function getActiveBalanceOf(address account) public view returns (uint256 activeBalance_)
+```
+
+Returns the number of tokens available for transfer (total balance minus frozen tokens).
+
+| Name | Type | Description |
+|-----------|-----------|-------------|
+| `account` | `address` | The address to query. |
+
+---
+
+#### `getFrozenTokens(address)`
+
+```solidity
+function getFrozenTokens(address account) public view returns (uint256 frozenBalance_)
+```
+
+Returns frozen token count. Overrides both `ERC20EnforcementModule` and `IERC7551ERC20Enforcement`.
+
+---
+
+#### `forcedTransfer(address,address,uint256,bytes)`
+
+```solidity
+function forcedTransfer(address from, address to, uint256 value, bytes calldata data)
+ public virtual onlyForcedTransferManager returns (bool)
+```
+
+Forced transfer with additional `data` payload for audit or compliance metadata. Unfreezes tokens from `from` as needed.
+Emits ERC-7551 event `ForcedTransfer(operator, from, to, value, data)`.
+If tokens were unfrozen to fulfill the transfer, also emits `TokensUnfrozen(from, amount, data)`.
+
+**Requirements:** caller must have `DEFAULT_ADMIN_ROLE`.
+
+---
+
+#### `freezePartialTokens(address,uint256,bytes)`
+
+```solidity
+function freezePartialTokens(address account, uint256 value, bytes calldata data)
+ public virtual onlyERC20Enforcer
+```
+
+Freezes `value` tokens on `account`, with a `data` payload attached to the freeze event.
+
+**Requirements:** caller must have `ERC20ENFORCER_ROLE`.
+
+---
+
+#### `unfreezePartialTokens(address,uint256,bytes)`
+
+```solidity
+function unfreezePartialTokens(address account, uint256 value, bytes calldata data)
+ public virtual onlyERC20Enforcer
+```
+
+Unfreezes `value` tokens on `account`, with a `data` payload attached to the unfreeze event.
+
+**Requirements:** caller must have `ERC20ENFORCER_ROLE`.
diff --git a/doc/modules/security/access.md b/doc/modules/security/access.md
index 44842ebb..1ddb09f1 100644
--- a/doc/modules/security/access.md
+++ b/doc/modules/security/access.md
@@ -32,6 +32,19 @@ This behavior is implemented by overriding the function `hasRole` from OpenZeppe

+## rc1 — Document Composition Level (Hierarchy Refactor)
+
+In v3.3.0-rc1, a new `CMTATBaseDocument` contract was introduced at **level 1** in the inheritance hierarchy. It is a thin composition wrapper (`abstract contract CMTATBaseDocument is DocumentERC1643Module {}`) that places document module composition at a distinct inheritance level below the RBAC layer.
+
+Key points:
+- `DOCUMENT_ROLE` is defined as a constant in `DocumentERC1643Module` (the wrapper module).
+- `_authorizeDocumentManagement()` is declared abstract in `DocumentERC1643Module` and is inherited through `CMTATBaseDocument` without implementation.
+- The concrete implementation of `_authorizeDocumentManagement()` remains in `CMTATBaseAccessControl` (level 2): `onlyRole(DOCUMENT_ROLE)`.
+
+The practical effect is that the document composition level is now separable from RBAC management, and the dependency graph makes the layering explicit.
+
## API for Ethereum
See [docs.openzeppelin.com - AccessControl](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl)
+
+For the full role and function table, see [access-control.md](../../technical/access-control.md).
diff --git a/doc/schema/drawio/architecture-ERC.drawio.png b/doc/schema/drawio/architecture-ERC.drawio.png
index 06acb59e..75a4f05c 100644
Binary files a/doc/schema/drawio/architecture-ERC.drawio.png and b/doc/schema/drawio/architecture-ERC.drawio.png differ
diff --git a/doc/schema/drawio/architecture.drawio b/doc/schema/drawio/architecture.drawio
index 1d6f0b01..86453aa1 100644
--- a/doc/schema/drawio/architecture.drawio
+++ b/doc/schema/drawio/architecture.drawio
@@ -1 +1 @@
-7Vtbc5s4FP41mUkf3AHE9TF2nbbbpsnaSZPpS0YG2agBRIVo7Pz6lUA4BuRcuuDEnTwkto4Eks537pIPwChefqQwDU9IgKIDQwuWB+DDgWHowDL4h6CsSoph61ZJWVAcyFH3hCm+Q5KoSWqOA5TVBjJCIobTOtEnSYJ8VqNBSsltfdicRPVZU7hALcLUh1GbeokDFsptAGDfd3xCeBFWU9uWWfbEsBott5KFMCC3GyQwPgAjSggrv8XLEYoE+yrGlM8db+ldr4yihD3lgc/h1+HReTy5+geeXqFvMB/+YAP5lt8wyuWO5WLZqmIBJXkSIPES7QAMb0PM0DSFvui95ahzWsjiiLd0/nVOEiZR1F3ebi+ymhFRhpYbJLnoj4jEiNEVHyJ7XVsysJIhTbZvNwAxJS3cwMJ2JBFKIVis333PJv5FcuoZXDNaXDsnNyjBd5BhkrQ4yDfK6mzKGOUPjEhEKKckJEGCdziKGiQY4UXCmz5nH+L0oWAb5uJ5JDtiHARiGiUudeQKaOSi+oLKMd5bNbB0WwGWpgAL9IWV+folXNfNPxRxw+uLbZaCbXbEpOwmixoH7V+5sGLDGVkOMnyHeTc44iNmhAaIDji5YBS30oV0iy66mB1anC18ddr957tynODxYA5jHK3K0XwKGAsg5ESnKeJqpk1hkjW7ylc1qaMIQfqsJz6h6DcSusb7viHOBOVTG6NE84hiGKnfN0ULwl+iXXzm/8Yx+YnVb8z4CgcZoni+wYusEDjBCd1NJTOFVRlIAyF6IjQv36LNoH+zKIR60OC4YbrlLJtfSqbb61XYC/lZwp3C5I/A3rbw+4k0P4JZVntpHAzSCOKkvZ4zSpZCZ7I8TQllYkMogoyrrVwoF/NyrfX1C7KU2Krj9Zrnzu0KeNwag11aY73tOseT0cDh8lEBNqMVUlNGqIjPDC2BMcoK7gm5EoqcSnHggR+jkEd+nRr1TawPDDCfI9v3W4LBewLHm2laV3DZbt0NgDZcuqOAqzcvoIM98J6m/gTvqYo5TKs3vrWjjnPkh4mwDXtif+rhYhcweXWYdKsNk71TW2QrbZHhODVbpHB9j7u20oAdniAm4ofzZREQHIuEFmYRyrJ3Hc3Qq9kLIHLnSrNn+y6azbvSX9DQX5XZU0mG3ZtkOErJsDUPdITbKM8YifkIRCmh2dqtFQKoiehOJJTZ3+DVmvCaxhPh7c+rueogxNWMrhTfpyTL/LCIZDUeoCTZHFGh9X+fuoKn4un2Vo7RWnh+QGlEVrHYplgYXxfPvC7OphuR46HAXHcNo19UkB5YyFGh4tkOgHZPsSNQeFfd3aWWGe3aYsFxUzMVoT6O00hE9xPE+YT9Iq/Tiqoa/5wymASQBv2qj4XcwFQB5RozYHcElOuBRolsHRfVonxrl0jtQY3MapTIdAXXlCUyYPbGtrca2VuN7FXVyNr28q00ts2cNCpjCne528qYsSUb1drOcqducTdZguXU8TAq4/pipS9DnSTowAZtRM7gCs6K+EVis/cBpeU0onz3xQHxWoCMCBU8PyFBHqG/IVl2GlGOKog3FEzv7aQbtFOraYp8PMc+pwabWRbfZaY6/d5D2W84BxUKqgS3PxTaqdQE/cpxIf3C3/L/RcEC8U2K4Kppn8ZLhpISHS3egbbsJpfy9OZ1g5dHyngmUtppynaIy25KRGsb9QAsKt/RBSy2c/Tv1++r2Wm4pHP268uQonCgOsYqdUQwTBm6P7XUx4OCkl+MpzWR4EJRyhBGsahhlHBHYpNVLyW/a8fW5RoeLejrj8O/kMmCkJTsBjE/rBrV5TO9I4hB49DNdN4rAgRLBbLVE8iqKkZHIB/nxfQ+4dBimBTn0LKqyELRKKTguYA+QZ/XuGkPodsFoKb7uM6q6oe96ewD1ZVt6fYzdHag2yZ4JD/+32dzHS33A/FzGWSdwAQuUNnYi7UfKkzfu61r79/2vUzR1/UagQoASnvpau8VhV9d78tkts85u/SLA7ChY+3yRXniOUGLXN7j0sZLP4TJQgRBzYcOzyoPuyk9u/acr+TIwFGdkLu2QnKMvqyz3k5Jyu2/zhJiDcWtWPd9B8az6j52oLdx7OsKjBrFdrpyTGj8BuKDkdILong9vb65Co0fX1Y/0+9Dc3xLhkDxIw5hfC3b8TqKBiqLfYIThotzLZgIez3MaVK0977w1rrVsD5v3MUtFSWq7Zy1uKRiWYqbsugy/dgrCrspvLU9na3Qrd4Ox6+Xq7llwQvvegKv/cuTq1PH26JcjqeKbPLJpdCjAf+7SLAoiBYlngkqPi4JjYTWHGUZErHVZ2ER58Wl5r0vxbUjXPUJTjfI8eb97+aKvo3fH4Lxfw==5Vpbc+I2FP41zHQfYHzBBh4TSJpOZyc7m+lu2zdhH2NNjOWVRYD++kqy5JucQjbY2U3JJEGyrMs5nz5959gjd7k9/EpRFn8kISQjxwoPI3c1chzb9Rz+T9QcixrHt72iZkNxqFpVFQ/4H1CVlqrd4RDyRkNGSMJw1qwMSJpCwBp1iFKybzaLSNIcNUMbMCoeApSYtV9xyGK1DNf1qwt3gDexHtr3psWVLdKt1VLyGIVkX6tyb0bukhLCim/bwxISYT5tmOK+22euljOjkLJzboii6NvdHbpb7a2v+Xw59X+P4rHq5QklO7ViNVl21CagZJeGIDqxRu71PsYMHjIUiKt77nVeF7Ntwks2/6q6A8rg8Ow87XL1HDhAtsDokTdRNyyUvRRkPFXcV+af6yZx3fLazki5fFP2XBmFf1F2eYGNHMNG1ygHXsPxvuNWepXBIpIyBXt7Lso4SZYkIVT25YYI5lHA63NGySPUrvjBHNbRZUw+dZs2d2am0cstWTf6oi+bu4bNV5Al5LgVK5LbnVHE9/vrbN+0NdihB7MuWy/8mYv8Dm/1YPvp4kzbz/uy/dSw/c2BQRrmhrV55ZUgWV5aJyR45BbhVdpAflG8xWJ46Y+a7ZuO4raixz9FYeLp4l+qpSysDvWWq6MqFTOC0CDxlvX5rMmOBnAacQzRDbBTbGB6s+Yt21eeoZAghp+ac+tyl+ruE8ES3QfNfE1kuH7L48Wa1F115m915PsnOioWbXQk0VOu8fsB5XUDKsckFQelZFEOLj/hdr9eU/5tw6Rzixqx6Rq487/tiL4wziXarngD28kOxW3quu7oF5hsJrzBzecl/5NGhFtNEEnB3x/0OHxtxVB6+B55PYrADzp5PZwt1pZ1IW6Zeg3HzzuoxfVMapn1RS2+gYQlodVROgQIPuL/gePdFnV0OL7US4M4fmY4/j5jQ+//Fazfv+v9xek97wy55+cdrof0b8gySLAAQILXFImBhjkA/sg2FIWA1kK68yVZn9AuF6XahbfBhyd+OrW+/KgeavXFpx/KGDtdQnQ+JGks3kCIHjBTOrS4jZeFEB1bE8vRFZUYFYVjrfAJKOZrB/rj6FqdNTmla+fD6dppS45+p6ydei3E2u1wtGddq6OyGkB/S7nzU5QMq2vbklbP4o2Ouch55pjz177nX+iYc9vOdzroyhqSrmwzmfbDBs41nhNWbvCcvXgxz70BX9lWNz5+ZMKauhO39mkKtbGRweybvszE5pDnaw111n8C7pLgGg40/qxNUO2E3fmwaSuzoYFiZmPfO1Ccc1loQBJq0kWJipfCqd2R2+6obzSZ+eVbXEimKq1vhTLdz+HgWDJLwGKRJpKYCmKE04kBvTxGmfiaEganRcwaBY8bCbn7HeNxKKj6ENHHe34XZhJVE8trKR7vQvpl3tzU064UzaIjTu/tkYttpmlXwCP1EKcb7QXMchGww5N4zitiZyScUjwNqzkvQKIxSnIi7kljrhbkjRElW9mVaM9VoRDJMv1HuHup2VU+6VLPP7XfW24vn+w0gmxn0uH4/h5w2mZa9vmopap54MPX4xy+BjmW8nsGlIclwt8SDXAoI6MAyXaM7BEVZ4hqkG6wBAaOJNLEn7wAQ4Q3OwphJxouHEt9QQkOkUhNFqHUZ/57o2c25q3RViBKDW5Vl8+OtX4uvNpWKy/UFWe5bkecZWtCuTxezWzyUjAGSRKgoyEj7zZa3nFe2babOOg6r2aDhttmYvlKnx0aCYJp8uaJk/PDi0oakodO3mAwJogLZVlylIKNGxQHwrt5KUMoSvNI9H273tFUTLwQV4TTHVJNf+oN3zqgxl2vgnT5ucTH5R1t5oH1NsszeXSc3sjeMxv5qnS/mHkgVQrKlbARzskKXQJsD5A2BU91XypkauuphgQbNtKBkxpDFLM3j9dXrEcTk3imAfr9pA4J1v3M422A6/R1Up17UFl9IVcflS2KMgXzFh1rgnmbJaBedEphL5wGiHEBJPynHVywj4Ke4iDEyBYLyjt+0ABUIqwSWWerMD3QQ4qyPCasVDnvid3K2LfObp1vF7ZzfmdghBertzuL6Ll6S9a9+Rc=3Vptd6I4FP41ftTDi0T8WLW2e2Z72jPuzO7stwhBMg2EE2LV+fWbhKBAqLYdtNvacyq5JCF57nNvngR77jTZ3jCYxXc0RKTnWOG25856jmO7niO+pGVXWBxge4VlxXCoax0MC/wLaaOlrWscorxWkVNKOM7qxoCmKQp4zQYZo5t6tYiS+lMzuEKGYRFAYlr/xiGP9TRcFxxu3CK8istHA29Y3ElgWVtPJY9hSDcVk3vdc6eMUl5cJdspIhK+Epii3fyZu/uRMZTylzT4kdhf6M3V5PvMSh8W87t4HFz13aKXJ0jWesZ6sHxXQsDoOg2R7MTquZNNjDlaZDCQdzfC68IW84SIki0uzUHpcT4hxtG2YtKDvEE0QZztRBV9d6zx0pTxdHFzgN8vq8RV5EucoXb5at/zARRxoXFpx+jOt0fw53Jxvfnm+OtkuJ2TX33bwGgCcyQsgu9rgdJvARbRlGva274sY0KmlFCm+nJDiPwoEPacM/qIKndA4KNl1A3kQ7eOuTMyQd+HZBX08bkwdwzMZygjdJfISapw5wyKeP897OtYIzv00KgN6zEYuRC0eOsM2A+H3suw98+F/dDA/nrLURrmBtrCeCWTrCgtCQ0eBSLCVAIEiuIcy8crf1SwrztKwMd2/8jCwCuLP3RNVZhtqzVnO116Fv+crlmAThOMQ7ZC/HTwo7C2TpjerHjLBtozDBHI8VN9KWlzl+7ugWLF7m2Z+erMcEHD48Ukdatq5m90BMCJjgoUjI4Ue/ZzfDuhvHZC5ZimcqFUWdQkV5dpNIoQCFrTaDgaL62jVHpFKI/qOPtmFrXHnhnJow4ieTa+nVlfJ3jJJ+wLf/r5DXxNW1auKWWHleszYO7apzF3WrJnF5jH/ZvJ/fy7u0tu/wLhMkHen/MWzO8z/tmYDkoaP4+6yF8XRN3UC/cZSv9FWYYIltgTvGRQP+hs2Hvyr1WsqY/uoWIvPh1FQmO56O/VWdUr/iVjwdxdnF9JbDHXQqJoJspSSfStgeWUhoOakIVdpfCAGBZzR+wSwuTYjqwqTI4x/l2EybChJ96oS4Zeg7F2cz/RnTBpxdAUJn+kwvcpJBfL1pHzTLYGS+CBjrK128TZuaAyaUUevENmeGMoVzKKBLmWUezxqzPK+TOD9wkyw9AduJVPXW30jbOe7vJEK/KmurjkOlbhnHWUbi+i1v+NMmDUTE7Ng42Xk6YpgC5Mk/c4ODkXTY4dhlQz0LFM9T4ZqJ4r9qR4LZuaHbnNjs5MJlObzHEhTA6Hn1aoDkUFGxxL7TB5LHf3ilJBDOXGp0G8PIaZvEwpR6fVyxIGjytFuPs1F/sopO0hZI/3ohXmilMDy2tIHa8j4QKeceYp3dLFuXSrV3zDKzMkNpohTlelDzDP5X4TPcl3YVM5COmS4o1BxXUBlJUhyalsk8ZCJqiGEaOJ6krWF2pQClF1ZkOFc5nZlZlcPpaPR9ZoUPdy2ysfx2rZt9pNedGZm8eGm6/2OwL5PAW7fGzhXYlqVjgH8Q1Cad3rh3apjNTGyYTyMTb2HYOeAwiXDhL3wUpeLcTsqhsTAZCaiiaRGEFEWaKeI7Pvdt9lAFU9TjeQhfm+QrrCimU4UrSV//KCWRFerZlMKx+aWrbVOBxsIZbrXpRY5YBqR7IikCkhiH2Gk0G7sde85HlsO+LmgexVmT4V6jo+8nrSzUX+Zip4VN7Na3HHZbiJkCc7JVgEoDiQZ7z5fh1mMM0j2fd8uWapHHghLqgIUqirfujY8htau+2N8agttOzXO1oUDz+TKPTV4ecm7vV/7V1Zd5vIEv41fpQO3c366NjOODNxxtd27CQvc5CEbBJJyAhv+fUXJJCgusTmbmiPx+fMREKAUNXXtVf1ATuaP/8Rusu7s2DizQ6oNnk+YMcHlFLdoPE/yZGXzRFiE7I5chv6k/TY7sCl/9tLD2rp0Qd/4q0KJ0ZBMIv8ZfHgOFgsvHFUOOaGYfBUPG0azIrfunRvPe7A5did8Udv/El0lx4lmrb74NTzb+/Sr7aN9IORO/51GwYPi/T7Dij7uP7bfDx3s3ul56/u3EnwlDvETg7YURgE0ebV/PnImyXEzci2ue7jnk+3zx16i6jOBRdPj19+nJ4tV4fGpXcbmY82fRwQZ3ObR3f24GW/Y/200UtGofVv9JK7kAP24enOj7zLpTtOPn2KQREfu4vms/TjqT+bHQWzIFxfyxzn6CimCPuwisLgl5f7xBzb3miaXBEsohQWRI/f878r/amPXhh5z7lD6e/8wwvmXhS+xKeknw6MDF0ZKo2Ma087HpuGsTl2l2MvMdODboqr2+3dd7SNX6TkxUn947t56kx+fr6Yfpt9udZ8Yv22BsRqQmqtMamn03H8h5GamcxhEzmkNo0ipQcUIbStIYR2NFmENqsJHS/GZfIyIVEVncMgciM/WMRvB47GE35EJpOphhGeaBZzPDmE13U6NKwiyskw++056luOOdQcjAGOPbSkoV2TK1gmrmdPUbTLFCzMKqLdNBG0mwjat1rgNYT+uQityf3LcfAtXD5S/fhp7n8fGHLpPJ16Ji5VJpYz0jQ5dCa6WST0VqDnCE1RsWIIIPRfbProui/2/enPyPxOHp/D8/MY0UyuAPfIxPAsjNSOaTHXlEXqIqUdxlOaMA0hNWOySO00Eh7NKd2P8NCBqkyMTF5aM1nSA6W0UUNXvk58TOke8WGOTEMSprcYfgH0yxFa1zFCS4M0kUvnWHLYEx2js01HzJRE54GpAetPx6SHRhFSby8VTmrKkfoo/unec3RAzVn87R9GYYHw5v1D4oOtCTRYrSl0GJ9A9OXzmkzZ5/Gr2+Tfr8vb0J147ii+/nVSSQJHdGChDJjOc8RB+CFNb2IGiunOE1rMUrIW3ml+zKxwmhAtwU364W3h1OydCHZ+Ork4oprSTCUcUy1kmRldchXTG+px9cyL3In7DtY9rQMQDYl3SAMIH+1Yc+Qd8GJAoFakiAwmuFKUxA0+zJdww7JIQ36wPfxINawUtjBBbHEAV2yEKZj1LY0pSIzkcDz2VquEmmEwE8QblZkCo4cYTzpdKIQ31M/dh1VCPJXpOKDMqKYk5vLIoyRvhyeU9M6CyYOCUptZRQI6jtE3FPl4U2LPXD0L0qGKMmKg20VOEFOzhjWZYUljhs7L6ofoLgj93+vkgKLEJAYIhRiIYUix6J48WPMOIWcZpgCNfQZF6WoZUFr0rrh4jywlq/bhIVQVn4apGh0pb5RduzN/klvlF/F/J4tbf+F9SpzahTtTjq4OMKwYkv/elmB0Q1fesPrgKmsNEOooB0zenjp5jrzFZMVRLz54mJTGxO9Gs2D8K6ZJfCgjkbl5+9FPvn9N30KyO0/4mIDhy7f0o/Wb78knsTZO3x4/5888fknfQY54z370bX2lZaRvv2cXxq93d0neZDfZy8ZV8BCOvRrKOnLDWy8qOzFlljcpFAnxsMhzPeNw6M1iofDoFZ4NY3t6u/Mg1mc5iG3LIlKI6bAiYvM708t26OHuxICO12G6aEMH7kYxRtyX3GnL5IRVgyceGFrpgxFSfkH8YvMMu1WxpXn7hcJ4u/no7OrwKtGEscSJ/zkK5vNgoZzQsUDSm+iYE9ep1NZ5s/dkMQ1iWM49ZY0zAgNwuPBGoqHy6IjV2UF793LhLld3QbSxLRQlrg1K62wkt4qmIqTR1sDqMlLa1nKQrT0O8t9Lb/HDWy69mb/YJikWo9WyeZpi31d8mi9n66W0qTBLbxqTYZSdwQFgnckscLmY810EC++gmCBOD8Vm7G1SxTb2ErM1PpBw3R+7s8P0g7k/mSRfg8KqCLw8sixBjj/UYwMdKZDYZjYKpSjSsIUVbYrA1s5z0LKF/p557wDVRxF/hWCFddI4b5oc9RMr8TJ9G4TRXXAbxBw82R0FdNqd8zkIlinDfnpR9JJSz32IgiI7d4Zy3k7OPsHt5NpCvtLKfaVFC515G4r8ugZt5Y32GLSiLEiH19afFn7kx4vot5opRwaq+Pov+9hmm3NEvIlpsfQSjSlIfe6xkVIxWVc27uGNlb1Pb0zKpCYnXwVwFfDUxrLIWEpHl8dTm+Op/BhEJhLzgYNdHAGXidvAhTak22DFVpQ2iFzsZWNlECJzQyuDELSmdJYQg7AAxIgBQwd1RfZAhxKIy8UIikIMYB3t9qGlRhWIxiuF7uJvuZBbHRSja0aMESEO95mW7QP4JqioI1wxe23gE+C1EFm4hyFpktV6ysV9nRbBHODHM3e18sdlqN4fHe4iOJxJuCawKyutfC0SoQi22wKRaRV3EhUG1mCc0ukCh0gCSb2S09ge07dWrmJOAswJovVvXZaIElqjJTYnWlJzfeKu7rZtEooKGUspGcOZZqS1lQfv9GoZI9p3J5T3UcpAlRloBVQVzbOc7UabQG4vfPqweKpZVxcEXDOCpHQj/J7sgSWrmWbmjkT4tDX+98Ku0iI3/g3w5MvvGRR3oixyYJB3hNDM3+gfoauYkBHQzpmeJTktWx6/zuFc1/UmSF+/O/dCP6ZpEnR7pdLWac11QvoU5MRi2tAk1HQsopvENlkBhMS0hvba2NOophOqm+2WEdG4GSqS3AkLNGYQVlVWwl1hVlzA/Razk4Vao+lXlOdMNFqIj2rr8HVJvAfMHlj/cTHz/PCY5HJxa00xL5xowNpgbXNXXHiSwkZnQevGsfHvEYVpdNoIj+h1kbHKlZyATLF1gPm9kgpWUCKivbMCagouvfFD6EfJj/+vpiCJjwI1YVCki0RWUcFH6nrzx5tf82Pt+uXqw4uvf/9ngFTTyU4hKO2Uwq41whkZdcUudyetZs2AlMgEynyk70XV/FFt0NQwlftDly4OXTpE16uTPKLRhbT/vAN0mf2hy6Si0KVz6IJDKHtHFzLN4R2gq8d4mE1EoctUXzO+ocoKcejKWit6iSERUxS8Yn9KeXwhgzbeAcB6DVIyQxjAiKU+wJpF+vC604/u3J8lv/HUmz16iSONwCF5n7nhE2/qPqwdfM4TL7rwuxP3okmROJw4h5DAgkT+VuKqyHFQ0EagqBH+bVPDIL6wTxGo2LDcSYN56LpQ2baw9YYUvoPtHegn0qcBREFGyGlbEkOhoa7JypPBR7aK5Z9IuzYrveDVGQIcy3yMs5kq7CB8KbPUigrCFae/uDvJFko1RkO/JfXVJhIp09Lhgj5tkQLDnJ0DpVkVp/pAaRFUlAkU6Em1tnNgxLJzoDSrzFQfKC3igzKBAmM6WtueFhh87Bwo0ltOsMq1WkDAd9FSCgdOVneUmX1tKykJbG2yJFX6ck8suKEPBRky6O1NS6M28WSZ7jlMj2mwDqo+DEGJY9fiCO08EoOUPE6G5S3N4pCimMtkcwmq1j4TNKrrIqW5L85Z752IrDddP5QVSK6LU1NTUEJox4G1vtw8hPqpLVBAZsM7CeuohAXN2TOjcEJaHgpXDwDNgul05cmRjH3MgxAUuOy2IZDU7opvLpvF9eDAVnazrQcBB/vbknqRBzo0M4yKXoAB/I2VF4CInp3mu+VK+j5KIrYLgr6V+JywSsF9AyObN5/t2w9XMPB1UHXhVCQDGIxLV5zP/RCni+QB0jHT03whCbZ4WUNFXeNJGxKSFRvIqMfew/Tm6wAuA1nDKAbwkbdRr/3ynHs2veKKigv2WWfy7S9k1HHZQmkUw+hHCagVezfgFPjW64FbWZKyxNwTV/RSMqhHBE/oxmHbLEfcNqDyPtMAFgzet7Vl9kFJ+JwHuJeKYAii+9MrEElp44DmnF8GeuWH2qYFWEq//NfP7NOImF+d6fFyNvluzZ//OckGF1YXomrNF4iwQh+4kzzhxpXUDwcBG1rWPgtwD19TK5fhsBPYcMrP536IIXiAF7ri0BpZEW2v64W78oNFTNL/Gl8P+I4PM1sCXfS94rynknh/FITef1xPJR2IhFFkev52o+Bu2I4VfAibnr+Z7PeeWW7DjX/6XucNc+rZyKBW5hQ6fGjPflVW0w2r9jKn0tipXSX/5tJh3J0MSdlV/otoSci9l2wYiv6G0Ziq0ueNkLpJIcGaoFQRV3RgwR6N1tNtoY27m3YrvggEZy4Ws2igy2I+7TFhzq4O36Yao6XuYwM1BnmLWS7dKrLMgpa2lPc16BWm9L259W7A9c6t0trOtkEgKCTVXkBnuwtfmL1yBNReYfKWHSFR4oQwUE3Tu/vLZO0ilu1reRm5i4kbTuKXx95yFrwkW8ptiLZ69/vKWcAx3k2y7A0Q2aRRcQmQffqkqHkwpYKlTsoHtu7lyRsbiz4wuMRu611A4NTH2glvYQkN4algsZCqKqn414DKgUBonzOGt+Lm9svGlPAW0LeCKaKYYQ1NGs4abr1LzKBmVlcYpoR3iwrG1DtBFIU4aBsW5FVf15pPeFupAER1UlTeola8U0i11ny8NSVrCwdQPr79IrnFJ8L7W0UgtkHB378GshBnreu+ObVKJI19325JDr9IKmIzOqmF2E4ad1oUL8lELAyLtpaxrCMRS+ATdyJiDeE9u2/EzFQLrnBXJw5kteFqdiRfOctDsHi9n59/oP/c3/99duP+TY9/XWnfrvbUxqm0t+WxN4pOFrf+Qr0dPuAgwC73tbz3rgYnx19v/Ke/L67/Yk/u6s8/kE1SykRPxa6WyfFzN4q5vVgfoRrjhA7lhNVesioiF3ZT8raVAe0HEMNeU2jEifM/UXZTjt3rtMzX5W3oTjx3pOCmOCaQprtNirrYFAelIh++XlNxk9maBQrKHUe3hrqT+yuSNNsVuUBSiw4RSSSNqD1sOdKqr+ZaeyQ/r9jPu/tgcvj8h0bPZs9tpiqJm77vDEE1rdlWPiH3MiTNkcAeu6J3AHs6wbtYoshENpRINhI7WUyDmKqb9PXOcikWNygmBwwwd820kW2mMFkKXTdhy54PiB4H44eEqBsTTlFCwmpBE5WgXRISGcxcJjmrysD20kgRq8wE7prd1luzzIobSTbJGg4hVn5il2qj1+EMFb1t3HQ7UbAhUBr3mMIR74bgIBQOw563fLNAG4TjsOxA3SFJjTpG880RZVq/wbQLJxtrmDKOObxKEGT0QfXTWvpJ2HFp3xc56BN3OZcCB34Pu9EJH1TXMfqqVGZb3WtJAh/3wGWB0k7BJzy7uss42cTOGQBkqFm0kQnQehPt0pZqRcwCQnRtaFq7gIhdBKKjDa3cp1ZbfJuF23KOuexwH58KfTMzD9vLRBmjGWDg1mndLMKFgF8dYHkFauj93ejC+cxujw5PRxdWzIQLs2FOIENLISlQxEoOSLSe7GJ6XnYlfae0XHi1FlZltl/BRizLhfUyBxCUWbK2fo1pVNxIlAWYTVbIos7F2B3vuZl22fmvdoNQ7DdzxkVifyc2rUZycy/K8+hFf2uPW8YSWvQGuDrMBjsuDm1Ht5hp67Fs1YEeH0jcHq2MpsVYMTENlTNssLoGT7Ch2SAReen5vf3hxlpd3oz0P//85l9ff7k8qaODdmQjNciWawU7oGzievZ0fAArZeJPzLHtjaZyCM2PYt+Gg/NzT7ACAK7bRxilKUJppco5NsmWWOKGK0G3VHkxEpOCJNeAISAhWpersVlqQaBWRGN8LZyLWkqybHn0oSQtKJdbK0kQUR4wSaFruMHkQLTNhrKIt9k+HY7H3mp1FKMnDGZKL3cLUgxTvg6y2EUkElFyNhsnIccEbrS4M7cx6wSW2RWcLZxKuaH3JzcICLW3rruObzRkEKBEUkEItYo7J2XBK1GiA9+Iird+rt2ZP4nJHywULT2IfSdoRaLFB5KKt/CpEf1urtLMYxa4LXSP1gGhYBRR+2mxum4MtdxfUXwQLSsaEt5tATPdjFaEhODeQ1UX6HCfycYXlM7PF9UBkglsJUY8d6BF9T7XDYMVIQyKxdabTkrcUJ1b7BXD8vlna34FEayCUUNJ2ryhjfE/88L/Zi1nIILhJ4aMm5I2dvfLsXXz+c/g9OH387fJ4PP/zj4OFmicT7XoU6wCdA4lfVuBDt/8xbFSWisRysr+UifdNtli1mEZtvvJV4OKl9YqjtLyG4nLpzjknyv9ULdv/Bk5vfn58KDfROrLh03nz8Jdru6CSDkpQQjYM6fLhkOUobyU6HCzQKvV7iViIs21C6crvc5sJEcfgsUBZfdEbx1cInAAK3crUa1G0GvUBUelz61r7Xz6OzC//fX5aHp6vfg9XaLqUCnJtU5MZ6P4FJJZsOGzS5GFcrK/gPgrBZe+qaLKbbtUtbdA+12Xypq78hKtbK30IdBMSoaWuYt90aK149jDbLJg42ZKy0raGnRqb/5fLM+WFUa3gb1GKzZYgt0mVPBMaefbzfnIufp8Hz6xL/oh+X71+Qdacx9LI2ayd5Dh57autpAeTMwJFxG9x9nBx2C+fj2/jI8oTUfD7o+OF0+PX36cni1Xh8aldxuZjzZ9RJyV2LYN3U9Jo/Bc5ZSSDZJ8aDer3iUp+YqT7gPiOUVqAD26DsmJU6R5BVmGLEXbgUChSvt2IHAjS5JDsK9/qe5zVZ3vMLvs/E7ajVAYIdWpuyEGG9n0KfFCFu5MORlF4O4XWT6jELzWuhRSPXQOvtYlEFRbXp3h02tKtj6L0AkIDDitC+wYbA+StIU8gXNrzYod5AkjpRe82r5HmcpXg8CqmkzMbDbFVE7UgKgptlshxSpw5ZmWfXTytZE17UVG7a2Xd0YOgy1FHJfEyQrgJ7ffmpmCFVl3d7jm5TXwiypqX/gnK5MVXdotSB/rbsijDJ8KtIt4ZGJ4icnPtYs4psVcU5BDCwcz7wZ5dTHqDqc85Sj/9zLabGBdc+aVevUULHufPiQRwDyDm8FmDfl4BDYRSkRtRdme9yVa+CL+L5uUCrkJz1W1EIJBp5Eia8aWpKtRuveR4pTddJ+348vApmaEQtiwMFN3hrF1v/0rjnewTH1oaNxMCcF6XTf7jy6gEODd4URJ/4vVs4E15slSz2VzR+Ek2g/uqiDbFRPZFrO42Z8Wpi6JIUluo8Tk9eWWmKoqPwuOprYxi1FW5B6l4p7hyCkVqXYUBqvV0Z3rL9SjJnD7iYO2Z3dJTQWmIgstr+xlQjLIt9LWOztwd9JkZfG5LzIrOmP2PZmoOB+KTgVG5719dOoQnW0jS9ydZHWj8F9kVaBz35NJRScyt7u7kKngiGmZqs37ZmWGTS/lVSDVSpzW6IbdSdydxJWio1Tso8W1UzjRmnBSSJWT1im73uGEZHQul97Yn/rj+OjEW86Cl83eAokFu/KD19rLvfjMBmzxtbByXmxD+xYmdfw2DJI6wB2fYjLcnQUTLznj/w==
\ No newline at end of file
+7Vtbc5s4FP41nkkf3AHEzY+x67Tdbpqsndv2JSODDGoAESHHdn79SiAcA0qTdMGJO3lIQEcCSec7d+EeGMWrzxSm4THxUdQzNH/VA596hqEDy+AXQVkXFMPWrYISUOzLUQ+EKb5HkqhJ6gL7KKsMZIREDKdVokeSBHmsQoOUkmV12JxE1VlTGKAGYerBqEm9xD4L5TYAsB86viAchOXUtmUWPTEsR8utZCH0yXKLBMY9MKKEsOIuXo1QJNhXMqZ47uiR3s3KKErYcx74Gv49PDyLJ1d/wZMr9B0uhj9YX77lDkYLuWO5WLYuWUDJIvGReInWA8NliBmaptATvUuOOqeFLI54S+e3c5IwiaLu8nZzkeWMiDK02iLJRX9GJEaMrvkQ2evakoGlDGmyvdwCxJS0cAsL25FEKIUg2Lz7gU38RnLqBVwzGlw7IzcowfeQYZI0OMg3yqpsyhjlD4xIRCinJCRBgnc4imokGOEg4U2Psw9x+lCwDXPxPJQdMfZ9MY0SlypyOTRyUV1B5RgfrQpYuq0AS1OABbrCynz7Eq7r5m+KuDHoim2Wgm12xKTsJkGFg/btQlix4Yys+hm+x7wbHPIRM0J9RPucnDOKW+lcukUXDWYHFmcLX532cP1QjBM87s9hjKN1MZpPAWMBhJzoJEVczbQpTLJ6V/GqOnUUIUhf9MQXFN0hoWu87zviTFA+tTVKNA8phpH6fVMUEP4S7fwr/zeOyU+sfmPGV9jPEMXzLV5kucAJTuhuKpkprEpfGgjRE6F58RZtBr2bIBfqfo3jhukWs2zfFEy3N6uwA3kt4E5h8ltgP7bwh4k0L4JZVnlp7PfTCOKkuZ5TSlZCZ7JFmhLKxIZQBBlXW7lQLubFWqvrF2QpsWXH2zXPrdsV8LQ1Bru0xnrTdY4no77D5aMEbEZLpKaMUBGfGVoCY5Tl3BNyJRQ5leLAAz9GIY/8WjXq21j3DDCfI9vzGoLBe3xnMNO0tuCy3aobAE24dEcBV2deQAd74D1N/RneUxVzmFZnfGtGHWfICxNhG/bE/lTDxTZgGlRh0q0mTPZObZGttEWG41RskcL1Pe3aCgN2cIyYiB/OVnlAcCQSWphFKMs+tDRDp2bPh8idK82e7bloNm9Lf0FNf1VmTyUZdmeS4Sglw9YGoCXcRouMkZiPQJQSmm3cWi6AmojuREKZ/QlerQ6vaTwT3u68mqsOQlzNaEvxPUqyzAvzSFbjAUqSzREVWv/nqSt4Lp5uZ+UYrYHnJ5RGZB2LbYqF8XXxzOv8dLoVOR4IzHXXMLpFBem+hRwVKgPbAdDuKHYECu+qu7vUMqNZW8w5bmqmItTHcRqJ6H6COJ+wl+d1Wl5V49cpg4kPqd+t+ljI9U0VUK4xA3ZLQLkDUCuRbeKiSpRv7RKpPaiRWbUSma7gmrJEBszO2PZeI3uvkb2pGlnTXr6Xxh4zJ7XKmMJd7rYyZjySjWpNZ7lTt7ibLMFyqngYpXF9tdKXoU4SdGCDJiKncA1nefwisdn7gNJyalG+++qADBqAjAgVPD8m/iJCf0Ky7NSiHFUQbyiY3tlJN2imVtMUeXiOPU71t7MsvstMdfq9h7Jfcw4qFFQJbncoNFOpCbpd4Fz6hb/l//OCBeKbFMFV3T6NVwwlBTpavANt2U0uNdDrnxu8PlLGC5HSTlK2Q1x2UyLa2KhfwKLyHW3AYjuH//x9sZ6dhCs6Z7ffhhSFfdUxVqEjgmHK0P25pT4eFBT8YjytiQQX8lKGMIp5DaOAOxKbLHspuascWxdreLKgrz8NfyCTBSEp2Q1iXlg2yo/P9JYgBrVDN9P5qAgQLBXIVkcgq6oYLYF8tMin9wiHFsMkP4eWVUUWikYuBS8F9Bn6vMFN+xW6bQBquk/rrKp+2JnONs9g2tTZPrBNRSBfplbFacwEBQv5jYk2XnkhTAJhoOsPHZyW2v/hFbX6jZQzHdXpnWs3BWfjJFqXHL0ZLhXbf5vljQqKj2Ld9fn8wKrqf19v4tjV8bwaxWYodURo/A7iL634K6J4Pb2+uQqNH9/WP9OLoTlekiFQfGAujK9lO4OWjlpLi32ME4bzmjtMhL0eLmiSt/e+KNA4cd2cheziBF2JajOezg/QLUvxFR+6TD93isJuigJNT2crdKuzg7vr1XpuWfB8cD2B197l8dWJM3hEuZyBKrJZTC6FHvX533mCRbEmTz8nKL9cEhoJrTnMMiRiq6/CIs7zDy73vkzguoMacurqckfI3QbGdLS8OLq4+3n/Hf1gK+L+q/gFSV5cVsakn4i3kDW2Y5jAABWNt4BLAwQFVC/ABSi+T9adTWb5P5HhzYdfW+V9W79aA+P/AA==7VpLU+M4EP41qYJDpmzLzyMEBubADkOYovao2IqjRba8kgIJv34lWyZ+iCJAnIWBSxy1ZLnVX7/tEZhkqzMGi8UFTRAZOVayGoGTkePYwHPkRVHWFSXy7YqQMpzoRRvCFD8gTbQ0dYkTxFsLBaVE4KJNjGmeo1i0aJAxet9eNqek/dQCpqhHmMaQ9Kk3OBGLiuoA4G8mzhFOF/Wjfc+tZjJYr9ZH4QuY0PsGCZyOwIRRKqp/2WqCiJJeLZi/f9mz9GeOfrk3x6fk+jyGdxfjarPvL7nl8QwM5WK3W2t07yBZaoHps4p1LUFGl3mC1CbWCBzfL7BA0wLGavZe6oykLURG5MiWf+c0F1oJ7FCOt+Rcn/AOMYFWDeD0Sc4QzZBga7lEz4a+BkWrpWPp8X0DZFfTFg18/UAToVas9HHvjezkHy2+F4gS9ER5TW9Rjh+gwDTviVUeVLRlxwWTN0wooUxScpojJVBMSIcECU5zOYylTJGkHyuxYanyR3oiw0miHmMEqw1niZdmaq/4Bc43r4Wg7RsQtAwIgqEAdD+oLdi2+0pjcKKhZOkZZOkTobU8T1ti9f9dKh96PKOrMccPWE6DI7liRlmC2FiSS+nJGFHagZpi6ezAk2KR3Fmb62G1Tgl+PIcZJutqtXwEzBQ6+kE/CyQN0prCnHenqq261AlBkL3ojnNE7pCySjn3F5JCMN7VWKWGRwxDYt5vilIqN7F+/5A/pxn9B5t35JLDMUcMzxuy4KUWKknYYaGFqfzPWLsSNUPQvNrFmsH4Ni01fdyRuOOG1VOafyqh+49c+Km+VnAXMH8V2E8xvnmQFRPIeWvTLBkXBOK8z88loytlM3xZFJQJdSBEoJC2rBmVal7x2uZfkbXG1hPv15Hvx9mA5/022Kff9nu+5vRqMg6kztQgzliN3lRQpjJGx8phhngpUaVryrgLrSIyFRUMylx0p96/if/IAfM58uO4pyxyJgmimWUNCqEftuMF6ENoBwYIBwsXwUcNva69Reg1ZTGuN5Qsw34eiuJFrvzKB/Fd7aR0MOiiNnS214fO36cfi4x+zAmClh8zhNLnQ2Xl/A4ukFD5yPWqTDC+q/IccoI4P9zREwZ1mQlE4dzoMv04RLP5oHYOOnZucpkmbfGH0pba8XTUxbcisCMwJ0suaCZXIMYo449xstRKS6WQqr7lnwZz19kS88HCpG0bMQ9Cy9mVi4gZ5TxelDm0JdOgnM8RU/7hk4AMtgU5HAzkfk/uBBWErjN1dsWY5EsWgr8vp42k9UApgh06zrBQvae0FRgCth3u1R77Pb8SBtdyDaUHzgqiqo0rJIWH47L2tMoeobxOBcwTyJJhDc1DYeKa0AudGfD9IRt+UbfhZ4Qv8PYJ30ft+HleJxuxDVWHqeEH3MFk+dXx++r4vauOX9+zfjX6XuRjOn2+wOBj9trns82NvtJyOrF2r1EV2TKuBqaoGvkBgENGVS9sg+S4niGm7jUl6rfyypQI+KAP0yVcw1mZE2nA/lSUOoWk9X+j5Jgyn2fc97YlZAm374Jn/O2bO007YveExktdWV3AHKaoGnwI3g84UcpClK7J6oLRO5QcPsn7W4wr1YFXLeW3SMSLelB/FGO/t3KjZXJeZKwVvxnKDbtOZXdvdU/nyArxN1sdaFhdPxZWzbsrlC71e0/rdBUvYJ4i3r/p4BLKDAUSsm7qU8Xl59Qn0ClfA1MHOPQN+uQM5sX7r3qUGnh+EO3IU9W6c4FzgcsaTuZT8vd4yfJy/Em6gp67ZVdwuIhtfjsUeJ7hLTe6Kc6GxeY9WaJrqEz220iqtaULTmTyx8urG2VzY1Xa51genKsOgHTM5eWGMqIs7IhzpCLCD1UxzsvPFP5QPMOog6fjGNJjc6x+BaJyuPlkt5xrfPkMTv8D7Vxdc9u4Ff01nkkeqBFJkaIeHdnedLqpM3F3t+3LDkSCEmqKYEAokvbX914C4Lci2ZZkJ5UzscULECDuPTg4F6B95U6Xm18EyRafeESTK2cYba7cmyvHsV3PgR9o2SqL49uesswFi3StyvDA/qLaONTWFYto3qgoOU8ky5rGkKcpDWXDRoTg62a1mCfNXjMypx3DQ0iSrvUPFsmFHobr+lXBR8rmC9O1741UyZKY2noo+YJEfF0zubdX7lRwLtWn5WZKE3SfcYy6725HaflkgqbykBviOP768SP5eLMe/pEH05H/93hh6Va+kWSlR6wfVm6NCwRfpRHFRoZX7of1gkn6kJEQS9cQdbAt5DKBKxs+dh/K9ECFpJuaST/kL5QvqRRbqKJLJ9pfGjKevlxX7g9MlUXd88bPRId8XrZcOQU+aL88wUdOx0cfSE7BAnhfgZde5LCYp1LD3g7wmiXJlCdcFG25EaFBHII9l4I/0lqJHwZ0Fh/H5SO36XNn3HV6OSXrTp+cyudux+c3NEv4domDLKa7FATm+8t83/Q1tSOPjvt8PfHHLvF7onUC348mB/o+OJXvRx3f324kTaO8420wXiPJwtUs4eEjeARMxkG+urxj2H0Rj5rvm4EC94ntv/Bi4JnLf+uaxcXNpl7zZquvdvo/5ysR0v0Ak0TMqdw/+WnUWCe60axFy/Z1ZARNiGTfmktJX7h0c585K9C9MczXRIbrtyKuBqnvqjN/qyHf39OQ8kKnoQI95RifDyivH1A54ykulAWLArj8BALxYSbg01wWwVUWnHQN3PlfV9wUWHmBtmuoYDvZRt2my01D7+hgPoAKt1+m8C2NOXgNiUTx93vTD4xNdWW6PyGvxzH1w15ej8aT2fC72H4Ct4y8RuCDHmpxvS61jE9FLX4HCVMuqqX0HCD4xP4PAu+2qKMn8KVeOkvgx53A32fy3PP/hs5+/tD7k/1z3jnnnA96Qk/T/9AsowlDACRsJgh2dJ4F4LdsLkhEyQylOwxp+JmscryqFbwOPjz816v1iy/dQs2uvk5DGZbTJ0SDc5LG5BWE6IZJrUPVbXCNQtQaDoaOMVRiFC+2tYvPVDAYOxWvpmvNJsk+XRu8oq4dteToM2XtyGsh1m6noyfWtSYrqwH0bykEPyXJeXVtW9Kap3ilZS52dixz/sz3/CMtc247+E4PXQ3PSVd2dzPtzSbONZ5DLzd4zp48medOz1dmrv3QhDVyB27tqynUrM4O5qnpq7uxec71tYa64XcB9wJwvSJo/HGboNobdofDpq3Mzg2U7m7sTwYU51AWek0SatJFiYqnwqndkNtu6NRo6u4v3zElmapt/WFUbPcDHJxhsUsgF7hNVGAqXBCWDjrQyxckw48pl3S/iJmR8HFeQO5+JSEPpdoeEfF4D3cxWaBqMPRaisc7kn4JmpN61LdFM+nJ00925GJ3t2lvKGTqEUvnJgpM5piw0294zou5M8GgqNOwWvBCgpVJknO8J12AWihujAVfFk1hfVCFKJKL7T8O4RXdpvJBn3r+oePeCnt5stNIsp1BT+BPd8Bpd7dld2ctleUBuq/nOTCGoi8d94wKSEsw3gUa6KbMjEJS1JN8TQSuIbpCOmcFMFhcIA2/5QoMMZuvBI160XDkXOp3krCI4NakSqW+wP9b82QW1CZLRJTufFgVH5xr/Vh4tYetfaG+PMt1e/Is2xDK8fHa3U2eImPwJKHi6pyZdxstP/G+sm03cdC3Xo3Pmm53N5avzdphkIBMkzdXnBwWL1HQULHo5A0Gk0hcJMuSbSHYwKEsxOjmpQwRJM1jbPtuthIpPrgSVxzojuiqP/SEby1QVt+rIH1xLvFx/EB394HNNMuzYunYP5G9HRP5ugw/PnlYqBSSa2GDwcmULqFyTWnaFDzVfSnK1NapRgE21tkOHNQYQj19d3l9wXgMMeGZBjXvJ/VIsP4zj9cBrnOqlerQhWp4KuSapbJFUV3BvCTbmmBeZgnVLzqldI1Bo0SCAML4mQAr9tHQ0xxEJF8ypLztewNALcIqkXWwCjMdPaQkyxdclirnZ2K3Mvets1vv24XtPb/nYOQf/uOf9u9/er8+Br/99c87OZre/9r7BqaiAmgf2QbSXZHrXQkz3VcyxhOc9uwvSaTq1FSJeJhbho4sfK3Wsof+2In8mTUG8FoejQKLTCau5ZGYeAENRqM4rPexi5bW2k/XKSANoNXHS+bJVklvO0siAF2W5ACX62FlmHEJmNa2jESYi8IoEDhWLonAXkfBDi40fSYM4yYYsVTiWu/Y3jPAhOXAu2i25DbT7BuxPFQ3tGk5yGStICZLBkqiKLqG/nXOnIOEsHIgZPX2JvBAIdiwlpjP3gUTVa36+V7Vq+aOVbulUCRmTpRdlzEBw0hLQP20aoxYUIuXKvuGXkpltxRml7QiGnKlcUwFnL4f9PxD4rFADs91KZKcmuCN0IDzRNPDUuwOXYY+4a2YZMCEMFr1JPvCB0Ax8/jaHrhBB2yZ7IObjuNzn/tgXXIBzD7AKMfep2rFjKhePGM9nO+KKTBnPTYkhLdNS85xaWl0QdmFlp5CSxfAHEZLD+VmwkpJeqisVPrXFZMMP+PQgbWk9pnEVCvkLH1/LO668MgbgsWFRy6AeRGP/HclWB6pXccrk98LOldgOAphgBH1ziVJerOguLDIBTDPYJFplR4tVznuCM6KVCmhG1a+7V7sQxNRcgslOSuOO0hEMqneij+9MLlQyoVSeijFdi6c8lYQoxz7SRGJPpqYqdMkSefQfPFyFktzFqH1Fk9T6QoPl6D3fJtLip/f3X6ZHi3V6VUueBRb2VqnE+iOqwP/akHnFKHnrGH3+1xO82Sh79e4Pb/nZMFp/zLuAScLcFn93Qj1Xl719zfc2/8B5Vpdc5s4FP01ntl9sAeQkc1jYsftzk43mc1+tH0TcG20kREry7W9v34lEOZDtHbaQjMTMpNwr8QF3XN0dBEZocX2+EaQLHnHY2Ajz4mPI7QceZ6LfE/90Z5T4fGw6xeejaCx6VU5Hul/YJyO8e5pDLtGR8k5kzRrOiOephDJho8IwQ/NbmvOmnfNyAYsx2NEmO39m8YyMcNACFcNb4FukvLW2J8WLVtS9jZD2SUk5oeaC92N0EJwLouz7XEBTKevTMwfK+/tb6ebD+E/y/3jbPWrdD4G4yLY6jmXnMcgIJXfN7SB9xNhe5MwM1Z5KjMo+D6NQQdxRuj2kFAJjxmJdOtBkUb5ErllynLVqQkHQsKxBcCFh3fPGVVkBL4FKU7qOhMlMBgYGvrGPFSQzssuSR3NEjtiaLQ5R64ypU5Msp6ROGQl7pbsQHnUHNqr1H1TFtc8lWYquXNtU8YWnHGRx0Ixgfk6Uv6dFPwJai04mkO47hGHKWoC4c1sJM5zv45E0BcQUwuIJWSMn7Z6mLmuSEGUsHwbIE0AwI19mHUBEOAZIrgDwqEAmQZXAjLvCxDfAuTuKCGNdxYEynmjJV5ZIePRk0qTcpVZw4W5ovr2OUg1QJroqQSK03ttTPzS/GB65sbyWO+5PBmreCKIrSXkGkjUUPheRHCZm5KIDXwpHuqGuAahiw1cAhiR9FPzgbswNOEeOM3nwbEUziZdEG7RoBiTuaq+mrQCYXwhUDFoK1BOqfMYv55luJtlO8pTvXbnIqwYh5nK+20o1NlG5ogXHj09G2TE/+552TDe5RS8UR1cLzsWl5n2MtBPMNlMVIe73xfqV7rmKmtacgr5/7m8jxpbcavy9j0uC+s14KhzWYhnQeg4farQ1G+wYd4hQsi3RWjWlwjNLHosuKiW5yGY8Y6+Vjaglsh0sOFcmA3ChrnFhvtMDq0USwhfKR9wcFkdvCHVIejgA6QfIcuAUc0KRkNB9I2GWT/+zDaCxEBC/eKghuQ8kP1OW7WGH0MaX/90vmnkh4lQ8xfHgOIy9roq3vmQ8lKW14OWvEcqTcVbXKZsXfKOnYnjlY6q7NXGqWY8gKBq8CBeeAXtXVlBB8NV0NNW4fuVBfTUb/HYbb8i91xBu67F2l9SxYiUsGEr6HbxXD7FD1om195nlkkcYh/3uUyiNiO8DmVzBlU2e3/wxb7M1xRRZ7mhiG7wbEV8KcrmfoY0L1napmiCakez+htbm7J9C529Vzvk8lyjovNFFvbNuAGZhGdtKWtvN17PpXa5NzR77A3mV8kedKVeeQPKVVNYzlR5LsfagVA7UN8Us7fMV7Qow6rPF06cf9ZQHPGcfOdCJno/KydalBCaTiw+7hKS6dOUS7hcGIUketrkPLzfS/UaDMYfE/F0r66iMqfaxPFbVZTfZ000b07/addeUtCxd9Db9ybX3kxaaJA4Y6p2GLJw/oswGhO9j/U6t5Vct8mNLmrMvk+1rMzqO38x7av/l0B3/wM=3Vptd6I4FP41ftTDi0T8WLW2e2Z72jPuzO7stwhBMg2EE2LV+fWbhKBAqLYdtNvacyq5JCF57nNvngR77jTZ3jCYxXc0RKTnWOG25856jmO7niO+pGVXWBxge4VlxXCoax0MC/wLaaOlrWscorxWkVNKOM7qxoCmKQp4zQYZo5t6tYiS+lMzuEKGYRFAYlr/xiGP9TRcFxxu3CK8istHA29Y3ElgWVtPJY9hSDcVk3vdc6eMUl5cJdspIhK+Epii3fyZu/uRMZTylzT4kdhf6M3V5PvMSh8W87t4HFz13aKXJ0jWesZ6sHxXQsDoOg2R7MTquZNNjDlaZDCQdzfC68IW84SIki0uzUHpcT4hxtG2YtKDvEE0QZztRBV9d6zx0pTxdHFzgN8vq8RV5EucoXb5at/zARRxoXFpx+jOt0fw53Jxvfnm+OtkuJ2TX33bwGgCcyQsgu9rgdJvARbRlGva274sY0KmlFCm+nJDiPwoEPacM/qIKndA4KNl1A3kQ7eOuTMyQd+HZBX08bkwdwzMZygjdJfISapw5wyKeP897OtYIzv00KgN6zEYuRC0eOsM2A+H3suw98+F/dDA/nrLURrmBtrCeCWTrCgtCQ0eBSLCVAIEiuIcy8crf1SwrztKwMd2/8jCwCuLP3RNVZhtqzVnO116Fv+crlmAThOMQ7ZC/HTwo7C2TpjerHjLBtozDBHI8VN9KWlzl+7ugWLF7m2Z+erMcEHD48Ukdatq5m90BMCJjgoUjI4Ue/ZzfDuhvHZC5ZimcqFUWdQkV5dpNIoQCFrTaDgaL62jVHpFKI/qOPtmFrXHnhnJow4ieTa+nVlfJ3jJJ+wLf/r5DXxNW1auKWWHleszYO7apzF3WrJnF5jH/ZvJ/fy7u0tu/wLhMkHen/MWzO8z/tmYDkoaP4+6yF8XRN3UC/cZSv9FWYYIltgTvGRQP+hs2Hvyr1WsqY/uoWIvPh1FQmO56O/VWdUr/iVjwdxdnF9JbDHXQqJoJspSSfStgeWUhoOakIVdpfCAGBZzR+wSwuTYjqwqTI4x/l2EybChJ96oS4Zeg7F2cz/RnTBpxdAUJn+kwvcpJBfL1pHzTLYGS+CBjrK128TZuaAyaUUevENmeGMoVzKKBLmWUezxqzPK+TOD9wkyw9AduJVPXW30jbOe7vJEK/KmurjkOlbhnHWUbi+i1v+NMmDUTE7Ng42Xk6YpgC5Mk/c4ODkXTY4dhlQz0LFM9T4ZqJ4r9qR4LZuaHbnNjs5MJlObzHEhTA6Hn1aoDkUFGxxL7TB5LHf3ilJBDOXGp0G8PIaZvEwpR6fVyxIGjytFuPs1F/sopO0hZI/3ohXmilMDy2tIHa8j4QKeceYp3dLFuXSrV3zDKzMkNpohTlelDzDP5X4TPcl3YVM5COmS4o1BxXUBlJUhyalsk8ZCJqiGEaOJ6krWF2pQClF1ZkOFc5nZlZlcPpaPR9ZoUPdy2ysfx2rZt9pNedGZm8eGm6/2OwL5PAW7fGzhXYlqVjgH8Q1Cad3rh3apjNTGyYTyMTb2HYOeAwiXDhL3wUpeLcTsqhsTAZCaiiaRGEFEWaKeI7Pvdt9lAFU9TjeQhfm+QrrCimU4UrSV//KCWRFerZlMKx+aWrbVOBxsIZbrXpRY5YBqR7IikCkhiH2Gk0G7sde85HlsO+LmgexVmT4V6jo+8nrSzUX+Zip4VN7Na3HHZbiJkCc7JVgEoDiQZ7z5fh1mMM0j2fd8uWapHHghLqgIUqirfujY8htau+2N8agttOzXO1oUDz+TKPTV4ecm7vV/7V1Zd5vIEv41fpQO3c366NjOODNxxtd27CQvc5CEbBJJyAhv+fUXJJCgusTmbmiPx+fMREKAUNXXtVf1ATuaP/8Rusu7s2DizQ6oNnk+YMcHlFLdoPE/yZGXzRFiE7I5chv6k/TY7sCl/9tLD2rp0Qd/4q0KJ0ZBMIv8ZfHgOFgsvHFUOOaGYfBUPG0azIrfunRvPe7A5did8Udv/El0lx4lmrb74NTzb+/Sr7aN9IORO/51GwYPi/T7Dij7uP7bfDx3s3ul56/u3EnwlDvETg7YURgE0ebV/PnImyXEzci2ue7jnk+3zx16i6jOBRdPj19+nJ4tV4fGpXcbmY82fRwQZ3ObR3f24GW/Y/200UtGofVv9JK7kAP24enOj7zLpTtOPn2KQREfu4vms/TjqT+bHQWzIFxfyxzn6CimCPuwisLgl5f7xBzb3miaXBEsohQWRI/f878r/amPXhh5z7lD6e/8wwvmXhS+xKeknw6MDF0ZKo2Ma087HpuGsTl2l2MvMdODboqr2+3dd7SNX6TkxUn947t56kx+fr6Yfpt9udZ8Yv22BsRqQmqtMamn03H8h5GamcxhEzmkNo0ipQcUIbStIYR2NFmENqsJHS/GZfIyIVEVncMgciM/WMRvB47GE35EJpOphhGeaBZzPDmE13U6NKwiyskw++056luOOdQcjAGOPbSkoV2TK1gmrmdPUbTLFCzMKqLdNBG0mwjat1rgNYT+uQityf3LcfAtXD5S/fhp7n8fGHLpPJ16Ji5VJpYz0jQ5dCa6WST0VqDnCE1RsWIIIPRfbProui/2/enPyPxOHp/D8/MY0UyuAPfIxPAsjNSOaTHXlEXqIqUdxlOaMA0hNWOySO00Eh7NKd2P8NCBqkyMTF5aM1nSA6W0UUNXvk58TOke8WGOTEMSprcYfgH0yxFa1zFCS4M0kUvnWHLYEx2js01HzJRE54GpAetPx6SHRhFSby8VTmrKkfoo/unec3RAzVn87R9GYYHw5v1D4oOtCTRYrSl0GJ9A9OXzmkzZ5/Gr2+Tfr8vb0J147ii+/nVSSQJHdGChDJjOc8RB+CFNb2IGiunOE1rMUrIW3ml+zKxwmhAtwU364W3h1OydCHZ+Ork4oprSTCUcUy1kmRldchXTG+px9cyL3In7DtY9rQMQDYl3SAMIH+1Yc+Qd8GJAoFakiAwmuFKUxA0+zJdww7JIQ36wPfxINawUtjBBbHEAV2yEKZj1LY0pSIzkcDz2VquEmmEwE8QblZkCo4cYTzpdKIQ31M/dh1VCPJXpOKDMqKYk5vLIoyRvhyeU9M6CyYOCUptZRQI6jtE3FPl4U2LPXD0L0qGKMmKg20VOEFOzhjWZYUljhs7L6ofoLgj93+vkgKLEJAYIhRiIYUix6J48WPMOIWcZpgCNfQZF6WoZUFr0rrh4jywlq/bhIVQVn4apGh0pb5RduzN/klvlF/F/J4tbf+F9SpzahTtTjq4OMKwYkv/elmB0Q1fesPrgKmsNEOooB0zenjp5jrzFZMVRLz54mJTGxO9Gs2D8K6ZJfCgjkbl5+9FPvn9N30KyO0/4mIDhy7f0o/Wb78knsTZO3x4/5888fknfQY54z370bX2lZaRvv2cXxq93d0neZDfZy8ZV8BCOvRrKOnLDWy8qOzFlljcpFAnxsMhzPeNw6M1iofDoFZ4NY3t6u/Mg1mc5iG3LIlKI6bAiYvM708t26OHuxICO12G6aEMH7kYxRtyX3GnL5IRVgyceGFrpgxFSfkH8YvMMu1WxpXn7hcJ4u/no7OrwKtGEscSJ/zkK5vNgoZzQsUDSm+iYE9ep1NZ5s/dkMQ1iWM49ZY0zAgNwuPBGoqHy6IjV2UF793LhLld3QbSxLRQlrg1K62wkt4qmIqTR1sDqMlLa1nKQrT0O8t9Lb/HDWy69mb/YJikWo9WyeZpi31d8mi9n66W0qTBLbxqTYZSdwQFgnckscLmY810EC++gmCBOD8Vm7G1SxTb2ErM1PpBw3R+7s8P0g7k/mSRfg8KqCLw8sixBjj/UYwMdKZDYZjYKpSjSsIUVbYrA1s5z0LKF/p557wDVRxF/hWCFddI4b5oc9RMr8TJ9G4TRXXAbxBw82R0FdNqd8zkIlinDfnpR9JJSz32IgiI7d4Zy3k7OPsHt5NpCvtLKfaVFC515G4r8ugZt5Y32GLSiLEiH19afFn7kx4vot5opRwaq+Pov+9hmm3NEvIlpsfQSjSlIfe6xkVIxWVc27uGNlb1Pb0zKpCYnXwVwFfDUxrLIWEpHl8dTm+Op/BhEJhLzgYNdHAGXidvAhTak22DFVpQ2iFzsZWNlECJzQyuDELSmdJYQg7AAxIgBQwd1RfZAhxKIy8UIikIMYB3t9qGlRhWIxiuF7uJvuZBbHRSja0aMESEO95mW7QP4JqioI1wxe23gE+C1EFm4hyFpktV6ysV9nRbBHODHM3e18sdlqN4fHe4iOJxJuCawKyutfC0SoQi22wKRaRV3EhUG1mCc0ukCh0gCSb2S09ge07dWrmJOAswJovVvXZaIElqjJTYnWlJzfeKu7rZtEooKGUspGcOZZqS1lQfv9GoZI9p3J5T3UcpAlRloBVQVzbOc7UabQG4vfPqweKpZVxcEXDOCpHQj/J7sgSWrmWbmjkT4tDX+98Ku0iI3/g3w5MvvGRR3oixyYJB3hNDM3+gfoauYkBHQzpmeJTktWx6/zuFc1/UmSF+/O/dCP6ZpEnR7pdLWac11QvoU5MRi2tAk1HQsopvENlkBhMS0hvba2NOophOqm+2WEdG4GSqS3AkLNGYQVlVWwl1hVlzA/Razk4Vao+lXlOdMNFqIj2rr8HVJvAfMHlj/cTHz/PCY5HJxa00xL5xowNpgbXNXXHiSwkZnQevGsfHvEYVpdNoIj+h1kbHKlZyATLF1gPm9kgpWUCKivbMCagouvfFD6EfJj/+vpiCJjwI1YVCki0RWUcFH6nrzx5tf82Pt+uXqw4uvf/9ngFTTyU4hKO2Uwq41whkZdcUudyetZs2AlMgEynyk70XV/FFt0NQwlftDly4OXTpE16uTPKLRhbT/vAN0mf2hy6Si0KVz6IJDKHtHFzLN4R2gq8d4mE1EoctUXzO+ocoKcejKWit6iSERUxS8Yn9KeXwhgzbeAcB6DVIyQxjAiKU+wJpF+vC604/u3J8lv/HUmz16iSONwCF5n7nhE2/qPqwdfM4TL7rwuxP3okmROJw4h5DAgkT+VuKqyHFQ0EagqBH+bVPDIL6wTxGo2LDcSYN56LpQ2baw9YYUvoPtHegn0qcBREFGyGlbEkOhoa7JypPBR7aK5Z9IuzYrveDVGQIcy3yMs5kq7CB8KbPUigrCFae/uDvJFko1RkO/JfXVJhIp09Lhgj5tkQLDnJ0DpVkVp/pAaRFUlAkU6Em1tnNgxLJzoDSrzFQfKC3igzKBAmM6WtueFhh87Bwo0ltOsMq1WkDAd9FSCgdOVneUmX1tKykJbG2yJFX6ck8suKEPBRky6O1NS6M28WSZ7jlMj2mwDqo+DEGJY9fiCO08EoOUPE6G5S3N4pCimMtkcwmq1j4TNKrrIqW5L85Z752IrDddP5QVSK6LU1NTUEJox4G1vtw8hPqpLVBAZsM7CeuohAXN2TOjcEJaHgpXDwDNgul05cmRjH3MgxAUuOy2IZDU7opvLpvF9eDAVnazrQcBB/vbknqRBzo0M4yKXoAB/I2VF4CInp3mu+VK+j5KIrYLgr6V+JywSsF9AyObN5/t2w9XMPB1UHXhVCQDGIxLV5zP/RCni+QB0jHT03whCbZ4WUNFXeNJGxKSFRvIqMfew/Tm6wAuA1nDKAbwkbdRr/3ynHs2veKKigv2WWfy7S9k1HHZQmkUw+hHCagVezfgFPjW64FbWZKyxNwTV/RSMqhHBE/oxmHbLEfcNqDyPtMAFgzet7Vl9kFJ+JwHuJeKYAii+9MrEElp44DmnF8GeuWH2qYFWEq//NfP7NOImF+d6fFyNvluzZ//OckGF1YXomrNF4iwQh+4kzzhxpXUDwcBG1rWPgtwD19TK5fhsBPYcMrP536IIXiAF7ri0BpZEW2v64W78oNFTNL/Gl8P+I4PM1sCXfS94rynknh/FITef1xPJR2IhFFkev52o+Bu2I4VfAibnr+Z7PeeWW7DjX/6XucNc+rZyKBW5hQ6fGjPflVW0w2r9jKn0tipXSX/5tJh3J0MSdlV/otoSci9l2wYiv6G0Ziq0ueNkLpJIcGaoFQRV3RgwR6N1tNtoY27m3YrvggEZy4Ws2igy2I+7TFhzq4O36Yao6XuYwM1BnmLWS7dKrLMgpa2lPc16BWm9L259W7A9c6t0trOtkEgKCTVXkBnuwtfmL1yBNReYfKWHSFR4oQwUE3Tu/vLZO0ilu1reRm5i4kbTuKXx95yFrwkW8ptiLZ69/vKWcAx3k2y7A0Q2aRRcQmQffqkqHkwpYKlTsoHtu7lyRsbiz4wuMRu611A4NTH2glvYQkN4algsZCqKqn414DKgUBonzOGt+Lm9svGlPAW0LeCKaKYYQ1NGs4abr1LzKBmVlcYpoR3iwrG1DtBFIU4aBsW5FVf15pPeFupAER1UlTeola8U0i11ny8NSVrCwdQPr79IrnFJ8L7W0UgtkHB378GshBnreu+ObVKJI19325JDr9IKmIzOqmF2E4ad1oUL8lELAyLtpaxrCMRS+ATdyJiDeE9u2/EzFQLrnBXJw5kteFqdiRfOctDsHi9n59/oP/c3/99duP+TY9/XWnfrvbUxqm0t+WxN4pOFrf+Qr0dPuAgwC73tbz3rgYnx19v/Ke/L67/Yk/u6s8/kE1SykRPxa6WyfFzN4q5vVgfoRrjhA7lhNVesioiF3ZT8raVAe0HEMNeU2jEifM/UXZTjt3rtMzX5W3oTjx3pOCmOCaQprtNirrYFAelIh++XlNxk9maBQrKHUe3hrqT+yuSNNsVuUBSiw4RSSSNqD1sOdKqr+ZaeyQ/r9jPu/tgcvj8h0bPZs9tpiqJm77vDEE1rdlWPiH3MiTNkcAeu6J3AHs6wbtYoshENpRINhI7WUyDmKqb9PXOcikWNygmBwwwd820kW2mMFkKXTdhy54PiB4H44eEqBsTTlFCwmpBE5WgXRISGcxcJjmrysD20kgRq8wE7prd1luzzIobSTbJGg4hVn5il2qj1+EMFb1t3HQ7UbAhUBr3mMIR74bgIBQOw563fLNAG4TjsOxA3SFJjTpG880RZVq/wbQLJxtrmDKOObxKEGT0QfXTWvpJ2HFp3xc56BN3OZcCB34Pu9EJH1TXMfqqVGZb3WtJAh/3wGWB0k7BJzy7uss42cTOGQBkqFm0kQnQehPt0pZqRcwCQnRtaFq7gIhdBKKjDa3cp1ZbfJuF23KOuexwH58KfTMzD9vLRBmjGWDg1mndLMKFgF8dYHkFauj93ejC+cxujw5PRxdWzIQLs2FOIENLISlQxEoOSLSe7GJ6XnYlfae0XHi1FlZltl/BRizLhfUyBxCUWbK2fo1pVNxIlAWYTVbIos7F2B3vuZl22fmvdoNQ7DdzxkVifyc2rUZycy/K8+hFf2uPW8YSWvQGuDrMBjsuDm1Ht5hp67Fs1YEeH0jcHq2MpsVYMTENlTNssLoGT7Ch2SAReen5vf3hxlpd3oz0P//85l9ff7k8qaODdmQjNciWawU7oGzievZ0fAArZeJPzLHtjaZyCM2PYt+Gg/NzT7ACAK7bRxilKUJppco5NsmWWOKGK0G3VHkxEpOCJNeAISAhWpersVlqQaBWRGN8LZyLWkqybHn0oSQtKJdbK0kQUR4wSaFruMHkQLTNhrKIt9k+HY7H3mp1FKMnDGZKL3cLUgxTvg6y2EUkElFyNhsnIccEbrS4M7cx6wSW2RWcLZxKuaH3JzcICLW3rruObzRkEKBEUkEItYo7J2XBK1GiA9+Iird+rt2ZP4nJHywULT2IfSdoRaLFB5KKt/CpEf1urtLMYxa4LXSP1gGhYBRR+2mxum4MtdxfUXwQLSsaEt5tATPdjFaEhODeQ1UX6HCfycYXlM7PF9UBkglsJUY8d6BF9T7XDYMVIQyKxdabTkrcUJ1b7BXD8vlna34FEayCUUNJ2ryhjfE/88L/Zi1nIILhJ4aMm5I2dvfLsXXz+c/g9OH387fJ4PP/zj4OFmicT7XoU6wCdA4lfVuBDt/8xbFSWisRysr+UifdNtli1mEZtvvJV4OKl9YqjtLyG4nLpzjknyv9ULdv/Bk5vfn58KDfROrLh03nz8Jdru6CSDkpQQjYM6fLhkOUobyU6HCzQKvV7iViIs21C6crvc5sJEcfgsUBZfdEbx1cInAAK3crUa1G0GvUBUelz61r7Xz6OzC//fX5aHp6vfg9XaLqUCnJtU5MZ6P4FJJZsOGzS5GFcrK/gPgrBZe+qaLKbbtUtbdA+12Xypq78hKtbK30IdBMSoaWuYt90aK149jDbLJg42ZKy0raGnRqb/5fLM+WFUa3gb1GKzZYgt0mVPBMaefbzfnIufp8Hz6xL/oh+X71+Qdacx9LI2ayd5Dh57autpAeTMwJFxG9x9nBx2C+fj2/jI8oTUfD7o+OF0+PX36cni1Xh8aldxuZjzZ9RJyV2LYN3U9Jo/Bc5ZSSDZJ8aDer3iUp+YqT7gPiOUVqAD26DsmJU6R5BVmGLEXbgUChSvt2IHAjS5JDsK9/qe5zVZ3vMLvs/E7ajVAYIdWpuyEGG9n0KfFCFu5MORlF4O4XWT6jELzWuhRSPXQOvtYlEFRbXp3h02tKtj6L0AkIDDitC+wYbA+StIU8gXNrzYod5AkjpRe82r5HmcpXg8CqmkzMbDbFVE7UgKgptlshxSpw5ZmWfXTytZE17UVG7a2Xd0YOgy1FHJfEyQrgJ7ffmpmCFVl3d7jm5TXwiypqX/gnK5MVXdotSB/rbsijDJ8KtIt4ZGJ4icnPtYs4psVcU5BDCwcz7wZ5dTHqDqc85Sj/9zLabGBdc+aVevUULHufPiQRwDyDm8FmDfl4BDYRSkRtRdme9yVa+CL+L5uUCrkJz1W1EIJBp5Eia8aWpKtRuveR4pTddJ+348vApmaEQtiwMFN3hrF1v/0rjnewTH1oaNxMCcF6XTf7jy6gEODd4URJ/4vVs4E15slSz2VzR+Ek2g/uqiDbFRPZFrO42Z8Wpi6JIUluo8Tk9eWWmKoqPwuOprYxi1FW5B6l4p7hyCkVqXYUBqvV0Z3rL9SjJnD7iYO2Z3dJTQWmIgstr+xlQjLIt9LWOztwd9JkZfG5LzIrOmP2PZmoOB+KTgVG5719dOoQnW0jS9ydZHWj8F9kVaBz35NJRScyt7u7kKngiGmZqs37ZmWGTS/lVSDVSpzW6IbdSdydxJWio1Tso8W1UzjRmnBSSJWT1im73uGEZHQul97Yn/rj+OjEW86Cl83eAokFu/KD19rLvfjMBmzxtbByXmxD+xYmdfw2DJI6wB2fYjLcnQUTLznj/w==
\ No newline at end of file
diff --git a/doc/schema/drawio/architecture_simplified.png b/doc/schema/drawio/architecture_simplified.png
new file mode 100644
index 00000000..46a48cc4
Binary files /dev/null and b/doc/schema/drawio/architecture_simplified.png differ
diff --git a/doc/schema/surya_graph/surya_graph_0_CMTATBaseCommon.sol.png b/doc/schema/surya_graph/surya_graph_0_CMTATBaseCommon.sol.png
index 73bcbdef..c628a23c 100644
Binary files a/doc/schema/surya_graph/surya_graph_0_CMTATBaseCommon.sol.png and b/doc/schema/surya_graph/surya_graph_0_CMTATBaseCommon.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_0_CMTATBaseCore.sol.png b/doc/schema/surya_graph/surya_graph_0_CMTATBaseCore.sol.png
index b388b3ba..3e9f2bbb 100644
Binary files a/doc/schema/surya_graph/surya_graph_0_CMTATBaseCore.sol.png and b/doc/schema/surya_graph/surya_graph_0_CMTATBaseCore.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_0_CMTATBaseSnapshot.sol.png b/doc/schema/surya_graph/surya_graph_0_CMTATBaseSnapshot.sol.png
new file mode 100644
index 00000000..9fb83fe2
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_0_CMTATBaseSnapshot.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_1_CMTATBaseAccessControl.sol.png b/doc/schema/surya_graph/surya_graph_1_CMTATBaseAccessControl.sol.png
deleted file mode 100644
index f15017d2..00000000
Binary files a/doc/schema/surya_graph/surya_graph_1_CMTATBaseAccessControl.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_1_CMTATBaseDocument.sol.png b/doc/schema/surya_graph/surya_graph_1_CMTATBaseDocument.sol.png
new file mode 100644
index 00000000..5b4fa6b1
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_1_CMTATBaseDocument.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_2_CMTATBaseAccessControl.sol.png b/doc/schema/surya_graph/surya_graph_2_CMTATBaseAccessControl.sol.png
new file mode 100644
index 00000000..d71dff99
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_2_CMTATBaseAccessControl.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_2_CMTATBaseAllowlist.sol.png b/doc/schema/surya_graph/surya_graph_2_CMTATBaseAllowlist.sol.png
deleted file mode 100644
index a543408b..00000000
Binary files a/doc/schema/surya_graph/surya_graph_2_CMTATBaseAllowlist.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_2_CMTATBaseRuleEngine.sol.png b/doc/schema/surya_graph/surya_graph_2_CMTATBaseRuleEngine.sol.png
deleted file mode 100644
index 5efe3ce4..00000000
Binary files a/doc/schema/surya_graph/surya_graph_2_CMTATBaseRuleEngine.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_3_CMTATBaseAllowlist.sol.png b/doc/schema/surya_graph/surya_graph_3_CMTATBaseAllowlist.sol.png
new file mode 100644
index 00000000..ef680934
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_3_CMTATBaseAllowlist.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_3_CMTATBaseDebt.sol.png b/doc/schema/surya_graph/surya_graph_3_CMTATBaseDebt.sol.png
deleted file mode 100644
index 71bd75ff..00000000
Binary files a/doc/schema/surya_graph/surya_graph_3_CMTATBaseDebt.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_3_CMTATBaseRuleEngine.sol.png b/doc/schema/surya_graph/surya_graph_3_CMTATBaseRuleEngine.sol.png
new file mode 100644
index 00000000..f32e7147
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_3_CMTATBaseRuleEngine.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_4_CMTATBaseDebt.sol.png b/doc/schema/surya_graph/surya_graph_4_CMTATBaseDebt.sol.png
new file mode 100644
index 00000000..e2a5e816
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_4_CMTATBaseDebt.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_3_CMTATBaseERC1404.sol.png b/doc/schema/surya_graph/surya_graph_4_CMTATBaseERC1404.sol.png
similarity index 100%
rename from doc/schema/surya_graph/surya_graph_3_CMTATBaseERC1404.sol.png
rename to doc/schema/surya_graph/surya_graph_4_CMTATBaseERC1404.sol.png
diff --git a/doc/schema/surya_graph/surya_graph_4_CMTATBaseERC20CrossChain.sol.png b/doc/schema/surya_graph/surya_graph_4_CMTATBaseERC20CrossChain.sol.png
deleted file mode 100644
index 1c7b4cc8..00000000
Binary files a/doc/schema/surya_graph/surya_graph_4_CMTATBaseERC20CrossChain.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_5_CMTATBaseDebtEngine.sol.png b/doc/schema/surya_graph/surya_graph_5_CMTATBaseDebtEngine.sol.png
deleted file mode 100644
index 6f5c5636..00000000
Binary files a/doc/schema/surya_graph/surya_graph_5_CMTATBaseDebtEngine.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_5_CMTATBaseERC20CrossChain.sol.png b/doc/schema/surya_graph/surya_graph_5_CMTATBaseERC20CrossChain.sol.png
new file mode 100644
index 00000000..35e01298
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_5_CMTATBaseERC20CrossChain.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_6_CMTATBaseDebtEngine.sol.png b/doc/schema/surya_graph/surya_graph_6_CMTATBaseDebtEngine.sol.png
new file mode 100644
index 00000000..7a93e394
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_6_CMTATBaseDebtEngine.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_6_CMTATBaseERC1363.sol.png b/doc/schema/surya_graph/surya_graph_6_CMTATBaseERC1363.sol.png
deleted file mode 100644
index 58ffde48..00000000
Binary files a/doc/schema/surya_graph/surya_graph_6_CMTATBaseERC1363.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_6_CMTATBaseERC2612.sol.png b/doc/schema/surya_graph/surya_graph_6_CMTATBaseERC2612.sol.png
new file mode 100644
index 00000000..2701538b
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_6_CMTATBaseERC2612.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_5_CMTATBaseERC2771.sol.png b/doc/schema/surya_graph/surya_graph_6_CMTATBaseERC2771.sol.png
similarity index 100%
rename from doc/schema/surya_graph/surya_graph_5_CMTATBaseERC2771.sol.png
rename to doc/schema/surya_graph/surya_graph_6_CMTATBaseERC2771.sol.png
diff --git a/doc/schema/surya_graph/surya_graph_7_CMTATBaseERC2771Snapshot.sol.png b/doc/schema/surya_graph/surya_graph_7_CMTATBaseERC2771Snapshot.sol.png
new file mode 100644
index 00000000..a581ff45
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_7_CMTATBaseERC2771Snapshot.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_7_CMTATBaseERC7551Enforcement.sol.png b/doc/schema/surya_graph/surya_graph_7_CMTATBaseERC7551Enforcement.sol.png
new file mode 100644
index 00000000..87dc3f76
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_7_CMTATBaseERC7551Enforcement.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_8_CMTATBaseERC1363.sol.png b/doc/schema/surya_graph/surya_graph_8_CMTATBaseERC1363.sol.png
new file mode 100644
index 00000000..112338b3
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_8_CMTATBaseERC1363.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_6_CMTATBaseERC7551.sol.png b/doc/schema/surya_graph/surya_graph_8_CMTATBaseERC7551.sol.png
similarity index 100%
rename from doc/schema/surya_graph/surya_graph_6_CMTATBaseERC7551.sol.png
rename to doc/schema/surya_graph/surya_graph_8_CMTATBaseERC7551.sol.png
diff --git a/doc/schema/surya_graph/surya_graph_CMTATDocumentEngineModuleMock.sol.png b/doc/schema/surya_graph/surya_graph_CMTATDocumentEngineModuleMock.sol.png
new file mode 100644
index 00000000..02a9bb1e
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATDocumentEngineModuleMock.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATEngineInitializerMock.sol.png b/doc/schema/surya_graph/surya_graph_CMTATEngineInitializerMock.sol.png
new file mode 100644
index 00000000..4f7d5f17
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATEngineInitializerMock.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATMsgDataMock.sol.png b/doc/schema/surya_graph/surya_graph_CMTATMsgDataMock.sol.png
new file mode 100644
index 00000000..e4c96ab9
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATMsgDataMock.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATStandalone.sol.png b/doc/schema/surya_graph/surya_graph_CMTATStandalone.sol.png
deleted file mode 100644
index 9720e1ed..00000000
Binary files a/doc/schema/surya_graph/surya_graph_CMTATStandalone.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATStandalonePermit.sol.png b/doc/schema/surya_graph/surya_graph_CMTATStandalonePermit.sol.png
new file mode 100644
index 00000000..2f288846
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATStandalonePermit.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATStandaloneSnapshot.sol.png b/doc/schema/surya_graph/surya_graph_CMTATStandaloneSnapshot.sol.png
new file mode 100644
index 00000000..68c26e7e
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATStandaloneSnapshot.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATStandardStandalone.sol.png b/doc/schema/surya_graph/surya_graph_CMTATStandardStandalone.sol.png
new file mode 100644
index 00000000..58147f94
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATStandardStandalone.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATStandardUpgradeable.sol.png b/doc/schema/surya_graph/surya_graph_CMTATStandardUpgradeable.sol.png
new file mode 100644
index 00000000..50bff74c
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATStandardUpgradeable.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATUpgradeable.sol.png b/doc/schema/surya_graph/surya_graph_CMTATUpgradeable.sol.png
deleted file mode 100644
index 15f6d01a..00000000
Binary files a/doc/schema/surya_graph/surya_graph_CMTATUpgradeable.sol.png and /dev/null differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATUpgradeablePermit.sol.png b/doc/schema/surya_graph/surya_graph_CMTATUpgradeablePermit.sol.png
new file mode 100644
index 00000000..dceba0d6
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATUpgradeablePermit.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_CMTATUpgradeableSnapshot.sol.png b/doc/schema/surya_graph/surya_graph_CMTATUpgradeableSnapshot.sol.png
new file mode 100644
index 00000000..0c0c426f
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_CMTATUpgradeableSnapshot.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_DebtEngineModule.sol.png b/doc/schema/surya_graph/surya_graph_DebtEngineModule.sol.png
index e6f9e615..a07a8fc7 100644
Binary files a/doc/schema/surya_graph/surya_graph_DebtEngineModule.sol.png and b/doc/schema/surya_graph/surya_graph_DebtEngineModule.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_DocumentERC1643Module.sol.png b/doc/schema/surya_graph/surya_graph_DocumentERC1643Module.sol.png
new file mode 100644
index 00000000..0ef43333
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_DocumentERC1643Module.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_DocumentEngineModule.sol.png b/doc/schema/surya_graph/surya_graph_DocumentEngineModule.sol.png
index c908982c..e59c9e37 100644
Binary files a/doc/schema/surya_graph/surya_graph_DocumentEngineModule.sol.png and b/doc/schema/surya_graph/surya_graph_DocumentEngineModule.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ERC1404ExtendInterfaceId.sol.png b/doc/schema/surya_graph/surya_graph_ERC1404ExtendInterfaceId.sol.png
new file mode 100644
index 00000000..5b4fa6b1
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_ERC1404ExtendInterfaceId.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ERC20CrossChainModule.sol.png b/doc/schema/surya_graph/surya_graph_ERC20CrossChainModule.sol.png
index ce95f63a..04ea9b9a 100644
Binary files a/doc/schema/surya_graph/surya_graph_ERC20CrossChainModule.sol.png and b/doc/schema/surya_graph/surya_graph_ERC20CrossChainModule.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ERC20EnforcementERC7551Module.sol.png b/doc/schema/surya_graph/surya_graph_ERC20EnforcementERC7551Module.sol.png
new file mode 100644
index 00000000..4a341a3a
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_ERC20EnforcementERC7551Module.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ERC20EnforcementModule.sol.png b/doc/schema/surya_graph/surya_graph_ERC20EnforcementModule.sol.png
index 8a362232..e69de29b 100644
Binary files a/doc/schema/surya_graph/surya_graph_ERC20EnforcementModule.sol.png and b/doc/schema/surya_graph/surya_graph_ERC20EnforcementModule.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ERC20EnforcementModuleInternal.sol.png b/doc/schema/surya_graph/surya_graph_ERC20EnforcementModuleInternal.sol.png
index 513e4407..ecce6521 100644
Binary files a/doc/schema/surya_graph/surya_graph_ERC20EnforcementModuleInternal.sol.png and b/doc/schema/surya_graph/surya_graph_ERC20EnforcementModuleInternal.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ERC721MockUpgradeable.sol.png b/doc/schema/surya_graph/surya_graph_ERC721MockUpgradeable.sol.png
index d18eb334..00010446 100644
Binary files a/doc/schema/surya_graph/surya_graph_ERC721MockUpgradeable.sol.png and b/doc/schema/surya_graph/surya_graph_ERC721MockUpgradeable.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_EnforcementModuleInternal.sol.png b/doc/schema/surya_graph/surya_graph_EnforcementModuleInternal.sol.png
index 82dca335..0db2e1de 100644
Binary files a/doc/schema/surya_graph/surya_graph_EnforcementModuleInternal.sol.png and b/doc/schema/surya_graph/surya_graph_EnforcementModuleInternal.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_IRuleTransferHook.sol.png b/doc/schema/surya_graph/surya_graph_IRuleTransferHook.sol.png
new file mode 100644
index 00000000..408db6b2
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_IRuleTransferHook.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_PauseModule.sol.png b/doc/schema/surya_graph/surya_graph_PauseModule.sol.png
index 782c0ee7..c0b9e540 100644
Binary files a/doc/schema/surya_graph/surya_graph_PauseModule.sol.png and b/doc/schema/surya_graph/surya_graph_PauseModule.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_RuleEngineInterfaceId.sol.png b/doc/schema/surya_graph/surya_graph_RuleEngineInterfaceId.sol.png
new file mode 100644
index 00000000..5b4fa6b1
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_RuleEngineInterfaceId.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_RuleSpenderAuthorized.sol.png b/doc/schema/surya_graph/surya_graph_RuleSpenderAuthorized.sol.png
new file mode 100644
index 00000000..7ff42d33
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_RuleSpenderAuthorized.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_RuleTokenHolderTracker.sol.png b/doc/schema/surya_graph/surya_graph_RuleTokenHolderTracker.sol.png
new file mode 100644
index 00000000..bf7aac1a
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_RuleTokenHolderTracker.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_SnapshotEngineModule.sol.png b/doc/schema/surya_graph/surya_graph_SnapshotEngineModule.sol.png
index e46427c1..5c8434bb 100644
Binary files a/doc/schema/surya_graph/surya_graph_SnapshotEngineModule.sol.png and b/doc/schema/surya_graph/surya_graph_SnapshotEngineModule.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ValidationModule.sol.png b/doc/schema/surya_graph/surya_graph_ValidationModule.sol.png
index 5419b9c4..e83950e9 100644
Binary files a/doc/schema/surya_graph/surya_graph_ValidationModule.sol.png and b/doc/schema/surya_graph/surya_graph_ValidationModule.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ValidationModuleAllowance.sol.png b/doc/schema/surya_graph/surya_graph_ValidationModuleAllowance.sol.png
new file mode 100644
index 00000000..1d808a6b
Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_ValidationModuleAllowance.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ValidationModuleAllowlist.sol.png b/doc/schema/surya_graph/surya_graph_ValidationModuleAllowlist.sol.png
index 46615da3..9f2131e1 100644
Binary files a/doc/schema/surya_graph/surya_graph_ValidationModuleAllowlist.sol.png and b/doc/schema/surya_graph/surya_graph_ValidationModuleAllowlist.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_ValidationModuleRuleEngine.sol.png b/doc/schema/surya_graph/surya_graph_ValidationModuleRuleEngine.sol.png
index 4f7df43c..3134263f 100644
Binary files a/doc/schema/surya_graph/surya_graph_ValidationModuleRuleEngine.sol.png and b/doc/schema/surya_graph/surya_graph_ValidationModuleRuleEngine.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_draft-IERC1643.sol.png b/doc/schema/surya_graph/surya_graph_draft-IERC1643.sol.png
index f6ae1821..48dab804 100644
Binary files a/doc/schema/surya_graph/surya_graph_draft-IERC1643.sol.png and b/doc/schema/surya_graph/surya_graph_draft-IERC1643.sol.png differ
diff --git a/doc/schema/surya_graph/surya_graph_draft-IERC7943.sol.png b/doc/schema/surya_graph/surya_graph_draft-IERC7943.sol.png
index fd0437d9..df6fc941 100644
Binary files a/doc/schema/surya_graph/surya_graph_draft-IERC7943.sol.png and b/doc/schema/surya_graph/surya_graph_draft-IERC7943.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseCommon.sol.png b/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseCommon.sol.png
index db03c9d3..b29cb31d 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseCommon.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseCommon.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseCore.sol.png b/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseCore.sol.png
index fc4e3ff6..9093439b 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseCore.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseCore.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseGeneric.sol.png b/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseGeneric.sol.png
index b4254562..df82ddcd 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseGeneric.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseGeneric.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseSnapshot.sol.png b/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseSnapshot.sol.png
new file mode 100644
index 00000000..d956b7a4
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_0_CMTATBaseSnapshot.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_1_CMTATBaseAccessControl.sol.png b/doc/schema/surya_inheritance/surya_inheritance_1_CMTATBaseAccessControl.sol.png
deleted file mode 100644
index 4d6db777..00000000
Binary files a/doc/schema/surya_inheritance/surya_inheritance_1_CMTATBaseAccessControl.sol.png and /dev/null differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_1_CMTATBaseDocument.sol.png b/doc/schema/surya_inheritance/surya_inheritance_1_CMTATBaseDocument.sol.png
new file mode 100644
index 00000000..2c3a7a89
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_1_CMTATBaseDocument.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_2_CMTATBaseAccessControl.sol.png b/doc/schema/surya_inheritance/surya_inheritance_2_CMTATBaseAccessControl.sol.png
new file mode 100644
index 00000000..3de7a730
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_2_CMTATBaseAccessControl.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_2_CMTATBaseAllowlist.sol.png b/doc/schema/surya_inheritance/surya_inheritance_2_CMTATBaseAllowlist.sol.png
deleted file mode 100644
index 68852f1d..00000000
Binary files a/doc/schema/surya_inheritance/surya_inheritance_2_CMTATBaseAllowlist.sol.png and /dev/null differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseAllowlist.sol.png b/doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseAllowlist.sol.png
new file mode 100644
index 00000000..5c2f3185
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseAllowlist.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseDebt.sol.png b/doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseDebt.sol.png
deleted file mode 100644
index a3d3d12f..00000000
Binary files a/doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseDebt.sol.png and /dev/null differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_2_CMTATBaseRuleEngine.sol.png b/doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseRuleEngine.sol.png
similarity index 100%
rename from doc/schema/surya_inheritance/surya_inheritance_2_CMTATBaseRuleEngine.sol.png
rename to doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseRuleEngine.sol.png
diff --git a/doc/schema/surya_inheritance/surya_inheritance_4_CMTATBaseDebt.sol.png b/doc/schema/surya_inheritance/surya_inheritance_4_CMTATBaseDebt.sol.png
new file mode 100644
index 00000000..01737f63
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_4_CMTATBaseDebt.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseERC1404.sol.png b/doc/schema/surya_inheritance/surya_inheritance_4_CMTATBaseERC1404.sol.png
similarity index 100%
rename from doc/schema/surya_inheritance/surya_inheritance_3_CMTATBaseERC1404.sol.png
rename to doc/schema/surya_inheritance/surya_inheritance_4_CMTATBaseERC1404.sol.png
diff --git a/doc/schema/surya_inheritance/surya_inheritance_5_CMTATBaseDebtEngine.sol.png b/doc/schema/surya_inheritance/surya_inheritance_5_CMTATBaseDebtEngine.sol.png
deleted file mode 100644
index faa08796..00000000
Binary files a/doc/schema/surya_inheritance/surya_inheritance_5_CMTATBaseDebtEngine.sol.png and /dev/null differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_4_CMTATBaseERC20CrossChain.sol.png b/doc/schema/surya_inheritance/surya_inheritance_5_CMTATBaseERC20CrossChain.sol.png
similarity index 100%
rename from doc/schema/surya_inheritance/surya_inheritance_4_CMTATBaseERC20CrossChain.sol.png
rename to doc/schema/surya_inheritance/surya_inheritance_5_CMTATBaseERC20CrossChain.sol.png
diff --git a/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseDebtEngine.sol.png b/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseDebtEngine.sol.png
new file mode 100644
index 00000000..70568b31
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseDebtEngine.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC1363.sol.png b/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC1363.sol.png
deleted file mode 100644
index b47ac467..00000000
Binary files a/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC1363.sol.png and /dev/null differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC2612.sol.png b/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC2612.sol.png
new file mode 100644
index 00000000..ca9a5eb9
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC2612.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_5_CMTATBaseERC2771.sol.png b/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC2771.sol.png
similarity index 100%
rename from doc/schema/surya_inheritance/surya_inheritance_5_CMTATBaseERC2771.sol.png
rename to doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC2771.sol.png
diff --git a/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC7551.sol.png b/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC7551.sol.png
deleted file mode 100644
index 90860613..00000000
Binary files a/doc/schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC7551.sol.png and /dev/null differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_7_CMTATBaseERC2771Snapshot.sol.png b/doc/schema/surya_inheritance/surya_inheritance_7_CMTATBaseERC2771Snapshot.sol.png
new file mode 100644
index 00000000..8a8c745a
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_7_CMTATBaseERC2771Snapshot.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_7_CMTATBaseERC7551Enforcement.sol.png b/doc/schema/surya_inheritance/surya_inheritance_7_CMTATBaseERC7551Enforcement.sol.png
new file mode 100644
index 00000000..bc9ea565
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_7_CMTATBaseERC7551Enforcement.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_8_CMTATBaseERC1363.sol.png b/doc/schema/surya_inheritance/surya_inheritance_8_CMTATBaseERC1363.sol.png
new file mode 100644
index 00000000..10fbb5dc
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_8_CMTATBaseERC1363.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_8_CMTATBaseERC7551.sol.png b/doc/schema/surya_inheritance/surya_inheritance_8_CMTATBaseERC7551.sol.png
new file mode 100644
index 00000000..9d889cb2
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_8_CMTATBaseERC7551.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATDocumentEngineModuleMock.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATDocumentEngineModuleMock.sol.png
new file mode 100644
index 00000000..91bfc469
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATDocumentEngineModuleMock.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATEngineInitializerMock.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATEngineInitializerMock.sol.png
new file mode 100644
index 00000000..79e21fb8
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATEngineInitializerMock.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATMsgDataMock.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATMsgDataMock.sol.png
new file mode 100644
index 00000000..56ca5b79
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATMsgDataMock.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandalone.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandalone.sol.png
deleted file mode 100644
index 9288629e..00000000
Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandalone.sol.png and /dev/null differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandalonePermit.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandalonePermit.sol.png
new file mode 100644
index 00000000..ba4cf2a7
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandalonePermit.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandaloneSnapshot.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandaloneSnapshot.sol.png
new file mode 100644
index 00000000..9e1aad97
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandaloneSnapshot.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardStandalone.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardStandalone.sol.png
new file mode 100644
index 00000000..94c37a4f
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardStandalone.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardUpgradeable.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardUpgradeable.sol.png
new file mode 100644
index 00000000..a34d5a5e
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardUpgradeable.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeable.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeable.sol.png
deleted file mode 100644
index 7a8bdc74..00000000
Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeable.sol.png and /dev/null differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeablePermit.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeablePermit.sol.png
new file mode 100644
index 00000000..2bac1d96
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeablePermit.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableSnapshot.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableSnapshot.sol.png
new file mode 100644
index 00000000..c99b7e1f
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableSnapshot.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTAT_PROXY_TEST.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTAT_PROXY_TEST.sol.png
index 0e721fde..c1785bbd 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTAT_PROXY_TEST.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_CMTAT_PROXY_TEST.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_DocumentERC1643Module.sol.png b/doc/schema/surya_inheritance/surya_inheritance_DocumentERC1643Module.sol.png
new file mode 100644
index 00000000..6f267fcf
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_DocumentERC1643Module.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_ERC1404ExtendInterfaceId.sol.png b/doc/schema/surya_inheritance/surya_inheritance_ERC1404ExtendInterfaceId.sol.png
new file mode 100644
index 00000000..b65b55d7
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_ERC1404ExtendInterfaceId.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementERC7551Module.sol.png b/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementERC7551Module.sol.png
new file mode 100644
index 00000000..11e7efb6
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementERC7551Module.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementModule.sol.png b/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementModule.sol.png
index 1d67a5dc..d13f7037 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementModule.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementModule.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementModuleInternal.sol.png b/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementModuleInternal.sol.png
index 6fa12da4..b22652b9 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementModuleInternal.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_ERC20EnforcementModuleInternal.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_IERC3643Partial.sol.png b/doc/schema/surya_inheritance/surya_inheritance_IERC3643Partial.sol.png
index 95f51f5f..77dd687c 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_IERC3643Partial.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_IERC3643Partial.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_IRuleTransferHook.sol.png b/doc/schema/surya_inheritance/surya_inheritance_IRuleTransferHook.sol.png
new file mode 100644
index 00000000..1827c9b2
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_IRuleTransferHook.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_RuleEngineInterfaceId.sol.png b/doc/schema/surya_inheritance/surya_inheritance_RuleEngineInterfaceId.sol.png
new file mode 100644
index 00000000..674b4dfb
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_RuleEngineInterfaceId.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_RuleSpenderAuthorized.sol.png b/doc/schema/surya_inheritance/surya_inheritance_RuleSpenderAuthorized.sol.png
new file mode 100644
index 00000000..cfd9f187
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_RuleSpenderAuthorized.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_RuleTokenHolderTracker.sol.png b/doc/schema/surya_inheritance/surya_inheritance_RuleTokenHolderTracker.sol.png
new file mode 100644
index 00000000..ce3af0ae
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_RuleTokenHolderTracker.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_ValidationModule.sol.png b/doc/schema/surya_inheritance/surya_inheritance_ValidationModule.sol.png
index fe27dc4d..0df0ef5c 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_ValidationModule.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_ValidationModule.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_ValidationModuleAllowance.sol.png b/doc/schema/surya_inheritance/surya_inheritance_ValidationModuleAllowance.sol.png
new file mode 100644
index 00000000..47caa93b
Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_ValidationModuleAllowance.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_ValidationModuleRuleEngine.sol.png b/doc/schema/surya_inheritance/surya_inheritance_ValidationModuleRuleEngine.sol.png
index 95d191c1..22deb2f6 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_ValidationModuleRuleEngine.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_ValidationModuleRuleEngine.sol.png differ
diff --git a/doc/schema/surya_inheritance/surya_inheritance_draft-IERC7943.sol.png b/doc/schema/surya_inheritance/surya_inheritance_draft-IERC7943.sol.png
index a8dd2e6c..dd16df1a 100644
Binary files a/doc/schema/surya_inheritance/surya_inheritance_draft-IERC7943.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_draft-IERC7943.sol.png differ
diff --git a/doc/schema/surya_report/surya_report_0_CMTATBaseCommon.sol.md b/doc/schema/surya_report/surya_report_0_CMTATBaseCommon.sol.md
index ff7c5727..9e890052 100644
--- a/doc/schema/surya_report/surya_report_0_CMTATBaseCommon.sol.md
+++ b/doc/schema/surya_report/surya_report_0_CMTATBaseCommon.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/0_CMTATBaseCommon.sol | e9342a8ffa60ec57e4d636ee52e4abab937d3dfa |
+| ./modules/0_CMTATBaseCommon.sol | ef3159d406b8c61dbc2520fb37c0c29c5827d2bc |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseCommon** | Implementation | VersionModule, ERC20MintModule, ERC20BurnModule, ERC20BaseModule, SnapshotEngineModule, ERC20EnforcementModule, DocumentEngineModule, ExtraInformationModule, IBurnMintERC20, IERC5679 |||
+| **CMTATBaseCommon** | Implementation | VersionModule, ERC20MintModule, ERC20BurnModule, ERC20BaseModule, ERC20EnforcementModule, ExtraInformationModule, IBurnMintERC20, IERC5679 |||
| └ | decimals | Public ❗️ | |NO❗️ |
| └ | name | Public ❗️ | |NO❗️ |
| └ | symbol | Public ❗️ | |NO❗️ |
@@ -23,7 +23,6 @@
| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
| └ | burnAndMint | Public ❗️ | 🛑 |NO❗️ |
| └ | _checkTransferred | Internal 🔒 | 🛑 | |
-| └ | _update | Internal 🔒 | 🛑 | |
| └ | _mintOverride | Internal 🔒 | 🛑 | |
| └ | _burnOverride | Internal 🔒 | 🛑 | |
| └ | _minterTransferOverride | Internal 🔒 | 🛑 | |
diff --git a/doc/schema/surya_report/surya_report_0_CMTATBaseCore.sol.md b/doc/schema/surya_report/surya_report_0_CMTATBaseCore.sol.md
index 6bc2e996..d85109f6 100644
--- a/doc/schema/surya_report/surya_report_0_CMTATBaseCore.sol.md
+++ b/doc/schema/surya_report/surya_report_0_CMTATBaseCore.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/0_CMTATBaseCore.sol | 2e7402c9225bdab6f6d450f6fbc4c116c4459b2a |
+| ./modules/0_CMTATBaseCore.sol | 6e879243185b8c9f76fcedb367b2aee8b27ba60e |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseCore** | Implementation | Initializable, ContextUpgradeable, VersionModule, ERC20MintModule, ERC20BurnModule, ValidationModuleCore, ERC20BaseModule, AccessControlModule, IForcedBurnERC20, IBurnMintERC20, IERC7551ERC20EnforcementEvent, IERC5679, IERC7943FungibleTransferError |||
+| **CMTATBaseCore** | Implementation | Initializable, ContextUpgradeable, VersionModule, ERC20MintModule, ERC20BurnModule, ValidationModuleAllowance, ERC20BaseModule, AccessControlModule, IForcedBurnERC20, IBurnMintERC20, IERC7551ERC20EnforcementEvent, IERC5679, IERC7943FungibleTransferError |||
| └ | initialize | Public ❗️ | 🛑 | initializer |
| └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
@@ -25,6 +25,7 @@
| └ | symbol | Public ❗️ | |NO❗️ |
| └ | supportsInterface | Public ❗️ | |NO❗️ |
| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
| └ | burnAndMint | Public ❗️ | 🛑 |NO❗️ |
| └ | forcedBurn | Public ❗️ | 🛑 | onlyERC20ForcedBurnManager |
diff --git a/doc/schema/surya_report/surya_report_0_CMTATBaseGeneric.sol.md b/doc/schema/surya_report/surya_report_0_CMTATBaseGeneric.sol.md
index 38d79e86..2484b42a 100644
--- a/doc/schema/surya_report/surya_report_0_CMTATBaseGeneric.sol.md
+++ b/doc/schema/surya_report/surya_report_0_CMTATBaseGeneric.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/0_CMTATBaseGeneric.sol | e8e6861bf8be3034cd7e46099eea88c806efda69 |
+| ./modules/0_CMTATBaseGeneric.sol | 2db1ecb2c69ee4f60e17917ff565907e44da1daf |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseGeneric** | Implementation | Initializable, ContextUpgradeable, ValidationModule, VersionModule, DocumentEngineModule, ExtraInformationModule, AccessControlModule |||
+| **CMTATBaseGeneric** | Implementation | Initializable, ContextUpgradeable, ValidationModule, VersionModule, DocumentERC1643Module, ExtraInformationModule, AccessControlModule |||
| └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
diff --git a/doc/schema/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md b/doc/schema/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md
new file mode 100644
index 00000000..0819ad75
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md
@@ -0,0 +1,27 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/0_CMTATBaseSnapshot.sol | a6d54586c8a7ed63bffceed0c7bd1abe35b5e5cd |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseSnapshot** | Implementation | ERC20Upgradeable, SnapshotEngineModule |||
+| └ | _update | Internal 🔒 | 🛑 | |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_1_CMTATBaseDocument.sol.md b/doc/schema/surya_report/surya_report_1_CMTATBaseDocument.sol.md
new file mode 100644
index 00000000..d85f71c1
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_1_CMTATBaseDocument.sol.md
@@ -0,0 +1,26 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/1_CMTATBaseDocument.sol | 6d9a534014f54d5736d99d1dc3f7e6d4ba7cb93d |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseDocument** | Implementation | DocumentERC1643Module |||
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md b/doc/schema/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md
new file mode 100644
index 00000000..6e38fe59
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md
@@ -0,0 +1,35 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/2_CMTATBaseAccessControl.sol | cf934aa8b26c9bdc2aeb336391b3c4098da70c18 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseAccessControl** | Implementation | AccessControlModule, CMTATBaseCommon, CMTATBaseDocument |||
+| └ | __CMTAT_commonModules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
+| └ | supportsInterface | Public ❗️ | |NO❗️ |
+| └ | _authorizeERC20AttributeManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeMint | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeBurn | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeDocumentManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeExtraInfoManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeERC20Enforcer | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeForcedTransfer | Internal 🔒 | 🛑 | onlyRole |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/modules/base/surya_report/surya_report_1_CMTATBaseAllowlist.sol.md b/doc/schema/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md
similarity index 59%
rename from doc/modules/base/surya_report/surya_report_1_CMTATBaseAllowlist.sol.md
rename to doc/schema/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md
index becb961c..93574cec 100644
--- a/doc/modules/base/surya_report/surya_report_1_CMTATBaseAllowlist.sol.md
+++ b/doc/schema/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/1_CMTATBaseAllowlist.sol | a03434fbd8327f1ce333d2d710a1989c3275fbe6 |
+| ./modules/3_CMTATBaseAllowlist.sol | 517b746b223a533ad42e9dad2a49520c1fd14d1f |
### Contracts Description Table
@@ -15,20 +15,34 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseAllowlist** | Implementation | Initializable, ContextUpgradeable, CMTATBaseCommon, ValidationModuleAllowlist, ValidationModuleCore, ERC2771Module |||
+| **CMTATBaseAllowlist** | Implementation | Initializable, ContextUpgradeable, CMTATBaseAccessControl, ValidationModuleAllowlist, ValidationModuleAllowance, ERC2771Module, ERC20EnforcementERC7551Module, IERC7943FungibleTransferError |||
| └ | initialize | Public ❗️ | 🛑 | initializer |
| └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
+| └ | approve | Public ❗️ | 🛑 | whenNotPaused |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
| └ | canTransfer | Public ❗️ | |NO❗️ |
| └ | canTransferFrom | Public ❗️ | |NO❗️ |
| └ | _authorizePause | Internal 🔒 | 🛑 | onlyRole |
| └ | _authorizeDeactivate | Internal 🔒 | 🛑 | onlyRole |
| └ | _authorizeFreeze | Internal 🔒 | 🛑 | onlyRole |
| └ | _authorizeAllowlistManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeERC20Enforcer | Internal 🔒 | 🛑 | |
+| └ | _authorizeForcedTransfer | Internal 🔒 | 🛑 | |
| └ | _canMintBurnByModule | Internal 🔒 | | |
-| └ | _canTransferGenericByModule | Internal 🔒 | | |
+| └ | _canMintByModuleAndRevert | Internal 🔒 | | |
+| └ | _canBurnByModuleAndRevert | Internal 🔒 | | |
+| └ | _canSend | Internal 🔒 | | |
+| └ | _canReceive | Internal 🔒 | | |
+| └ | _canTransferStandardByModule | Internal 🔒 | | |
+| └ | _canTransferStandardByModuleAndRevert | Internal 🔒 | | |
| └ | _checkTransferred | Internal 🔒 | 🛑 | |
+| └ | getFrozenTokens | Public ❗️ | |NO❗️ |
| └ | _msgSender | Internal 🔒 | | |
| └ | _contextSuffixLength | Internal 🔒 | | |
| └ | _msgData | Internal 🔒 | | |
diff --git a/doc/modules/base/surya_report/surya_report_1_CMTATBaseRuleEngine.sol.md b/doc/schema/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md
similarity index 80%
rename from doc/modules/base/surya_report/surya_report_1_CMTATBaseRuleEngine.sol.md
rename to doc/schema/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md
index 2b0d9b11..bc23215b 100644
--- a/doc/modules/base/surya_report/surya_report_1_CMTATBaseRuleEngine.sol.md
+++ b/doc/schema/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/1_CMTATBaseRuleEngine.sol | a8f439a039694270eba59e58d219a64f094a02ca |
+| ./modules/3_CMTATBaseRuleEngine.sol | b9bc5276aceceae7c6224027123f31f4ed47c61b |
### Contracts Description Table
@@ -15,12 +15,14 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseRuleEngine** | Implementation | CMTATBaseCommon, ValidationModuleRuleEngine |||
+| **CMTATBaseRuleEngine** | Implementation | CMTATBaseAccessControl, ValidationModuleRuleEngine, IERC7943FungibleTransferError |||
| └ | initialize | Public ❗️ | 🛑 | initializer |
+| └ | _initialize | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_internal_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
| └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
+| └ | approve | Public ❗️ | 🛑 | whenNotPaused |
| └ | canTransfer | Public ❗️ | |NO❗️ |
| └ | canTransferFrom | Public ❗️ | |NO❗️ |
| └ | _authorizePause | Internal 🔒 | 🛑 | onlyRole |
diff --git a/doc/schema/surya_report/surya_report_4_CMTATBaseDebt.sol.md b/doc/schema/surya_report/surya_report_4_CMTATBaseDebt.sol.md
new file mode 100644
index 00000000..8f161dd7
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_4_CMTATBaseDebt.sol.md
@@ -0,0 +1,35 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/4_CMTATBaseDebt.sol | 593ad8bf57d7bbd52a5ee426a3e0f11d2e2d49c6 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseDebt** | Implementation | CMTATBaseRuleEngine, DebtModule, CMTATBaseSnapshot |||
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+| └ | _update | Internal 🔒 | 🛑 | |
+| └ | _authorizeDebtManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeSnapshots | Internal 🔒 | 🛑 | onlyRole |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_3_CMTATBaseERC1404.sol.md b/doc/schema/surya_report/surya_report_4_CMTATBaseERC1404.sol.md
similarity index 92%
rename from doc/schema/surya_report/surya_report_3_CMTATBaseERC1404.sol.md
rename to doc/schema/surya_report/surya_report_4_CMTATBaseERC1404.sol.md
index 4d4afc25..109c43e4 100644
--- a/doc/schema/surya_report/surya_report_3_CMTATBaseERC1404.sol.md
+++ b/doc/schema/surya_report/surya_report_4_CMTATBaseERC1404.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/3_CMTATBaseERC1404.sol | 480c97434b4fd3b301f436c3c4fc8a7a76dd05dd |
+| ./modules/4_CMTATBaseERC1404.sol | 2f40fd05006c12aae809d94f8db9f500fc0d6eba |
### Contracts Description Table
diff --git a/doc/modules/base/surya_report/surya_report_3_CMTATBaseERC20CrossChain.sol.md b/doc/schema/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md
similarity index 86%
rename from doc/modules/base/surya_report/surya_report_3_CMTATBaseERC20CrossChain.sol.md
rename to doc/schema/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md
index 952cd362..989d2adc 100644
--- a/doc/modules/base/surya_report/surya_report_3_CMTATBaseERC20CrossChain.sol.md
+++ b/doc/schema/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/3_CMTATBaseERC20CrossChain.sol | 7d21beb134346630d07186c7ebb7672af11df4e9 |
+| ./modules/5_CMTATBaseERC20CrossChain.sol | 5900451fe62bc9ac7ae8d5ba8b03c8851206fb60 |
### Contracts Description Table
@@ -16,19 +16,20 @@
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
| **CMTATBaseERC20CrossChain** | Implementation | ERC20CrossChainModule, CCIPModule, CMTATBaseERC1404 |||
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
-| └ | _mintOverride | Internal 🔒 | 🛑 | |
-| └ | _burnOverride | Internal 🔒 | 🛑 | |
-| └ | _minterTransferOverride | Internal 🔒 | 🛑 | |
| └ | decimals | Public ❗️ | |NO❗️ |
| └ | name | Public ❗️ | |NO❗️ |
| └ | symbol | Public ❗️ | |NO❗️ |
| └ | supportsInterface | Public ❗️ | |NO❗️ |
+| └ | _mintOverride | Internal 🔒 | 🛑 | |
+| └ | _burnOverride | Internal 🔒 | 🛑 | |
+| └ | _minterTransferOverride | Internal 🔒 | 🛑 | |
| └ | _authorizeCCIPSetAdmin | Internal 🔒 | 🛑 | onlyRole |
| └ | _checkTokenBridge | Internal 🔒 | 🛑 | whenNotPaused |
| └ | _authorizeBurnFrom | Internal 🔒 | 🛑 | onlyRole whenNotPaused |
-| └ | _update | Internal 🔒 | 🛑 | |
+| └ | _authorizeSelfBurn | Internal 🔒 | 🛑 | onlyRole whenNotPaused |
### Legend
diff --git a/doc/schema/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md b/doc/schema/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md
new file mode 100644
index 00000000..0ad6c074
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md
@@ -0,0 +1,35 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/6_CMTATBaseDebtEngine.sol | bfeb152012d9b39da44296cc36fa90eb0f2b8035 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseDebtEngine** | Implementation | DebtEngineModule, CMTATBaseERC20CrossChain, CMTATBaseSnapshot |||
+| └ | _update | Internal 🔒 | 🛑 | |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+| └ | _authorizeDebtEngineManagement | Internal 🔒 | 🛑 | onlyRole |
+| └ | _authorizeSnapshots | Internal 🔒 | 🛑 | onlyRole |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_6_CMTATBaseERC2612.sol.md b/doc/schema/surya_report/surya_report_6_CMTATBaseERC2612.sol.md
new file mode 100644
index 00000000..80d81a3c
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_6_CMTATBaseERC2612.sol.md
@@ -0,0 +1,34 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/6_CMTATBaseERC2612.sol | 45670849fccf2fa62ef778ee4800b8a0ff0040d9 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseERC2612** | Implementation | CMTATBaseERC20CrossChain, ERC20PermitUpgradeable, MulticallUpgradeable |||
+| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
+| └ | permit | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/modules/base/surya_report/surya_report_4_CMTATBaseERC2771.sol.md b/doc/schema/surya_report/surya_report_6_CMTATBaseERC2771.sol.md
similarity index 91%
rename from doc/modules/base/surya_report/surya_report_4_CMTATBaseERC2771.sol.md
rename to doc/schema/surya_report/surya_report_6_CMTATBaseERC2771.sol.md
index cdef2c5f..a0e88367 100644
--- a/doc/modules/base/surya_report/surya_report_4_CMTATBaseERC2771.sol.md
+++ b/doc/schema/surya_report/surya_report_6_CMTATBaseERC2771.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/4_CMTATBaseERC2771.sol | 18a1e63f5488933e24d4b1c9de1d12ecd30f36af |
+| ./modules/6_CMTATBaseERC2771.sol | f10975c79346dd77a446db967bf938e9de46af36 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md b/doc/schema/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md
new file mode 100644
index 00000000..b0b2ff7d
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md
@@ -0,0 +1,37 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/7_CMTATBaseERC2771Snapshot.sol | 73abac918adab1aa31671e98a0cecb7e6435cd73 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseERC2771Snapshot** | Implementation | CMTATBaseERC2771, CMTATBaseSnapshot |||
+| └ | _update | Internal 🔒 | 🛑 | |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+| └ | _msgSender | Internal 🔒 | | |
+| └ | _msgData | Internal 🔒 | | |
+| └ | _contextSuffixLength | Internal 🔒 | | |
+| └ | _authorizeSnapshots | Internal 🔒 | 🛑 | onlyRole |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md b/doc/schema/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md
new file mode 100644
index 00000000..cebd5a77
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md
@@ -0,0 +1,38 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/7_CMTATBaseERC7551Enforcement.sol | 56d471f72113e2f281ea95c65ff066fd8bd44f7c |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATBaseERC7551Enforcement** | Implementation | CMTATBaseERC2771, ERC20EnforcementERC7551Module |||
+| └ | _authorizeERC20Enforcer | Internal 🔒 | 🛑 | |
+| └ | _authorizeForcedTransfer | Internal 🔒 | 🛑 | |
+| └ | _msgSender | Internal 🔒 | | |
+| └ | _msgData | Internal 🔒 | | |
+| └ | _contextSuffixLength | Internal 🔒 | | |
+| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
+| └ | name | Public ❗️ | |NO❗️ |
+| └ | symbol | Public ❗️ | |NO❗️ |
+| └ | decimals | Public ❗️ | |NO❗️ |
+| └ | getFrozenTokens | Public ❗️ | |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/modules/base/surya_report/surya_report_5_CMTATBaseERC1363.sol.md b/doc/schema/surya_report/surya_report_8_CMTATBaseERC1363.sol.md
similarity index 88%
rename from doc/modules/base/surya_report/surya_report_5_CMTATBaseERC1363.sol.md
rename to doc/schema/surya_report/surya_report_8_CMTATBaseERC1363.sol.md
index 300cf0d1..c291424e 100644
--- a/doc/modules/base/surya_report/surya_report_5_CMTATBaseERC1363.sol.md
+++ b/doc/schema/surya_report/surya_report_8_CMTATBaseERC1363.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/5_CMTATBaseERC1363.sol | dcff19612eb00bcdf0f95c3d310c597a74b41ef9 |
+| ./modules/8_CMTATBaseERC1363.sol | 55f464bf7e8bc8fb2ed679b564f13727f61bbf96 |
### Contracts Description Table
@@ -15,15 +15,15 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseERC1363** | Implementation | ERC1363Upgradeable, CMTATBaseERC2771 |||
+| **CMTATBaseERC1363** | Implementation | ERC1363Upgradeable, CMTATBaseERC7551Enforcement |||
| └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing |
+| └ | approve | Public ❗️ | 🛑 |NO❗️ |
| └ | transfer | Public ❗️ | 🛑 |NO❗️ |
| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ |
| └ | supportsInterface | Public ❗️ | |NO❗️ |
| └ | decimals | Public ❗️ | |NO❗️ |
| └ | name | Public ❗️ | |NO❗️ |
| └ | symbol | Public ❗️ | |NO❗️ |
-| └ | _update | Internal 🔒 | 🛑 | |
| └ | _msgSender | Internal 🔒 | | |
| └ | _contextSuffixLength | Internal 🔒 | | |
| └ | _msgData | Internal 🔒 | | |
diff --git a/doc/schema/surya_report/surya_report_6_CMTATBaseERC7551.sol.md b/doc/schema/surya_report/surya_report_8_CMTATBaseERC7551.sol.md
similarity index 79%
rename from doc/schema/surya_report/surya_report_6_CMTATBaseERC7551.sol.md
rename to doc/schema/surya_report/surya_report_8_CMTATBaseERC7551.sol.md
index 0284e282..83be16aa 100644
--- a/doc/schema/surya_report/surya_report_6_CMTATBaseERC7551.sol.md
+++ b/doc/schema/surya_report/surya_report_8_CMTATBaseERC7551.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/6_CMTATBaseERC7551.sol | c249226e1b95db5af3aea191d0fe51602a1ea6b6 |
+| ./modules/8_CMTATBaseERC7551.sol | ea759e98774152ca4f29fcd2b45e77f401fc6103 |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseERC7551** | Implementation | CMTATBaseERC2771, ERC7551Module |||
+| **CMTATBaseERC7551** | Implementation | CMTATBaseERC7551Enforcement, ERC7551Module |||
| └ | _authorizeExtraInfoManagement | Internal 🔒 | 🛑 | |
diff --git a/doc/schema/surya_report/surya_report_CMTATDocumentEngineModuleMock.sol.md b/doc/schema/surya_report/surya_report_CMTATDocumentEngineModuleMock.sol.md
new file mode 100644
index 00000000..564af7c4
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_CMTATDocumentEngineModuleMock.sol.md
@@ -0,0 +1,29 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./mocks/engine/CMTATDocumentEngineModuleMock.sol | 87644503f36fd2c746bdea200155504741731c62 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATDocumentEngineModuleMock** | Implementation | CMTATBaseCore, DocumentEngineModule |||
+| └ | | Public ❗️ | 🛑 |NO❗️ |
+| └ | initialize | Public ❗️ | 🛑 | initializer |
+| └ | _authorizeDocumentManagement | Internal 🔒 | 🛑 | onlyRole |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_CMTATEngineInitializerMock.sol.md b/doc/schema/surya_report/surya_report_CMTATEngineInitializerMock.sol.md
new file mode 100644
index 00000000..c290d9cb
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_CMTATEngineInitializerMock.sol.md
@@ -0,0 +1,28 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./mocks/engine/CMTATEngineInitializerMock.sol | 639fe248933ed4fb1320877a2ba2115ea7acc60f |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATEngineInitializerMock** | Implementation | CMTATUpgradeableSnapshot |||
+| └ | | Public ❗️ | 🛑 | CMTATUpgradeableSnapshot |
+| └ | initializeWithEngines | Public ❗️ | 🛑 | reinitializer |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_CMTATMsgDataMock.sol.md b/doc/schema/surya_report/surya_report_CMTATMsgDataMock.sol.md
new file mode 100644
index 00000000..8ec23090
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_CMTATMsgDataMock.sol.md
@@ -0,0 +1,44 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./mocks/CMTATMsgDataMock.sol | 717bd7b3aaa6b7b348909cefaca7a40bbb75e8aa |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATStandaloneMsgDataMock** | Implementation | CMTATStandardStandalone |||
+| └ | | Public ❗️ | 🛑 | CMTATStandardStandalone |
+| └ | getMsgData | External ❗️ | 🛑 |NO❗️ |
+||||||
+| **CMTATStandaloneAllowlistMsgDataMock** | Implementation | CMTATStandaloneAllowlist |||
+| └ | | Public ❗️ | 🛑 | CMTATStandaloneAllowlist |
+| └ | getMsgData | External ❗️ | 🛑 |NO❗️ |
+||||||
+| **CMTATStandaloneERC1363MsgDataMock** | Implementation | CMTATStandaloneERC1363 |||
+| └ | | Public ❗️ | 🛑 | CMTATStandaloneERC1363 |
+| └ | getMsgData | External ❗️ | 🛑 |NO❗️ |
+||||||
+| **CMTATUpgradeableERC1363MsgDataMock** | Implementation | CMTATUpgradeableERC1363 |||
+| └ | | Public ❗️ | 🛑 | CMTATUpgradeableERC1363 |
+| └ | getMsgData | External ❗️ | |NO❗️ |
+||||||
+| **CMTATStandaloneSnapshotMsgDataMock** | Implementation | CMTATStandaloneSnapshot |||
+| └ | | Public ❗️ | 🛑 | CMTATStandaloneSnapshot |
+| └ | getMsgData | External ❗️ | 🛑 |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md
index c2e8d0d9..fbe45162 100644
--- a/doc/schema/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/allowlist/CMTATStandaloneAllowlist.sol | 5961f1f083f7d9bdff10caf3eb433cea4b940df8 |
+| ./deployment/allowlist/CMTATStandaloneAllowlist.sol | 33fceec2f171be4d27a5d9babf29dde1ac8b95ca |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneDebt.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneDebt.sol.md
index dfff3705..1b5e9fdc 100644
--- a/doc/schema/surya_report/surya_report_CMTATStandaloneDebt.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATStandaloneDebt.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/debt/CMTATStandaloneDebt.sol | fd00b06c2eea8106b1ec06632ca9d81954be02b4 |
+| ./deployment/debt/CMTATStandaloneDebt.sol | 2f88cd470cf75eba04a65c0db901ae57d0607ca8 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneDebtEngine.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneDebtEngine.sol.md
index 74643d62..255be825 100644
--- a/doc/schema/surya_report/surya_report_CMTATStandaloneDebtEngine.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATStandaloneDebtEngine.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/debtEngine/CMTATStandaloneDebtEngine.sol | d28d0e759d7a972e166b5fc7b8efe6e8fcb69c04 |
+| ./deployment/debtEngine/CMTATStandaloneDebtEngine.sol | 9ab5b185f630b533a61ffd3caf77dfd1b7337e49 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneERC1363.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneERC1363.sol.md
index a151ab4e..74acac5d 100644
--- a/doc/schema/surya_report/surya_report_CMTATStandaloneERC1363.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATStandaloneERC1363.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/ERC1363/CMTATStandaloneERC1363.sol | dd59cc363dc0bc2079d29342ffb167b009cc6002 |
+| ./deployment/ERC1363/CMTATStandaloneERC1363.sol | da970ccf28dcced367bc90c3f85e03075d8fffe3 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneERC7551.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneERC7551.sol.md
index 3677ecff..79f44e2c 100644
--- a/doc/schema/surya_report/surya_report_CMTATStandaloneERC7551.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATStandaloneERC7551.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/ERC7551/CMTATStandaloneERC7551.sol | b3829a4db5e5eb4f4c53031e1dedec1001cc52c6 |
+| ./deployment/ERC7551/CMTATStandaloneERC7551.sol | 1b120e793a8075832b795935ed212914d5a42ac8 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATStandalonePermit.sol.md b/doc/schema/surya_report/surya_report_CMTATStandalonePermit.sol.md
new file mode 100644
index 00000000..d58ec67d
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_CMTATStandalonePermit.sol.md
@@ -0,0 +1,27 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./deployment/permit/CMTATStandalonePermit.sol | bd2f7108a6c38f4782ced0ac404679b25068343c |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATStandalonePermit** | Implementation | CMTATBaseERC2612 |||
+| └ | | Public ❗️ | 🛑 |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/modules/base/surya_report/surya_report_2_CMTATBaseDebt.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md
similarity index 71%
rename from doc/modules/base/surya_report/surya_report_2_CMTATBaseDebt.sol.md
rename to doc/schema/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md
index 074fade3..6b71f591 100644
--- a/doc/modules/base/surya_report/surya_report_2_CMTATBaseDebt.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/2_CMTATBaseDebt.sol | e426d5e5e529f32ab738f8f40eb3365b1c359b65 |
+| ./deployment/snapshot/CMTATStandaloneSnapshot.sol | 5a2b56bc133d7119e798781364a809c2b600e933 |
### Contracts Description Table
@@ -15,8 +15,8 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseDebt** | Implementation | CMTATBaseRuleEngine, DebtEngineModule |||
-| └ | _authorizeDebtManagement | Internal 🔒 | 🛑 | onlyRole |
+| **CMTATStandaloneSnapshot** | Implementation | CMTATBaseERC2771Snapshot |||
+| └ | | Public ❗️ | 🛑 | ERC2771Module |
### Legend
diff --git a/doc/schema/surya_report/surya_report_CMTATStandalone.sol.md b/doc/schema/surya_report/surya_report_CMTATStandardStandalone.sol.md
similarity index 79%
rename from doc/schema/surya_report/surya_report_CMTATStandalone.sol.md
rename to doc/schema/surya_report/surya_report_CMTATStandardStandalone.sol.md
index b1030bbd..644ac46c 100644
--- a/doc/schema/surya_report/surya_report_CMTATStandalone.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATStandardStandalone.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/CMTATStandalone.sol | 9db76271b8ab061cb2028a48b7050efe39d83635 |
+| ./deployment/CMTATStandardStandalone.sol | 5bfd01883b5b2efb0304c154db283d25d1897e2c |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATStandalone** | Implementation | CMTATBaseERC2771 |||
+| **CMTATStandardStandalone** | Implementation | CMTATBaseERC7551Enforcement |||
| └ | | Public ❗️ | 🛑 | ERC2771Module |
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeable.sol.md b/doc/schema/surya_report/surya_report_CMTATStandardUpgradeable.sol.md
similarity index 79%
rename from doc/schema/surya_report/surya_report_CMTATUpgradeable.sol.md
rename to doc/schema/surya_report/surya_report_CMTATStandardUpgradeable.sol.md
index 6c72316a..80d675ad 100644
--- a/doc/schema/surya_report/surya_report_CMTATUpgradeable.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATStandardUpgradeable.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/CMTATUpgradeable.sol | ece48ffc420b1b5575248062ef35c35a9e46fc26 |
+| ./deployment/CMTATStandardUpgradeable.sol | 111c634b1adf563c6c1462c96c5129e0df16a7f2 |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATUpgradeable** | Implementation | CMTATBaseERC2771 |||
+| **CMTATStandardUpgradeable** | Implementation | CMTATBaseERC7551Enforcement |||
| └ | | Public ❗️ | 🛑 | ERC2771Module |
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md
index 63e3227e..15a38759 100644
--- a/doc/schema/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/allowlist/CMTATUpgradeableAllowlist.sol | 1732526cb212c3c28bdb91a268281bc64cb6bc1f |
+| ./deployment/allowlist/CMTATUpgradeableAllowlist.sol | 937c915adc27f04d34800d12c6800b73ac10bcf9 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableDebt.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableDebt.sol.md
index 4d92c42f..4df01a28 100644
--- a/doc/schema/surya_report/surya_report_CMTATUpgradeableDebt.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableDebt.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/debt/CMTATUpgradeableDebt.sol | fa17bc24043bdaa324df02073955e8214eb077b7 |
+| ./deployment/debt/CMTATUpgradeableDebt.sol | 38a5a244bd6afb659810b50f39c78d7ea7df9dfc |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableDebtEngine.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableDebtEngine.sol.md
index 44652732..ee2a0b17 100644
--- a/doc/schema/surya_report/surya_report_CMTATUpgradeableDebtEngine.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableDebtEngine.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/debtEngine/CMTATUpgradeableDebtEngine.sol | 3281a4180d6c3aaa9bf72ba5fb35958c078ef3b8 |
+| ./deployment/debtEngine/CMTATUpgradeableDebtEngine.sol | 4542e03ae84802efbe35a991f883df818ff711da |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableERC1363.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableERC1363.sol.md
index fc555998..3ec619d2 100644
--- a/doc/schema/surya_report/surya_report_CMTATUpgradeableERC1363.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableERC1363.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/ERC1363/CMTATUpgradeableERC1363.sol | 99947fb135aa1478e8faaeda0031230c3d8a079b |
+| ./deployment/ERC1363/CMTATUpgradeableERC1363.sol | b5222a85340412d060e6eb8571b9c88fd22d6302 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableERC7551.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableERC7551.sol.md
index 72ff8c9a..f0f30506 100644
--- a/doc/schema/surya_report/surya_report_CMTATUpgradeableERC7551.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableERC7551.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/ERC7551/CMTATUpgradeableERC7551.sol | 20959d1a0d35311059307f9366f60e66beb6f53c |
+| ./deployment/ERC7551/CMTATUpgradeableERC7551.sol | cd3cc4dcb7a8332128bc4efe1de76a5a3b627dd0 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeablePermit.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeablePermit.sol.md
new file mode 100644
index 00000000..e2e826bb
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_CMTATUpgradeablePermit.sol.md
@@ -0,0 +1,27 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./deployment/permit/CMTATUpgradeablePermit.sol | 875f318122e65ed6ec8bbf8fd6ec510582c56c8b |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATUpgradeablePermit** | Implementation | CMTATBaseERC2612 |||
+| └ | | Public ❗️ | 🛑 |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md
new file mode 100644
index 00000000..d9b44a82
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md
@@ -0,0 +1,27 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./deployment/snapshot/CMTATUpgradeableSnapshot.sol | d8fb75c0bdcf0cd6a53750b0ce9f6261b8c9b3da |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **CMTATUpgradeableSnapshot** | Implementation | CMTATBaseERC2771Snapshot |||
+| └ | | Public ❗️ | 🛑 | ERC2771Module |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md
index 491ccefc..b644ef85 100644
--- a/doc/schema/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./deployment/CMTATUpgradeableUUPS.sol | 3a078291a75791fddd25a110e0500de74c05d356 |
+| ./deployment/CMTATUpgradeableUUPS.sol | b433edf187002f7d33efde3419c07c0b32a101a8 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_CMTAT_PROXY_TEST.sol.md b/doc/schema/surya_report/surya_report_CMTAT_PROXY_TEST.sol.md
index 25160b3f..421d8472 100644
--- a/doc/schema/surya_report/surya_report_CMTAT_PROXY_TEST.sol.md
+++ b/doc/schema/surya_report/surya_report_CMTAT_PROXY_TEST.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./mocks/test/proxy/CMTAT_PROXY_TEST.sol | 39750d80d95a709dabf4dbe75c337588dc4b94c9 |
+| ./mocks/test/proxy/CMTAT_PROXY_TEST.sol | 75c01c5597d04bc00863a78c109d878cadca89e6 |
### Contracts Description Table
@@ -15,8 +15,8 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTAT_PROXY_TEST** | Implementation | CMTATUpgradeable |||
-| └ | | Public ❗️ | 🛑 | CMTATUpgradeable |
+| **CMTAT_PROXY_TEST** | Implementation | CMTATStandardUpgradeable |||
+| └ | | Public ❗️ | 🛑 | CMTATStandardUpgradeable |
### Legend
diff --git a/doc/schema/surya_report/surya_report_DebtEngineModule.sol.md b/doc/schema/surya_report/surya_report_DebtEngineModule.sol.md
index a8725699..b08d9bae 100644
--- a/doc/schema/surya_report/surya_report_DebtEngineModule.sol.md
+++ b/doc/schema/surya_report/surya_report_DebtEngineModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/options/DebtEngineModule.sol | b30b55f3f6cbe7c55f0c7eca58020064ec56be9a |
+| ./modules/wrapper/options/DebtEngineModule.sol | 29a73703471628d0643a7ef88501bac44608562d |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_DebtModule.sol.md b/doc/schema/surya_report/surya_report_DebtModule.sol.md
index 0360d54b..35f3efc3 100644
--- a/doc/schema/surya_report/surya_report_DebtModule.sol.md
+++ b/doc/schema/surya_report/surya_report_DebtModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/options/DebtModule.sol | 9a1410e5d2b6c34a0fad40b7f7f752b9da7b11ce |
+| ./modules/wrapper/options/DebtModule.sol | 9736762f32486a96d64571276dfc4f727815ade0 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_DocumentERC1643Module.sol.md b/doc/schema/surya_report/surya_report_DocumentERC1643Module.sol.md
new file mode 100644
index 00000000..84d99152
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_DocumentERC1643Module.sol.md
@@ -0,0 +1,32 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/wrapper/extensions/DocumentERC1643Module.sol | f8675c688868cd9bdfc0246b3a6e7f310e8e43df |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **DocumentERC1643Module** | Implementation | Initializable, IERC1643 |||
+| └ | getDocument | Public ❗️ | |NO❗️ |
+| └ | getAllDocuments | Public ❗️ | |NO❗️ |
+| └ | setDocument | Public ❗️ | 🛑 | onlyDocumentManager |
+| └ | removeDocument | Public ❗️ | 🛑 | onlyDocumentManager |
+| └ | _authorizeDocumentManagement | Internal 🔒 | 🛑 | |
+| └ | _getDocumentERC1643ModuleStorage | Private 🔐 | | |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_DocumentEngineMock.sol.md b/doc/schema/surya_report/surya_report_DocumentEngineMock.sol.md
index 37a504c6..df25c09d 100644
--- a/doc/schema/surya_report/surya_report_DocumentEngineMock.sol.md
+++ b/doc/schema/surya_report/surya_report_DocumentEngineMock.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./mocks/DocumentEngineMock.sol | 10f35a33f7354343ac75070a0d70bdc6c32e2d88 |
+| ./mocks/DocumentEngineMock.sol | 2f44cd6e8871f3d48ecae589c6c3a8c0555aa009 |
### Contracts Description Table
@@ -22,6 +22,7 @@
| **DocumentEngineMock** | Implementation | IERC1643Whole |||
| └ | getDocument | External ❗️ | |NO❗️ |
| └ | setDocument | External ❗️ | 🛑 |NO❗️ |
+| └ | setDocument | External ❗️ | 🛑 |NO❗️ |
| └ | removeDocument | External ❗️ | 🛑 |NO❗️ |
| └ | getAllDocuments | External ❗️ | |NO❗️ |
diff --git a/doc/schema/surya_report/surya_report_DocumentEngineModule.sol.md b/doc/schema/surya_report/surya_report_DocumentEngineModule.sol.md
index e443c64f..aac50375 100644
--- a/doc/schema/surya_report/surya_report_DocumentEngineModule.sol.md
+++ b/doc/schema/surya_report/surya_report_DocumentEngineModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/extensions/DocumentEngineModule.sol | a96b453eb169a3ac7cd0f614bfb17dfb8eb7fbbe |
+| ./modules/wrapper/options/DocumentEngineModule.sol | a52dc80f2561c58367d49f7194774d2e06ca6c83 |
### Contracts Description Table
@@ -20,6 +20,8 @@
| └ | documentEngine | Public ❗️ | |NO❗️ |
| └ | getDocument | Public ❗️ | |NO❗️ |
| └ | getAllDocuments | Public ❗️ | |NO❗️ |
+| └ | setDocument | Public ❗️ | 🛑 | onlyDocumentManager |
+| └ | removeDocument | Public ❗️ | 🛑 | onlyDocumentManager |
| └ | setDocumentEngine | Public ❗️ | 🛑 | onlyDocumentManager |
| └ | _setDocumentEngine | Internal 🔒 | 🛑 | |
| └ | _authorizeDocumentManagement | Internal 🔒 | 🛑 | |
diff --git a/doc/schema/surya_report/surya_report_ERC1363ReceiverMock.sol.md b/doc/schema/surya_report/surya_report_ERC1363ReceiverMock.sol.md
index d71568d8..97f51bc8 100644
--- a/doc/schema/surya_report/surya_report_ERC1363ReceiverMock.sol.md
+++ b/doc/schema/surya_report/surya_report_ERC1363ReceiverMock.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./mocks/ERC1363ReceiverMock.sol | 8dff9e47540acb071d54410f8b5f9b8762ce929f |
+| ./mocks/ERC1363ReceiverMock.sol | d1f84a7ad0898829c31a52d18c9420908974311e |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_ERC1404ExtendInterfaceId.sol.md b/doc/schema/surya_report/surya_report_ERC1404ExtendInterfaceId.sol.md
new file mode 100644
index 00000000..8aa329ff
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_ERC1404ExtendInterfaceId.sol.md
@@ -0,0 +1,26 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./library/ERC1404ExtendInterfaceId.sol | d800730a47d9f56318fd0345826318a533448308 |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **ERC1404ExtendInterfaceId** | Library | |||
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_ERC20BaseModule.sol.md b/doc/schema/surya_report/surya_report_ERC20BaseModule.sol.md
index db822dd1..2580da93 100644
--- a/doc/schema/surya_report/surya_report_ERC20BaseModule.sol.md
+++ b/doc/schema/surya_report/surya_report_ERC20BaseModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/core/ERC20BaseModule.sol | cab390d71b15a78a4f9cda1a6e00095545de8ef8 |
+| ./modules/wrapper/core/ERC20BaseModule.sol | a0b3a36795491f5bc959177862c02a4665a703c2 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_ERC20BurnModule.sol.md b/doc/schema/surya_report/surya_report_ERC20BurnModule.sol.md
index b5b4cd2b..e41506f3 100644
--- a/doc/schema/surya_report/surya_report_ERC20BurnModule.sol.md
+++ b/doc/schema/surya_report/surya_report_ERC20BurnModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/core/ERC20BurnModule.sol | 29d72656d403fe9ea2843efe91ffcddb5deddd2c |
+| ./modules/wrapper/core/ERC20BurnModule.sol | 557e0b6654ac5f5d442c5186672fbb5cbd03849b |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_ERC20CrossChainModule.sol.md b/doc/schema/surya_report/surya_report_ERC20CrossChainModule.sol.md
index 1a83c9c7..9597fc8c 100644
--- a/doc/schema/surya_report/surya_report_ERC20CrossChainModule.sol.md
+++ b/doc/schema/surya_report/surya_report_ERC20CrossChainModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/options/ERC20CrossChainModule.sol | 629309df46b4679f71c59c2585cd64e1afe6d7b0 |
+| ./modules/wrapper/options/ERC20CrossChainModule.sol | 6c08dc2d19539886ef2dce29828dda6393da3af0 |
### Contracts Description Table
@@ -22,7 +22,7 @@
| └ | burn | Public ❗️ | 🛑 | onlySelfBurn |
| └ | supportsInterface | Public ❗️ | |NO❗️ |
| └ | _burnFrom | Internal 🔒 | 🛑 | |
-| └ | _burn | Internal 🔒 | 🛑 | |
+| └ | _burnFromOperator | Internal 🔒 | 🛑 | |
| └ | _checkTokenBridge | Internal 🔒 | 🛑 | |
| └ | _authorizeBurnFrom | Internal 🔒 | 🛑 | |
| └ | _authorizeSelfBurn | Internal 🔒 | 🛑 | |
diff --git a/doc/schema/surya_report/surya_report_ERC20EnforcementERC7551Module.sol.md b/doc/schema/surya_report/surya_report_ERC20EnforcementERC7551Module.sol.md
new file mode 100644
index 00000000..17b5e492
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_ERC20EnforcementERC7551Module.sol.md
@@ -0,0 +1,31 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./modules/wrapper/options/ERC20EnforcementERC7551Module.sol | 8cb73e41161a89d4d8d4e95547ac9fce6c84cbaa |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **ERC20EnforcementERC7551Module** | Implementation | ERC20EnforcementModule, IERC7551ERC20Enforcement |||
+| └ | getFrozenTokens | Public ❗️ | |NO❗️ |
+| └ | getActiveBalanceOf | Public ❗️ | |NO❗️ |
+| └ | forcedTransfer | Public ❗️ | 🛑 | onlyForcedTransferManager |
+| └ | freezePartialTokens | Public ❗️ | 🛑 | onlyERC20Enforcer |
+| └ | unfreezePartialTokens | Public ❗️ | 🛑 | onlyERC20Enforcer |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_ERC20EnforcementModule.sol.md b/doc/schema/surya_report/surya_report_ERC20EnforcementModule.sol.md
index bfd46083..540464ad 100644
--- a/doc/schema/surya_report/surya_report_ERC20EnforcementModule.sol.md
+++ b/doc/schema/surya_report/surya_report_ERC20EnforcementModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/extensions/ERC20EnforcementModule.sol | 6206454ac2fc86adb14fc2e6a9f8eccd19990701 |
+| ./modules/wrapper/extensions/ERC20EnforcementModule.sol | 289591feebe8af7feae0d3382c4e6af23aa951a7 |
### Contracts Description Table
@@ -15,16 +15,14 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **ERC20EnforcementModule** | Implementation | ERC20EnforcementModuleInternal, IERC7551ERC20Enforcement, IERC3643ERC20Enforcement, IERC7943ERC20EnforcementSpecific |||
+| **ERC20EnforcementModule** | Implementation | ERC20EnforcementModuleInternal, IERC3643ERC20Enforcement, IERC7943FungibleEnforcementSpecific |||
| └ | getFrozenTokens | Public ❗️ | |NO❗️ |
-| └ | getActiveBalanceOf | Public ❗️ | |NO❗️ |
-| └ | forcedTransfer | Public ❗️ | 🛑 | onlyForcedTransferManager |
| └ | forcedTransfer | Public ❗️ | 🛑 | onlyForcedTransferManager |
| └ | freezePartialTokens | Public ❗️ | 🛑 | onlyERC20Enforcer |
| └ | unfreezePartialTokens | Public ❗️ | 🛑 | onlyERC20Enforcer |
| └ | setFrozenTokens | Public ❗️ | 🛑 | onlyERC20Enforcer |
-| └ | freezePartialTokens | Public ❗️ | 🛑 | onlyERC20Enforcer |
-| └ | unfreezePartialTokens | Public ❗️ | 🛑 | onlyERC20Enforcer |
+| └ | _freezeTokensEmitEvents | Internal 🔒 | 🛑 | |
+| └ | _unfreezeTokensEmitEvents | Internal 🔒 | 🛑 | |
| └ | _authorizeERC20Enforcer | Internal 🔒 | 🛑 | |
| └ | _authorizeForcedTransfer | Internal 🔒 | 🛑 | |
diff --git a/doc/schema/surya_report/surya_report_ERC20EnforcementModuleInternal.sol.md b/doc/schema/surya_report/surya_report_ERC20EnforcementModuleInternal.sol.md
index 265a99a1..72887795 100644
--- a/doc/schema/surya_report/surya_report_ERC20EnforcementModuleInternal.sol.md
+++ b/doc/schema/surya_report/surya_report_ERC20EnforcementModuleInternal.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/internal/ERC20EnforcementModuleInternal.sol | 27f44eaac70af6fac87e5ccd29917d399cb6289a |
+| ./modules/internal/ERC20EnforcementModuleInternal.sol | 7b41c597240a14e1121f4484607f9aa1f570c155 |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **ERC20EnforcementModuleInternal** | Implementation | ERC20Upgradeable, IERC7551ERC20EnforcementEvent, IERC7551ERC20EnforcementTokenFrozenEvent, IERC7943FungibleEnforcementEvent |||
+| **ERC20EnforcementModuleInternal** | Implementation | ERC20Upgradeable, IERC7943FungibleEnforcementEventAndError |||
| └ | _setFrozenTokens | Internal 🔒 | 🛑 | |
| └ | _freezePartialTokens | Internal 🔒 | 🛑 | |
| └ | _unfreezePartialTokens | Internal 🔒 | 🛑 | |
diff --git a/doc/schema/surya_report/surya_report_ERC721MockUpgradeable.sol.md b/doc/schema/surya_report/surya_report_ERC721MockUpgradeable.sol.md
index ac796c25..e6a22128 100644
--- a/doc/schema/surya_report/surya_report_ERC721MockUpgradeable.sol.md
+++ b/doc/schema/surya_report/surya_report_ERC721MockUpgradeable.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./mocks/ERC721MockUpgradeable.sol | 5f419987ec55d9a5a87fd44fe60ca6c7ecb3c622 |
+| ./mocks/ERC721MockUpgradeable.sol | d83ab7d6f2e934f059007b1e4e5a462e139a0ac7 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_ERC7551Module.sol.md b/doc/schema/surya_report/surya_report_ERC7551Module.sol.md
index 8f82edc2..33f87f62 100644
--- a/doc/schema/surya_report/surya_report_ERC7551Module.sol.md
+++ b/doc/schema/surya_report/surya_report_ERC7551Module.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/options/ERC7551Module.sol | 94eb7cec5c4edfe9ac01ee51d453f3a2a5fce06a |
+| ./modules/wrapper/options/ERC7551Module.sol | 830414e8ca73ac810caaf673b11e738b825559d4 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_EnforcementModuleInternal.sol.md b/doc/schema/surya_report/surya_report_EnforcementModuleInternal.sol.md
index 81c45f3d..c4a859d5 100644
--- a/doc/schema/surya_report/surya_report_EnforcementModuleInternal.sol.md
+++ b/doc/schema/surya_report/surya_report_EnforcementModuleInternal.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/internal/EnforcementModuleInternal.sol | 588f7cf95b9987ab6d7bd8a89f0b382151a39e53 |
+| ./modules/internal/EnforcementModuleInternal.sol | 0751620527b5e3c99438c1c7c2a2a1679a6180d3 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_ExtraInformationModule.sol.md b/doc/schema/surya_report/surya_report_ExtraInformationModule.sol.md
index 1086830d..fca50d72 100644
--- a/doc/schema/surya_report/surya_report_ExtraInformationModule.sol.md
+++ b/doc/schema/surya_report/surya_report_ExtraInformationModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/extensions/ExtraInformationModule.sol | 680577e18b2a57f51832acafe479a07161315369 |
+| ./modules/wrapper/extensions/ExtraInformationModule.sol | b7f6063f1c7bee208cad4f4af3becc2e590aa6af |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_ICMTAT.sol.md b/doc/schema/surya_report/surya_report_ICMTAT.sol.md
index d1dd30c2..d19858e9 100644
--- a/doc/schema/surya_report/surya_report_ICMTAT.sol.md
+++ b/doc/schema/surya_report/surya_report_ICMTAT.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./interfaces/tokenization/ICMTAT.sol | 1027687f80e8c7e30e8025eb6426aec2b4c1769c |
+| ./interfaces/tokenization/ICMTAT.sol | 442cb59b9909e14766f0912248c7e3839884ced8 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_IERC20Allowance.sol.md b/doc/schema/surya_report/surya_report_IERC20Allowance.sol.md
index 81337aa8..a54d2caa 100644
--- a/doc/schema/surya_report/surya_report_IERC20Allowance.sol.md
+++ b/doc/schema/surya_report/surya_report_IERC20Allowance.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./interfaces/technical/IERC20Allowance.sol | d82b6ed708bf2891f078ae3c3a1c05ed35975758 |
+| ./interfaces/technical/IERC20Allowance.sol | 17476edb94781aa3089e8e5a83f7b6b92760d19c |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_IERC3643Partial.sol.md b/doc/schema/surya_report/surya_report_IERC3643Partial.sol.md
index 01f3e442..f0c61770 100644
--- a/doc/schema/surya_report/surya_report_IERC3643Partial.sol.md
+++ b/doc/schema/surya_report/surya_report_IERC3643Partial.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./interfaces/tokenization/IERC3643Partial.sol | 7a6285d133815b6a9a828f10f837b3c6b6c9dd69 |
+| ./interfaces/tokenization/IERC3643Partial.sol | a37900ea71692f4520d1c92f3dad50e5a732d68d |
### Contracts Description Table
@@ -37,7 +37,7 @@
| └ | setAddressFrozen | External ❗️ | 🛑 |NO❗️ |
| └ | batchSetAddressFrozen | External ❗️ | 🛑 |NO❗️ |
||||||
-| **IERC3643ERC20Enforcement** | Interface | IERC7943ERC20Enforcement |||
+| **IERC3643ERC20Enforcement** | Interface | IERC7943FungibleEnforcement |||
| └ | freezePartialTokens | External ❗️ | 🛑 |NO❗️ |
| └ | unfreezePartialTokens | External ❗️ | 🛑 |NO❗️ |
||||||
diff --git a/doc/schema/surya_report/surya_report_IMintBurnToken.sol.md b/doc/schema/surya_report/surya_report_IMintBurnToken.sol.md
index 8734138c..1b52c70f 100644
--- a/doc/schema/surya_report/surya_report_IMintBurnToken.sol.md
+++ b/doc/schema/surya_report/surya_report_IMintBurnToken.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./interfaces/technical/IMintBurnToken.sol | 34c1820fe68b24778f81c2e2a0eae6252585c49d |
+| ./interfaces/technical/IMintBurnToken.sol | eba4d44fba424bc179c6f52082d02e3d0961a68e |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_IRuleTransferHook.sol.md b/doc/schema/surya_report/surya_report_IRuleTransferHook.sol.md
new file mode 100644
index 00000000..da854342
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_IRuleTransferHook.sol.md
@@ -0,0 +1,27 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./mocks/RuleEngine/interfaces/IRuleTransferHook.sol | 859b60c5ee96645445129b103cd836ea646235dd |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **IRuleTransferHook** | Interface | |||
+| └ | transferred | External ❗️ | 🛑 |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_PauseModule.sol.md b/doc/schema/surya_report/surya_report_PauseModule.sol.md
index 4f9599a9..188b0e9c 100644
--- a/doc/schema/surya_report/surya_report_PauseModule.sol.md
+++ b/doc/schema/surya_report/surya_report_PauseModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/core/PauseModule.sol | 0980a0d824c410ca19ee321e50b766924453fd56 |
+| ./modules/wrapper/core/PauseModule.sol | b6a8708f72a244ed4133f02b4fd4af2f8c027928 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_RuleEngineInterfaceId.sol.md b/doc/schema/surya_report/surya_report_RuleEngineInterfaceId.sol.md
new file mode 100644
index 00000000..bc1a9180
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_RuleEngineInterfaceId.sol.md
@@ -0,0 +1,26 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./library/RuleEngineInterfaceId.sol | 4090104820c3f97398174965e58b1b1fc61cb8ed |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **RuleEngineInterfaceId** | Library | |||
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_RuleEngineMock.sol.md b/doc/schema/surya_report/surya_report_RuleEngineMock.sol.md
index 3ffe3846..123f6716 100644
--- a/doc/schema/surya_report/surya_report_RuleEngineMock.sol.md
+++ b/doc/schema/surya_report/surya_report_RuleEngineMock.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./mocks/RuleEngine/RuleEngineMock.sol | e2ab7dc1d6e3884a8d66203f6a512111f4f6e429 |
+| ./mocks/RuleEngine/RuleEngineMock.sol | 45d26d4227e2759175a6a7a969b6e3d11797cf2c |
### Contracts Description Table
@@ -25,11 +25,13 @@
| └ | detectTransferRestrictionFrom | Public ❗️ | |NO❗️ |
| └ | canTransfer | Public ❗️ | |NO❗️ |
| └ | canTransferFrom | Public ❗️ | |NO❗️ |
-| └ | transferred | Public ❗️ | |NO❗️ |
-| └ | transferred | Public ❗️ | |NO❗️ |
+| └ | transferred | Public ❗️ | 🛑 |NO❗️ |
+| └ | transferred | Public ❗️ | 🛑 |NO❗️ |
+| └ | holderTrackerRule | External ❗️ | |NO❗️ |
| └ | messageForTransferRestriction | Public ❗️ | |NO❗️ |
| └ | supportsInterface | Public ❗️ | |NO❗️ |
| └ | returnInterfaceId | Public ❗️ | |NO❗️ |
+| └ | _callRuleHooks | Internal 🔒 | 🛑 | |
### Legend
diff --git a/doc/schema/surya_report/surya_report_RuleSpenderAuthorized.sol.md b/doc/schema/surya_report/surya_report_RuleSpenderAuthorized.sol.md
new file mode 100644
index 00000000..5e2b3584
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_RuleSpenderAuthorized.sol.md
@@ -0,0 +1,32 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./mocks/RuleEngine/RuleSpenderAuthorized.sol | 498f27e9d42bb5ecb81647c185055ee085376c3b |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **RuleSpenderAuthorized** | Implementation | IRule, CodeList |||
+| └ | | Public ❗️ | 🛑 |NO❗️ |
+| └ | canTransfer | Public ❗️ | |NO❗️ |
+| └ | detectTransferRestriction | Public ❗️ | |NO❗️ |
+| └ | detectTransferRestrictionFrom | Public ❗️ | |NO❗️ |
+| └ | canReturnTransferRestrictionCode | Public ❗️ | |NO❗️ |
+| └ | messageForTransferRestriction | External ❗️ | |NO❗️ |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_RuleTokenHolderTracker.sol.md b/doc/schema/surya_report/surya_report_RuleTokenHolderTracker.sol.md
new file mode 100644
index 00000000..fa887b3c
--- /dev/null
+++ b/doc/schema/surya_report/surya_report_RuleTokenHolderTracker.sol.md
@@ -0,0 +1,37 @@
+## Sūrya's Description Report
+
+### Files Description Table
+
+
+| File Name | SHA-1 Hash |
+|-------------|--------------|
+| ./mocks/RuleEngine/RuleTokenHolderTracker.sol | 389c2c6c2709dee695c05844a4386ad229b0ef4b |
+
+
+### Contracts Description Table
+
+
+| Contract | Type | Bases | | |
+|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
+| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
+||||||
+| **RuleTokenHolderTracker** | Implementation | IRule, IRuleTransferHook, CodeList |||
+| └ | transferred | External ❗️ | 🛑 |NO❗️ |
+| └ | trackedBalance | External ❗️ | |NO❗️ |
+| └ | isHolder | External ❗️ | |NO❗️ |
+| └ | holdersCount | External ❗️ | |NO❗️ |
+| └ | holderAt | External ❗️ | |NO❗️ |
+| └ | canTransfer | External ❗️ | |NO❗️ |
+| └ | detectTransferRestriction | Public ❗️ | |NO❗️ |
+| └ | detectTransferRestrictionFrom | Public ❗️ | |NO❗️ |
+| └ | canReturnTransferRestrictionCode | External ❗️ | |NO❗️ |
+| └ | messageForTransferRestriction | External ❗️ | |NO❗️ |
+| └ | _updateHolderStatus | Private 🔐 | 🛑 | |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/schema/surya_report/surya_report_SnapshotEngineModule.sol.md b/doc/schema/surya_report/surya_report_SnapshotEngineModule.sol.md
index 653c30cd..9f856d8a 100644
--- a/doc/schema/surya_report/surya_report_SnapshotEngineModule.sol.md
+++ b/doc/schema/surya_report/surya_report_SnapshotEngineModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/extensions/SnapshotEngineModule.sol | 5f1218c204060cf6c0be75453d8554bea2c703b8 |
+| ./modules/wrapper/extensions/SnapshotEngineModule.sol | 1f97921c2fb50a51d8af7fd623dbe21b6d687ad2 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_ValidationModule.sol.md b/doc/schema/surya_report/surya_report_ValidationModule.sol.md
index db8e9dc0..8dff16a7 100644
--- a/doc/schema/surya_report/surya_report_ValidationModule.sol.md
+++ b/doc/schema/surya_report/surya_report_ValidationModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/controllers/ValidationModule.sol | b5066172e0053da26db7aa93b04ffa09fa40feec |
+| ./modules/wrapper/controllers/ValidationModule.sol | 82cb97a858b7c94bfb8c6b9ceaf307383d9d1836 |
### Contracts Description Table
@@ -15,17 +15,20 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **ValidationModule** | Implementation | PauseModule, EnforcementModule, IERC7943TransactError, IERC7943FungibleTransactCheck |||
-| └ | canTransact | Public ❗️ | |NO❗️ |
+| **ValidationModule** | Implementation | PauseModule, EnforcementModule, IERC7943FungibleSendReceiveError, IERC7943FungibleSendReceiveCheck |||
+| └ | canSend | Public ❗️ | |NO❗️ |
+| └ | canReceive | Public ❗️ | |NO❗️ |
| └ | _canTransferGenericByModule | Internal 🔒 | | |
| └ | _canTransferGenericByModuleAndRevert | Internal 🔒 | | |
| └ | _canMintBurnByModule | Internal 🔒 | | |
-| └ | _canMintBurnByModuleAndRevert | Internal 🔒 | | |
+| └ | _canMintByModuleAndRevert | Internal 🔒 | | |
+| └ | _canBurnByModuleAndRevert | Internal 🔒 | | |
| └ | _canTransferisFrozen | Internal 🔒 | | |
| └ | _canTransferisFrozenAndRevert | Internal 🔒 | | |
| └ | _canTransferStandardByModule | Internal 🔒 | | |
| └ | _canTransferStandardByModuleAndRevert | Internal 🔒 | | |
-| └ | _canTransact | Internal 🔒 | | |
+| └ | _canSend | Internal 🔒 | | |
+| └ | _canReceive | Internal 🔒 | | |
### Legend
diff --git a/doc/schema/surya_report/surya_report_5_CMTATBaseDebtEngine.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleAllowance.sol.md
similarity index 68%
rename from doc/schema/surya_report/surya_report_5_CMTATBaseDebtEngine.sol.md
rename to doc/schema/surya_report/surya_report_ValidationModuleAllowance.sol.md
index 7d962739..5670a347 100644
--- a/doc/schema/surya_report/surya_report_5_CMTATBaseDebtEngine.sol.md
+++ b/doc/schema/surya_report/surya_report_ValidationModuleAllowance.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/5_CMTATBaseDebtEngine.sol | 574eac6aaa70384c2f064c049c015fda9cbb7313 |
+| ./modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol | 6305cf0201a987b2fa3222c72f27989833dc4cfb |
### Contracts Description Table
@@ -15,8 +15,8 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **CMTATBaseDebtEngine** | Implementation | DebtEngineModule, CMTATBaseERC20CrossChain |||
-| └ | _authorizeDebtEngineManagement | Internal 🔒 | 🛑 | onlyRole |
+| **ValidationModuleAllowance** | Implementation | ValidationModuleCore |||
+| └ | _canAuthorizeAllowanceByModuleAndRevert | Internal 🔒 | | |
### Legend
diff --git a/doc/schema/surya_report/surya_report_ValidationModuleAllowlist.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleAllowlist.sol.md
index 94acb483..354d8caf 100644
--- a/doc/schema/surya_report/surya_report_ValidationModuleAllowlist.sol.md
+++ b/doc/schema/surya_report/surya_report_ValidationModuleAllowlist.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/controllers/ValidationModuleAllowlist.sol | 5ba20a5d7578bd0b73ad66a9f768e39cd9c9a941 |
+| ./modules/wrapper/controllers/ValidationModuleAllowlist.sol | ba5af4e8ea17a9e4d3b06b627ecfe0a502da1a02 |
### Contracts Description Table
@@ -19,8 +19,10 @@
| └ | _canMintBurnByModule | Internal 🔒 | | |
| └ | _canTransferStandardByModuleAllowlist | Internal 🔒 | | |
| └ | _canTransferStandardByModule | Internal 🔒 | | |
-| └ | _canTransact | Internal 🔒 | | |
-| └ | _canMintBurnByModuleAndRevert | Internal 🔒 | | |
+| └ | _canSend | Internal 🔒 | | |
+| └ | _canReceive | Internal 🔒 | | |
+| └ | _canMintByModuleAndRevert | Internal 🔒 | | |
+| └ | _canBurnByModuleAndRevert | Internal 🔒 | | |
| └ | _canTransferStandardByModuleAndRevert | Internal 🔒 | | |
| └ | _canTransferStandardByModuleAllowlistAndRevert | Internal 🔒 | | |
diff --git a/doc/schema/surya_report/surya_report_ValidationModuleRuleEngine.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleRuleEngine.sol.md
index 2c742416..f997ec92 100644
--- a/doc/schema/surya_report/surya_report_ValidationModuleRuleEngine.sol.md
+++ b/doc/schema/surya_report/surya_report_ValidationModuleRuleEngine.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol | 51e9f0eec70789922ff3f9cebdf7a5b3a1c25ae9 |
+| ./modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol | 81c68ccc0b558c936e79aca880f811ac85311489 |
### Contracts Description Table
@@ -15,7 +15,7 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **ValidationModuleRuleEngine** | Implementation | ValidationModuleCore, ValidationModuleRuleEngineInternal |||
+| **ValidationModuleRuleEngine** | Implementation | ValidationModuleAllowance, ValidationModuleRuleEngineInternal |||
| └ | setRuleEngine | Public ❗️ | 🛑 | onlyRuleEngineManager |
| └ | canTransfer | Public ❗️ | |NO❗️ |
| └ | canTransferFrom | Public ❗️ | |NO❗️ |
diff --git a/doc/schema/surya_report/surya_report_VersionModule.sol.md b/doc/schema/surya_report/surya_report_VersionModule.sol.md
index 8f508122..df848498 100644
--- a/doc/schema/surya_report/surya_report_VersionModule.sol.md
+++ b/doc/schema/surya_report/surya_report_VersionModule.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/wrapper/core/VersionModule.sol | b0e1751720a827e7b61eddce5325b9bfccd36097 |
+| ./modules/wrapper/core/VersionModule.sol | 6cb2300286d764778ccd745ae40b2d12df918a53 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_draft-IERC1643.sol.md b/doc/schema/surya_report/surya_report_draft-IERC1643.sol.md
index 7bec5453..ba6942b8 100644
--- a/doc/schema/surya_report/surya_report_draft-IERC1643.sol.md
+++ b/doc/schema/surya_report/surya_report_draft-IERC1643.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./interfaces/tokenization/draft-IERC1643.sol | 5e6aabb7f05bca44c712b5b8b2707c066c1b27fc |
+| ./interfaces/tokenization/draft-IERC1643.sol | 47587eef86ac973699403fe890a8afae3f58e403 |
### Contracts Description Table
@@ -18,6 +18,8 @@
| **IERC1643** | Interface | |||
| └ | getDocument | External ❗️ | |NO❗️ |
| └ | getAllDocuments | External ❗️ | |NO❗️ |
+| └ | setDocument | External ❗️ | 🛑 |NO❗️ |
+| └ | removeDocument | External ❗️ | 🛑 |NO❗️ |
### Legend
diff --git a/doc/schema/surya_report/surya_report_draft-IERC1643CMTAT.sol.md b/doc/schema/surya_report/surya_report_draft-IERC1643CMTAT.sol.md
index cf16f526..bd39c2c3 100644
--- a/doc/schema/surya_report/surya_report_draft-IERC1643CMTAT.sol.md
+++ b/doc/schema/surya_report/surya_report_draft-IERC1643CMTAT.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./interfaces/tokenization/draft-IERC1643CMTAT.sol | 2cdcd1ef8e3598b9875d6013e1801c6d536dee62 |
+| ./interfaces/tokenization/draft-IERC1643CMTAT.sol | 11856388fcb0cbf7182cff41314ffc03c602eb01 |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_draft-IERC7551.sol.md b/doc/schema/surya_report/surya_report_draft-IERC7551.sol.md
index d3cafef9..c07d8b39 100644
--- a/doc/schema/surya_report/surya_report_draft-IERC7551.sol.md
+++ b/doc/schema/surya_report/surya_report_draft-IERC7551.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./interfaces/tokenization/draft-IERC7551.sol | 6cf8e034093a4e55d267c35c5497a9e91fbebd63 |
+| ./interfaces/tokenization/draft-IERC7551.sol | 293d5f5a08b58a7d74a511dc903fea659bcc905a |
### Contracts Description Table
diff --git a/doc/schema/surya_report/surya_report_draft-IERC7943.sol.md b/doc/schema/surya_report/surya_report_draft-IERC7943.sol.md
index 38c55a12..da580d00 100644
--- a/doc/schema/surya_report/surya_report_draft-IERC7943.sol.md
+++ b/doc/schema/surya_report/surya_report_draft-IERC7943.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./interfaces/tokenization/draft-IERC7943.sol | 2c8f570f09b25d0c080dcc3edebee3a636dc302f |
+| ./interfaces/tokenization/draft-IERC7943.sol | 93a6a2a87297d7f4f18a64ef3fdf4257280fa7e8 |
### Contracts Description Table
@@ -15,21 +15,22 @@
|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:|
| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** |
||||||
-| **IERC7943ERC20Enforcement** | Interface | |||
+| **IERC7943FungibleEnforcement** | Interface | |||
| └ | getFrozenTokens | External ❗️ | |NO❗️ |
| └ | forcedTransfer | External ❗️ | 🛑 |NO❗️ |
||||||
-| **IERC7943ERC20EnforcementSpecific** | Interface | |||
+| **IERC7943FungibleEnforcementSpecific** | Interface | |||
| └ | setFrozenTokens | External ❗️ | 🛑 |NO❗️ |
||||||
-| **IERC7943FungibleEnforcementEvent** | Interface | |||
+| **IERC7943FungibleEnforcementEventAndError** | Interface | |||
||||||
-| **IERC7943TransactError** | Interface | |||
+| **IERC7943FungibleSendReceiveError** | Interface | |||
||||||
| **IERC7943FungibleTransferError** | Interface | |||
||||||
-| **IERC7943FungibleTransactCheck** | Interface | |||
-| └ | canTransact | External ❗️ | |NO❗️ |
+| **IERC7943FungibleSendReceiveCheck** | Interface | |||
+| └ | canSend | External ❗️ | |NO❗️ |
+| └ | canReceive | External ❗️ | |NO❗️ |
### Legend
diff --git a/doc/audits/ABDK-CMTAT-audit-20210910/ABDK-CMTAT-audit-20210910.pdf b/doc/security/audit/ABDK-CMTAT-audit-20210910/ABDK-CMTAT-audit-20210910.pdf
similarity index 100%
rename from doc/audits/ABDK-CMTAT-audit-20210910/ABDK-CMTAT-audit-20210910.pdf
rename to doc/security/audit/ABDK-CMTAT-audit-20210910/ABDK-CMTAT-audit-20210910.pdf
diff --git a/doc/audits/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.odt b/doc/security/audit/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.odt
similarity index 100%
rename from doc/audits/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.odt
rename to doc/security/audit/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.odt
diff --git a/doc/audits/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.pdf b/doc/security/audit/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.pdf
similarity index 100%
rename from doc/audits/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.pdf
rename to doc/security/audit/ABDK-CMTAT-audit-20210910/CMTAT-Audit-20210910-summary.pdf
diff --git a/doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0/ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf b/doc/security/audit/ABDK_CMTA_CMTATRuleEngine_v_1_0/ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf
similarity index 100%
rename from doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0/ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf
rename to doc/security/audit/ABDK_CMTA_CMTATRuleEngine_v_1_0/ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf
diff --git a/doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0/Taurus. Audit 3.3. Collected.ods b/doc/security/audit/ABDK_CMTA_CMTATRuleEngine_v_1_0/Taurus. Audit 3.3. Collected.ods
similarity index 100%
rename from doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0/Taurus. Audit 3.3. Collected.ods
rename to doc/security/audit/ABDK_CMTA_CMTATRuleEngine_v_1_0/Taurus. Audit 3.3. Collected.ods
diff --git a/doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0/Taurus.Audit3.1.CollectedIssues.ods b/doc/security/audit/ABDK_CMTA_CMTATRuleEngine_v_1_0/Taurus.Audit3.1.CollectedIssues.ods
similarity index 100%
rename from doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0/Taurus.Audit3.1.CollectedIssues.ods
rename to doc/security/audit/ABDK_CMTA_CMTATRuleEngine_v_1_0/Taurus.Audit3.1.CollectedIssues.ods
diff --git a/doc/audits/Halborn-CMTATv3.0.0-2025/Taurus_CMTAT_Smart_Contract_Security_Assessment_Report_Halborn.pdf b/doc/security/audit/Halborn-CMTATv3.0.0-2025/Taurus_CMTAT_Smart_Contract_Security_Assessment_Report_Halborn.pdf
similarity index 100%
rename from doc/audits/Halborn-CMTATv3.0.0-2025/Taurus_CMTAT_Smart_Contract_Security_Assessment_Report_Halborn.pdf
rename to doc/security/audit/Halborn-CMTATv3.0.0-2025/Taurus_CMTAT_Smart_Contract_Security_Assessment_Report_Halborn.pdf
diff --git a/doc/audits/Halborn-CMTATv3.0.0-2025/halborn-review.pdf b/doc/security/audit/Halborn-CMTATv3.0.0-2025/halborn-review.pdf
similarity index 100%
rename from doc/audits/Halborn-CMTATv3.0.0-2025/halborn-review.pdf
rename to doc/security/audit/Halborn-CMTATv3.0.0-2025/halborn-review.pdf
diff --git a/doc/audits/Halborn-CMTATv3.0.0-2025/hallobrn-review.md b/doc/security/audit/Halborn-CMTATv3.0.0-2025/hallobrn-review.md
similarity index 100%
rename from doc/audits/Halborn-CMTATv3.0.0-2025/hallobrn-review.md
rename to doc/security/audit/Halborn-CMTATv3.0.0-2025/hallobrn-review.md
diff --git a/doc/security/pre-review/SequentReport-feedback.md b/doc/security/pre-review/SequentReport-feedback.md
new file mode 100644
index 00000000..b9ce2789
--- /dev/null
+++ b/doc/security/pre-review/SequentReport-feedback.md
@@ -0,0 +1,172 @@
+# CMTAT Feedback on Sequent Pre-Verification Report
+
+Date: 2026-05-13
+Source reviewed: `doc/general/feedback/sequent-report-CMTAT.pdf`
+
+## Table of Contents
+- [Scope and Method](#scope-and-method)
+- [Findings Summary](#findings-summary)
+- [Executive Summary](#executive-summary)
+- [Finding-by-Finding Assessment](#finding-by-finding-assessment)
+ - [1) Reverting snapshot engine can halt state-changing operations](#1-reverting-snapshot-engine-can-halt-state-changing-operations)
+ - [2) `setFrozenTokens` can exceed balance and break internal assumptions](#2-setfrozentokens-can-exceed-balance-and-break-internal-assumptions)
+ - [3) Operator identity propagation in burn/mint/cross-chain RuleEngine paths](#3-operator-identity-propagation-in-burnmintcross-chain-ruleengine-paths)
+ - [4) `setAddressFrozen(address(0))` should be rejected](#4-setaddressfrozenaddress0-should-be-rejected)
+- [Action Plan for Next Release](#action-plan-for-next-release)
+
+## Scope and Method
+This feedback cross-checks each Sequent finding against the current CMTAT codebase and current architecture decisions (including recent deployment-variant split changes).
+
+## Findings Summary
+| # | Finding | Assessment | Status | Affected Releases | Fixed Commit | Report Severity (Sequent) | Severity (CMTAT Maintainer Perspective) | Severity Rationale (with Access Control Context) |
+|---|---|---|---|---|---|---|---|---|
+| 1 | Reverting snapshot engine can halt state-changing operations | Valid liveness/trust-boundary risk in snapshot-enabled variants | Accepted (open) | v3.0.0, v3.1.0, v3.2.0 (snapshot-enabled variants) | N/A (design/ops hardening pending) | Medium | Informational | Primarily a design/operational trust-boundary issue: snapshot engine address is configured via privileged roles, so arbitrary users cannot trigger this path by themselves; impact depends on governance hygiene. |
+| 2 | `setFrozenTokens` can exceed balance and break internal assumptions | Valid internal-consistency issue under ERC-7943 permissive semantics | Fixed (with specification nuance) | v3.2.0 | `5982e79` | Medium | Medium | Trigger path is role-gated (`ERC20ENFORCER_ROLE`/admin-controlled workflows). The issue was due to missing robustness checks for `frozen > balance`; behavior is now hardened while keeping ERC-7943 permissive semantics by design. |
+| 3 | Operator identity propagation in burn/mint/cross-chain RuleEngine paths | Valid policy-consistency gap for operator-aware RuleEngine policies | Fixed | v3.0.0, v3.1.0, v3.2.0 (only when RuleEngine is enabled and rules target spender/operator) | `10e87ff`, `7a7c975` | Medium | Informational | Initial design intentionally targeted spender checks primarily in the `transferFrom` path, which is not access-controlled. The gap was about policy scope consistency (not privilege bypass), and became relevant only for deployments relying on spender/operator-aware RuleEngine rules outside classic `transferFrom`. |
+| 4 | `setAddressFrozen(address(0))` should be rejected | Valid misuse vector enabling unintended global blocking patterns | Fixed | v3.0.0, v3.1.0, v3.2.0 | `a61bdb0` | Medium (linked to Sequent Finding 2) | Low | Invocation is access-controlled (`ENFORCER_ROLE`/admin) and operationally reversible: admin can revoke compromised enforcer privileges and rollback the freeze state; no direct theft vector. |
+
+## Finding-by-Finding Assessment
+
+### 1) Reverting snapshot engine can halt state-changing operations
+Status: **Accepted (snapshot-enabled deployments)**
+
+#### Assessment
+- For deployments including SnapshotEngine, a reverting snapshot engine can cause transfer-path reverts.
+- This is a trust-boundary/liveness risk tied to privileged configuration.
+- The impact is reduced in variants where snapshot was removed from standard flow.
+- Snapshot behavior has been separated by deployment version, reducing unintended coupling in non-snapshot variants.
+
+#### CMTAT Maintainer Position
+- Accepted as an expected risk in snapshot-enabled variants unless additional governance controls are applied.
+- This risk is now explicitly documented in CMTAT documentation (`doc/technical/snapshot.md` and access-control notes) as a transfer-liveness halt scenario if a reverting snapshot engine is configured.
+
+#### Planned Action
+- Clarify trust assumptions in docs and evaluate stronger governance constraints for `setSnapshotEngine` (allowlist/timelock/process controls).
+
+#### Operational Runbook
+If this occurs in production:
+1. **Containment**
+ - Revoke `SNAPSHOOTER_ROLE` from non-emergency operators.
+ - If available in the deployment, pause token operations with the dedicated pause authority.
+2. **Diagnosis**
+ - Confirm transfer-path reverts originate from snapshot engine callback execution.
+ - Verify current `snapshotEngine()` and recent privileged role actions.
+3. **Recovery**
+ - Set snapshot engine to `address(0)` (disable) or to a known-good approved engine.
+ - Re-test representative state-changing flows (transfer/mint/burn/forced transfer) with small amounts.
+4. **State reconciliation**
+ - Reconcile planned snapshot schedules and any off-chain dependencies before resuming normal operations.
+5. **Hardening**
+ - Enforce multisig + timelock for snapshot engine changes.
+ - Keep an allowlist of approved engine addresses/bytecode.
+ - Add monitoring alerts for revert spikes after snapshot-engine updates.
+
+---
+
+### 2) `setFrozenTokens` can exceed balance and break internal assumptions
+Status: **Fixed (with specification nuance)**
+
+#### Assessment
+- Sequent correctly identifies internal-path fragility when `frozen > balance` interacts with active-balance logic.
+- However, ERC-7943 spec text explicitly allows this behavior:
+ - `setFrozenTokens` MUST allow freezing more assets than currently held.
+ - `getFrozenTokens` MAY exceed current balance.
+- If internal logic is not hardened for this state, concrete consequences include:
+ - unexpected reverts in transfer paths due to underflow-prone active-balance arithmetic;
+ - incorrect `getActiveBalanceOf` behavior for wallets and integrators relying on that view;
+ - forced-transfer/unfreeze workflows failing or behaving inconsistently under extreme frozen states;
+ - operational incidents where compliance teams can set a legally valid frozen amount but trigger unintended token liveness issues;
+ - mismatch between off-chain assumptions and on-chain execution, increasing integration and monitoring risk.
+
+Example flow with actors:
+1. **Issuer Admin** mints `100` tokens to **Investor A**.
+2. **Compliance Officer** (has `ERC20ENFORCER_ROLE`) calls `setFrozenTokens(InvestorA, 150)` to pre-freeze future inflows (ERC-7943-permissive scenario).
+3. **Investor A** still has on-chain `balance = 100`, `frozen = 150`.
+4. **Custodian UI / Middleware** reads `getActiveBalanceOf(InvestorA)` to determine transferable amount.
+5. If arithmetic is not hardened, this read path or subsequent transfer checks can revert with Solidity arithmetic underflow panic (`panic code 0x11`) instead of cleanly returning active balance `0`.
+6. **Transfer Agent** attempts a compliance `forcedTransfer` of `20` from **Investor A** to **Investor B**.
+7. If unfreeze/active-balance math is not robust to `frozen > balance`, forced transfer can revert with Solidity arithmetic underflow panic (`panic code 0x11`) before enforcement logic completes, creating an operational incident despite valid permissions.
+
+#### CMTAT Maintainer Position
+- This is not a pure ERC-7943 non-compliance issue.
+- It was a CMTAT internal consistency issue caused by missing robustness checks when `frozen > balance`.
+- The issue is remediated, while ERC-7943 permissive behavior remains an intentional design choice.
+
+#### Clarification: Theft Risk and Recovery Procedure
+- This issue is **not** a direct token-theft issue by itself.
+- It does **not** grant unauthorized transfer rights to arbitrary actors.
+- The main risk is operational/liveness failure (reverts, blocked compliance operations, inconsistent transfer behavior).
+
+Safe recovery procedure (without allowing holder free transfer):
+1. Keep the holder blocked at account level (`setAddressFrozen(holder, true)`) when available.
+2. Use privileged enforcement role to normalize frozen accounting with `setFrozenTokens(holder, safeAmount)` under your selected policy/model.
+3. If legal/compliance workflow requires custody movement, use `forcedTransfer(holder, recoveryWallet, amount)` while the holder remains frozen.
+4. Reconcile balances/frozen values off-chain and on-chain before any unfreeze.
+5. Unfreeze only when policy checks are complete and incident state is closed.
+
+#### Planned Action
+- Continue regression and edge-case test coverage around `frozen > balance` states under the retained ERC-7943 permissive model.
+
+---
+
+### 3) Operator identity propagation in burn/mint/cross-chain RuleEngine paths
+Status: **Fixed**
+
+#### Assessment
+- Operator identity is not consistently propagated to RuleEngine write-path hooks in these flows.
+- This can diverge from issuer expectations when operator-specific controls are used.
+- This concern applies only to CMTAT deployments where RuleEngine is configured and the active rules explicitly target spender/operator semantics.
+
+#### CMTAT Maintainer Position
+- This was a policy-consistency issue, not a role-check bypass.
+- The issue is remediated with operator-as-spender propagation and dedicated regression tests.
+- Mint operator semantics are now explicitly documented: mint/crosschainMint propagate the effective operator as spender in compliance/RuleEngine paths.
+- Side effect: `ENFORCER_ROLE` can block mint operations by freezing the minter/operator address (`setAddressFrozen`), since the minter is evaluated as spender in these paths.
+
+#### Implementation Update (Current State)
+- Initial behavior (no spender/operator propagation on some mint/burn/cross-chain paths) was a deliberate design choice focused on simple transfer semantics and role-gated module calls.
+- After review, CMTAT decided to implement operator-as-spender propagation because it is a relevant feature for compliance policies and extends the RuleEngine use cases.
+- The effective operator (`_msgSender()`) is now propagated into RuleEngine write-path checks for:
+1. `burn`
+2. `batchBurn`
+3. `burnFrom`
+4. `mint`
+5. `batchMint`
+6. `crosschainBurn`
+7. `crosschainMint`
+- Practical effect: RuleEngine policies can now differentiate and restrict operations based on the acting operator (treated as spender), not only on `from`/`to`/`amount`.
+- `burnFrom` is treated as an access-controlled operator burn path (not as a classic `transferFrom` policy path). In hook-level parameters, `burn` and `burnFrom` both appear as burn semantics (`to == address(0)`), so RuleEngine cannot distinguish them from `(spender, from, to, value)` alone.
+- Therefore, `burnFrom`-specific restrictions must be implemented by targeting the operator addresses authorized for `burnFrom` (role-scoped policy at RuleEngine level).
+
+---
+
+### 4) `setAddressFrozen(address(0))` should be rejected
+Status: **Fixed**
+
+#### Assessment
+- Implemented zero-address guard in enforcement internal path.
+- Added tests covering direct and batch freeze calls.
+- Similar zero-address hardening also added to partial freeze/unfreeze paths.
+- This hardening is linked to Sequent Finding 2 (`setFrozenTokens` / `address(0)` accounting side effects): both concern `address(0)`-based freeze states impacting transfer/mint paths.
+- For report-severity mapping, this item is aligned to the same Sequent severity level as Finding 2 (**Medium**).
+- This issue was also flagged before the Sequent report by Nethermind Audit Agent on the CMTAT Confidential version, with **Informational** severity: https://github.com/CMTA/CMTAT/issues/372
+
+#### CMTAT Maintainer Position
+- Resolved.
+- CMTA maintainer severity is **Low** because:
+1. the entry points are protected by privileged roles (`ENFORCER_ROLE` / admin-managed authorization), so unprivileged actors cannot directly trigger it;
+2. there is no direct theft path from this issue;
+3. the effect is operationally reversible by governance actions (revoke compromised enforcer permissions and rollback freeze state).
+
+## Action Plan for Next Release
+1. `setFrozenTokens` policy is now aligned on the ERC-7943 permissive model; continue hardening/coverage with additional regression and edge-case tests around `frozen > balance` edge states.
+2. Keep operator-identity regression coverage in place for burn/mint/cross-chain flows where RuleEngine spender/operator rules are used.
+3. Strengthen and document snapshot-engine governance assumptions for snapshot-enabled deployments (multisig/timelock/allowlist and incident runbook enforcement).
+
+## Final Position
+CMTAT accepts Sequent’s report as materially valuable.
+We classify the findings as:
+- `Accepted/Open`: snapshot liveness risk (snapshot-enabled variants).
+- `Resolved`: `setFrozenTokens` internal consistency issue under ERC-7943 permissive semantics.
+- `Resolved`: operator-identity propagation consistency for RuleEngine spender/operator policies.
+- `Resolved`: zero-address freeze in enforcement paths.
diff --git a/doc/security/pre-review/sequent-report-CMTAT.pdf b/doc/security/pre-review/sequent-report-CMTAT.pdf
new file mode 100644
index 00000000..350832e3
Binary files /dev/null and b/doc/security/pre-review/sequent-report-CMTAT.pdf differ
diff --git a/doc/audits/tools/ackee-wake-arena/CMTAT-wake-arena-feedback.md b/doc/security/tools/ackee-wake-arena/CMTAT-wake-arena-feedback.md
similarity index 100%
rename from doc/audits/tools/ackee-wake-arena/CMTAT-wake-arena-feedback.md
rename to doc/security/tools/ackee-wake-arena/CMTAT-wake-arena-feedback.md
diff --git a/doc/audits/tools/ackee-wake-arena/Wake Arena Report - CMTA_ CMTAT-v3.2.0-rc2.pdf b/doc/security/tools/ackee-wake-arena/Wake Arena Report - CMTA_ CMTAT-v3.2.0-rc2.pdf
similarity index 100%
rename from doc/audits/tools/ackee-wake-arena/Wake Arena Report - CMTA_ CMTAT-v3.2.0-rc2.pdf
rename to doc/security/tools/ackee-wake-arena/Wake Arena Report - CMTA_ CMTAT-v3.2.0-rc2.pdf
diff --git a/doc/audits/tools/aderyn/v3.0.0-aderyn-report.md b/doc/security/tools/aderyn/archive/v3.0.0-aderyn-report.md
similarity index 100%
rename from doc/audits/tools/aderyn/v3.0.0-aderyn-report.md
rename to doc/security/tools/aderyn/archive/v3.0.0-aderyn-report.md
diff --git a/doc/audits/tools/aderyn/v3.1.0-aderyn-report.md b/doc/security/tools/aderyn/archive/v3.1.0-aderyn-report.md
similarity index 100%
rename from doc/audits/tools/aderyn/v3.1.0-aderyn-report.md
rename to doc/security/tools/aderyn/archive/v3.1.0-aderyn-report.md
diff --git a/doc/audits/tools/aderyn/v3.2.0-aderyn-report.md b/doc/security/tools/aderyn/archive/v3.2.0-aderyn-report.md
similarity index 96%
rename from doc/audits/tools/aderyn/v3.2.0-aderyn-report.md
rename to doc/security/tools/aderyn/archive/v3.2.0-aderyn-report.md
index ca949666..721ee9b9 100644
--- a/doc/audits/tools/aderyn/v3.2.0-aderyn-report.md
+++ b/doc/security/tools/aderyn/archive/v3.2.0-aderyn-report.md
@@ -81,9 +81,9 @@ This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a stati
| contracts/modules/2_CMTATBaseRuleEngine.sol | 99 |
| contracts/modules/3_CMTATBaseDebt.sol | 6 |
| contracts/modules/3_CMTATBaseERC1404.sol | 51 |
-| contracts/modules/4_CMTATBaseERC20CrossChain.sol | 72 |
-| contracts/modules/5_CMTATBaseDebtEngine.sol | 6 |
-| contracts/modules/5_CMTATBaseERC2771.sol | 27 |
+| contracts/modules/5_CMTATBaseERC20CrossChain.sol | 72 |
+| contracts/modules/6_CMTATBaseDebtEngine.sol | 6 |
+| contracts/modules/6_CMTATBaseERC2771.sol | 27 |
| contracts/modules/6_CMTATBaseERC1363.sol | 77 |
| contracts/modules/6_CMTATBaseERC7551.sol | 9 |
| contracts/modules/internal/AllowlistModuleInternal.sol | 49 |
@@ -151,7 +151,7 @@ Passing an arbitrary `from` address to `transferFrom` (or `safeTransferFrom`) ca
return ERC20BaseModule.transferFrom(from, to, value);
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 42](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L42)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 42](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L42)
```solidity
return CMTATBaseCommon.transferFrom(from, to, value);
@@ -368,25 +368,25 @@ Contracts have owners with privileged rights to perform admin tasks and need to
function _authorizeDebtManagement() internal virtual override(DebtModule) onlyRole(DEBT_ROLE){}
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 113](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L113)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 113](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L113)
```solidity
function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {}
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 133](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L133)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 133](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L133)
```solidity
function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{}
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 140](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L140)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 140](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L140)
```solidity
function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{}
```
-- Found in contracts/modules/5_CMTATBaseDebtEngine.sol [Line: 11](contracts/modules/5_CMTATBaseDebtEngine.sol#L11)
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 11](contracts/modules/6_CMTATBaseDebtEngine.sol#L11)
```solidity
function _authorizeDebtEngineManagement() internal virtual override(DebtEngineModule) onlyRole(DEBT_ENGINE_ROLE){}
@@ -429,13 +429,13 @@ ERC20 functions may not behave as expected. For example: return values are not a
return ERC20Upgradeable.approve(spender, value);
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 24](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L24)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 24](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L24)
```solidity
return CMTATBaseRuleEngine.approve(spender, value);
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 27](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L27)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 27](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L27)
```solidity
return CMTATBaseCommon.transfer(to, value);
@@ -753,19 +753,19 @@ Consider using a specific version of Solidity in your contracts instead of a wid
pragma solidity ^0.8.20;
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 3](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L3)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 3](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L3)
```solidity
pragma solidity ^0.8.20;
```
-- Found in contracts/modules/5_CMTATBaseDebtEngine.sol [Line: 3](contracts/modules/5_CMTATBaseDebtEngine.sol#L3)
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 3](contracts/modules/6_CMTATBaseDebtEngine.sol#L3)
```solidity
pragma solidity ^0.8.20;
```
-- Found in contracts/modules/5_CMTATBaseERC2771.sol [Line: 3](contracts/modules/5_CMTATBaseERC2771.sol#L3)
+- Found in contracts/modules/6_CMTATBaseERC2771.sol [Line: 3](contracts/modules/6_CMTATBaseERC2771.sol#L3)
```solidity
pragma solidity ^0.8.20;
@@ -1240,19 +1240,19 @@ Solc compiler version 0.8.20 switches the default target EVM version to Shanghai
pragma solidity ^0.8.20;
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 3](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L3)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 3](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L3)
```solidity
pragma solidity ^0.8.20;
```
-- Found in contracts/modules/5_CMTATBaseDebtEngine.sol [Line: 3](contracts/modules/5_CMTATBaseDebtEngine.sol#L3)
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 3](contracts/modules/6_CMTATBaseDebtEngine.sol#L3)
```solidity
pragma solidity ^0.8.20;
```
-- Found in contracts/modules/5_CMTATBaseERC2771.sol [Line: 3](contracts/modules/5_CMTATBaseERC2771.sol#L3)
+- Found in contracts/modules/6_CMTATBaseERC2771.sol [Line: 3](contracts/modules/6_CMTATBaseERC2771.sol#L3)
```solidity
pragma solidity ^0.8.20;
@@ -1690,25 +1690,25 @@ Consider removing empty blocks.
function _authorizeDebtManagement() internal virtual override(DebtModule) onlyRole(DEBT_ROLE){}
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 113](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L113)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 113](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L113)
```solidity
function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {}
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 133](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L133)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 133](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L133)
```solidity
function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{}
```
-- Found in contracts/modules/4_CMTATBaseERC20CrossChain.sol [Line: 140](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L140)
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 140](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L140)
```solidity
function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{}
```
-- Found in contracts/modules/5_CMTATBaseDebtEngine.sol [Line: 11](contracts/modules/5_CMTATBaseDebtEngine.sol#L11)
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 11](contracts/modules/6_CMTATBaseDebtEngine.sol#L11)
```solidity
function _authorizeDebtEngineManagement() internal virtual override(DebtEngineModule) onlyRole(DEBT_ENGINE_ROLE){}
diff --git a/doc/security/tools/aderyn/v3.3.0-aderyn-feedback.md b/doc/security/tools/aderyn/v3.3.0-aderyn-feedback.md
new file mode 100644
index 00000000..76f0c34c
--- /dev/null
+++ b/doc/security/tools/aderyn/v3.3.0-aderyn-feedback.md
@@ -0,0 +1,101 @@
+# CMTAT Maintainer Feedback - Aderyn v3.3.0
+
+Date: 2026-05-20
+Source report: [v3.3.0-aderyn-report.md](./v3.3.0-aderyn-report.md)
+
+## Scope
+This document provides CMTA maintainer assessment of Aderyn findings for CMTAT v3.3.0.
+
+## Report Snapshot
+
+- High: 2
+- Low: 10
+- Medium: 0
+- Informational: 0
+
+## Findings Summary
+
+| ID | Finding | Aderyn Severity | CMTA Validity | CMTA Assessment | Status |
+|---|---|---|---|---|---|
+| H-1 | Arbitrary `from` Passed to `transferFrom` | High | Invalid (false positive) | Standard ERC20 `transferFrom` semantics with allowance checks by OZ | Closed |
+| H-2 | Contract locks Ether without a withdraw function | High | Design choice | Payable upgrade path only; no operational need for ETH custody | Accepted |
+| L-1 | Centralization Risk | Low | Valid | Known RBAC governance tradeoff for regulated token operations | Accepted |
+| L-2 | Unsafe ERC20 Operation | Low | Invalid (false positive) | Core paths delegate to OpenZeppelin ERC20 behavior | Closed |
+| L-3 | Unspecific Solidity Pragma | Low | Design choice | Library-style pragma policy with pinned compiler in tooling | Accepted |
+| L-4 | PUSH0 Opcode | Low | Valid (environmental) | Deployment compatibility note for non-Shanghai chains | Accepted |
+| L-5 | Modifier Invoked Only Once | Low | Invalid (style-only) | Intentional readability/access-control structure | Closed |
+| L-6 | Empty Block | Low | Invalid (style-only) | Intentional access-control override stubs | Closed |
+| L-7 | Unused Error | Low | Valid | Interface-level draft error currently not used by runtime paths | Accepted |
+| L-8 | Loop Contains `require`/`revert` | Low | Design choice | Atomic batch behavior is intentional | Accepted |
+| L-9 | Costly operations inside loop | Low | Valid (optimization) | Potential micro-optimizations; no correctness issue | Accepted |
+| L-10 | Unchecked Return | Low | Invalid (false positive) | `_grantRole` return intentionally ignored in initializer flow | Closed |
+
+## Detailed Assessment
+
+### H-1: Arbitrary `from` Passed to `transferFrom`
+- CMTA validity: **Invalid (false positive)**.
+- Rationale: flagged callsites are standard ERC20 `transferFrom` wrappers/delegations. Authorization is enforced by OpenZeppelin allowance mechanics, so arbitrary transfer without allowance is not possible.
+- Action: no code change required.
+
+### H-2: Contract locks Ether without a withdraw function
+- CMTA validity: **Design choice**.
+- Rationale: the UUPS deployment contract can be payable through upgrade flow (`upgradeToAndCall` pattern), but ETH retention is not part of token operations. No treasury/custody model is implemented in this contract layer.
+- Action: accepted as non-critical; optional safeguard can be considered if operational policy requires it.
+
+### L-1: Centralization Risk
+- CMTA validity: **Valid**.
+- Rationale: CMTAT is role-driven by design (pause, freeze, mint/burn, rule management, upgrades). This is expected for regulated security-token workflows.
+- Action: governance/process mitigation (multisig, timelock, separation of duties) at deployment level.
+
+### L-2: Unsafe ERC20 Operation
+- CMTA validity: **Invalid (false positive)**.
+- Rationale: flagged functions are wrappers around OpenZeppelin ERC20 operations; token behavior follows inherited semantics.
+- Action: no code change required.
+
+### L-3: Unspecific Solidity Pragma
+- CMTA validity: **Design choice**.
+- Rationale: broad pragma is intentionally used for library compatibility; project compiler is pinned in build configuration.
+- Action: accepted.
+
+### L-4: PUSH0 Opcode
+- CMTA validity: **Valid (environmental)**.
+- Rationale: Solidity >=0.8.20 may emit PUSH0; deployment target must support Shanghai opcodes.
+- Action: keep deployment guidance in docs/tooling.
+
+### L-5: Modifier Invoked Only Once
+- CMTA validity: **Invalid (style-only)**.
+- Rationale: single-use modifiers are intentionally used for readability and access-control semantics.
+- Action: no code change required.
+
+### L-6: Empty Block
+- CMTA validity: **Invalid (style-only)**.
+- Rationale: empty override bodies are expected for authorization hooks where access control is expressed via modifiers.
+- Action: no code change required.
+
+### L-7: Unused Error
+- CMTA validity: **Valid**.
+- Rationale: `ERC7943CannotTransfer` exists at draft-interface level but current runtime paths use directional errors (`CannotSend`/`CannotReceive`) and other module-specific reverts.
+- Action: documented in ERC-7943 docs as “kept for potential future use”.
+
+### L-8: Loop Contains `require`/`revert`
+- CMTA validity: **Design choice**.
+- Rationale: batch functions are intentionally atomic; failing one element reverts the whole batch to preserve consistency.
+- Action: accepted.
+
+### L-9: Costly operations inside loop
+- CMTA validity: **Valid (optimization)**.
+- Rationale: potential gas improvements exist in loop-heavy internals; no direct security impact.
+- Action: optional optimization backlog.
+
+### L-10: Unchecked Return
+- CMTA validity: **Invalid (false positive)**.
+- Rationale: `_grantRole` return value is not security-critical in initialization context and duplicate grants are harmless.
+- Action: no code change required.
+
+## Final Position
+From a CMTA maintainer perspective, the v3.3.0 Aderyn output mainly contains:
+- expected RBAC/design tradeoffs for regulated-token operations,
+- style/tooling observations,
+- and a small set of documentation/optimization follow-ups.
+
+No critical exploitable issue requiring emergency patching was identified from this report alone.
diff --git a/doc/security/tools/aderyn/v3.3.0-aderyn-report.md b/doc/security/tools/aderyn/v3.3.0-aderyn-report.md
new file mode 100644
index 00000000..2a182efe
--- /dev/null
+++ b/doc/security/tools/aderyn/v3.3.0-aderyn-report.md
@@ -0,0 +1,2122 @@
+# Aderyn Analysis Report
+
+This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a static analysis tool built by [Cyfrin](https://cyfrin.io), a blockchain security company. This report is not a substitute for manual audit or security review. It should not be relied upon for any purpose other than to assist in the identification of potential security vulnerabilities.
+# Table of Contents
+
+- [Summary](#summary)
+ - [Files Summary](#files-summary)
+ - [Files Details](#files-details)
+ - [Issue Summary](#issue-summary)
+- [High Issues](#high-issues)
+ - [H-1: Arbitrary `from` Passed to `transferFrom`](#h-1-arbitrary-from-passed-to-transferfrom)
+ - [H-2: Contract locks Ether without a withdraw function](#h-2-contract-locks-ether-without-a-withdraw-function)
+- [Low Issues](#low-issues)
+ - [L-1: Centralization Risk](#l-1-centralization-risk)
+ - [L-2: Unsafe ERC20 Operation](#l-2-unsafe-erc20-operation)
+ - [L-3: Unspecific Solidity Pragma](#l-3-unspecific-solidity-pragma)
+ - [L-4: PUSH0 Opcode](#l-4-push0-opcode)
+ - [L-5: Modifier Invoked Only Once](#l-5-modifier-invoked-only-once)
+ - [L-6: Empty Block](#l-6-empty-block)
+ - [L-7: Unused Error](#l-7-unused-error)
+ - [L-8: Loop Contains `require`/`revert`](#l-8-loop-contains-requirerevert)
+ - [L-9: Costly operations inside loop](#l-9-costly-operations-inside-loop)
+ - [L-10: Unchecked Return](#l-10-unchecked-return)
+
+
+# Summary
+
+## Files Summary
+
+| Key | Value |
+| --- | --- |
+| .sol Files | 94 |
+| Total nSLOC | 3507 |
+
+
+## Files Details
+
+| Filepath | nSLOC |
+| --- | --- |
+| contracts/deployment/CMTATStandardStandalone.sol | 20 |
+| contracts/deployment/CMTATStandardUpgradeable.sol | 10 |
+| contracts/deployment/CMTATUpgradeableUUPS.sol | 13 |
+| contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol | 20 |
+| contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol | 10 |
+| contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol | 20 |
+| contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol | 10 |
+| contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol | 18 |
+| contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol | 8 |
+| contracts/deployment/debt/CMTATStandaloneDebt.sol | 18 |
+| contracts/deployment/debt/CMTATUpgradeableDebt.sol | 7 |
+| contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol | 18 |
+| contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol | 7 |
+| contracts/deployment/light/CMTATStandaloneLight.sol | 14 |
+| contracts/deployment/light/CMTATUpgradeableLight.sol | 7 |
+| contracts/deployment/permit/CMTATStandalonePermit.sol | 18 |
+| contracts/deployment/permit/CMTATUpgradeablePermit.sol | 7 |
+| contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol | 20 |
+| contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol | 10 |
+| contracts/interfaces/engine/IDebtEngine.sol | 4 |
+| contracts/interfaces/engine/IDocumentEngine.sol | 4 |
+| contracts/interfaces/engine/IRuleEngine.sol | 10 |
+| contracts/interfaces/engine/ISnapshotEngine.sol | 8 |
+| contracts/interfaces/modules/IAllowlistModule.sol | 11 |
+| contracts/interfaces/modules/IDebtEngineModule.sol | 11 |
+| contracts/interfaces/modules/IDebtModule.sol | 16 |
+| contracts/interfaces/modules/IDocumentEngineModule.sol | 10 |
+| contracts/interfaces/modules/ISnapshotEngineModule.sol | 10 |
+| contracts/interfaces/technical/ICMTATConstructor.sol | 18 |
+| contracts/interfaces/technical/IERC20Allowance.sol | 4 |
+| contracts/interfaces/technical/IERC5679.sol | 9 |
+| contracts/interfaces/technical/IERC7802.sol | 8 |
+| contracts/interfaces/technical/IGetCCIPAdmin.sol | 5 |
+| contracts/interfaces/technical/IMintBurnToken.sol | 36 |
+| contracts/interfaces/tokenization/ICMTAT.sol | 65 |
+| contracts/interfaces/tokenization/IERC3643Partial.sol | 49 |
+| contracts/interfaces/tokenization/draft-IERC1404.sol | 28 |
+| contracts/interfaces/tokenization/draft-IERC1643.sol | 14 |
+| contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol | 8 |
+| contracts/interfaces/tokenization/draft-IERC7551.sol | 44 |
+| contracts/interfaces/tokenization/draft-IERC7943.sol | 24 |
+| contracts/library/ERC1404ExtendInterfaceId.sol | 4 |
+| contracts/library/RuleEngineInterfaceId.sol | 4 |
+| contracts/modules/0_CMTATBaseCommon.sol | 74 |
+| contracts/modules/0_CMTATBaseCore.sol | 139 |
+| contracts/modules/0_CMTATBaseGeneric.sol | 38 |
+| contracts/modules/0_CMTATBaseSnapshot.sol | 18 |
+| contracts/modules/1_CMTATBaseDocument.sol | 3 |
+| contracts/modules/2_CMTATBaseAccessControl.sol | 33 |
+| contracts/modules/3_CMTATBaseAllowlist.sol | 209 |
+| contracts/modules/3_CMTATBaseRuleEngine.sol | 102 |
+| contracts/modules/4_CMTATBaseDebt.sol | 46 |
+| contracts/modules/4_CMTATBaseERC1404.sol | 51 |
+| contracts/modules/5_CMTATBaseERC20CrossChain.sol | 62 |
+| contracts/modules/6_CMTATBaseDebtEngine.sol | 45 |
+| contracts/modules/6_CMTATBaseERC2612.sol | 79 |
+| contracts/modules/6_CMTATBaseERC2771.sol | 27 |
+| contracts/modules/7_CMTATBaseERC2771Snapshot.sol | 60 |
+| contracts/modules/7_CMTATBaseERC7551Enforcement.sol | 85 |
+| contracts/modules/8_CMTATBaseERC1363.sol | 71 |
+| contracts/modules/8_CMTATBaseERC7551.sol | 9 |
+| contracts/modules/internal/AllowlistModuleInternal.sol | 49 |
+| contracts/modules/internal/ERC20BurnModuleInternal.sol | 22 |
+| contracts/modules/internal/ERC20EnforcementModuleInternal.sol | 136 |
+| contracts/modules/internal/ERC20MintModuleInternal.sol | 36 |
+| contracts/modules/internal/EnforcementModuleInternal.sol | 40 |
+| contracts/modules/internal/ValidationModuleRuleEngineInternal.sol | 37 |
+| contracts/modules/internal/common/EnforcementModuleLibrary.sol | 10 |
+| contracts/modules/wrapper/controllers/ValidationModule.sol | 123 |
+| contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol | 94 |
+| contracts/modules/wrapper/core/ERC20BaseModule.sol | 75 |
+| contracts/modules/wrapper/core/ERC20BurnModule.sol | 49 |
+| contracts/modules/wrapper/core/ERC20MintModule.sol | 36 |
+| contracts/modules/wrapper/core/EnforcementModule.sol | 35 |
+| contracts/modules/wrapper/core/PauseModule.sol | 61 |
+| contracts/modules/wrapper/core/ValidationModuleCore.sol | 32 |
+| contracts/modules/wrapper/core/VersionModule.sol | 8 |
+| contracts/modules/wrapper/extensions/DocumentERC1643Module.sol | 57 |
+| contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol | 46 |
+| contracts/modules/wrapper/extensions/ExtraInformationModule.sol | 81 |
+| contracts/modules/wrapper/extensions/SnapshotEngineModule.sol | 44 |
+| contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol | 16 |
+| contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol | 110 |
+| contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol | 96 |
+| contracts/modules/wrapper/options/AllowlistModule.sol | 43 |
+| contracts/modules/wrapper/options/CCIPModule.sol | 30 |
+| contracts/modules/wrapper/options/DebtEngineModule.sol | 49 |
+| contracts/modules/wrapper/options/DebtModule.sol | 50 |
+| contracts/modules/wrapper/options/DocumentEngineModule.sol | 67 |
+| contracts/modules/wrapper/options/ERC20CrossChainModule.sol | 60 |
+| contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol | 36 |
+| contracts/modules/wrapper/options/ERC2771Module.sol | 8 |
+| contracts/modules/wrapper/options/ERC7551Module.sol | 39 |
+| contracts/modules/wrapper/security/AccessControlModule.sol | 22 |
+| **Total** | **3507** |
+
+
+## Issue Summary
+
+| Category | No. of Issues |
+| --- | --- |
+| High | 2 |
+| Low | 10 |
+
+
+# High Issues
+
+## H-1: Arbitrary `from` Passed to `transferFrom`
+
+Passing an arbitrary `from` address to `transferFrom` (or `safeTransferFrom`) can lead to loss of funds, because anyone can transfer tokens from the `from` address if an approval is made.
+
+11 Found Instances
+
+
+- Found in contracts/modules/0_CMTATBaseCommon.sol [Line: 91](contracts/modules/0_CMTATBaseCommon.sol#L91)
+
+ ```solidity
+ return ERC20BaseModule.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 206](contracts/modules/0_CMTATBaseCore.sol#L206)
+
+ ```solidity
+ return ERC20BaseModule.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 142](contracts/modules/3_CMTATBaseAllowlist.sol#L142)
+
+ ```solidity
+ return CMTATBaseCommon.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 31](contracts/modules/4_CMTATBaseDebt.sol#L31)
+
+ ```solidity
+ return CMTATBaseCommon.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 42](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L42)
+
+ ```solidity
+ return CMTATBaseCommon.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 37](contracts/modules/6_CMTATBaseDebtEngine.sol#L37)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 87](contracts/modules/6_CMTATBaseERC2612.sol#L87)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transferFrom(sender, recipient, amount);
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 36](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L36)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC7551Enforcement.sol [Line: 72](contracts/modules/7_CMTATBaseERC7551Enforcement.sol#L72)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 62](contracts/modules/8_CMTATBaseERC1363.sol#L62)
+
+ ```solidity
+ return CMTATBaseERC7551Enforcement.transferFrom(sender, recipient, amount);
+ ```
+
+- Found in contracts/modules/wrapper/core/ERC20BaseModule.sol [Line: 78](contracts/modules/wrapper/core/ERC20BaseModule.sol#L78)
+
+ ```solidity
+ bool result = ERC20Upgradeable.transferFrom(from, to, value);
+ ```
+
+
+
+
+
+## H-2: Contract locks Ether without a withdraw function
+
+It appears that the contract includes a payable function to accept Ether but lacks a corresponding function to withdraw it, which leads to the Ether being locked in the contract. To resolve this issue, please implement a public or external function that allows for the withdrawal of Ether from the contract.
+
+1 Found Instances
+
+
+- Found in contracts/deployment/CMTATUpgradeableUUPS.sol [Line: 11](contracts/deployment/CMTATUpgradeableUUPS.sol#L11)
+
+ ```solidity
+ contract CMTATUpgradeableUUPS is CMTATBaseERC2771, UUPSUpgradeable {
+ ```
+
+
+
+
+
+# Low Issues
+
+## L-1: Centralization Risk
+
+Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds.
+
+33 Found Instances
+
+
+- Found in contracts/deployment/CMTATUpgradeableUUPS.sol [Line: 32](contracts/deployment/CMTATUpgradeableUUPS.sol#L32)
+
+ ```solidity
+ function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyRole(PROXY_UPGRADE_ROLE) {}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 268](contracts/modules/0_CMTATBaseCore.sol#L268)
+
+ ```solidity
+ function _authorizeForcedBurn() internal virtual onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 270](contracts/modules/0_CMTATBaseCore.sol#L270)
+
+ ```solidity
+ function _authorizeMint() internal virtual override(ERC20MintModule) onlyRole(MINTER_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 272](contracts/modules/0_CMTATBaseCore.sol#L272)
+
+ ```solidity
+ function _authorizeBurn() internal virtual override(ERC20BurnModule) onlyRole(BURNER_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 274](contracts/modules/0_CMTATBaseCore.sol#L274)
+
+ ```solidity
+ function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 275](contracts/modules/0_CMTATBaseCore.sol#L275)
+
+ ```solidity
+ function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 277](contracts/modules/0_CMTATBaseCore.sol#L277)
+
+ ```solidity
+ function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 279](contracts/modules/0_CMTATBaseCore.sol#L279)
+
+ ```solidity
+ function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseGeneric.sol [Line: 86](contracts/modules/0_CMTATBaseGeneric.sol#L86)
+
+ ```solidity
+ function _authorizeDocumentManagement() internal virtual override(DocumentERC1643Module) onlyRole(DOCUMENT_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseGeneric.sol [Line: 87](contracts/modules/0_CMTATBaseGeneric.sol#L87)
+
+ ```solidity
+ function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) onlyRole(EXTRA_INFORMATION_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 66](contracts/modules/2_CMTATBaseAccessControl.sol#L66)
+
+ ```solidity
+ function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 72](contracts/modules/2_CMTATBaseAccessControl.sol#L72)
+
+ ```solidity
+ function _authorizeMint() internal virtual override(ERC20MintModule) onlyRole(MINTER_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 78](contracts/modules/2_CMTATBaseAccessControl.sol#L78)
+
+ ```solidity
+ function _authorizeBurn() internal virtual override(ERC20BurnModule) onlyRole(BURNER_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 84](contracts/modules/2_CMTATBaseAccessControl.sol#L84)
+
+ ```solidity
+ function _authorizeDocumentManagement() internal virtual override(DocumentERC1643Module) onlyRole(DOCUMENT_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 90](contracts/modules/2_CMTATBaseAccessControl.sol#L90)
+
+ ```solidity
+ function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) onlyRole(EXTRA_INFORMATION_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 96](contracts/modules/2_CMTATBaseAccessControl.sol#L96)
+
+ ```solidity
+ function _authorizeERC20Enforcer() internal virtual override(ERC20EnforcementModule) onlyRole(ERC20ENFORCER_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 102](contracts/modules/2_CMTATBaseAccessControl.sol#L102)
+
+ ```solidity
+ function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 214](contracts/modules/3_CMTATBaseAllowlist.sol#L214)
+
+ ```solidity
+ function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 215](contracts/modules/3_CMTATBaseAllowlist.sol#L215)
+
+ ```solidity
+ function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 217](contracts/modules/3_CMTATBaseAllowlist.sol#L217)
+
+ ```solidity
+ function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 219](contracts/modules/3_CMTATBaseAllowlist.sol#L219)
+
+ ```solidity
+ function _authorizeAllowlistManagement() internal virtual override(AllowlistModule) onlyRole(ALLOWLIST_ROLE) {}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 169](contracts/modules/3_CMTATBaseRuleEngine.sol#L169)
+
+ ```solidity
+ function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 170](contracts/modules/3_CMTATBaseRuleEngine.sol#L170)
+
+ ```solidity
+ function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 172](contracts/modules/3_CMTATBaseRuleEngine.sol#L172)
+
+ ```solidity
+ function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 174](contracts/modules/3_CMTATBaseRuleEngine.sol#L174)
+
+ ```solidity
+ function _authorizeRuleEngineManagement() internal virtual override(ValidationModuleRuleEngine) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 58](contracts/modules/4_CMTATBaseDebt.sol#L58)
+
+ ```solidity
+ function _authorizeDebtManagement() internal virtual override(DebtModule) onlyRole(DEBT_ROLE){}
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 60](contracts/modules/4_CMTATBaseDebt.sol#L60)
+
+ ```solidity
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 113](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L113)
+
+ ```solidity
+ function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {}
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 133](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L133)
+
+ ```solidity
+ function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{}
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 140](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L140)
+
+ ```solidity
+ function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{}
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 68](contracts/modules/6_CMTATBaseDebtEngine.sol#L68)
+
+ ```solidity
+ function _authorizeDebtEngineManagement() internal virtual override(DebtEngineModule) onlyRole(DEBT_ENGINE_ROLE) {}
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 70](contracts/modules/6_CMTATBaseDebtEngine.sol#L70)
+
+ ```solidity
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 89](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L89)
+
+ ```solidity
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+ ```
+
+
+
+
+
+## L-2: Unsafe ERC20 Operation
+
+ERC20 functions may not behave as expected. For example: return values are not always meaningful. It is recommended to use OpenZeppelin's SafeERC20 library.
+
+25 Found Instances
+
+
+- Found in contracts/modules/0_CMTATBaseCommon.sol [Line: 91](contracts/modules/0_CMTATBaseCommon.sol#L91)
+
+ ```solidity
+ return ERC20BaseModule.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 190](contracts/modules/0_CMTATBaseCore.sol#L190)
+
+ ```solidity
+ return ERC20Upgradeable.approve(spender, value);
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 206](contracts/modules/0_CMTATBaseCore.sol#L206)
+
+ ```solidity
+ return ERC20BaseModule.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 124](contracts/modules/3_CMTATBaseAllowlist.sol#L124)
+
+ ```solidity
+ return ERC20Upgradeable.approve(spender, value);
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 133](contracts/modules/3_CMTATBaseAllowlist.sol#L133)
+
+ ```solidity
+ return CMTATBaseCommon.transfer(to, value);
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 130](contracts/modules/3_CMTATBaseRuleEngine.sol#L130)
+
+ ```solidity
+ return ERC20Upgradeable.approve(spender, value);
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 19](contracts/modules/4_CMTATBaseDebt.sol#L19)
+
+ ```solidity
+ return CMTATBaseRuleEngine.approve(spender, value);
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 25](contracts/modules/4_CMTATBaseDebt.sol#L25)
+
+ ```solidity
+ return CMTATBaseCommon.transfer(to, value);
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 24](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L24)
+
+ ```solidity
+ return CMTATBaseRuleEngine.approve(spender, value);
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 27](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L27)
+
+ ```solidity
+ return CMTATBaseCommon.transfer(to, value);
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 31](contracts/modules/6_CMTATBaseDebtEngine.sol#L31)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transfer(to, value);
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 37](contracts/modules/6_CMTATBaseDebtEngine.sol#L37)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 43](contracts/modules/6_CMTATBaseDebtEngine.sol#L43)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.approve(spender, value);
+ ```
+
+- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 61](contracts/modules/6_CMTATBaseERC2612.sol#L61)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.approve(spender, value);
+ ```
+
+- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 71](contracts/modules/6_CMTATBaseERC2612.sol#L71)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transfer(to, value);
+ ```
+
+- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 87](contracts/modules/6_CMTATBaseERC2612.sol#L87)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transferFrom(sender, recipient, amount);
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 30](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L30)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transfer(to, value);
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 36](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L36)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 42](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L42)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.approve(spender, value);
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC7551Enforcement.sol [Line: 64](contracts/modules/7_CMTATBaseERC7551Enforcement.sol#L64)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transfer(to, value);
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC7551Enforcement.sol [Line: 72](contracts/modules/7_CMTATBaseERC7551Enforcement.sol#L72)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.transferFrom(from, to, value);
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC7551Enforcement.sol [Line: 80](contracts/modules/7_CMTATBaseERC7551Enforcement.sol#L80)
+
+ ```solidity
+ return CMTATBaseERC20CrossChain.approve(spender, value);
+ ```
+
+- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 39](contracts/modules/8_CMTATBaseERC1363.sol#L39)
+
+ ```solidity
+ return CMTATBaseERC7551Enforcement.approve(spender, value);
+ ```
+
+- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 46](contracts/modules/8_CMTATBaseERC1363.sol#L46)
+
+ ```solidity
+ return CMTATBaseERC7551Enforcement.transfer(to, value);
+ ```
+
+- Found in contracts/modules/wrapper/core/ERC20BaseModule.sol [Line: 78](contracts/modules/wrapper/core/ERC20BaseModule.sol#L78)
+
+ ```solidity
+ bool result = ERC20Upgradeable.transferFrom(from, to, value);
+ ```
+
+
+
+
+
+## L-3: Unspecific Solidity Pragma
+
+Consider using a specific version of Solidity in your contracts instead of a wide version. For example, instead of `pragma solidity ^0.8.0;`, use `pragma solidity 0.8.0;`
+
+91 Found Instances
+
+
+- Found in contracts/deployment/CMTATStandardStandalone.sol [Line: 3](contracts/deployment/CMTATStandardStandalone.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/CMTATStandardUpgradeable.sol [Line: 3](contracts/deployment/CMTATStandardUpgradeable.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/CMTATUpgradeableUUPS.sol [Line: 3](contracts/deployment/CMTATUpgradeableUUPS.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol [Line: 3](contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol [Line: 3](contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol [Line: 3](contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol [Line: 3](contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol [Line: 3](contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol [Line: 3](contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/debt/CMTATStandaloneDebt.sol [Line: 3](contracts/deployment/debt/CMTATStandaloneDebt.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/debt/CMTATUpgradeableDebt.sol [Line: 3](contracts/deployment/debt/CMTATUpgradeableDebt.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol [Line: 3](contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol [Line: 3](contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/light/CMTATStandaloneLight.sol [Line: 3](contracts/deployment/light/CMTATStandaloneLight.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/light/CMTATUpgradeableLight.sol [Line: 3](contracts/deployment/light/CMTATUpgradeableLight.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/permit/CMTATStandalonePermit.sol [Line: 3](contracts/deployment/permit/CMTATStandalonePermit.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/permit/CMTATUpgradeablePermit.sol [Line: 3](contracts/deployment/permit/CMTATUpgradeablePermit.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol [Line: 3](contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol [Line: 3](contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/engine/IDebtEngine.sol [Line: 3](contracts/interfaces/engine/IDebtEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/engine/IDocumentEngine.sol [Line: 3](contracts/interfaces/engine/IDocumentEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/engine/IRuleEngine.sol [Line: 3](contracts/interfaces/engine/IRuleEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/engine/ISnapshotEngine.sol [Line: 3](contracts/interfaces/engine/ISnapshotEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/IAllowlistModule.sol [Line: 4](contracts/interfaces/modules/IAllowlistModule.sol#L4)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/IDebtEngineModule.sol [Line: 4](contracts/interfaces/modules/IDebtEngineModule.sol#L4)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/IDebtModule.sol [Line: 4](contracts/interfaces/modules/IDebtModule.sol#L4)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/IDocumentEngineModule.sol [Line: 3](contracts/interfaces/modules/IDocumentEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/ISnapshotEngineModule.sol [Line: 3](contracts/interfaces/modules/ISnapshotEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/ICMTATConstructor.sol [Line: 2](contracts/interfaces/technical/ICMTATConstructor.sol#L2)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IERC20Allowance.sol [Line: 3](contracts/interfaces/technical/IERC20Allowance.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IERC5679.sol [Line: 2](contracts/interfaces/technical/IERC5679.sol#L2)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IERC7802.sol [Line: 3](contracts/interfaces/technical/IERC7802.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IGetCCIPAdmin.sol [Line: 2](contracts/interfaces/technical/IGetCCIPAdmin.sol#L2)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IMintBurnToken.sol [Line: 3](contracts/interfaces/technical/IMintBurnToken.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/ICMTAT.sol [Line: 3](contracts/interfaces/tokenization/ICMTAT.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/IERC3643Partial.sol [Line: 10](contracts/interfaces/tokenization/IERC3643Partial.sol#L10)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC1404.sol [Line: 3](contracts/interfaces/tokenization/draft-IERC1404.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC1643.sol [Line: 3](contracts/interfaces/tokenization/draft-IERC1643.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol [Line: 3](contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC7551.sol [Line: 5](contracts/interfaces/tokenization/draft-IERC7551.sol#L5)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC7943.sol [Line: 3](contracts/interfaces/tokenization/draft-IERC7943.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCommon.sol [Line: 3](contracts/modules/0_CMTATBaseCommon.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 3](contracts/modules/0_CMTATBaseCore.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/0_CMTATBaseGeneric.sol [Line: 3](contracts/modules/0_CMTATBaseGeneric.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/0_CMTATBaseSnapshot.sol [Line: 3](contracts/modules/0_CMTATBaseSnapshot.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/1_CMTATBaseDocument.sol [Line: 3](contracts/modules/1_CMTATBaseDocument.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 3](contracts/modules/2_CMTATBaseAccessControl.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 3](contracts/modules/3_CMTATBaseAllowlist.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 3](contracts/modules/3_CMTATBaseRuleEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 3](contracts/modules/4_CMTATBaseDebt.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/4_CMTATBaseERC1404.sol [Line: 3](contracts/modules/4_CMTATBaseERC1404.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 3](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 3](contracts/modules/6_CMTATBaseDebtEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 3](contracts/modules/6_CMTATBaseERC2612.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/6_CMTATBaseERC2771.sol [Line: 3](contracts/modules/6_CMTATBaseERC2771.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 3](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC7551Enforcement.sol [Line: 3](contracts/modules/7_CMTATBaseERC7551Enforcement.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 3](contracts/modules/8_CMTATBaseERC1363.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/8_CMTATBaseERC7551.sol [Line: 3](contracts/modules/8_CMTATBaseERC7551.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/AllowlistModuleInternal.sol [Line: 3](contracts/modules/internal/AllowlistModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/ERC20BurnModuleInternal.sol [Line: 3](contracts/modules/internal/ERC20BurnModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/ERC20EnforcementModuleInternal.sol [Line: 3](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/ERC20MintModuleInternal.sol [Line: 3](contracts/modules/internal/ERC20MintModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/EnforcementModuleInternal.sol [Line: 3](contracts/modules/internal/EnforcementModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/ValidationModuleRuleEngineInternal.sol [Line: 3](contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/controllers/ValidationModule.sol [Line: 3](contracts/modules/wrapper/controllers/ValidationModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol [Line: 3](contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/ERC20BaseModule.sol [Line: 3](contracts/modules/wrapper/core/ERC20BaseModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/ERC20BurnModule.sol [Line: 3](contracts/modules/wrapper/core/ERC20BurnModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/ERC20MintModule.sol [Line: 3](contracts/modules/wrapper/core/ERC20MintModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/EnforcementModule.sol [Line: 3](contracts/modules/wrapper/core/EnforcementModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/PauseModule.sol [Line: 3](contracts/modules/wrapper/core/PauseModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/ValidationModuleCore.sol [Line: 3](contracts/modules/wrapper/core/ValidationModuleCore.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/VersionModule.sol [Line: 3](contracts/modules/wrapper/core/VersionModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/DocumentERC1643Module.sol [Line: 3](contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol [Line: 3](contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ExtraInformationModule.sol [Line: 3](contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/SnapshotEngineModule.sol [Line: 3](contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol [Line: 3](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol [Line: 3](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol [Line: 3](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/AllowlistModule.sol [Line: 3](contracts/modules/wrapper/options/AllowlistModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/CCIPModule.sol [Line: 3](contracts/modules/wrapper/options/CCIPModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/DebtEngineModule.sol [Line: 3](contracts/modules/wrapper/options/DebtEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/DebtModule.sol [Line: 3](contracts/modules/wrapper/options/DebtModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/DocumentEngineModule.sol [Line: 3](contracts/modules/wrapper/options/DocumentEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 3](contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol [Line: 3](contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC2771Module.sol [Line: 3](contracts/modules/wrapper/options/ERC2771Module.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC7551Module.sol [Line: 3](contracts/modules/wrapper/options/ERC7551Module.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/security/AccessControlModule.sol [Line: 3](contracts/modules/wrapper/security/AccessControlModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+
+
+
+
+## L-4: PUSH0 Opcode
+
+Solc compiler version 0.8.20 switches the default target EVM version to Shanghai, which means that the generated bytecode will include PUSH0 opcodes. Be sure to select the appropriate EVM version in case you intend to deploy on a chain other than mainnet like L2 chains that may not support PUSH0, otherwise deployment of your contracts will fail.
+
+94 Found Instances
+
+
+- Found in contracts/deployment/CMTATStandardStandalone.sol [Line: 3](contracts/deployment/CMTATStandardStandalone.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/CMTATStandardUpgradeable.sol [Line: 3](contracts/deployment/CMTATStandardUpgradeable.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/CMTATUpgradeableUUPS.sol [Line: 3](contracts/deployment/CMTATUpgradeableUUPS.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol [Line: 3](contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol [Line: 3](contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol [Line: 3](contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol [Line: 3](contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol [Line: 3](contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol [Line: 3](contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/debt/CMTATStandaloneDebt.sol [Line: 3](contracts/deployment/debt/CMTATStandaloneDebt.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/debt/CMTATUpgradeableDebt.sol [Line: 3](contracts/deployment/debt/CMTATUpgradeableDebt.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol [Line: 3](contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol [Line: 3](contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/light/CMTATStandaloneLight.sol [Line: 3](contracts/deployment/light/CMTATStandaloneLight.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/light/CMTATUpgradeableLight.sol [Line: 3](contracts/deployment/light/CMTATUpgradeableLight.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/permit/CMTATStandalonePermit.sol [Line: 3](contracts/deployment/permit/CMTATStandalonePermit.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/permit/CMTATUpgradeablePermit.sol [Line: 3](contracts/deployment/permit/CMTATUpgradeablePermit.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol [Line: 3](contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol [Line: 3](contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/engine/IDebtEngine.sol [Line: 3](contracts/interfaces/engine/IDebtEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/engine/IDocumentEngine.sol [Line: 3](contracts/interfaces/engine/IDocumentEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/engine/IRuleEngine.sol [Line: 3](contracts/interfaces/engine/IRuleEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/engine/ISnapshotEngine.sol [Line: 3](contracts/interfaces/engine/ISnapshotEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/IAllowlistModule.sol [Line: 4](contracts/interfaces/modules/IAllowlistModule.sol#L4)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/IDebtEngineModule.sol [Line: 4](contracts/interfaces/modules/IDebtEngineModule.sol#L4)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/IDebtModule.sol [Line: 4](contracts/interfaces/modules/IDebtModule.sol#L4)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/IDocumentEngineModule.sol [Line: 3](contracts/interfaces/modules/IDocumentEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/modules/ISnapshotEngineModule.sol [Line: 3](contracts/interfaces/modules/ISnapshotEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/ICMTATConstructor.sol [Line: 2](contracts/interfaces/technical/ICMTATConstructor.sol#L2)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IERC20Allowance.sol [Line: 3](contracts/interfaces/technical/IERC20Allowance.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IERC5679.sol [Line: 2](contracts/interfaces/technical/IERC5679.sol#L2)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IERC7802.sol [Line: 3](contracts/interfaces/technical/IERC7802.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IGetCCIPAdmin.sol [Line: 2](contracts/interfaces/technical/IGetCCIPAdmin.sol#L2)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/technical/IMintBurnToken.sol [Line: 3](contracts/interfaces/technical/IMintBurnToken.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/ICMTAT.sol [Line: 3](contracts/interfaces/tokenization/ICMTAT.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/IERC3643Partial.sol [Line: 10](contracts/interfaces/tokenization/IERC3643Partial.sol#L10)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC1404.sol [Line: 3](contracts/interfaces/tokenization/draft-IERC1404.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC1643.sol [Line: 3](contracts/interfaces/tokenization/draft-IERC1643.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol [Line: 3](contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC7551.sol [Line: 5](contracts/interfaces/tokenization/draft-IERC7551.sol#L5)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/interfaces/tokenization/draft-IERC7943.sol [Line: 3](contracts/interfaces/tokenization/draft-IERC7943.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/library/ERC1404ExtendInterfaceId.sol [Line: 2](contracts/library/ERC1404ExtendInterfaceId.sol#L2)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/library/RuleEngineInterfaceId.sol [Line: 2](contracts/library/RuleEngineInterfaceId.sol#L2)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCommon.sol [Line: 3](contracts/modules/0_CMTATBaseCommon.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 3](contracts/modules/0_CMTATBaseCore.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/0_CMTATBaseGeneric.sol [Line: 3](contracts/modules/0_CMTATBaseGeneric.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/0_CMTATBaseSnapshot.sol [Line: 3](contracts/modules/0_CMTATBaseSnapshot.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/1_CMTATBaseDocument.sol [Line: 3](contracts/modules/1_CMTATBaseDocument.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 3](contracts/modules/2_CMTATBaseAccessControl.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 3](contracts/modules/3_CMTATBaseAllowlist.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 3](contracts/modules/3_CMTATBaseRuleEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 3](contracts/modules/4_CMTATBaseDebt.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/4_CMTATBaseERC1404.sol [Line: 3](contracts/modules/4_CMTATBaseERC1404.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 3](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 3](contracts/modules/6_CMTATBaseDebtEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 3](contracts/modules/6_CMTATBaseERC2612.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/6_CMTATBaseERC2771.sol [Line: 3](contracts/modules/6_CMTATBaseERC2771.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 3](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC7551Enforcement.sol [Line: 3](contracts/modules/7_CMTATBaseERC7551Enforcement.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 3](contracts/modules/8_CMTATBaseERC1363.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/8_CMTATBaseERC7551.sol [Line: 3](contracts/modules/8_CMTATBaseERC7551.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/AllowlistModuleInternal.sol [Line: 3](contracts/modules/internal/AllowlistModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/ERC20BurnModuleInternal.sol [Line: 3](contracts/modules/internal/ERC20BurnModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/ERC20EnforcementModuleInternal.sol [Line: 3](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/ERC20MintModuleInternal.sol [Line: 3](contracts/modules/internal/ERC20MintModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/EnforcementModuleInternal.sol [Line: 3](contracts/modules/internal/EnforcementModuleInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/ValidationModuleRuleEngineInternal.sol [Line: 3](contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/internal/common/EnforcementModuleLibrary.sol [Line: 3](contracts/modules/internal/common/EnforcementModuleLibrary.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/controllers/ValidationModule.sol [Line: 3](contracts/modules/wrapper/controllers/ValidationModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol [Line: 3](contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/ERC20BaseModule.sol [Line: 3](contracts/modules/wrapper/core/ERC20BaseModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/ERC20BurnModule.sol [Line: 3](contracts/modules/wrapper/core/ERC20BurnModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/ERC20MintModule.sol [Line: 3](contracts/modules/wrapper/core/ERC20MintModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/EnforcementModule.sol [Line: 3](contracts/modules/wrapper/core/EnforcementModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/PauseModule.sol [Line: 3](contracts/modules/wrapper/core/PauseModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/ValidationModuleCore.sol [Line: 3](contracts/modules/wrapper/core/ValidationModuleCore.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/core/VersionModule.sol [Line: 3](contracts/modules/wrapper/core/VersionModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/DocumentERC1643Module.sol [Line: 3](contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol [Line: 3](contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ExtraInformationModule.sol [Line: 3](contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/SnapshotEngineModule.sol [Line: 3](contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol [Line: 3](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol [Line: 3](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol [Line: 3](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/AllowlistModule.sol [Line: 3](contracts/modules/wrapper/options/AllowlistModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/CCIPModule.sol [Line: 3](contracts/modules/wrapper/options/CCIPModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/DebtEngineModule.sol [Line: 3](contracts/modules/wrapper/options/DebtEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/DebtModule.sol [Line: 3](contracts/modules/wrapper/options/DebtModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/DocumentEngineModule.sol [Line: 3](contracts/modules/wrapper/options/DocumentEngineModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 3](contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol [Line: 3](contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC2771Module.sol [Line: 3](contracts/modules/wrapper/options/ERC2771Module.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC7551Module.sol [Line: 3](contracts/modules/wrapper/options/ERC7551Module.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+- Found in contracts/modules/wrapper/security/AccessControlModule.sol [Line: 3](contracts/modules/wrapper/security/AccessControlModule.sol#L3)
+
+ ```solidity
+ pragma solidity ^0.8.20;
+ ```
+
+
+
+
+
+## L-5: Modifier Invoked Only Once
+
+Consider removing the modifier or inlining the logic into the calling function.
+
+8 Found Instances
+
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 57](contracts/modules/0_CMTATBaseCore.sol#L57)
+
+ ```solidity
+ modifier onlyERC20ForcedBurnManager() {
+ ```
+
+- Found in contracts/modules/wrapper/core/PauseModule.sol [Line: 45](contracts/modules/wrapper/core/PauseModule.sol#L45)
+
+ ```solidity
+ modifier onlyDeactivateContractManager() {
+ ```
+
+- Found in contracts/modules/wrapper/extensions/SnapshotEngineModule.sol [Line: 29](contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L29)
+
+ ```solidity
+ modifier onlySnapshooter() {
+ ```
+
+- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol [Line: 27](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L27)
+
+ ```solidity
+ modifier onlyRuleEngineManager() {
+ ```
+
+- Found in contracts/modules/wrapper/options/CCIPModule.sol [Line: 30](contracts/modules/wrapper/options/CCIPModule.sol#L30)
+
+ ```solidity
+ modifier onlyCCIPSetAdmin() {
+ ```
+
+- Found in contracts/modules/wrapper/options/DebtEngineModule.sol [Line: 27](contracts/modules/wrapper/options/DebtEngineModule.sol#L27)
+
+ ```solidity
+ modifier onlyDebtEngineManager {
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 38](contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L38)
+
+ ```solidity
+ modifier onlyBurnerFrom() {
+ ```
+
+- Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 44](contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L44)
+
+ ```solidity
+ modifier onlySelfBurn() {
+ ```
+
+
+
+
+
+## L-6: Empty Block
+
+Consider removing empty blocks.
+
+33 Found Instances
+
+
+- Found in contracts/deployment/CMTATUpgradeableUUPS.sol [Line: 32](contracts/deployment/CMTATUpgradeableUUPS.sol#L32)
+
+ ```solidity
+ function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyRole(PROXY_UPGRADE_ROLE) {}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 268](contracts/modules/0_CMTATBaseCore.sol#L268)
+
+ ```solidity
+ function _authorizeForcedBurn() internal virtual onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 270](contracts/modules/0_CMTATBaseCore.sol#L270)
+
+ ```solidity
+ function _authorizeMint() internal virtual override(ERC20MintModule) onlyRole(MINTER_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 272](contracts/modules/0_CMTATBaseCore.sol#L272)
+
+ ```solidity
+ function _authorizeBurn() internal virtual override(ERC20BurnModule) onlyRole(BURNER_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 274](contracts/modules/0_CMTATBaseCore.sol#L274)
+
+ ```solidity
+ function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 275](contracts/modules/0_CMTATBaseCore.sol#L275)
+
+ ```solidity
+ function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 277](contracts/modules/0_CMTATBaseCore.sol#L277)
+
+ ```solidity
+ function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 279](contracts/modules/0_CMTATBaseCore.sol#L279)
+
+ ```solidity
+ function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseGeneric.sol [Line: 86](contracts/modules/0_CMTATBaseGeneric.sol#L86)
+
+ ```solidity
+ function _authorizeDocumentManagement() internal virtual override(DocumentERC1643Module) onlyRole(DOCUMENT_ROLE){}
+ ```
+
+- Found in contracts/modules/0_CMTATBaseGeneric.sol [Line: 87](contracts/modules/0_CMTATBaseGeneric.sol#L87)
+
+ ```solidity
+ function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) onlyRole(EXTRA_INFORMATION_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 66](contracts/modules/2_CMTATBaseAccessControl.sol#L66)
+
+ ```solidity
+ function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 72](contracts/modules/2_CMTATBaseAccessControl.sol#L72)
+
+ ```solidity
+ function _authorizeMint() internal virtual override(ERC20MintModule) onlyRole(MINTER_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 78](contracts/modules/2_CMTATBaseAccessControl.sol#L78)
+
+ ```solidity
+ function _authorizeBurn() internal virtual override(ERC20BurnModule) onlyRole(BURNER_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 84](contracts/modules/2_CMTATBaseAccessControl.sol#L84)
+
+ ```solidity
+ function _authorizeDocumentManagement() internal virtual override(DocumentERC1643Module) onlyRole(DOCUMENT_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 90](contracts/modules/2_CMTATBaseAccessControl.sol#L90)
+
+ ```solidity
+ function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) onlyRole(EXTRA_INFORMATION_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 96](contracts/modules/2_CMTATBaseAccessControl.sol#L96)
+
+ ```solidity
+ function _authorizeERC20Enforcer() internal virtual override(ERC20EnforcementModule) onlyRole(ERC20ENFORCER_ROLE){}
+ ```
+
+- Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 102](contracts/modules/2_CMTATBaseAccessControl.sol#L102)
+
+ ```solidity
+ function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 214](contracts/modules/3_CMTATBaseAllowlist.sol#L214)
+
+ ```solidity
+ function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 215](contracts/modules/3_CMTATBaseAllowlist.sol#L215)
+
+ ```solidity
+ function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 217](contracts/modules/3_CMTATBaseAllowlist.sol#L217)
+
+ ```solidity
+ function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 219](contracts/modules/3_CMTATBaseAllowlist.sol#L219)
+
+ ```solidity
+ function _authorizeAllowlistManagement() internal virtual override(AllowlistModule) onlyRole(ALLOWLIST_ROLE) {}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 169](contracts/modules/3_CMTATBaseRuleEngine.sol#L169)
+
+ ```solidity
+ function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 170](contracts/modules/3_CMTATBaseRuleEngine.sol#L170)
+
+ ```solidity
+ function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 172](contracts/modules/3_CMTATBaseRuleEngine.sol#L172)
+
+ ```solidity
+ function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}
+ ```
+
+- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 174](contracts/modules/3_CMTATBaseRuleEngine.sol#L174)
+
+ ```solidity
+ function _authorizeRuleEngineManagement() internal virtual override(ValidationModuleRuleEngine) onlyRole(DEFAULT_ADMIN_ROLE){}
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 58](contracts/modules/4_CMTATBaseDebt.sol#L58)
+
+ ```solidity
+ function _authorizeDebtManagement() internal virtual override(DebtModule) onlyRole(DEBT_ROLE){}
+ ```
+
+- Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 60](contracts/modules/4_CMTATBaseDebt.sol#L60)
+
+ ```solidity
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 113](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L113)
+
+ ```solidity
+ function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {}
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 133](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L133)
+
+ ```solidity
+ function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{}
+ ```
+
+- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 140](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L140)
+
+ ```solidity
+ function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{}
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 68](contracts/modules/6_CMTATBaseDebtEngine.sol#L68)
+
+ ```solidity
+ function _authorizeDebtEngineManagement() internal virtual override(DebtEngineModule) onlyRole(DEBT_ENGINE_ROLE) {}
+ ```
+
+- Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 70](contracts/modules/6_CMTATBaseDebtEngine.sol#L70)
+
+ ```solidity
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+ ```
+
+- Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 89](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L89)
+
+ ```solidity
+ function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {}
+ ```
+
+
+
+
+
+## L-7: Unused Error
+
+Consider using or removing the unused error.
+
+1 Found Instances
+
+
+- Found in contracts/interfaces/tokenization/draft-IERC7943.sol [Line: 116](contracts/interfaces/tokenization/draft-IERC7943.sol#L116)
+
+ ```solidity
+ error ERC7943CannotTransfer(address from, address to, uint256 amount);
+ ```
+
+
+
+
+
+## L-8: Loop Contains `require`/`revert`
+
+Avoid `require` / `revert` statements in a loop because a single bad item can cause the whole transaction to fail. It's better to forgive on fail and return failed elements post processing of the loop
+
+4 Found Instances
+
+
+- Found in contracts/modules/internal/ERC20BurnModuleInternal.sol [Line: 34](contracts/modules/internal/ERC20BurnModuleInternal.sol#L34)
+
+ ```solidity
+ for (uint256 i = 0; i < accounts.length; ++i ) {
+ ```
+
+- Found in contracts/modules/internal/ERC20MintModuleInternal.sol [Line: 38](contracts/modules/internal/ERC20MintModuleInternal.sol#L38)
+
+ ```solidity
+ for (uint256 i = 0; i < accounts.length; ++i ) {
+ ```
+
+- Found in contracts/modules/internal/ERC20MintModuleInternal.sol [Line: 52](contracts/modules/internal/ERC20MintModuleInternal.sol#L52)
+
+ ```solidity
+ for (uint256 i = 0; i < tos.length; ++i) {
+ ```
+
+- Found in contracts/modules/internal/EnforcementModuleInternal.sol [Line: 48](contracts/modules/internal/EnforcementModuleInternal.sol#L48)
+
+ ```solidity
+ for (uint256 i = 0; i < accounts.length; ++i) {
+ ```
+
+
+
+
+
+## L-9: Costly operations inside loop
+
+Invoking `SSTORE` operations in loops may waste gas. Use a local variable to hold the loop computation result.
+
+5 Found Instances
+
+
+- Found in contracts/modules/internal/AllowlistModuleInternal.sol [Line: 51](contracts/modules/internal/AllowlistModuleInternal.sol#L51)
+
+ ```solidity
+ for (uint256 i = 0; i < accounts.length; ++i) {
+ ```
+
+- Found in contracts/modules/internal/ERC20BurnModuleInternal.sol [Line: 34](contracts/modules/internal/ERC20BurnModuleInternal.sol#L34)
+
+ ```solidity
+ for (uint256 i = 0; i < accounts.length; ++i ) {
+ ```
+
+- Found in contracts/modules/internal/ERC20MintModuleInternal.sol [Line: 38](contracts/modules/internal/ERC20MintModuleInternal.sol#L38)
+
+ ```solidity
+ for (uint256 i = 0; i < accounts.length; ++i ) {
+ ```
+
+- Found in contracts/modules/internal/ERC20MintModuleInternal.sol [Line: 52](contracts/modules/internal/ERC20MintModuleInternal.sol#L52)
+
+ ```solidity
+ for (uint256 i = 0; i < tos.length; ++i) {
+ ```
+
+- Found in contracts/modules/internal/EnforcementModuleInternal.sol [Line: 48](contracts/modules/internal/EnforcementModuleInternal.sol#L48)
+
+ ```solidity
+ for (uint256 i = 0; i < accounts.length; ++i) {
+ ```
+
+
+
+
+
+## L-10: Unchecked Return
+
+Function returns a value but it is ignored. Consider checking the return value.
+
+1 Found Instances
+
+
+- Found in contracts/modules/wrapper/security/AccessControlModule.sol [Line: 31](contracts/modules/wrapper/security/AccessControlModule.sol#L31)
+
+ ```solidity
+ _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ ```
+
+
+
+
+
diff --git a/doc/audits/tools/mythril/v2.5.0/myth_proxy_report.md b/doc/security/tools/mythril/v2.5.0/myth_proxy_report.md
similarity index 100%
rename from doc/audits/tools/mythril/v2.5.0/myth_proxy_report.md
rename to doc/security/tools/mythril/v2.5.0/myth_proxy_report.md
diff --git a/doc/audits/tools/mythril/v2.5.0/myth_standalone_report.md b/doc/security/tools/mythril/v2.5.0/myth_standalone_report.md
similarity index 100%
rename from doc/audits/tools/mythril/v2.5.0/myth_standalone_report.md
rename to doc/security/tools/mythril/v2.5.0/myth_standalone_report.md
diff --git a/doc/audits/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_AuditAgent_Report_Comment_v3.0.0-rc5.pdf b/doc/security/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_AuditAgent_Report_Comment_v3.0.0-rc5.pdf
similarity index 100%
rename from doc/audits/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_AuditAgent_Report_Comment_v3.0.0-rc5.pdf
rename to doc/security/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_AuditAgent_Report_Comment_v3.0.0-rc5.pdf
diff --git a/doc/audits/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_AuditAgent_Report_Commentv3.0.0-rc5.md b/doc/security/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_AuditAgent_Report_Commentv3.0.0-rc5.md
similarity index 100%
rename from doc/audits/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_AuditAgent_Report_Commentv3.0.0-rc5.md
rename to doc/security/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_AuditAgent_Report_Commentv3.0.0-rc5.md
diff --git a/doc/audits/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_audit_agent_reportv3.0.0-rc5.pdf b/doc/security/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_audit_agent_reportv3.0.0-rc5.pdf
similarity index 100%
rename from doc/audits/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_audit_agent_reportv3.0.0-rc5.pdf
rename to doc/security/tools/nethermind-audit-agent/v3.0.0-rc5/CMTAT_audit_agent_reportv3.0.0-rc5.pdf
diff --git a/doc/audits/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.md b/doc/security/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.md
similarity index 100%
rename from doc/audits/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.md
rename to doc/security/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.md
diff --git a/doc/audits/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.pdf b/doc/security/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.pdf
similarity index 100%
rename from doc/audits/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.pdf
rename to doc/security/tools/nethermind-audit-agent/v3.1.0/CMTAT_AuditAgent_Report_Comment_v3.1.0.pdf
diff --git a/doc/audits/tools/nethermind-audit-agent/v3.1.0/CMTAT_audit_agent_reportv3.1.0.pdf b/doc/security/tools/nethermind-audit-agent/v3.1.0/CMTAT_audit_agent_reportv3.1.0.pdf
similarity index 100%
rename from doc/audits/tools/nethermind-audit-agent/v3.1.0/CMTAT_audit_agent_reportv3.1.0.pdf
rename to doc/security/tools/nethermind-audit-agent/v3.1.0/CMTAT_audit_agent_reportv3.1.0.pdf
diff --git a/doc/audits/tools/slither/v2.3.0-slither-report.md b/doc/security/tools/slither/archive/v2.3.0-slither-report.md
similarity index 100%
rename from doc/audits/tools/slither/v2.3.0-slither-report.md
rename to doc/security/tools/slither/archive/v2.3.0-slither-report.md
diff --git a/doc/audits/tools/slither/v2.5.0-slither-report.md b/doc/security/tools/slither/archive/v2.5.0-slither-report.md
similarity index 100%
rename from doc/audits/tools/slither/v2.5.0-slither-report.md
rename to doc/security/tools/slither/archive/v2.5.0-slither-report.md
diff --git a/doc/audits/tools/slither/v3.0.0-slither-report.md b/doc/security/tools/slither/archive/v3.0.0-slither-report.md
similarity index 100%
rename from doc/audits/tools/slither/v3.0.0-slither-report.md
rename to doc/security/tools/slither/archive/v3.0.0-slither-report.md
diff --git a/doc/audits/tools/slither/v3.1.0-slither-report.md b/doc/security/tools/slither/archive/v3.1.0-slither-report.md
similarity index 100%
rename from doc/audits/tools/slither/v3.1.0-slither-report.md
rename to doc/security/tools/slither/archive/v3.1.0-slither-report.md
diff --git a/doc/audits/tools/slither/v3.2.0-slither-report.md b/doc/security/tools/slither/archive/v3.2.0-slither-report.md
similarity index 98%
rename from doc/audits/tools/slither/v3.2.0-slither-report.md
rename to doc/security/tools/slither/archive/v3.2.0-slither-report.md
index d5d6c6ce..0b46721a 100644
--- a/doc/audits/tools/slither/v3.2.0-slither-report.md
+++ b/doc/security/tools/slither/archive/v3.2.0-slither-report.md
@@ -130,9 +130,9 @@ contracts/modules/6_CMTATBaseERC1363.sol#L144-L151
- [ ] ID-16
-[CMTATBaseERC2771._msgData()](contracts/modules/5_CMTATBaseERC2771.sol#L41-L48) is never used and should be removed
+[CMTATBaseERC2771._msgData()](contracts/modules/6_CMTATBaseERC2771.sol#L41-L48) is never used and should be removed
-contracts/modules/5_CMTATBaseERC2771.sol#L41-L48
+contracts/modules/6_CMTATBaseERC2771.sol#L41-L48
- [ ] ID-17
@@ -318,9 +318,9 @@ contracts/modules/wrapper/options/ERC7551Module.sol#L20
- [ ] ID-46
-Parameter [CMTATBaseERC20CrossChain.supportsInterface(bytes4)._interfaceId](contracts/modules/4_CMTATBaseERC20CrossChain.sol#L75) is not in mixedCase
+Parameter [CMTATBaseERC20CrossChain.supportsInterface(bytes4)._interfaceId](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L75) is not in mixedCase
-contracts/modules/4_CMTATBaseERC20CrossChain.sol#L75
+contracts/modules/5_CMTATBaseERC20CrossChain.sol#L75
- [ ] ID-47
diff --git a/doc/security/tools/slither/v3.3.0-slither-feedback.md b/doc/security/tools/slither/v3.3.0-slither-feedback.md
new file mode 100644
index 00000000..4d7ead20
--- /dev/null
+++ b/doc/security/tools/slither/v3.3.0-slither-feedback.md
@@ -0,0 +1,59 @@
+# CMTAT Maintainer Feedback - Slither v3.3.0
+
+Date: 2026-05-20
+Source report: [v3.3.0-slither-report.md](./v3.3.0-slither-report.md)
+
+## Scope
+This document provides CMTA maintainer assessment of Slither findings for CMTAT v3.3.0.
+
+## Report Snapshot
+
+- Medium: 1 (`uninitialized-local`)
+- Low: 1 category (`calls-loop`, 28 instances)
+- Informational: 4 categories (`assembly`, `dead-code`, `naming-convention`, `unindexed-event-address`)
+
+## Findings Summary
+
+| ID | Detector | Slither Impact | Instances | CMTA Validity | CMTA Assessment | Status |
+|---|---|---|---:|---|---|---|
+| S-1 | `uninitialized-local` | Medium | 1 | Invalid (false positive) | Local variable default value is `0` in Solidity; behavior is intentional in this path | Closed |
+| S-2 | `calls-loop` | Low | 28 | Design choice / context dependent | External calls in loop are expected in batch + module-hook architecture | Accepted |
+| S-3 | `assembly` | Informational | 14 | Valid | Expected usage for storage-slot patterns (ERC-7201 style) | Accepted |
+| S-4 | `dead-code` | Informational | 1 | Invalid (false positive) | `_msgData()` override is mandatory for multiple-inheritance disambiguation | Closed |
+| S-5 | `naming-convention` | Informational | 57 | Style-only | Naming style warnings; no security impact | Closed |
+| S-6 | `unindexed-event-address` | Informational | 1 | Valid (minor) | Event indexing optimization/opsec suggestion | Accepted |
+
+## Detailed Assessment
+
+### S-1: `uninitialized-local` (Medium)
+- Detector points to a local variable in `ERC20EnforcementModuleInternal._unfreezeTokens(...)`.
+- CMTA assessment: **Invalid (false positive)**.
+- Rationale: in Solidity, local `uint256` variables default to `0`. In this function, `activeBalance = 0` is intentional for the branch where frozen balance is greater than or equal to wallet balance (ERC-7943 permissive frozen model).
+- Action: no functional fix required; optional readability refactor can explicitly initialize to `0`.
+
+### S-2: `calls-loop` (Low)
+- Most instances come from batch operations that intentionally trigger compliance/snapshot hooks per item.
+- CMTA assessment: **Design choice / context dependent**.
+- Rationale: batch operations are intentionally atomic and must execute policy hooks per transfer.
+- Action: accepted with operational guidance (gas budgeting and trusted-module assumptions).
+
+### S-3: `assembly` (Informational)
+- Instances are expected where explicit storage-slot placement is used.
+- CMTA assessment: **Valid but expected**.
+- Action: no change required.
+
+### S-4: `dead-code` (Informational)
+- CMTA assessment: **Invalid (false positive)**.
+- Rationale: `CMTATBaseERC2771Snapshot._msgData()` is required to resolve multiple inheritance between `ContextUpgradeable` and `CMTATBaseERC2771`. Removing it causes compilation errors (`Derived contract must override function "_msgData"`), including in snapshot deployments and engine mocks.
+- Action: keep as-is.
+
+### S-5: `naming-convention` (Informational)
+- CMTA assessment: **Style-only**.
+- Action: no security-driven change required.
+
+### S-6: `unindexed-event-address` (Informational)
+- CMTA assessment: **Valid minor improvement item**.
+- Action: optional optimization/backlog item.
+
+## Final Position
+From a CMTA maintainer perspective, the v3.3.0 Slither output is mostly architectural/style/context-driven and does not currently indicate a confirmed critical correctness issue.
diff --git a/doc/security/tools/slither/v3.3.0-slither-report.md b/doc/security/tools/slither/v3.3.0-slither-report.md
new file mode 100644
index 00000000..91d6df42
--- /dev/null
+++ b/doc/security/tools/slither/v3.3.0-slither-report.md
@@ -0,0 +1,822 @@
+**THIS CHECKLIST IS NOT COMPLETE**. Use `--show-ignored-findings` to show all the results.
+Summary
+ - [uninitialized-local](#uninitialized-local) (1 results) (Medium)
+ - [calls-loop](#calls-loop) (28 results) (Low)
+ - [assembly](#assembly) (14 results) (Informational)
+ - [dead-code](#dead-code) (1 results) (Informational)
+ - [naming-convention](#naming-convention) (57 results) (Informational)
+## uninitialized-local
+Impact: Medium
+Confidence: Medium
+ - [ ] ID-0
+[ERC20EnforcementModuleInternal._unfreezeTokens(address,uint256).activeBalance](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L90) is a local variable never initialized
+
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L90
+
+
+## calls-loop
+Impact: Low
+Confidence: Medium
+ - [ ] ID-1
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[],bytes)
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseERC20CrossChain._burnOverride(address,uint256)
+ CMTATBaseCommon._burnOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-2
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20MintModule.batchMint(address[],uint256[])
+ ERC20MintModuleInternal._batchMint(address[],uint256[])
+ CMTATBaseERC20CrossChain._mintOverride(address,uint256)
+ CMTATBaseCommon._mintOverride(address,uint256)
+ ERC20MintModuleInternal._mintOverride(address,uint256)
+ ERC20Upgradeable._mint(address,uint256)
+ CMTATBaseDebtEngine._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-3
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[])
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseCommon._burnOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-4
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20MintModule.batchMint(address[],uint256[])
+ ERC20MintModuleInternal._batchMint(address[],uint256[])
+ CMTATBaseERC20CrossChain._mintOverride(address,uint256)
+ CMTATBaseCommon._mintOverride(address,uint256)
+ ERC20MintModuleInternal._mintOverride(address,uint256)
+ ERC20Upgradeable._mint(address,uint256)
+ CMTATBaseERC2771Snapshot._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-5
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145)
+ Calls stack containing the loop:
+ ERC20MintModule.batchMint(address[],uint256[])
+ ERC20MintModuleInternal._batchMint(address[],uint256[])
+ CMTATBaseERC20CrossChain._mintOverride(address,uint256)
+ CMTATBaseCommon._mintOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-6
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[])
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseERC20CrossChain._burnOverride(address,uint256)
+ CMTATBaseCommon._burnOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-7
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[])
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseERC20CrossChain._burnOverride(address,uint256)
+ CMTATBaseCommon._burnOverride(address,uint256)
+ ERC20BurnModuleInternal._burnOverride(address,uint256)
+ ERC20Upgradeable._burn(address,uint256)
+ CMTATBaseERC2771Snapshot._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-8
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[],bytes)
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseCommon._burnOverride(address,uint256)
+ ERC20BurnModuleInternal._burnOverride(address,uint256)
+ ERC20Upgradeable._burn(address,uint256)
+ CMTATBaseDebt._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-9
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20MintModule.batchTransfer(address[],uint256[])
+ ERC20MintModuleInternal._batchTransfer(address[],uint256[])
+ CMTATBaseERC20CrossChain._minterTransferOverride(address,address,uint256)
+ CMTATBaseCommon._minterTransferOverride(address,address,uint256)
+ ERC20MintModuleInternal._minterTransferOverride(address,address,uint256)
+ ERC20Upgradeable._transfer(address,address,uint256)
+ CMTATBaseDebtEngine._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-10
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[])
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseERC20CrossChain._burnOverride(address,uint256)
+ CMTATBaseCommon._burnOverride(address,uint256)
+ ERC20BurnModuleInternal._burnOverride(address,uint256)
+ ERC20Upgradeable._burn(address,uint256)
+ CMTATBaseDebtEngine._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-11
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20MintModule.batchTransfer(address[],uint256[])
+ ERC20MintModuleInternal._batchTransfer(address[],uint256[])
+ CMTATBaseERC20CrossChain._minterTransferOverride(address,address,uint256)
+ CMTATBaseCommon._minterTransferOverride(address,address,uint256)
+ ERC20MintModuleInternal._minterTransferOverride(address,address,uint256)
+ ERC20Upgradeable._transfer(address,address,uint256)
+ CMTATBaseERC2771Snapshot._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-12
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145)
+ Calls stack containing the loop:
+ ERC20MintModule.batchTransfer(address[],uint256[])
+ ERC20MintModuleInternal._batchTransfer(address[],uint256[])
+ CMTATBaseCommon._minterTransferOverride(address,address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-13
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[],bytes)
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseERC20CrossChain._burnOverride(address,uint256)
+ CMTATBaseCommon._burnOverride(address,uint256)
+ ERC20BurnModuleInternal._burnOverride(address,uint256)
+ ERC20Upgradeable._burn(address,uint256)
+ CMTATBaseERC2771Snapshot._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-14
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143)
+ Calls stack containing the loop:
+ ERC20MintModule.batchTransfer(address[],uint256[])
+ ERC20MintModuleInternal._batchTransfer(address[],uint256[])
+ CMTATBaseERC20CrossChain._minterTransferOverride(address,address,uint256)
+ CMTATBaseCommon._minterTransferOverride(address,address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-15
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[],bytes)
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseERC20CrossChain._burnOverride(address,uint256)
+ CMTATBaseCommon._burnOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-16
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145)
+ Calls stack containing the loop:
+ ERC20MintModule.batchTransfer(address[],uint256[])
+ ERC20MintModuleInternal._batchTransfer(address[],uint256[])
+ CMTATBaseERC20CrossChain._minterTransferOverride(address,address,uint256)
+ CMTATBaseCommon._minterTransferOverride(address,address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-17
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20MintModule.batchMint(address[],uint256[])
+ ERC20MintModuleInternal._batchMint(address[],uint256[])
+ CMTATBaseCommon._mintOverride(address,uint256)
+ ERC20MintModuleInternal._mintOverride(address,uint256)
+ ERC20Upgradeable._mint(address,uint256)
+ CMTATBaseDebt._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-18
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143)
+ Calls stack containing the loop:
+ ERC20MintModule.batchMint(address[],uint256[])
+ ERC20MintModuleInternal._batchMint(address[],uint256[])
+ CMTATBaseERC20CrossChain._mintOverride(address,uint256)
+ CMTATBaseCommon._mintOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-19
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[])
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseCommon._burnOverride(address,uint256)
+ ERC20BurnModuleInternal._burnOverride(address,uint256)
+ ERC20Upgradeable._burn(address,uint256)
+ CMTATBaseDebt._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-20
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143)
+ Calls stack containing the loop:
+ ERC20MintModule.batchMint(address[],uint256[])
+ ERC20MintModuleInternal._batchMint(address[],uint256[])
+ CMTATBaseCommon._mintOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-21
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145)
+ Calls stack containing the loop:
+ ERC20MintModule.batchMint(address[],uint256[])
+ ERC20MintModuleInternal._batchMint(address[],uint256[])
+ CMTATBaseCommon._mintOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-22
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[])
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseCommon._burnOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-23
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20MintModule.batchTransfer(address[],uint256[])
+ ERC20MintModuleInternal._batchTransfer(address[],uint256[])
+ CMTATBaseCommon._minterTransferOverride(address,address,uint256)
+ ERC20MintModuleInternal._minterTransferOverride(address,address,uint256)
+ ERC20Upgradeable._transfer(address,address,uint256)
+ CMTATBaseDebt._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-24
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[],bytes)
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseCommon._burnOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-25
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143)
+ Calls stack containing the loop:
+ ERC20MintModule.batchTransfer(address[],uint256[])
+ ERC20MintModuleInternal._batchTransfer(address[],uint256[])
+ CMTATBaseCommon._minterTransferOverride(address,address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-26
+[CMTATBaseSnapshot._update(address,address,uint256)](contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30) has external calls inside a loop: [snapshotEngineLocal.operateOnTransfer(from,to,fromBalanceBefore,toBalanceBefore,totalSupplyBefore)](contracts/modules/0_CMTATBaseSnapshot.sol#L26)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[],bytes)
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseERC20CrossChain._burnOverride(address,uint256)
+ CMTATBaseCommon._burnOverride(address,uint256)
+ ERC20BurnModuleInternal._burnOverride(address,uint256)
+ ERC20Upgradeable._burn(address,uint256)
+ CMTATBaseDebtEngine._update(address,address,uint256)
+
+contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30
+
+
+ - [ ] ID-27
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[])
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseERC20CrossChain._burnOverride(address,uint256)
+ CMTATBaseCommon._burnOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+ - [ ] ID-28
+[ValidationModuleRuleEngine._transferred(address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143)
+ Calls stack containing the loop:
+ ERC20BurnModule.batchBurn(address[],uint256[],bytes)
+ ERC20BurnModuleInternal._batchBurn(address[],uint256[])
+ CMTATBaseCommon._burnOverride(address,uint256)
+ CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256)
+
+contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148
+
+
+## assembly
+Impact: Informational
+Confidence: High
+ - [ ] ID-29
+[ExtraInformationModule._getExtraInformationModuleStorage()](contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L156-L160) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L157-L159)
+
+contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L156-L160
+
+
+ - [ ] ID-30
+[EnforcementModuleInternal._getEnforcementModuleInternalStorage()](contracts/modules/internal/EnforcementModuleInternal.sol#L63-L67) uses assembly
+ - [INLINE ASM](contracts/modules/internal/EnforcementModuleInternal.sol#L64-L66)
+
+contracts/modules/internal/EnforcementModuleInternal.sol#L63-L67
+
+
+ - [ ] ID-31
+[SnapshotEngineModule._getSnapshotEngineModuleStorage()](contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L94-L98) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L95-L97)
+
+contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L94-L98
+
+
+ - [ ] ID-32
+[DocumentEngineModule._getDocumentEngineModuleStorage()](contracts/modules/wrapper/options/DocumentEngineModule.sol#L121-L125) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/options/DocumentEngineModule.sol#L122-L124)
+
+contracts/modules/wrapper/options/DocumentEngineModule.sol#L121-L125
+
+
+ - [ ] ID-33
+[ERC20EnforcementModuleInternal._getEnforcementModuleStorage()](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L185-L189) uses assembly
+ - [INLINE ASM](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L186-L188)
+
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L185-L189
+
+
+ - [ ] ID-34
+[PauseModule._getPauseModuleStorage()](contracts/modules/wrapper/core/PauseModule.sol#L125-L129) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/core/PauseModule.sol#L126-L128)
+
+contracts/modules/wrapper/core/PauseModule.sol#L125-L129
+
+
+ - [ ] ID-35
+[DebtModule._getDebtModuleStorage()](contracts/modules/wrapper/options/DebtModule.sol#L101-L105) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/options/DebtModule.sol#L102-L104)
+
+contracts/modules/wrapper/options/DebtModule.sol#L101-L105
+
+
+ - [ ] ID-36
+[CCIPModule._getCCIPModuleStorage()](contracts/modules/wrapper/options/CCIPModule.sol#L66-L70) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/options/CCIPModule.sol#L67-L69)
+
+contracts/modules/wrapper/options/CCIPModule.sol#L66-L70
+
+
+ - [ ] ID-37
+[ERC7551Module._getERC7551ModuleStorage()](contracts/modules/wrapper/options/ERC7551Module.sol#L82-L86) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/options/ERC7551Module.sol#L83-L85)
+
+contracts/modules/wrapper/options/ERC7551Module.sol#L82-L86
+
+
+ - [ ] ID-38
+[DocumentERC1643Module._getDocumentERC1643ModuleStorage()](contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L75-L79) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L76-L78)
+
+contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L75-L79
+
+
+ - [ ] ID-39
+[DebtEngineModule._getDebtEngineModuleStorage()](contracts/modules/wrapper/options/DebtEngineModule.sol#L105-L109) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/options/DebtEngineModule.sol#L106-L108)
+
+contracts/modules/wrapper/options/DebtEngineModule.sol#L105-L109
+
+
+ - [ ] ID-40
+[ERC20BaseModule._getERC20BaseModuleStorage()](contracts/modules/wrapper/core/ERC20BaseModule.sol#L157-L161) uses assembly
+ - [INLINE ASM](contracts/modules/wrapper/core/ERC20BaseModule.sol#L158-L160)
+
+contracts/modules/wrapper/core/ERC20BaseModule.sol#L157-L161
+
+
+ - [ ] ID-41
+[AllowlistModuleInternal._getAllowlistModuleInternalStorage()](contracts/modules/internal/AllowlistModuleInternal.sol#L84-L88) uses assembly
+ - [INLINE ASM](contracts/modules/internal/AllowlistModuleInternal.sol#L85-L87)
+
+contracts/modules/internal/AllowlistModuleInternal.sol#L84-L88
+
+
+ - [ ] ID-42
+[ValidationModuleRuleEngineInternal._getValidationModuleRuleEngineStorage()](contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L74-L78) uses assembly
+ - [INLINE ASM](contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L75-L77)
+
+contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L74-L78
+
+
+## dead-code
+Impact: Informational
+Confidence: Medium
+ - [ ] ID-43
+[CMTATBaseERC2771Snapshot._msgData()](contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L73-L77) is never used and should be removed
+
+contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L73-L77
+
+
+## naming-convention
+Impact: Informational
+Confidence: High
+ - [ ] ID-44
+Function [ERC20BaseModule.__ERC20BaseModule_init_unchained(uint8,string,string)](contracts/modules/wrapper/core/ERC20BaseModule.sol#L50-L59) is not in mixedCase
+
+contracts/modules/wrapper/core/ERC20BaseModule.sol#L50-L59
+
+
+ - [ ] ID-45
+Function [SnapshotEngineModule.__SnapshotEngineModule_init_unchained(ISnapshotEngine)](contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L43-L49) is not in mixedCase
+
+contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L43-L49
+
+
+ - [ ] ID-46
+Function [ExtraInformationModule.__ExtraInformationModule_init_unchained(string,IERC1643CMTAT.DocumentInfo,string)](contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L40-L52) is not in mixedCase
+
+contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L40-L52
+
+
+ - [ ] ID-47
+Constant [EnforcementModuleInternal.EnforcementModuleInternalStorageLocation](contracts/modules/internal/EnforcementModuleInternal.sol#L22) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/internal/EnforcementModuleInternal.sol#L22
+
+
+ - [ ] ID-48
+Function [ValidationModuleRuleEngineInternal.__ValidationRuleEngine_init_unchained(IRuleEngine)](contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L35-L41) is not in mixedCase
+
+contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L35-L41
+
+
+ - [ ] ID-49
+Parameter [CMTATBaseERC2612.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/6_CMTATBaseERC2612.sol#L25) is not in mixedCase
+
+contracts/modules/6_CMTATBaseERC2612.sol#L25
+
+
+ - [ ] ID-50
+Function [CMTATBaseAllowlist.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/3_CMTATBaseAllowlist.sol#L68-L85) is not in mixedCase
+
+contracts/modules/3_CMTATBaseAllowlist.sol#L68-L85
+
+
+ - [ ] ID-51
+Constant [PauseModule.PauseModuleStorageLocation](contracts/modules/wrapper/core/PauseModule.sol#L32) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/core/PauseModule.sol#L32
+
+
+ - [ ] ID-52
+Constant [AllowlistModuleInternal.AllowlistModuleInternalStorageLocation](contracts/modules/internal/AllowlistModuleInternal.sol#L19) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/internal/AllowlistModuleInternal.sol#L19
+
+
+ - [ ] ID-53
+Parameter [CMTATBaseCore.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/0_CMTATBaseCore.sol#L87) is not in mixedCase
+
+contracts/modules/0_CMTATBaseCore.sol#L87
+
+
+ - [ ] ID-54
+Constant [SnapshotEngineModule.SnapshotEngineModuleStorageLocation](contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L22) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L22
+
+
+ - [ ] ID-55
+Parameter [CMTATBaseAccessControl.__CMTAT_commonModules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/2_CMTATBaseAccessControl.sol#L32) is not in mixedCase
+
+contracts/modules/2_CMTATBaseAccessControl.sol#L32
+
+
+ - [ ] ID-56
+Function [DocumentEngineModule.__DocumentEngineModule_init_unchained(IERC1643)](contracts/modules/wrapper/options/DocumentEngineModule.sol#L41-L47) is not in mixedCase
+
+contracts/modules/wrapper/options/DocumentEngineModule.sol#L41-L47
+
+
+ - [ ] ID-57
+Parameter [CMTATBaseERC1363.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/8_CMTATBaseERC1363.sol#L25) is not in mixedCase
+
+contracts/modules/8_CMTATBaseERC1363.sol#L25
+
+
+ - [ ] ID-58
+Function [CMTATBaseERC1363.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes)](contracts/modules/8_CMTATBaseERC1363.sol#L25-L28) is not in mixedCase
+
+contracts/modules/8_CMTATBaseERC1363.sol#L25-L28
+
+
+ - [ ] ID-59
+Function [CMTATBaseAllowlist.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/3_CMTATBaseAllowlist.sol#L101-L105) is not in mixedCase
+
+contracts/modules/3_CMTATBaseAllowlist.sol#L101-L105
+
+
+ - [ ] ID-60
+Function [CMTATBaseRuleEngine.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,ICMTATConstructor.Engine)](contracts/modules/3_CMTATBaseRuleEngine.sol#L75-L95) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L75-L95
+
+
+ - [ ] ID-61
+Enum [IERC1404Extend.REJECTED_CODE_BASE](contracts/interfaces/tokenization/draft-IERC1404.sol#L49-L57) is not in CapWords
+
+contracts/interfaces/tokenization/draft-IERC1404.sol#L49-L57
+
+
+ - [ ] ID-62
+Parameter [CMTATBaseRuleEngine.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/3_CMTATBaseRuleEngine.sol#L100) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L100
+
+
+ - [ ] ID-63
+Function [CMTATBaseAllowlist.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes)](contracts/modules/3_CMTATBaseAllowlist.sol#L90-L96) is not in mixedCase
+
+contracts/modules/3_CMTATBaseAllowlist.sol#L90-L96
+
+
+ - [ ] ID-64
+Parameter [CMTATBaseAllowlist.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ExtraInformationAttributes_](contracts/modules/3_CMTATBaseAllowlist.sol#L101) is not in mixedCase
+
+contracts/modules/3_CMTATBaseAllowlist.sol#L101
+
+
+ - [ ] ID-65
+Function [AllowlistModuleInternal.__Allowlist_init_unchained()](contracts/modules/internal/AllowlistModuleInternal.sol#L29-L33) is not in mixedCase
+
+contracts/modules/internal/AllowlistModuleInternal.sol#L29-L33
+
+
+ - [ ] ID-66
+Parameter [CMTATBaseAccessControl.__CMTAT_commonModules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ExtraInformationModuleAttributes_](contracts/modules/2_CMTATBaseAccessControl.sol#L32) is not in mixedCase
+
+contracts/modules/2_CMTATBaseAccessControl.sol#L32
+
+
+ - [ ] ID-67
+Function [CMTATBaseRuleEngine.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes)](contracts/modules/3_CMTATBaseRuleEngine.sol#L100-L106) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L100-L106
+
+
+ - [ ] ID-68
+Function [CMTATBaseRuleEngine.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/3_CMTATBaseRuleEngine.sol#L118-L120) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L118-L120
+
+
+ - [ ] ID-69
+Constant [DocumentEngineModule.DocumentEngineModuleStorageLocation](contracts/modules/wrapper/options/DocumentEngineModule.sol#L21) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/options/DocumentEngineModule.sol#L21
+
+
+ - [ ] ID-70
+Function [CMTATBaseGeneric.__CMTAT_openzeppelin_init_unchained()](contracts/modules/0_CMTATBaseGeneric.sol#L65-L69) is not in mixedCase
+
+contracts/modules/0_CMTATBaseGeneric.sol#L65-L69
+
+
+ - [ ] ID-71
+Constant [ERC7551Module.ERC7551ModuleStorageLocation](contracts/modules/wrapper/options/ERC7551Module.sol#L20) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/options/ERC7551Module.sol#L20
+
+
+ - [ ] ID-72
+Parameter [CMTATBaseERC20CrossChain.supportsInterface(bytes4)._interfaceId](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L75) is not in mixedCase
+
+contracts/modules/5_CMTATBaseERC20CrossChain.sol#L75
+
+
+ - [ ] ID-73
+Function [CMTATBaseCore.__CMTAT_openzeppelin_init_unchained()](contracts/modules/0_CMTATBaseCore.sol#L106-L110) is not in mixedCase
+
+contracts/modules/0_CMTATBaseCore.sol#L106-L110
+
+
+ - [ ] ID-74
+Constant [ERC20BaseModule.ERC20BaseModuleStorageLocation](contracts/modules/wrapper/core/ERC20BaseModule.sol#L28) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/core/ERC20BaseModule.sol#L28
+
+
+ - [ ] ID-75
+Parameter [CMTATBaseAllowlist.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/3_CMTATBaseAllowlist.sol#L90) is not in mixedCase
+
+contracts/modules/3_CMTATBaseAllowlist.sol#L90
+
+
+ - [ ] ID-76
+Parameter [CMTATBaseAllowlist.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/3_CMTATBaseAllowlist.sol#L101) is not in mixedCase
+
+contracts/modules/3_CMTATBaseAllowlist.sol#L101
+
+
+ - [ ] ID-77
+Constant [ValidationModuleRuleEngineInternal.ValidationModuleRuleEngineStorageLocation](contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L28) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L28
+
+
+ - [ ] ID-78
+Parameter [CMTATBaseRuleEngine.initialize(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,ICMTATConstructor.Engine).ERC20Attributes_](contracts/modules/3_CMTATBaseRuleEngine.sol#L43) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L43
+
+
+ - [ ] ID-79
+Constant [DebtEngineModule.DebtEngineModuleStorageLocation](contracts/modules/wrapper/options/DebtEngineModule.sol#L20) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/options/DebtEngineModule.sol#L20
+
+
+ - [ ] ID-80
+Function [CMTATBaseRuleEngine.__CMTAT_internal_init_unchained(ICMTATConstructor.Engine)](contracts/modules/3_CMTATBaseRuleEngine.sol#L111-L113) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L111-L113
+
+
+ - [ ] ID-81
+Function [CMTATBaseAccessControl.__CMTAT_commonModules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/2_CMTATBaseAccessControl.sol#L32-L39) is not in mixedCase
+
+contracts/modules/2_CMTATBaseAccessControl.sol#L32-L39
+
+
+ - [ ] ID-82
+Parameter [CMTATBaseCore.initialize(address,ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/0_CMTATBaseCore.sol#L73) is not in mixedCase
+
+contracts/modules/0_CMTATBaseCore.sol#L73
+
+
+ - [ ] ID-83
+Parameter [CMTATBaseRuleEngine.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,ICMTATConstructor.Engine).ExtraInformationAttributes_](contracts/modules/3_CMTATBaseRuleEngine.sol#L78) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L78
+
+
+ - [ ] ID-84
+Parameter [CMTATBaseAllowlist.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/3_CMTATBaseAllowlist.sol#L70) is not in mixedCase
+
+contracts/modules/3_CMTATBaseAllowlist.sol#L70
+
+
+ - [ ] ID-85
+Parameter [ERC20CrossChainModule.supportsInterface(bytes4)._interfaceId](contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L103) is not in mixedCase
+
+contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L103
+
+
+ - [ ] ID-86
+Parameter [CMTATBaseRuleEngine.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/3_CMTATBaseRuleEngine.sol#L118) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L118
+
+
+ - [ ] ID-87
+Function [CMTATBaseERC2612.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes)](contracts/modules/6_CMTATBaseERC2612.sol#L24-L31) is not in mixedCase
+
+contracts/modules/6_CMTATBaseERC2612.sol#L24-L31
+
+
+ - [ ] ID-88
+Constant [ExtraInformationModule.ExtraInformationModuleStorageLocation](contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L21) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L21
+
+
+ - [ ] ID-89
+Function [CMTATBaseGeneric.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/0_CMTATBaseGeneric.sol#L74-L79) is not in mixedCase
+
+contracts/modules/0_CMTATBaseGeneric.sol#L74-L79
+
+
+ - [ ] ID-90
+Function [AccessControlModule.__AccessControlModule_init_unchained(address)](contracts/modules/wrapper/security/AccessControlModule.sol#L23-L32) is not in mixedCase
+
+contracts/modules/wrapper/security/AccessControlModule.sol#L23-L32
+
+
+ - [ ] ID-91
+Function [CMTATBaseCore.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes)](contracts/modules/0_CMTATBaseCore.sol#L116-L120) is not in mixedCase
+
+contracts/modules/0_CMTATBaseCore.sol#L116-L120
+
+
+ - [ ] ID-92
+Parameter [CMTATBaseRuleEngine.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,ICMTATConstructor.Engine).ERC20Attributes_](contracts/modules/3_CMTATBaseRuleEngine.sol#L77) is not in mixedCase
+
+contracts/modules/3_CMTATBaseRuleEngine.sol#L77
+
+
+ - [ ] ID-93
+Parameter [CMTATBaseCore.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/0_CMTATBaseCore.sol#L116) is not in mixedCase
+
+contracts/modules/0_CMTATBaseCore.sol#L116
+
+
+ - [ ] ID-94
+Parameter [CMTATBaseAllowlist.initialize(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/3_CMTATBaseAllowlist.sol#L54) is not in mixedCase
+
+contracts/modules/3_CMTATBaseAllowlist.sol#L54
+
+
+ - [ ] ID-95
+Constant [CCIPModule.CCIPModuleStorageLocation](contracts/modules/wrapper/options/CCIPModule.sol#L17) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/options/CCIPModule.sol#L17
+
+
+ - [ ] ID-96
+Constant [DebtModule.DebtModuleStorageLocation](contracts/modules/wrapper/options/DebtModule.sol#L20) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/options/DebtModule.sol#L20
+
+
+ - [ ] ID-97
+Function [CMTATBaseCore.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes)](contracts/modules/0_CMTATBaseCore.sol#L85-L101) is not in mixedCase
+
+contracts/modules/0_CMTATBaseCore.sol#L85-L101
+
+
+ - [ ] ID-98
+Constant [DocumentERC1643Module.DocumentERC1643ModuleStorageLocation](contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L15) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L15
+
+
+ - [ ] ID-99
+Constant [ERC20EnforcementModuleInternal.ERC20EnforcementModuleStorageLocation](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L24) is not in UPPER_CASE_WITH_UNDERSCORES
+
+contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L24
+
+
+ - [ ] ID-100
+Function [CMTATBaseGeneric.__CMTAT_init(address,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/0_CMTATBaseGeneric.sol#L44-L60) is not in mixedCase
+
+contracts/modules/0_CMTATBaseGeneric.sol#L44-L60
+
+
diff --git a/doc/summary.md b/doc/summary.md
deleted file mode 100644
index 2c0a5d07..00000000
--- a/doc/summary.md
+++ /dev/null
@@ -1,50 +0,0 @@
-## Deployment Variants
-
-- **Standalone** - Immutable, no proxy
-- **Upgradeable** - Transparent/Beacon/UUPS proxy patterns
-- **Light** - Minimal for stablecoins
-- **Allowlist** - Whitelist-based transfers (KYC)
-- **Debt** - Bond-specific fields (maturity, coupon)
-- **DebtEngine** - Debt with external engine
-- **ERC-7551** - German eWpG compliance
-- **ERC-1363** - transferAndCall support
-
----
-
-## Architecture Highlights
-
-1. **Modular composition** - Mix-and-match features via inheritance
-2. **Engine pattern** - External contracts for complex logic (RuleEngine, SnapshotEngine, DocumentEngine, DebtEngine)
-3. **ERC-7201 storage** - Namespaced storage for safe upgrades
-4. **Role-based access control** - Granular permissions (not single owner)
-5. **10+ standard compliance** - ERC-20, ERC-3643, ERC-7551, ERC-2771, ERC-7802, etc.
-
----
-
-## Contract Inheritance Hierarchy
-
-```
-CMTATBaseCore (0) - Basic ERC20 + Mint + Burn + Validation + Access Control
- ↓
-CMTATBaseAccessControl (1) - RBAC roles management
- ↓
-CMTATBaseRuleEngine/Allowlist (2) - Transfer validation rules
- ↓
-CMTATBaseERC1404 (3) - ERC-1404 compliance (restrictedTransfer)
- ↓
-CMTATBaseERC20CrossChain (4) - CCIP & ERC-7802 support
- ↓
-CMTATBaseERC2771 (5) - Gasless meta-transactions
- ↓
-CMTATBaseERC1363/ERC7551 (6) - Additional standards
-```
-
----
-
-## Key Roles (Access Control)
-
-- `DEFAULT_ADMIN_ROLE` - Admin access (can grant/revoke roles)
-- `MINTER_ROLE` - Can mint tokens
-- `BURNER_ROLE` - Can burn tokens
-- `PAUSER_ROLE` - Can pause/unpause contract
-- `ENFORCER_ROLE` - Can freeze/unfreeze addresses
\ No newline at end of file
diff --git a/doc/technical/access-control.md b/doc/technical/access-control.md
new file mode 100644
index 00000000..3d5b980a
--- /dev/null
+++ b/doc/technical/access-control.md
@@ -0,0 +1,113 @@
+# Access Control (RBAC)
+
+CMTAT uses Role-Based Access Control (RBAC) from OpenZeppelin. Access control is modular: each wrapper module defines its required roles and declares `virtual` authorization hooks. The base contract `CMTATBaseAccessControl` provides the concrete implementation using `AccessControl`.
+
+The `AccessControlModule` overrides `hasRole` so that the `DEFAULT_ADMIN_ROLE` holder has all roles by default.
+
+See also [docs.openzeppelin.com - AccessControl](https://docs.openzeppelin.com/contracts/5.x/api/access#AccessControl)
+
+## Architecture
+
+**Wrapper modules** define:
+- The roles required to restrict their functions
+- Virtual `authorize` functions that must be overridden in the base module
+
+**CMTAT base modules** override those virtual functions and enforce RBAC. This separation allows replacing the access control mechanism without modifying the feature modules.
+
+## Role List
+
+| Role | Defined in | 32-byte Identifier |
+|---|---|---|
+| `DEFAULT_ADMIN_ROLE` | OpenZeppelin AccessControl | `0x0000000000000000000000000000000000000000000000000000000000000000` |
+| `BURNER_ROLE` | BurnModule | `0x3c11d16cbaffd01df69ce1c404f6340ee057498f5f00246190ea54220576a848` |
+| `MINTER_ROLE` | MintModule | `0x9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6` |
+| `ENFORCER_ROLE` | EnforcementModule | `0x973ef39d76cc2c6090feab1c030bec6ab5db557f64df047a4c4f9b5953cf1df3` |
+| `PAUSER_ROLE` | PauseModule | `0x65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a` |
+| `SNAPSHOOTER_ROLE` | SnapshotEngineModule | `0x809a0fc49fc0600540f1d39e23454e1f6f215bc7505fa22b17c154616570ddef` |
+| `DOCUMENT_ROLE` | DocumentERC1643Module | `0xdd7c9aafbb91d54fb2041db1d5b172ea665309b32f5fffdbddf452802a1e3b20` |
+| `DOCUMENT_ENGINE_ROLE` | DocumentEngineModule | `0x2d6f031e2eef5fafe7386c46356b86b5ed6513f04e6bcb34d4e0ff161e332117` |
+| `EXTRA_INFORMATION_ROLE` | ExtraInformationModule | `0x921df7a58eb4ea112afa962b8186161404ecda2e8fe97f8246026d02ad1a74b7` |
+| `ERC20ENFORCER_ROLE` | ERC20EnforcementModule | `0xd62f75bf68b069bc8e2abd495a949fafec67a4e5a5b7cb36aedf0dd51eec7e72` |
+| `ALLOWLIST_ROLE` | AllowlistModule | `0x26a560d834a19637eccba4611bbc09fb32970bb627da0a70f14f83fdc9822cbc` |
+| `DEBT_ROLE` | DebtModule | `0xc6f3350ab30f55ce45863160fc345c1663d4633fe7cacfd3b9bbb6420a9147f8` |
+| `DEBT_ENGINE_ROLE` | DebtEngineModule | `0x516b2a17ebe2d0badac282ee8b39b7f1c94deb40fe902ce0db99741f01cae093` |
+| `CROSS_CHAIN_ROLE` | ERC20CrossChainModule | `0x620d362b92b6ef580d4e86c5675d679fe08d31dff47b72f281959a4eecdd036a` |
+| `BURNER_FROM_ROLE` | ERC20CrossChainModule | `0x5bfe08abba057c54e6a28bce27ce8c53eb21d7a94376a70d475b5dee60b6c4e2` |
+| `BURNER_SELF_ROLE` | ERC20CrossChainModule | `0x13d9f3ea33477b975af6cd01437366c28412d5bd9b872fa0fc25bd3a160683af` |
+
+## Role by Module
+
+| Module | Function | Role Required |
+|---|---|---|
+| **ERC20BaseModule** | `setName(string)` | `DEFAULT_ADMIN_ROLE` |
+| | `setSymbol(string)` | `DEFAULT_ADMIN_ROLE` |
+| **ERC20BurnModule** | `burn(address, uint256, bytes)` | `BURNER_ROLE` |
+| | `batchBurn(address[], uint256[], bytes)` | `BURNER_ROLE` |
+| **ERC20MintModule** | `mint(address, uint256, bytes)` | `MINTER_ROLE` |
+| | `batchMint(address[], uint256[])` | `MINTER_ROLE` |
+| | `batchTransfer(address[], uint256[])` | `MINTER_ROLE` |
+| **EnforcementModule** | `setAddressFrozen(address, bool)` | `ENFORCER_ROLE` |
+| | `batchSetAddressFrozen(address[], bool[])` | `ENFORCER_ROLE` |
+| **PauseModule** | `pause()` | `PAUSER_ROLE` |
+| | `unpause()` | `PAUSER_ROLE` |
+| | `deactivateContract()` | `DEFAULT_ADMIN_ROLE` |
+| **ERC20EnforcementModule** | `forcedTransfer(address, address, uint256)` | `DEFAULT_ADMIN_ROLE` |
+| | `freezePartialTokens(address, uint256)` | `ERC20ENFORCER_ROLE` |
+| | `unfreezePartialTokens(address, uint256)` | `ERC20ENFORCER_ROLE` |
+| | `setFrozenTokens(address, uint256)` | `ERC20ENFORCER_ROLE` |
+| **ERC20EnforcementERC7551Module** | `forcedTransfer(address, address, uint256, bytes)` | `DEFAULT_ADMIN_ROLE` |
+| | `freezePartialTokens(address, uint256, bytes)` | `ERC20ENFORCER_ROLE` |
+| | `unfreezePartialTokens(address, uint256, bytes)` | `ERC20ENFORCER_ROLE` |
+| **ExtraInformationModule** | `setTokenId(string)` | `EXTRA_INFORMATION_ROLE` |
+| | `setTerms(DocumentInfo)` | `EXTRA_INFORMATION_ROLE` |
+| | `setInformation(string)` | `EXTRA_INFORMATION_ROLE` |
+| **ERC7551Module** | `setMetaData(string)` | `EXTRA_INFORMATION_ROLE` |
+| | `setTerms(bytes32, string)` | `EXTRA_INFORMATION_ROLE` |
+| **SnapshotEngineModule** | `setSnapshotEngine(address)` | `SNAPSHOOTER_ROLE` |
+| **DocumentERC1643Module** | `setDocument(bytes32, string, bytes32)` | `DOCUMENT_ROLE` |
+| | `removeDocument(bytes32)` | `DOCUMENT_ROLE` |
+| **DocumentEngineModule** | `setDocumentEngine(address)` | `DOCUMENT_ENGINE_ROLE` |
+| | `setDocument(bytes32, string, bytes32)` | `DOCUMENT_ENGINE_ROLE` |
+| | `removeDocument(bytes32)` | `DOCUMENT_ENGINE_ROLE` |
+| **AllowlistModule** | `setAddressAllowlist(address, bool)` | `ALLOWLIST_ROLE` |
+| | `setAddressAllowlist(address, bool, bytes)` | `ALLOWLIST_ROLE` |
+| | `batchSetAddressAllowlist(address[], bool[])` | `ALLOWLIST_ROLE` |
+| | `enableAllowlist(bool)` | `ALLOWLIST_ROLE` |
+| **ValidationModuleRuleEngine** | `setRuleEngine(address)` | `DEFAULT_ADMIN_ROLE` |
+| **DebtModule** | `setDebt(...)` | `DEBT_ROLE` |
+| | `setCreditEvents(...)` | `DEBT_ROLE` |
+| **DebtEngineModule** | `setDebtEngine(address)` | `DEBT_ENGINE_ROLE` |
+| **ERC20CrossChain** | `crosschainMint(address, uint256)` | `CROSS_CHAIN_ROLE` |
+| | `crosschainBurn(address, uint256)` | `CROSS_CHAIN_ROLE` |
+| | `burnFrom(address, uint256)` | `BURNER_FROM_ROLE` |
+| | `burn(uint256)` | `BURNER_SELF_ROLE` |
+| **CCIPModule** | `setCCIPAdmin(address)` | `DEFAULT_ADMIN_ROLE` |
+| **BaseCommon** | `burnAndMint(address, address, uint256, uint256, bytes)` | `BURNER_ROLE` + `MINTER_ROLE` |
+
+## Input Guards
+
+- `EnforcementModule.setAddressFrozen(...)` and `batchSetAddressFrozen(...)` reject `address(0)` (`CMTAT_Enforcement_ZeroAddressNotAllowed`).
+- `ERC20EnforcementModule.freezePartialTokens(...)` and `unfreezePartialTokens(...)` reject `address(0)` (`CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed`).
+
+## Role Interaction Notes
+
+- `ENFORCER_ROLE` can effectively block mint operations by freezing the minter/operator address with `setAddressFrozen(address, true)`.
+ In spender-aware compliance paths, mint uses the effective operator as spender, so a frozen operator reverts with `ERC7943CannotSend`.
+- `SNAPSHOOTER_ROLE` controls `setSnapshotEngine(address)`. Setting a snapshot engine that always reverts can create a **transfer-liveness halt** (a pause-like effect) for state-changing token flows that execute through `_update`.
+
+## Key Management
+
+Access to the `DEFAULT_ADMIN_ROLE` key must be adequately restricted. Access to any proxy contract must be segregated from the token contract.
+
+### UUPS Proxy
+
+For the UUPS deployment version there is no segregation between admin rights and the proxy upgrade authority. A compromise of `DEFAULT_ADMIN_ROLE` could allow an attacker to swap the implementation contract. Consider using a multisig or timelock for the admin account.
+
+## Transferring Admin
+
+To transfer admin to a new address:
+
+1. Call `grantRole(DEFAULT_ADMIN_ROLE, newAdmin)` from the current admin.
+2. Call `renounceRole(DEFAULT_ADMIN_ROLE, currentAdmin)` to remove the current admin.
+
+The new admin can also call `revokeRole` to remove the old admin. Multiple concurrent admins are supported.
diff --git a/doc/technical/cross-chain-bridge-integration.md b/doc/technical/cross-chain-bridge-integration.md
new file mode 100644
index 00000000..77182b64
--- /dev/null
+++ b/doc/technical/cross-chain-bridge-integration.md
@@ -0,0 +1,100 @@
+# Cross-Chain Bridge Integration
+
+CMTAT supports cross-chain token transfers through three mechanisms:
+
+| Mechanism | Standard | Module |
+|---|---|---|
+| Chainlink CCIP | [Cross-Chain Token (CCT)](https://docs.chain.link/ccip/concepts/cross-chain-token) | `CCIPModule` + `ERC20CrossChain` |
+| Optimism Superchain | [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) | `ERC20CrossChain` |
+| LayerZero | OFT adapter | External adapter (see [CMTAT-LayerZero](https://github.com/CMTA/CMTAT-LayerZero)) |
+
+## Chainlink CCIP (Cross-Chain Token Standard)
+
+CMTAT implements the [Cross-Chain Token Standard (CCT)](https://docs.chain.link/ccip/concepts/cross-chain-token/evm/tokens#overview), enabling self-service registration with Chainlink CCIP without needing Chainlink's assistance.
+
+### Registration
+
+CMTAT exposes `getCCIPAdmin()` (recommended over `owner()` by CCIP documentation) to return the address authorized to register the token.
+
+```solidity
+// CCIPModule
+function getCCIPAdmin() public view virtual returns (address)
+function setCCIPAdmin(address newAdmin) public virtual // DEFAULT_ADMIN_ROLE
+```
+
+### Transfer Functions (Burn and Mint)
+
+| Function | Module | Role |
+|---|---|---|
+| `mint(address, uint256)` | `ERC20MintModule` | `MINTER_ROLE` |
+| `burn(uint256)` | `ERC20CrossChain` | `BURNER_SELF_ROLE` |
+| `burnFrom(address, uint256)` | `ERC20CrossChain` | `BURNER_FROM_ROLE` |
+| `decimals()` | `ERC20BaseModule` | - |
+| `balanceOf(address)` | OpenZeppelin ERC20 | - |
+
+The CCIP pool must be granted the required `MINTER_ROLE` and `BURNER_FROM_ROLE` (or `BURNER_SELF_ROLE`) to operate.
+
+**Note**: Pausing the contract via `PauseModule` does **not** block `MintModule.mint()`, so CCIP minting still works while paused. However, `burnFrom`, `crosschainMint`, and `crosschainBurn` all have `whenNotPaused` checks and are blocked while paused. To block minting during a pause, revoke `MINTER_ROLE` from the CCIP pool.
+With spender-aware compliance enabled, freezing the minter/operator address (`setAddressFrozen`) also blocks mint because the operator is checked as spender in RuleEngine/compliance hooks.
+
+`Lock and Mint` / `Burn and Unlock` models are also compatible through the `Burn and Mint` requirement set. `Lock and Unlock` needs no special token contract support.
+
+### Example
+
+[CMTAT-CCIP](https://github.com/CMTA/CMTAT-CCIP) provides Foundry deployment scripts for CMTAT v3.1.0 with CCIP contracts, built by [Nox Labs](https://github.com/Nox-Labs) in collaboration with CMTA and [Taurus](https://www.taurushq.com).
+
+## Optimism Superchain (ERC-7802)
+
+CMTAT implements [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) in `ERC20CrossChain`, enabling asset interoperability within the Optimism Superchain by burning on the source chain and minting on the destination chain.
+
+Reference: [docs.optimism.io/interop/superchain-erc20](https://docs.optimism.io/interop/superchain-erc20)
+
+### Source Chain Flow
+
+1. User calls [`SuperchainTokenBridge.sendERC20`](https://github.com/ethereum-optimism/optimism/blob/develop/packages/contracts-bedrock/src/L2/SuperchainTokenBridge.sol#L52-L78).
+2. The bridge calls `CMTAT.crosschainBurn` to burn tokens.
+3. The bridge emits an initiating message via `L2ToL2CrossDomainMessenger`.
+
+### Destination Chain Flow
+
+1. An autorelayer (or any off-chain entity) sends an executing message to `L2ToL2CrossDomainMessenger`.
+2. The destination bridge calls `CMTAT.crosschainMint` to mint tokens for the recipient.
+
+### Requirements
+
+- Grant the `SuperchainTokenBridge` permission to call `crosschainMint` and `crosschainBurn` (`CROSS_CHAIN_ROLE`).
+- Deploy CMTAT at the **same address** on every Superchain network where the token should be available.
+
+## LayerZero
+
+Two OFT adapters (ERC-3643 and ERC-7802 variants) are available at [CMTAT-LayerZero](https://github.com/CMTA/CMTAT-LayerZero), built by [Nox Labs](https://github.com/Nox-Labs) in collaboration with CMTA and [Taurus](https://www.taurushq.com).
+
+CMTAT provides two burn/mint interfaces for adapters to use:
+
+- **Standard burn/mint** — same interface as ERC-3643 (`burn(address, uint256)` / `mint(address, uint256)`)
+- **Cross-chain burn/mint** — ERC-7802 (`crosschainBurn` / `crosschainMint`)
+
+Choose the adapter that matches the interface used by the LayerZero pool.
+
+## Access Control Summary
+
+| Function | Role | Notes |
+|---|---|---|
+| `crosschainMint(address, uint256)` | `CROSS_CHAIN_ROLE` | Grant to bridge/pool contract |
+| `crosschainBurn(address, uint256)` | `CROSS_CHAIN_ROLE` | Grant to bridge/pool contract |
+| `burnFrom(address, uint256)` | `BURNER_FROM_ROLE` | Grant to CCIP pool |
+| `burn(uint256)` | `BURNER_SELF_ROLE` | Grant to CCIP pool |
+| `mint(address, uint256)` | `MINTER_ROLE` | Grant to CCIP pool |
+| `setCCIPAdmin(address)` | `DEFAULT_ADMIN_ROLE` | Manage CCIP registration |
+
+## RuleEngine Operator Semantics
+
+- `burnFrom` uses allowance and now propagates `_msgSender()` into the compliance hook, so spender-aware RuleEngine checks are applied.
+- `crosschainBurn` also propagates `_msgSender()` to keep operator semantics consistent with `burnFrom`.
+- `crosschainMint` now also propagates `_msgSender()` to enable spender-aware RuleEngine checks for bridge-initiated mint flows.
+
+`burnFrom` is role-gated (`BURNER_FROM_ROLE`) and is not treated as a classic `transferFrom` policy path. In RuleEngine hook calls, `burn` and `burnFrom` both map to burn semantics (`to == address(0)`) and cannot be differentiated from hook parameters alone. To apply controls specific to `burnFrom`, define RuleEngine rules on the operator addresses that are authorized to execute `burnFrom`.
+
+If a RuleEngine restriction should apply only to classic `transferFrom` spender behavior, add guards to exclude mint/burn operator flows:
+- require `from != address(0)` to exclude mint paths,
+- require `to != address(0)` to exclude burn paths.
diff --git a/doc/technical/debt.md b/doc/technical/debt.md
new file mode 100644
index 00000000..e09e5495
--- /dev/null
+++ b/doc/technical/debt.md
@@ -0,0 +1,122 @@
+# Debt Module
+
+CMTAT provides two deployment versions for representing debt and credit events information on-chain.
+
+| Version | Module | Storage |
+|---|---|---|
+| `Debt` | `DebtModule` | Directly in the token contract |
+| `DebtEngine` | `DebtEngineModule` | External `DebtEngine` contract |
+
+The `DebtEngine` approach reduces the CMTAT contract size (which is near the maximum limit) and allows sharing debt information across multiple token contracts.
+
+See also [CMTAT - Standard for the tokenization of debt instruments using distributed ledger technology](https://cmta.ch/standards/standard-for-the-tokenization-of-debt-instruments-using-distributed-ledger-technology)
+
+## Data Structures
+
+### DebtInformation
+
+```solidity
+interface ICMTATDebt {
+ struct DebtInformation {
+ DebtIdentifier debtIdentifier;
+ DebtInstrument debtInstrument;
+ }
+}
+```
+
+### DebtIdentifier
+
+Information on the issuer and other persons involved.
+
+| Field | Type | Description |
+|---|---|---|
+| `issuerName` | string | Issuer identifier (LEI or equivalent) |
+| `issuerDescription` | string | - |
+| `guarantor` | string | Guarantor identifier (LEI or equivalent), if applicable |
+| `debtHolder` | string | Debtholders representative identifier (LEI or equivalent), if applicable |
+
+### DebtInstrument
+
+Information on the instrument.
+
+| Field | Type | Description |
+|---|---|---|
+| `interestRate` | uint256 | - |
+| `parValue` | uint256 | - |
+| `minimumDenomination` | uint256 | - |
+| `issuanceDate` | string | - |
+| `maturityDate` | string | - |
+| `couponPaymentFrequency` | string | - |
+| `interestScheduleFormat` | string | Format A: start/end/period; Format B: start/end/day of period; Format C: date1/date2/... |
+| `interestPaymentDate` | string | Format A: period between accrual and payment; Format B: specific date |
+| `dayCountConvention` | string | - |
+| `businessDayConvention` | string | - |
+| `currency` | string | - |
+| `currencyContract` | address | - |
+
+### CreditEvents
+
+```solidity
+interface ICMTATCreditEvents {
+ struct CreditEvents {
+ bool flagDefault;
+ bool flagRedeemed;
+ string rating;
+ }
+}
+```
+
+| Field | Type |
+|---|---|
+| `flagDefault` | bool |
+| `flagRedeemed` | bool |
+| `rating` | string |
+
+## Functions
+
+| Operation | Module | Function | Role |
+|---|---|---|---|
+| Read debt info | `DebtModule` / `DebtEngineModule` | `debt()` | - |
+| Write debt info | `DebtModule` | `setDebt(...)` | `DEBT_ROLE` |
+| Read credit events | `DebtModule` / `DebtEngineModule` | `creditEvents()` | - |
+| Write credit events | `DebtModule` | `setCreditEvents(...)` | `DEBT_ROLE` |
+| Set DebtEngine | `DebtEngineModule` | `setDebtEngine(address)` | `DEBT_ENGINE_ROLE` |
+
+## DebtEngine Interface
+
+```solidity
+interface IDebtEngine is ICMTATDebt, ICMTATCreditEvents {
+ // nothing more
+}
+```
+
+The `DebtEngine` must implement `debt()` and `creditEvents()`. The CMTAT token contract delegates read calls to the external engine; the engine is free to store and manage the data however it wants.
+
+## Deployment Versions
+
+| Contract | Type |
+|---|---|
+| `CMTATStandaloneDebt` | Standalone (immutable) |
+| `CMTATUpgradeableDebt` | Upgradeable (proxy) |
+| `CMTATStandaloneDebtEngine` | Standalone with external DebtEngine |
+| `CMTATUpgradeableDebtEngine` | Upgradeable with external DebtEngine |
+
+### Feature Matrix
+
+| Feature | `Debt` | `DebtEngine` |
+|---|---|---|
+| `DebtModule` (on-chain debt data) | ✓ | — |
+| `DebtEngineModule` (external engine) | — | ✓ |
+| `ERC20CrossChainModule` + `CCIPModule` | — | ✓ |
+| ERC-1404 (`restrictedTransferOf`) | — | ✓ (via `CMTATBaseERC20CrossChain`) |
+| `ERC2771Module` (meta-transactions) | — | — |
+| `CMTATBaseSnapshot` (SnapshotEngine support) | ✓ | ✓ |
+
+Both `Debt` and `DebtEngine` variants include `CMTATBaseSnapshot`, which wires the ERC-20 `_update` hook into an optional external `SnapshotEngine`. This means snapshot functionality is available on these variants without deploying the dedicated `Snapshot` deployment variant. Set the engine with `setSnapshotEngine(address)` (requires `SNAPSHOOTER_ROLE`).
+
+## Compatible DebtEngine Releases
+
+| CMTAT version | DebtEngine |
+|---|---|
+| CMTAT v3.0.0 | Under development |
+| CMTAT v2.5.0 (unaudited) | [DebtEngine v0.2.0](https://github.com/CMTA/DebtEngine/releases/tag/v0.2.0) |
diff --git a/doc/technical/deployment.md b/doc/technical/deployment.md
new file mode 100644
index 00000000..9664143f
--- /dev/null
+++ b/doc/technical/deployment.md
@@ -0,0 +1,104 @@
+# Deployment Model
+
+Deployment contracts are in `contracts/deployment/`. Each feature set comes in both a standalone (immutable) and an upgradeable (proxy-compatible) variant.
+
+## Summary
+
+| Model | Description | Type | Contract |
+|---|---|---|---|
+| **Standard** | Core + extension modules, ERC-2771 + cross-chain support | Standalone | `CMTATStandardStandalone` |
+| | | Upgradeable | `CMTATStandardUpgradeable` |
+| **UUPS** | Same as Standard + UUPS proxy support | Upgradeable only | `CMTATUpgradeableUUPS` |
+| **ERC-1363** | Standard + ERC-1363 payable token | Standalone | `CMTATStandaloneERC1363` |
+| | | Upgradeable | `CMTATUpgradeableERC1363` |
+| **Permit** | Standard + ERC-2612 Permit + ERC-6357 Multicall (no ERC-2771) | Standalone | `CMTATStandalonePermit` |
+| | | Upgradeable | `CMTATUpgradeablePermit` |
+| **Light** | Core modules only (no extensions) | Standalone | `CMTATStandaloneLight` |
+| | | Upgradeable | `CMTATUpgradeableLight` |
+| **Debt** | Standard + DebtModule (no ERC-2771, no ERC20CrossChain) | Standalone | `CMTATStandaloneDebt` |
+| | | Upgradeable | `CMTATUpgradeableDebt` |
+| **DebtEngine** | Standard + DebtEngineModule + ERC-1404 (no ERC-2771) | Standalone | `CMTATStandaloneDebtEngine` |
+| | | Upgradeable | `CMTATUpgradeableDebtEngine` |
+| **Allowlist** | Standard + AllowlistModule (no RuleEngine/ERC-1404, no ERC20CrossChain), with ERC-7551 enforcement functions | Standalone | `CMTATStandaloneAllowlist` |
+| | | Upgradeable | `CMTATUpgradeableAllowlist` |
+| **ERC-7551** | Standard + ERC7551Module | Standalone | `CMTATStandaloneERC7551` |
+| | | Upgradeable | `CMTATUpgradeableERC7551` |
+| **Snapshot** | Standard + SnapshotEngine support | Standalone | `CMTATStandaloneSnapshot` |
+| | | Upgradeable | `CMTATUpgradeableSnapshot` |
+
+## Standard Standalone
+
+Use `CMTATStandardStandalone` (file: `CMTATStandardStandalone.sol`) for a fully immutable deployment. Includes all core and extension modules (except Debt, Allowlist, UUPS), plus `ERC2771Module` and `ERC20CrossChain`.
+
+## Upgradeable (Transparent / Beacon Proxy)
+
+Use `CMTATStandardUpgradeable` (file: `CMTATStandardUpgradeable.sol`) as the implementation contract behind a Transparent or Beacon proxy.
+
+See [OpenZeppelin Upgrades Plugins](https://docs.openzeppelin.com/upgrades-plugins/1.x/) for proxy deployment tooling.
+
+## UUPS Proxy
+
+Use `CMTATUpgradeableUUPS` for a UUPS proxy. The upgrade logic is in the implementation contract itself.
+
+**Security note**: There is no segregation between admin rights and the proxy upgrade authority. Compromise of `DEFAULT_ADMIN_ROLE` would allow swapping the implementation. Use a multisig or timelock.
+
+## Light Version
+
+Includes only core modules: mint, burn, freeze, pause. No extensions (no documents, no snapshots, no partial freeze). Adds `forcedBurn` so the admin can burn from frozen addresses (since `ERC20EnforcementModule` with `forcedTransfer` is not included).
+
+## ERC-1363
+
+[ERC-1363](https://eips.ethereum.org/EIPS/eip-1363) allows executing code on a recipient after a transfer or on a spender after approval, in a single transaction. Available as `CMTATStandaloneERC1363` and `CMTATUpgradeableERC1363`.
+
+## Permit + Multicall
+
+See [`permit-multicall.md`](./permit-multicall.md).
+
+## Debt / DebtEngine
+
+See [`debt.md`](./debt.md).
+
+## Allowlist
+
+See the [Allowlist module documentation](../modules/options/allowlist/allowlist.md).
+
+## Factory
+
+Factory contracts for Beacon, Transparent, and UUPS proxy deployments are maintained in a separate repository: [CMTAT Factory](https://github.com/CMTA/CMTATFactory).
+
+| CMTAT version | CMTAT Factory |
+|---|---|
+| CMTAT v3.0.0 | [v0.2.0](https://github.com/CMTA/CMTATFactory/releases/tag/v0.2.0) (unaudited) |
+
+## Other Token Types (ERC-721, ERC-1155)
+
+To build a CMTAT-flavored ERC-721 or ERC-1155, extend `CMTATBaseGeneric`. A mock `ERC721MockUpgradeable` is available in `contracts/mocks/` as a reference.
+
+## Storage (ERC-7201)
+
+CMTAT implements [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) for namespaced storage, making upgradeable storage layout predictable and collision-free.
+
+| Module | Storage Variable | bytes32 Slot |
+|---|---|---|
+| AllowlistModuleInternal | `AllowlistModuleInternalStorageLocation` | `0x53076eaf2d1e2f915f2e0487c9f92cca686c37fd47bf11f95f0da313b2809800` |
+| EnforcementModuleInternal | `EnforcementModuleInternalStorageLocation` | `0x0c7bc8a17be064111d299d7669f49519cb26c58611b72d9f6ccc40a1e1184e00` |
+| ERC20EnforcementModuleInternal | `ERC20EnforcementModuleStorageLocation` | `0x9d8059a24cb596f1948a937c2c163cf14465c2a24abfd3cd009eec4ac4c39800` |
+| ERC20BaseModule | `ERC20BaseModuleStorageLocation` | `0x9bd8d607565c0370ae5f91651ca67fd26d4438022bf72037316600e29e6a3a00` |
+| PauseModule | - | `0xab1527b6135145d8da1edcbd6b7b270624e17f2b41c74a8c746ff388ad454700` |
+| DocumentEngineModule | `DocumentEngineModuleStorageLocation` | `0xbd0905600c85d707dc53eba2e146c1c2527cd32ac3ff6b86846155151b3e2700` |
+| DocumentERC1643Module | `DocumentERC1643ModuleStorageLocation` | `0x24fbb1cf6345ced60d5278ef6f68f4f7576fd9068704b4c8f1eec8f0bbd8a200` |
+| ExtraInformationModule | `ExtraInformationModuleStorageLocation` | `0xd2d5d34c4a4dea00599692d3257c0aebc5e0359176118cd2364ab9b008c2d100` |
+| SnapshotEngineModule | `SnapshotEngineModuleStorageLocation` | `0x1387b97dfab601d3023cb57858a6be29329babb05c85597ddbe4926c1193a900` |
+| CCIPModule | `CCIPModuleStorageLocation` | `0x364fbfd89c0eee55bbc8dd10b1a9bf3e04fba9f3ee606f4c79a82f9941ad7a00` |
+| DebtModule | `DebtModuleStorageLocation` | `0xf8a315cc5f2213f6481729acd86e55db7ccc930120ccf9fb78b53dcce75f7c00` |
+| ERC7551Module | `ERC7551ModuleStorageLocation` | `0x2727314c926b592b6f70e7d6d2e4677ebcac070f293306927f71fe77858eec00` |
+| OZ `EIP712Upgradeable` | `EIP712StorageLocation` | `0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100` |
+| OZ `NoncesUpgradeable` | `NoncesStorageLocation` | `0x5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00` |
+
+`EIP712Upgradeable` and `NoncesUpgradeable` slots are present in the Permit deployment variants (`CMTATStandalonePermit`, `CMTATUpgradeablePermit`) which inherit `ERC20PermitUpgradeable`. `DocumentERC1643Module` is present in all deployment variants that extend `CMTATBaseDocument` (level 1) — which is every variant except the mock/generic base. `ValidationModuleAllowance` has no dedicated ERC-7201 slot; it is stateless.
+
+## Initialize Functions
+
+Each upgradeable module exposes `__{ContractName}_init_unchained`. Call these in your proxy initializer instead of `__{ContractName}_init` to avoid double-initialization across the inheritance chain.
+
+See [OpenZeppelin - Multiple Inheritance](https://docs.openzeppelin.com/contracts/5.x/upgradeable#multiple-inheritance) for details.
diff --git a/doc/technical/document.md b/doc/technical/document.md
new file mode 100644
index 00000000..3719d45b
--- /dev/null
+++ b/doc/technical/document.md
@@ -0,0 +1,110 @@
+# Document Management
+
+CMTAT supports two layers of on-chain document management:
+
+1. **Terms** — the primary tokenization terms stored directly in the token contract via `ExtraInformationModule`.
+2. **Additional documents** — arbitrary ERC-1643 documents, managed through one of two patterns:
+ - **Native storage** (`DocumentERC1643Module`) — documents are stored directly in the token contract (available in all shipped deployment variants).
+ - **External engine delegation** (`DocumentEngineModule`) — documents are managed by a separate `DocumentEngine` contract (not integrated in any shipped deployment variant; available as an optional module).
+
+## Terms
+
+The tokenization terms are a single `CMTATTerms` struct stored in the token contract. They can be read by anyone and set by an address with `EXTRA_INFORMATION_ROLE`.
+
+```solidity
+interface ICMTATBase {
+ struct CMTATTerms {
+ string name;
+ IERC1643.Document doc;
+ }
+ event Terms(CMTATTerms newTerm);
+
+ function terms() external view returns (CMTATTerms memory);
+ function setTerms(IERC1643CMTAT.DocumentInfo calldata terms_) external;
+}
+```
+
+A `Document` contains:
+- `uri` — a URI pointing to the document (e.g., IPFS link or HTTPS URL)
+- `documentHash` — hash of the document contents for integrity verification
+- `lastModified` — block timestamp of the last on-chain update (set automatically)
+
+## Additional Documents — Native Storage (`DocumentERC1643Module`)
+
+`DocumentERC1643Module` implements the full ERC-1643 interface directly inside the token contract. Documents are stored in ERC-7201 namespaced storage (slot `0x24fbb1cf6345ced60d5278ef6f68f4f7576fd9068704b4c8f1eec8f0bbd8a200`) using:
+
+```solidity
+mapping(bytes32 => Document) _documents;
+bytes32[] _documentNames;
+mapping(bytes32 => uint256) _documentKey; // 1-based index for O(1) removal
+```
+
+All four ERC-1643 operations are available on the token contract directly — no external engine contract is required:
+
+```solidity
+function getDocument(bytes32 name) external view returns (Document memory);
+function getAllDocuments() external view returns (bytes32[] memory);
+function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external; // requires DOCUMENT_ROLE
+function removeDocument(bytes32 name) external; // requires DOCUMENT_ROLE
+```
+
+`removeDocument` uses a swap-and-pop pattern to keep the `_documentNames` array compact without gaps.
+
+### Deployment Availability
+
+`DocumentERC1643Module` is included in **all shipped CMTAT deployment variants except Light** through the inheritance chain `CMTATBaseDocument` (level 1) → `CMTATBaseAccessControl` (level 2). The Light variant (`CMTATStandaloneLight`, `CMTATUpgradeableLight`) is based on `CMTATBaseCore`, which does not extend `CMTATBaseDocument` and therefore has no ERC-1643 document support. The concrete access-control hook `_authorizeDocumentManagement()` enforces `DOCUMENT_ROLE` in `CMTATBaseAccessControl`.
+
+### Trade-offs vs External Engine
+
+| | `DocumentERC1643Module` | `DocumentEngineModule` |
+|---|---|---|
+| Storage location | On-chain in token contract | External engine contract |
+| Deployment complexity | None (built-in) | Requires separate engine deployment |
+| Token contract size | Adds storage overhead | Keeps token contract lean |
+| Multi-token sharing | One registry per token | One engine can serve many tokens |
+| Shipped in CMTAT variants | Yes (all standard variants) | No |
+
+---
+
+## Additional Documents via External Engine (`DocumentEngineModule`)
+
+`DocumentEngineModule` is an alternative to the native storage pattern. Instead of storing documents in the token contract, it delegates all four ERC-1643 operations to a separate `DocumentEngine` contract that implements [ERC-1643](https://github.com/ethereum/EIPs/issues/1643):
+
+```solidity
+interface IERC1643 {
+ struct Document {
+ string uri;
+ bytes32 documentHash;
+ uint256 lastModified;
+ }
+
+ function getDocument(bytes32 name) external view returns (Document memory doc);
+ function getAllDocuments() external view returns (bytes32[] memory);
+ function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external;
+ function removeDocument(bytes32 name) external;
+}
+```
+
+**Note**: CMTAT uses `bytes32` for document identifiers, aligned with the original EIP proposal. Only the CMTAT tokenization terms path (`IERC1643CMTAT.DocumentInfo`) still uses `string name`.
+
+The engine is completely free to implement its own storage and management logic. CMTAT forwards both read (`getDocument`, `getAllDocuments`) and write (`setDocument`, `removeDocument`) calls to the engine. Write operations and engine configuration require `DOCUMENT_ENGINE_ROLE`.
+
+### Setting the DocumentEngine
+
+An address with `DOCUMENT_ENGINE_ROLE` can update the engine:
+
+```solidity
+function setDocumentEngine(address documentEngine_) external;
+```
+
+### Benefits of the External Engine
+
+- Reduces CMTAT contract size (which is near the maximum EVM limit).
+- Allows one engine to serve multiple token contracts simultaneously.
+
+## Compatible DocumentEngine Releases
+
+| CMTAT version | DocumentEngine |
+|---|---|
+| CMTAT v3.0.0 | Under development |
+| CMTAT v2.5.0 (unaudited) | [DocumentEngine v0.3.0](https://github.com/CMTA/DocumentEngine/releases/tag/v0.3.0) |
diff --git a/doc/technical/erc-3643-implementation.md b/doc/technical/erc-3643-implementation.md
new file mode 100644
index 00000000..7611e5c3
--- /dev/null
+++ b/doc/technical/erc-3643-implementation.md
@@ -0,0 +1,124 @@
+# ERC-3643 Implementation In CMTAT
+
+## Scope
+
+This document explains how CMTAT implements ERC-3643 semantics, where it intentionally diverges from the T-REX profile, and how the implementation is composed across modules and deployment variants.
+
+Reference specification used for comparison: [doc/ERCSpecification/erc-3643-trex.md](../ERCSpecification/erc-3643-trex.md).
+
+## Executive Summary
+
+CMTAT implements a substantial ERC-3643-compatible token surface (pause, freeze, partial freeze, forced transfer, mint/burn, batch operations, compliance pre-checks), but it does not embed the full T-REX identity stack (`IdentityRegistry`, `TrustedIssuersRegistry`, `ClaimTopicsRegistry`, `onchainID` plumbing). Instead, CMTAT externalizes transfer eligibility/compliance to a configurable RuleEngine/validation architecture and uses RBAC roles instead of the Owner/Agent governance model described in T-REX.
+
+## Interface Coverage
+
+Primary CMTAT interface:
+- [IERC3643Partial.sol](/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/IERC3643Partial.sol)
+
+Implemented ERC-3643-related interface groups in CMTAT:
+- `IERC3643Pause`
+- `IERC3643ERC20Base`
+- `IERC3643BatchTransfer`
+- `IERC3643Version`
+- `IERC3643Enforcement` and `IERC3643EnforcementEvent`
+- `IERC3643ERC20Enforcement`
+- `IERC3643Mint`
+- `IERC3643Burn`
+- `IERC3643ComplianceRead`
+- `IERC3643IComplianceContract` (implemented by RuleEngine side, not token side)
+
+## Requirement Mapping (T-REX -> CMTAT)
+
+1. ERC-20 compatibility: implemented.
+2. On-chain identity system mandatory: not implemented in-core (intentional gap).
+3. Compliance rules on transfers: implemented through RuleEngine/validation hooks.
+4. Standard pre-check before transfer: implemented (`canTransfer` and related checks).
+5. Recovery system (lost key): not implemented in core CMTAT.
+6. Freeze wallet / partial freeze: implemented.
+7. Pause token: implemented.
+8. Mint and burn: implemented.
+9. Agent + Owner role model: replaced by granular RBAC roles.
+10. Forced transfers by privileged operator: implemented.
+11. Batch operations: implemented (batch mint/burn/transfer/freeze operations depending on module).
+
+## Module-Level Implementation
+
+Core ERC-3643 behavior is split across wrapper modules:
+
+- Pause:
+ - [PauseModule.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol)
+ - Implements `pause`, `unpause`, `paused`.
+
+- Token metadata updates:
+ - [ERC20BaseModule.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol)
+ - Implements `setName`, `setSymbol`.
+
+- Mint / batch mint / ERC-3643 batch transfer path:
+ - [ERC20MintModule.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol)
+ - `batchTransfer` is role-gated and mapped to internal minter-transfer flow.
+
+- Burn / batch burn:
+ - [ERC20BurnModule.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol)
+
+- Address freeze:
+ - [EnforcementModule.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol)
+ - Implements `setAddressFrozen`, `batchSetAddressFrozen`, `isFrozen`.
+
+- Partial freeze and forced transfer:
+ - [ERC20EnforcementModule.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol)
+ - Implements `freezePartialTokens`, `unfreezePartialTokens`, `forcedTransfer`, `getFrozenTokens`.
+
+- Compliance pre-check surface:
+ - [ValidationModuleCore.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol)
+ - Implements `canTransfer`; integrates with generic validation path.
+
+## Deployment Coverage
+
+From deployment composition, ERC-3643 functionality is not all-or-nothing across every variant.
+
+- Standard (`CMTATStandardStandalone`, `CMTATStandardUpgradeable`):
+ - Includes the main ERC-3643-compatible tokenization surface (without T-REX identity stack).
+
+- Light:
+ - Reduced surface; intended minimal feature set.
+
+- Allowlist / Debt / DebtEngine / Snapshot / ERC-7551 / ERC-1363 / Permit:
+ - Inherit different subsets/extensions; ERC-3643-related behavior is preserved where inherited modules remain in the chain.
+
+For exact variant inheritance, see [doc/SUMMARY.md](../SUMMARY.md) and the deployment table in [doc/README.md](../README.md).
+
+## Main Differences Vs ERC-3643 T-REX
+
+1. Identity architecture omitted in-core.
+CMTAT does not natively expose T-REX token getters/setters like `identityRegistry()`, `compliance()`, `setIdentityRegistry()`, `setCompliance()`, `onchainID()`, or identity-registry contract suite APIs.
+
+2. Governance model differs.
+T-REX relies on Owner/Agent role conventions; CMTAT uses granular `AccessControl` roles (admin, minter, burner, enforcers, etc.).
+
+3. Compliance integration model differs.
+T-REX couples token and compliance/identity contracts in a canonical stack; CMTAT uses pluggable RuleEngine/validation modules and can operate without on-chain identity.
+
+4. Extended events and overloads.
+CMTAT emits additional events and supports extra overloads (for example `bytes data` in several flows), which are beyond the strict minimal ERC-3643 interface profile.
+
+5. `batchTransfer` semantics.
+CMTAT models ERC-3643 `batchTransfer` through minter-controlled transfer logic; this is not identical to every T-REX token implementation assumption and should be treated as CMTAT policy design.
+
+6. Freeze event layering.
+At base level (ERC-7943 enforcement core), CMTAT uses `Frozen(account, amount)` as a normalized frozen-state update event for both increase and decrease of frozen balances. For ERC-3643 direction semantics, wrapper modules emit `TokensFrozen` and `TokensUnfrozen`. Integrations requiring freeze/unfreeze direction should consume ERC-3643 (or ERC-7551) directional events.
+
+## Practical Integration Notes
+
+If strict T-REX parity is required, a dedicated deployment variant should add:
+- token-level identity/compliance contract bindings (`identityRegistry`, `compliance`, `onchainID`),
+- identity-registry stack contracts and wiring,
+- recovery flows (`recoveryAddress`) and associated history/events,
+- any missing batch administrative functions expected by a target T-REX integration.
+
+If the objective is regulated transfer control without on-chain identity, current CMTAT architecture is intentional and already provides strong compliance hooks.
+
+## Cross-References
+
+- ERC-3643 reference: [erc-3643-trex.md](../ERCSpecification/erc-3643-trex.md)
+- CMTAT partial interface: [IERC3643Partial.sol](/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/IERC3643Partial.sol)
+- Main README ERC-3643 section: [doc/README.md](../README.md)
diff --git a/doc/technical/erc-7943-uRWA-integration.md b/doc/technical/erc-7943-uRWA-integration.md
new file mode 100644
index 00000000..4ec80c06
--- /dev/null
+++ b/doc/technical/erc-7943-uRWA-integration.md
@@ -0,0 +1,142 @@
+# ERC-7943 (uRWA) Integration
+
+> [ERC specification](https://eips.ethereum.org/EIPS/eip-7943) / [Ethereum Magicians](https://ethereum-magicians.org/t/erc-7943-universal-rwa-interface-urwa/23972)
+>
+> Status: Review
+
+## Overview
+
+ERC-7943 defines a standard set of interfaces for tokenized Real World Assets (RWAs). It extends ERC-20 (or ERC-721/ERC-1155) with essential compliance functions — transfer restrictions, asset freezing, forced transfer — while remaining minimal and unopinionated about internal implementation.
+
+CMTAT implements the fungible (`IERC7943Fungible`) variant of ERC-7943. The ERC-165 interface ID for the fungible interface is `0x3edbb4c4`.
+
+## Interface Breakdown
+
+All related interfaces are defined in [`draft-IERC7943.sol`](../../contracts/interfaces/tokenization/draft-IERC7943.sol).
+
+| Interface | Purpose |
+|---|---|
+| `IERC7943FungibleEnforcement` | `forcedTransfer`, `getFrozenTokens` |
+| `IERC7943FungibleEnforcementSpecific` | `setFrozenTokens` |
+| `IERC7943FungibleEnforcementEventAndError` | `Frozen`, `ForcedTransfer` events; `ERC7943InsufficientUnfrozenBalance` error |
+| `IERC7943FungibleSendReceiveError` | `ERC7943CannotSend`, `ERC7943CannotReceive` errors |
+| `IERC7943FungibleTransferError` | `ERC7943CannotTransfer` error |
+| `IERC7943FungibleSendReceiveCheck` | `canSend(account)`, `canReceive(account)` |
+
+## Implementation Mapping
+
+| ERC-7943 Requirement | CMTAT Implementation |
+|---|---|
+| **Functions** | |
+| `forcedTransfer(from, to, amount)` | `ERC20EnforcementModule.sol` |
+| `setFrozenTokens(account, amount)` | `ERC20EnforcementModule.sol` |
+| `getFrozenTokens(account)` | `ERC20EnforcementModule.sol` |
+| `canSend(account)` | `ValidationModule.sol` |
+| `canReceive(account)` | `ValidationModule.sol` |
+| `canTransfer(from, to, amount)` | `ValidationModuleCore.sol` |
+| **Errors** | |
+| `ERC7943CannotSend` | `ValidationModule.sol` |
+| `ERC7943CannotReceive` | `ValidationModule.sol` |
+| `ERC7943CannotTransfer` | Defined in `draft-IERC7943.sol` (interface only; not currently reverted by CMTAT — the RuleEngine uses its own errors) |
+| `ERC7943InsufficientUnfrozenBalance` | `ERC20EnforcementModuleInternal.sol` |
+| **Events** | |
+| `Frozen` | `ERC20EnforcementModuleInternal.sol` |
+| `ForcedTransfer` | `ERC20EnforcementModuleInternal.sol` |
+
+## Event Semantics Across ERC-7943 / ERC-3643 / ERC-7551
+
+At the base enforcement layer, CMTAT emits the ERC-7943 `Frozen(account, amount)` event as a normalized "frozen amount changed" signal. This applies to both freeze and unfreeze transitions, and `amount` is the resulting frozen amount after the operation.
+
+This is aligned with ERC-7943, which defines a single `Frozen` event and does not define a distinct `Unfrozen` event.
+
+For direction-aware integrations, CMTAT emits dedicated events at wrapper level:
+
+- ERC-3643 path: `TokensFrozen(account, value)` and `TokensUnfrozen(account, value)`.
+- ERC-7551 path: `TokensFrozen(account, value, data)` and `TokensUnfrozen(account, value, data)`.
+
+Indexer guidance:
+
+- If you need the current frozen-state trajectory only, indexing `Frozen` is sufficient.
+- If you need action direction (freeze vs unfreeze), index `TokensFrozen` and `TokensUnfrozen` (ERC-3643/ERC-7551 events) instead of relying on event name from `Frozen`.
+
+## `canSend` / `canReceive`
+
+These are account-level eligibility checks independent of transfer parameters.
+
+- `canSend(account)` returns `true` if the account is allowed to send tokens (not frozen, not on an allowlist that excludes it).
+- `canReceive(account)` returns `true` if the account is allowed to receive tokens.
+
+Both are public view functions defined in `ValidationModule` and can be overridden in subclasses (e.g., `ValidationModuleAllowlist` adds an allowlist check on top).
+
+## Transfer Flow Diagram
+
+When a standard transfer is attempted:
+
+```
+transfer(to, 100)
+│
+├─ Is contract paused? ──────────────→ revert EnforcedPause()
+│
+├─ Is sender/spender frozen? ────────→ revert ERC7943CannotSend(account)
+├─ Is receiver frozen? ──────────────→ revert ERC7943CannotReceive(account)
+│
+├─ RuleEngine says no? ─────────────→ RuleEngine reverts with its own errors
+│
+├─ Not enough active balance? ───────→ revert ERC7943InsufficientUnfrozenBalance(...)
+│
+└─ Transfer executes
+```
+
+## Operator-as-Spender Semantics (RuleEngine)
+
+In CMTAT RuleEngine-integrated deployments, the effective operator is propagated as `spender` in spender-aware compliance hooks.
+
+- `transferFrom`: spender is the delegated caller.
+- `burnFrom` / `crosschainBurn`: spender is the operator (`_msgSender()`), with `to == address(0)`.
+- `mint` / `crosschainMint`: spender is the operator (`_msgSender()`), with `from == address(0)`.
+- `minterTransfer` (ERC-3643 `batchTransfer` path): spender is the operator (`_msgSender()`), with `from != address(0)` and `to != address(0)`.
+
+RuleEngine implementations should explicitly support these mint/burn operator cases where `operator == spender`.
+
+For `minterTransfer`, spender restrictions apply in the same way as standard operator transfer checks. RuleEngine logic must not classify this path as mint based on `from == address(0)`, because `minterTransfer` is a transfer path.
+
+`burnFrom` remains an access-controlled operation (role-gated) and is not modeled as a classic `transferFrom` compliance case. At hook level, `burn` and `burnFrom` share burn semantics (`to == address(0)`) and cannot be distinguished solely from `(spender, from, to, value)`. If policy needs to differentiate `burnFrom`, it should target the operator addresses that hold the role allowing `burnFrom`.
+
+If a RuleEngine policy is meant to apply only to traditional `transferFrom` spender restrictions, it should explicitly exclude these operator mint/burn paths:
+- apply spender-only rule only when `from != address(0)` (exclude mint),
+- and `to != address(0)` (exclude burn).
+
+## Error Semantics
+
+| Error | When emitted |
+|---|---|
+| `ERC7943CannotSend(account)` | The sender, spender, or burn source is not allowed to send |
+| `ERC7943CannotReceive(account)` | The recipient or mint target is not allowed to receive |
+| `ERC7943CannotTransfer(from, to, amount)` | Defined by the standard; available for custom extensions but not currently reverted by CMTAT itself |
+| `ERC7943InsufficientUnfrozenBalance(account, amount, unfrozen)` | The transfer amount exceeds the unfrozen balance |
+
+Note: `ERC7943CannotTransfer` is currently kept for interface/spec completeness and potential future use, but is not emitted by current CMTAT runtime validation paths.
+
+## Pre-Check Functions
+
+CMTAT provides pre-check functions to verify whether a transfer will succeed before executing it.
+
+### ERC-7943 Native Pre-Checks
+
+| Function | Standard | Purpose | Module |
+|---|---|---|---|
+| `canTransfer(from, to, value)` | ERC-7943 | Check if a direct transfer is allowed | `ValidationModuleCore` |
+| `canSend(account)` | ERC-7943 | Check if an account is allowed to send | `ValidationModule` |
+| `canReceive(account)` | ERC-7943 | Check if an account is allowed to receive | `ValidationModule` |
+
+### CMTAT Extension / Related Standards
+
+The following function is not part of ERC-7943. It is included by CMTAT through ERC-7551-related compliance support:
+
+| Function | Standard | Purpose | Module |
+|---|---|---|---|
+| `canTransferFrom(spender, from, to, value)` | ERC-7551 | Check if a delegated transfer is allowed | `ValidationModuleCore` |
+
+## ERC-165
+
+CMTAT returns `true` for `supportsInterface(0x3edbb4c4)` (the fungible ERC-7943 interface ID).
diff --git a/doc/technical/erc7551.md b/doc/technical/erc7551.md
new file mode 100644
index 00000000..2548b936
--- /dev/null
+++ b/doc/technical/erc7551.md
@@ -0,0 +1,270 @@
+# ERC-7551 Implementation Guide
+
+ERC-7551 is a draft standard for regulated crypto-securities, designed to meet the requirements of the German **eWpG** (Gesetz über elektronische Wertpapiere — Electronic Securities Act). It extends ERC-20 with compliance checks, operator-controlled minting and burning, partial freeze, forced transfers, and on-chain anchoring of legally binding documents.
+
+> CMTAT is a co-author of the ERC-7551 specification. The draft is available at [`doc/ERCSpecification/draft-erc-7551-ewpg.md`](../ERCSpecification/draft-erc-7551-ewpg.md).
+
+---
+
+## Scope
+
+ERC-7551 support in CMTAT is split across two modules that appear in different deployment variants:
+
+| Module | What it adds | Variants that include it |
+|---|---|---|
+| `ERC20EnforcementERC7551Module` | `bytes data` overloads for enforcement functions; `getActiveBalanceOf` | Standard, ERC-7551, ERC-1363, Allowlist |
+| `ERC7551Module` | `metaData` / `setMetaData`; ERC-7551 `setTerms(bytes32,string)` / `termsHash` | ERC-7551 only |
+
+The **ERC-7551 deployment variant** (`CMTATStandaloneERC7551` / `CMTATUpgradeableERC7551`) is the only variant that satisfies the full ERC-7551 document interface. All other variants that include `ERC20EnforcementERC7551Module` expose the enforcement interface but not the document interface.
+
+---
+
+## Inheritance Chain
+
+```
+CMTATBaseERC2771 (6)
+ └── CMTATBaseERC7551Enforcement (7) — adds ERC20EnforcementERC7551Module
+ ├── CMTATBaseERC1363 (8) — adds ERC-1363 transferAndCall [ERC-1363 variant]
+ └── CMTATBaseERC7551 (8) — adds ERC7551Module [ERC-7551 variant only]
+```
+
+`CMTATBaseERC7551Enforcement` (level 7) is also the direct base of `CMTATStandardStandalone` / `CMTATStandardUpgradeable`, so Standard deployments expose the ERC-7551 enforcement functions without the document interface.
+
+`CMTATBaseAllowlist` (level 3) independently composes `ERC20EnforcementERC7551Module` (outside the Standard chain), so the Allowlist variant also exposes the enforcement interface.
+
+---
+
+## Deployment Contracts
+
+| Type | Contract | File |
+|---|---|---|
+| Standalone (immutable) | `CMTATStandaloneERC7551` | `contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol` |
+| Upgradeable (Transparent / Beacon proxy) | `CMTATUpgradeableERC7551` | `contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol` |
+
+Both extend `CMTATBaseERC7551` (`contracts/modules/8_CMTATBaseERC7551.sol`).
+
+### Constructor / Initializer Parameters
+
+```solidity
+constructor(
+ address forwarderIrrevocable,
+ address admin,
+ ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+ ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+ ICMTATConstructor.Engine memory engines_
+)
+```
+
+| Parameter | Type | Description |
+|---|---|---|
+| `forwarderIrrevocable` | `address` | ERC-2771 trusted forwarder (irrevocable after deployment). Pass `address(0)` to disable. |
+| `admin` | `address` | Address receiving `DEFAULT_ADMIN_ROLE`. |
+| `ERC20Attributes_.name` | `string` | Token name. |
+| `ERC20Attributes_.symbol` | `string` | Token symbol. |
+| `ERC20Attributes_.decimalsIrrevocable` | `uint8` | Token decimals (irrevocable). |
+| `extraInformationAttributes_.tokenId` | `string` | ISIN or other identifier. |
+| `extraInformationAttributes_.terms` | `DocumentInfo` | Initial tokenization terms (name, URI, hash). |
+| `extraInformationAttributes_.information` | `string` | Supplementary information string. |
+| `engines_.ruleEngine` | `IRuleEngine` | External rule engine (pass `address(0)` for none). |
+
+The ERC-7551 variant has the same parameter set as Standard. `metaData` is not set at construction time — call `setMetaData` after deployment.
+
+---
+
+## ERC7551Module
+
+`contracts/modules/wrapper/options/ERC7551Module.sol`
+
+Implements `IERC7551Document`. Extends `ExtraInformationModule` and adds ERC-7551-specific document and metadata functions.
+
+### Storage
+
+Uses ERC-7201 namespaced storage (`CMTAT.storage.ERC7551Module`) for the `_metadata` string. The `terms` fields (hash, URI) are stored in `ExtraInformationModule`'s storage and accessed via `_setTerms` / `terms()`.
+
+### Events
+
+#### `MetaData(string)`
+
+```solidity
+event MetaData(string newMetaData)
+```
+
+Emitted when the metadata string is updated.
+
+#### `Terms(bytes32,string)`
+
+```solidity
+event Terms(bytes32 hash_, string uri_)
+```
+
+Emitted when the terms hash and URI are updated via the ERC-7551 `setTerms(bytes32, string)` overload.
+
+> This is different from the CMTAT `Terms(CMTATTerms)` event emitted by `ExtraInformationModule.setTerms(DocumentInfo)`. Both setters write to the same underlying `terms` storage, but they emit distinct events and accept different parameters.
+
+### Functions
+
+#### `metaData() → string`
+
+```solidity
+function metaData() public view virtual override(IERC7551Document) returns (string memory metadata_)
+```
+
+Returns the metadata string. Per ERC-7551, this MUST be a JSON object of key-value pairs describing the crypto security. It MAY be empty.
+
+#### `setMetaData(string)`
+
+```solidity
+function setMetaData(string calldata metadata_) public virtual override(IERC7551Document) onlyExtraInfoManager
+```
+
+Sets the metadata string. Emits `MetaData(metadata_)`.
+
+**Requirements:** caller must have `EXTRA_INFORMATION_ROLE`.
+
+#### `termsHash() → bytes32`
+
+```solidity
+function termsHash() public view virtual override(IERC7551Document) returns (bytes32 hash_)
+```
+
+Returns `terms().doc.documentHash` — the SHA-256 hash of the current terms document. A value of `bytes32(0)` means no terms have been set.
+
+#### `setTerms(bytes32,string)`
+
+```solidity
+function setTerms(bytes32 hash_, string calldata uri_) public virtual override(IERC7551Document) onlyExtraInfoManager
+```
+
+Sets the terms document hash and URI using the ERC-7551 signature. Internally calls `_setTerms(DocumentInfo("", uri_, hash_))` to write the shared `terms` storage, then emits `Terms(hash_, uri_)`.
+
+**Requirements:** caller must have `EXTRA_INFORMATION_ROLE`.
+
+**Note:** the `name` field of `CMTATTerms` is set to `""` when using this setter. To preserve a name, use `ExtraInformationModule.setTerms(DocumentInfo)` instead.
+
+---
+
+## ERC20EnforcementERC7551Module
+
+`contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol`
+
+Implements `IERC7551ERC20Enforcement`. Extends `ERC20EnforcementModule` and adds `bytes data` overloads for enforcement functions (for audit trails) plus the `getActiveBalanceOf` view.
+
+### Functions
+
+#### `getActiveBalanceOf(address) → uint256`
+
+```solidity
+function getActiveBalanceOf(address account) public view virtual override(IERC7551ERC20Enforcement) returns (uint256 activeBalance_)
+```
+
+Returns the number of tokens available for standard ERC-20 transfers: `balanceOf(account) - getFrozenTokens(account)`. If frozen tokens exceed the total balance, returns `0`.
+
+#### `getFrozenTokens(address) → uint256`
+
+```solidity
+function getFrozenTokens(address account) public view virtual override(ERC20EnforcementModule, IERC7551ERC20Enforcement) returns (uint256 frozenBalance_)
+```
+
+Returns the frozen token count. Overrides both `ERC20EnforcementModule` and `IERC7551ERC20Enforcement` to resolve the diamond inheritance.
+
+#### `forcedTransfer(address,address,uint256,bytes) → bool`
+
+```solidity
+function forcedTransfer(address from, address to, uint256 value, bytes calldata data)
+ public virtual override(IERC7551ERC20Enforcement) onlyForcedTransferManager returns (bool)
+```
+
+Forced transfer with a `data` payload for audit or compliance metadata. If frozen tokens must be released to cover `value`, unfreezes them automatically before transferring.
+
+Emits:
+- `ForcedTransfer(operator, from, to, value, data)` — always
+- `TokensUnfrozen(from, unfrozenAmount, data)` — only if frozen tokens were released
+
+**Requirements:** caller must have `DEFAULT_ADMIN_ROLE`.
+
+#### `freezePartialTokens(address,uint256,bytes)`
+
+```solidity
+function freezePartialTokens(address account, uint256 value, bytes calldata data)
+ public virtual override(IERC7551ERC20Enforcement) onlyERC20Enforcer
+```
+
+Freezes `value` tokens on `account`. The `data` field is attached to the emitted event for audit purposes.
+
+Emits: `TokensFrozen(account, value, data)`
+
+**Requirements:** caller must have `ERC20ENFORCER_ROLE`.
+
+#### `unfreezePartialTokens(address,uint256,bytes)`
+
+```solidity
+function unfreezePartialTokens(address account, uint256 value, bytes calldata data)
+ public virtual override(IERC7551ERC20Enforcement) onlyERC20Enforcer
+```
+
+Unfreezes `value` tokens on `account`. The `data` field is attached to the emitted event.
+
+Emits: `TokensUnfrozen(account, value, data)`
+
+**Requirements:** caller must have `ERC20ENFORCER_ROLE`.
+
+---
+
+## Interface Compliance
+
+The table below maps each ERC-7551 interface requirement to the implementing CMTAT module.
+
+| ERC-7551 interface | Function / Event | Implementing module | Available in |
+|---|---|---|---|
+| `IERC7551Mint` | `mint(address, uint256, bytes)` | `ERC20MintModule` | All |
+| | `event Mint(minter, account, value, data)` | `ERC20MintModule` | All |
+| `IERC7551Burn` | `burn(address, uint256, bytes)` | `ERC20BurnModule` | All |
+| | `event Burn(burner, account, value, data)` | `ERC20BurnModule` | All |
+| `IERC7551Pause` | `paused()` / `pause()` / `unpause()` | `PauseModule` | All |
+| `IERC7551Compliance` | `canTransfer(from, to, value)` | `ValidationModuleCore` | All |
+| | `canTransferFrom(spender, from, to, value)` | `ValidationModuleCore` | All |
+| `IERC7551ERC20Enforcement` | `getActiveBalanceOf(address)` | `ERC20EnforcementERC7551Module` | Standard, ERC-7551, ERC-1363, Allowlist |
+| | `getFrozenTokens(address)` | `ERC20EnforcementERC7551Module` | Standard, ERC-7551, ERC-1363, Allowlist |
+| | `forcedTransfer(from, to, value, bytes)` | `ERC20EnforcementERC7551Module` | Standard, ERC-7551, ERC-1363, Allowlist |
+| | `freezePartialTokens(account, value, bytes)` | `ERC20EnforcementERC7551Module` | Standard, ERC-7551, ERC-1363, Allowlist |
+| | `unfreezePartialTokens(account, value, bytes)` | `ERC20EnforcementERC7551Module` | Standard, ERC-7551, ERC-1363, Allowlist |
+| | `event ForcedTransfer(operator, from, to, value, data)` | `ERC20EnforcementERC7551Module` | Standard, ERC-7551, ERC-1363, Allowlist |
+| | `event TokensFrozen(account, value, data)` | `ERC20EnforcementERC7551Module` | Standard, ERC-7551, ERC-1363, Allowlist |
+| | `event TokensUnfrozen(account, value, data)` | `ERC20EnforcementERC7551Module` | Standard, ERC-7551, ERC-1363, Allowlist |
+| `IERC7551Document` | `metaData()` / `setMetaData(string)` | `ERC7551Module` | ERC-7551 only |
+| | `termsHash()` | `ERC7551Module` | ERC-7551 only |
+| | `setTerms(bytes32, string)` | `ERC7551Module` | ERC-7551 only |
+| | `event MetaData(string)` | `ERC7551Module` | ERC-7551 only |
+| | `event Terms(bytes32, string)` | `ERC7551Module` | ERC-7551 only |
+
+---
+
+## setTerms Disambiguation
+
+The ERC-7551 variant exposes two `setTerms` overloads with different signatures and semantics:
+
+| Overload | Defined in | Parameters | Emits | Notes |
+|---|---|---|---|---|
+| `setTerms(DocumentInfo)` | `ExtraInformationModule` | `(string name, string uri, bytes32 hash)` | `Terms(CMTATTerms)` | Sets name, URI, and hash |
+| `setTerms(bytes32, string)` | `ERC7551Module` | `(bytes32 hash, string uri)` | `Terms(bytes32, string)` | Sets URI and hash; `name` is set to `""` |
+
+Both overloads write to the same underlying `terms` storage. Callers should use the `ExtraInformationModule` overload when a human-readable name for the terms document is required, and the `ERC7551Module` overload when strict ERC-7551 interface compatibility is needed.
+
+---
+
+## Deviations from the ERC-7551 Specification
+
+The ERC-7551 specification is a **draft**. The following requirements from the spec are not enforced in the current CMTAT implementation:
+
+| Spec requirement | CMTAT behaviour |
+|---|---|
+| `unpause()` MUST revert if `termsHash() == bytes32(0)` | Not enforced. `PauseModule.unpause()` does not check `termsHash`. The caller is responsible for setting a non-zero terms hash before unpausing in eWpG contexts. |
+
+---
+
+## See Also
+
+- [`doc/modules/options/erc7551/erc7551.md`](../modules/options/erc7551/erc7551.md) — module-level API reference
+- [`doc/modules/extensions/ERC20Enforcement/erc20enforcement.md`](../modules/extensions/ERC20Enforcement/erc20enforcement.md) — base enforcement module
+- [`doc/technical/access-control.md`](./access-control.md) — role list and function-to-role table
+- [`doc/ERCSpecification/draft-erc-7551-ewpg.md`](../ERCSpecification/draft-erc-7551-ewpg.md) — ERC-7551 specification
diff --git a/doc/technical/guideline-new-blockchain.md b/doc/technical/guideline-new-blockchain.md
new file mode 100644
index 00000000..e9b37b61
--- /dev/null
+++ b/doc/technical/guideline-new-blockchain.md
@@ -0,0 +1,75 @@
+### Guideline
+
+If you create a version for another blockchain, feel free to use this summary tab to build a correspondence table between CMTAT framework, CMTAT Solidity version and your implementation.
+
+#### CMTAT framework
+
+In the below table, the CMTAT framework required features are mapped to Solidity features.
+
+| **CMTAT framework mandatory functionalities** | **CMTAT Solidity corresponding features** |
+| --------------------------------------------- | ------------------------------------------------------------ |
+| Know total supply | ERC20 `totalSupply` |
+| Know balance | ERC20 `balanceOf` |
+| Transfer tokens | ERC20 `transfer` |
+| Create tokens (mint) | `Mint/batchMint` |
+| Cancel tokens (force burn) | `burn/batchBurn` *(Nb. we recommend to have a dedicated function to burn tokens without the token holder consent or from a frozen address*) |
+| Pause tokens | Pause (*Nb. With CMTAT Solidity it is still possible to burn and mint while transfers are paused.)* |
+| Unpause tokens | `unpause` |
+| Deactivate contract | `deactivateContract` |
+| Freeze | `setAddressFrozen` (previously `freeze`) |
+| Unfreeze | `setAddressFrozen` (previously `unfreeze`) |
+| Name attribute | ERC20 `name` attribute |
+| Ticker symbol attribute | ERC20 `symbol` attribute |
+| Token ID attribute | `tokenId` |
+| Reference to legally required documentation | `terms` (document name, hash and uri with at least the uri) |
+
+**Freeze**
+
+To be compatible with [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), the freeze functionality is implemented with only one function: `setAddressFrozen` which takes the target address and the frozen status (true/false).
+
+However, for non-EVM blockchains, it could be clearer and make more sense to separate the freeze and unfreeze (or `thaw`) functionality with two separate and distinct functions, such as:
+
+```solidity
+freeze(address targetAddress)
+unfreeze(address targetAddress)
+```
+
+#### CMTAT extended
+
+In the below table, the CMTAT framework extendedfeatures are mapped to Solidity features.
+
+| CMTAT Functionalities | **CMTAT Solidity corresponding features** | CMTAT Allowlist | CMTAT Light | CMTAT Debt | CMTAT Standard |
+| ------------------------------------ | ---------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| On-chain snapshot | `snapshotModule & snapshotEngine` | ✔ | ✘ | ✔ | ✔ |
+| Forced Transfer | `forcedTransfer` | ✔ | ✘ | ✔ | ✔ |
+| Forced burn | `forcedBurn` | ✘ | ✔ | ✘ | ✘ |
+| Freeze partial token | `freezePartialTokens`/ `unfreezePartialTokens` | ✔ | ✘ | ✔ | ✔ |
+| Integrated whitelisting/allowlisting | CMTAT Allowlist | ✔ | ✘ | ✘ | ✘ |
+| External Whitelisting/allowlisting | CMTAT with rule whitelist | ✘ | ✘ | ✔ | ✔ |
+| RuleEngine / transfer hook | CMTAT with RuleEngine | ✘ | ✘ | ✔ | ✔ |
+| Upgradibility | CMTAT Upgradeable version | ✔ | ✔ | ✔ | ✔ |
+| Feepayer/gasless | CMTAT with ERC-2771 module | ✔ | ✘ | ✘ | ✔ |
+
+**ForcedBurn/forcedTransfer:**
+
+In the standard burn function, it is not possible to burn token from a frozen wallet. CMTAT offers a dedicated function `forcedTransfer`which allows to force a transfer or a burn. If the `forcedTransfer` function is not available, the alternative is to implement only the function `forcedBurn`.
+
+This is what is done for the CMTAT light version which does not include `forcedTransfer`. You can also decide to implement both. In this case, we suggest that only `forcedBurn`can burn tokens and not `forcedTransfer`. With the CMTAT Solidity version, when `forcedTransfer` is available, we do not implement `forcedBurn` to reduce smart contract code size, but this limitation is not necessarily present with other blockchains.
+
+#### Implementation details
+
+| Functionalities | **CMTAT Solidity** | Note |
+| ---------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
+| Mint while pause | ✔ | Dedicated crosschain mint (e.g. `crosschainMint`) cannot be performed while the contract is in the pause state. |
+| Burn while pause | ✔ | Dedicated crosschain burn (e.g.`crosschainBurn`) cannot be performed while the contract is in the pause state. |
+| Self Burn | ✘ | Token holder can not burn their own tokens. Only authorised addresses are allowed to burn tokens. |
+| Standard burn on a frozen address | ✘ | Required to use `forcedTransfer` or `forcedBurn` |
+| Burn tokens with the function `forcedTransfer` | ✔ | See note above |
+
+**Self burn**
+
+It's deliberate that only the issuer (and not the tokenholder) can burn a token, and that this corresponds to a legal requirement in several countries.
+
+Indeed, once issued, a security can only be cancelled by its issuer, not by its holder. Since the token serves as a vehicle for the security, the same must apply to the token itself. An investor wishing to "get rid of" a token must transfer it to the issuer, who can then cancel it when the law allows.
+
+However, feel free to add it in your CMTAT version if this makes sense for you from a legal or business perspective.
\ No newline at end of file
diff --git a/doc/technical/permit-multicall.md b/doc/technical/permit-multicall.md
new file mode 100644
index 00000000..b5cdd505
--- /dev/null
+++ b/doc/technical/permit-multicall.md
@@ -0,0 +1,56 @@
+# Permit (ERC-2612) + Multicall (ERC-6357)
+
+The Permit deployment version adds support for [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) and [ERC-6357 single-contract Multicall](https://eips.ethereum.org/EIPS/eip-6357).
+
+## Deployment Contracts
+
+- `CMTATStandalonePermit` — immutable deployment
+- `CMTATUpgradeablePermit` — proxy-compatible deployment
+
+Compared to the standard deployment:
+- Adds signature-based approvals via `permit`
+- Adds call batching via `multicall`
+- Does **not** include `ERC2771Module`, to keep bytecode lean
+
+## ERC-2612 Permit
+
+`permit` allows a token owner to approve a spender using an off-chain signature instead of an on-chain transaction. This enables gas-sponsored approval workflows.
+
+```solidity
+function permit(
+ address owner,
+ address spender,
+ uint256 value,
+ uint256 deadline,
+ uint8 v, bytes32 r, bytes32 s
+) external;
+```
+
+### Allowance Authorization Checks
+
+The same checks apply to both `approve` and `permit`:
+
+- The contract must not be paused.
+- The `owner` must not be frozen (checked via `canSend`).
+- The `spender` must not be frozen (checked via `canSend`). In the Allowlist deployment variant, both must also be allowlisted.
+
+These checks are enforced in `ValidationModuleAllowance._canAuthorizeAllowanceByModuleAndRevert`.
+
+## ERC-6357 Multicall
+
+`multicall` batches multiple calls to the same contract in a single transaction. Useful for atomic combinations of mint, burn, freeze, or approve operations.
+
+```solidity
+function multicall(bytes[] calldata data) external returns (bytes[] memory results);
+```
+
+## How to Use
+
+1. Select `CMTATStandalonePermit` or `CMTATUpgradeablePermit`.
+2. Use `permit(owner, spender, value, deadline, v, r, s)` to set an allowance from an off-chain signature.
+3. Use `multicall(bytes[] calldata data)` to batch several operations in one transaction.
+
+This deployment version is well-suited for workflows that require:
+- Gas-sponsored approvals (the spender pays gas, not the owner)
+- Signature-based UX (no separate approve transaction)
+- Atomic batching of multiple token operations
diff --git a/doc/technical/ruleengine-integration.md b/doc/technical/ruleengine-integration.md
new file mode 100644
index 00000000..2aa27d29
--- /dev/null
+++ b/doc/technical/ruleengine-integration.md
@@ -0,0 +1,134 @@
+# RuleEngine Integration In CMTAT
+
+## Scope
+
+This document explains how CMTAT integrates an external RuleEngine, including:
+- interface requirements,
+- execution hooks and call paths,
+- operator/spender semantics,
+- deployment coverage and constraints,
+- implementation guidance for RuleEngine authors.
+
+## Core Contracts And Interfaces
+
+- RuleEngine interfaces:
+ - [IRuleEngine.sol](/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IRuleEngine.sol)
+- RuleEngine storage wiring:
+ - `ValidationModuleRuleEngineInternal` (engine slot + setter/getter)
+- RuleEngine extension wrapper:
+ - [ValidationModuleRuleEngine.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol)
+- Base integration point:
+ - [3_CMTATBaseRuleEngine.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol)
+- Generic validation flow:
+ - [ValidationModule.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol)
+ - [ValidationModuleCore.sol](/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol)
+
+## Interface Requirements
+
+Minimum RuleEngine target interface in CMTAT:
+
+1. `IRuleEngine`:
+- `transferred(address from, address to, uint256 value)` (ERC-3643-style)
+- `transferred(address spender, address from, address to, uint256 value)` (spender-aware extension)
+- `canTransfer(from, to, value)` (read-only pre-check)
+- `canTransferFrom(spender, from, to, value)` (spender-aware pre-check)
+
+2. Optional `IRuleEngineERC1404` (if ERC-1404-specific behavior is needed):
+- adds `detectTransferRestriction*` and `messageForTransferRestriction`.
+
+## Configuration Lifecycle
+
+RuleEngine is optional and can be zero-address.
+
+- Set/update entrypoint:
+ - `setRuleEngine(IRuleEngine)` in `ValidationModuleRuleEngine`.
+- Access control:
+ - gated by `_authorizeRuleEngineManagement`.
+ - in CMTAT base integration, this is restricted to `DEFAULT_ADMIN_ROLE`.
+- Same-value protection:
+ - reverts with `CMTAT_ValidationModule_SameValue()`.
+
+## Runtime Call Flow
+
+### A) Read-only checks
+
+1. Public check (`canTransfer`, `canTransferFrom`) enters `ValidationModuleRuleEngine`.
+2. Local CMTAT checks run first (pause/freeze/allowance and active-balance checks in base chain).
+3. If a RuleEngine is configured, CMTAT calls:
+- `ruleEngine.canTransfer(...)`, or
+- `ruleEngine.canTransferFrom(...)`.
+4. If no RuleEngine is configured, RuleEngine layer returns `true`.
+
+Important:
+- `canTransfer(from, to, value)` does not include a spender/operator argument, so it cannot enforce spender/operator-specific policies.
+- Use `canTransferFrom(spender, from, to, value)` when the policy must validate a delegated caller/operator.
+
+### B) State-changing token operations
+
+For transfer/mint/burn and related flows, CMTAT ultimately calls `_checkTransferred(...)`.
+
+In RuleEngine-enabled base chains (`CMTATBaseRuleEngine`), `_checkTransferred` extends common checks and then calls:
+- `ValidationModuleRuleEngine._transferred(spender, from, to, value)`.
+
+Inside `_transferred`:
+- local generic checks are executed first (`_canTransferGenericByModuleAndRevert`),
+- then RuleEngine hook is called if configured:
+ - spender-aware hook if `spender != address(0)`,
+ - ERC-3643 3-arg hook if `spender == address(0)`.
+
+RuleEngine is expected to revert if transfer is invalid.
+
+## Spender / Operator Semantics
+
+CMTAT uses spender-aware semantics beyond classic `transferFrom`:
+
+1. Classic delegated transfer:
+- `transferFrom`: `spender` is delegated caller.
+
+2. Mint / burn operator flows:
+- mint-like paths: `from == address(0)`, `spender == operator`.
+- burn-like paths: `to == address(0)`, `spender == operator`.
+
+3. Cross-chain operator flows:
+- `crosschainBurn` / `crosschainMint` propagate operator context for spender-aware RuleEngine logic.
+
+4. Minter transfer path:
+- ERC-3643 `batchTransfer` minter path propagates `_msgSender()` as `spender`.
+- This is a transfer path (`from != address(0)`), not mint classification.
+
+Practical implication:
+- if a RuleEngine rule should apply only to classic `transferFrom`, it must explicitly exclude mint/burn operator tuples.
+
+## Deployment Coverage
+
+RuleEngine support depends on deployment inheritance:
+
+- RuleEngine-capable variants include chains inheriting `CMTATBaseRuleEngine` (directly or indirectly through higher-level bases).
+- Variants based on allowlist-only paths without RuleEngine module do not expose runtime RuleEngine configuration.
+- Light variant is intentionally reduced and does not provide full RuleEngine feature surface.
+
+Use deployment summary in [doc/SUMMARY.md](../SUMMARY.md) and deployment tables in [doc/README.md](../README.md) to select the correct variant.
+
+## Authoring Guidelines For RuleEngine Implementers
+
+1. Restrict `transferred(...)` to authorized token contracts.
+2. Keep `canTransfer*` and `transferred*` policy-consistent (read-check and state-hook should not diverge unexpectedly).
+3. Handle spender/operator tuples explicitly:
+- classic delegated transfer,
+- operator mint,
+- operator burn,
+- cross-chain/operator-driven paths.
+4. Do not rely only on `from == address(0)`/`to == address(0)` unless policy intentionally treats operator mint/burn uniformly.
+5. If targeting ERC-1404 UX, implement `IRuleEngineERC1404` functions consistently with `canTransfer*`.
+
+## Known Design Choices
+
+1. RuleEngine address is not contract-type enforced at set-time by default (design choice).
+2. Read-only pre-checks are advisory; runtime may still revert on later checks/state changes.
+3. RuleEngine is optional; base validation still applies even when RuleEngine is unset.
+
+## Cross-References
+
+- Main RuleEngine section: [doc/README.md](../README.md)
+- ERC-7943 operator semantics: [erc-7943-uRWA-integration.md](./erc-7943-uRWA-integration.md)
+- ERC-3643 mapping: [erc-3643-implementation.md](./erc-3643-implementation.md)
diff --git a/doc/technical/snapshot.md b/doc/technical/snapshot.md
new file mode 100644
index 00000000..972489d2
--- /dev/null
+++ b/doc/technical/snapshot.md
@@ -0,0 +1,69 @@
+# Snapshot Engine
+
+The SnapshotEngine allows performing on-chain balance and total supply snapshots. It is defined in the `SnapshotEngineModule` and implemented through an external `SnapshotEngine` contract.
+
+## How It Works
+
+**Before** each transfer (mint, burn, or standard transfer), CMTAT calls `operateOnTransfer` on the configured engine. This records balances and total supply at that point in time so that historical queries remain accurate.
+
+```solidity
+interface ISnapshotEngine {
+ /**
+ * @notice Records balance and total supply snapshots before any token transfer occurs.
+ * @dev Called inside the {_update} hook before any state changes from {_mint}, {_burn}, or {_transfer}.
+ *
+ * @param from Address tokens are transferred from (zero address if minting).
+ * @param to Address tokens are transferred to (zero address if burning).
+ * @param balanceFrom Current balance of `from` before the transfer.
+ * @param balanceTo Current balance of `to` before the transfer.
+ * @param totalSupply Current total supply before the transfer.
+ */
+ function operateOnTransfer(
+ address from,
+ address to,
+ uint256 balanceFrom,
+ uint256 balanceTo,
+ uint256 totalSupply
+ ) external;
+}
+```
+
+## Setting the Engine
+
+An address with `SNAPSHOOTER_ROLE` configures the engine:
+
+```solidity
+function setSnapshotEngine(address snapshotEngine_) external;
+```
+
+## Security / Liveness Note
+
+`setSnapshotEngine` is a privileged operation. If `SNAPSHOOTER_ROLE` sets an engine that always reverts, token state-changing flows that call `_update` can fail, creating a **transfer-liveness halt** (pause-like behavior).
+
+## Deployment Versions
+
+`CMTATBaseSnapshot` (level 0) is the core mixin that wires the ERC-20 `_update` hook into an optional external `SnapshotEngine`. It is included in several deployment variants:
+
+| Deployment variant | Base | Snapshot support |
+|---|---|---|
+| `CMTATStandaloneSnapshot` / `CMTATUpgradeableSnapshot` | `CMTATBaseERC2771Snapshot` (level 7) | ✓ dedicated variant |
+| `CMTATStandaloneDebt` / `CMTATUpgradeableDebt` | `CMTATBaseDebt` (level 4, inherits `CMTATBaseSnapshot`) | ✓ built-in |
+| `CMTATStandaloneDebtEngine` / `CMTATUpgradeableDebtEngine` | `CMTATBaseDebtEngine` (level 6, inherits `CMTATBaseSnapshot`) | ✓ built-in |
+
+Issuers using the `Debt` or `DebtEngine` deployment variants can configure a `SnapshotEngine` directly on those contracts — there is no need to deploy the dedicated `Snapshot` variant to access this functionality.
+
+It is also possible to extend CMTAT directly to include snapshot logic without an external contract. The [SnapshotEngine](https://github.com/CMTA/SnapshotEngine) repository provides such a deployment variant.
+
+## Compatible SnapshotEngine Releases
+
+| CMTAT version | SnapshotEngine |
+|---|---|
+| CMTAT v3.3.0 | Testing against v0.3.0-compatible engines in progress |
+| CMTAT v3.0.0 | [v0.3.0](https://github.com/CMTA/SnapshotEngine/releases/tag/v0.3.0) (unaudited) |
+| CMTAT v2.3.0 | SnapshotEngine v0.1.0 (unaudited) |
+| CMTAT v2.4.0, v2.5.0 | Included inside SnapshotModule (unaudited) |
+| CMTAT v1.0.0 | Included inside SnapshotModule (audited) |
+
+## Use Case
+
+On-chain snapshots are primarily used for dividend distribution: a snapshot records balances at a given block, which can then be used by an external contract to compute and distribute dividends proportionally.
diff --git a/doc/technical/stablecoin.md b/doc/technical/stablecoin.md
new file mode 100644
index 00000000..c51472f8
--- /dev/null
+++ b/doc/technical/stablecoin.md
@@ -0,0 +1,427 @@
+# Stablecoin Deployment Guide
+
+This document describes the **Light** deployment variant, which is designed for stablecoins, and explains when to use one of the alternative variants (**Standard** or **Permit**) if more features are required.
+
+## Why Light for Stablecoins
+
+Stablecoins typically need a smaller set of compliance features than equity or debt instruments:
+
+- Issue and redeem tokens (mint / burn).
+- Globally freeze activity (pause).
+- Blacklist individual addresses (address freeze).
+- Emergency burn from a blacklisted address (forced burn).
+- Update name / symbol after deployment.
+
+The Light variant provides exactly these capabilities with no overhead from modules that are irrelevant to most stablecoin designs (document management, snapshots, partial balance freeze, debt fields, or cross-chain bridges). The result is a contract roughly half the size of the Standard variant.
+
+| Variant | Deployed bytecode |
+|---|---|
+| CMTAT Light | 11.298 KiB |
+| CMTAT Standard | 22.243 KiB |
+| CMTAT Permit | 23.268 KiB |
+
+The 24.576 KiB EVM deployed bytecode limit is not a concern for Light, leaving substantial room for integrators who extend the contract.
+
+---
+
+## Light Variant — Feature Set
+
+### Deployment contracts
+
+| Type | Contract | File |
+|---|---|---|
+| Standalone (immutable) | `CMTATStandaloneLight` | `contracts/deployment/light/CMTATStandaloneLight.sol` |
+| Upgradeable (Transparent / Beacon proxy) | `CMTATUpgradeableLight` | `contracts/deployment/light/CMTATUpgradeableLight.sol` |
+
+Both extend `CMTATBaseCore` (`contracts/modules/0_CMTATBaseCore.sol`), which bundles the complete feature set in a single level-0 base.
+
+### Constructor / Initializer Parameters
+
+The Light variant takes a minimal set of constructor parameters compared to other variants:
+
+```solidity
+constructor(
+ address admin,
+ ICMTATConstructor.ERC20Attributes memory ERC20Attributes_
+)
+```
+
+| Parameter | Type | Description |
+|---|---|---|
+| `admin` | `address` | Address receiving `DEFAULT_ADMIN_ROLE` on deployment. |
+| `ERC20Attributes_.name` | `string` | Token name. |
+| `ERC20Attributes_.symbol` | `string` | Token symbol. |
+| `ERC20Attributes_.decimalsIrrevocable` | `uint8` | Token decimals (irrevocable after deployment). |
+
+There is no `forwarderIrrevocable` parameter (no ERC-2771 support), no `extraInformationAttributes_` (no tokenId/terms/information), and no `engines_` (no external engine contracts).
+
+### Module Inventory
+
+| Module | What it provides |
+|---|---|
+| `ERC20BaseModule` | ERC-20 base — `transfer`, `transferFrom`, `approve`, `allowance`, `balanceOf`, `totalSupply`; updatable `name` / `symbol` (requires `DEFAULT_ADMIN_ROLE`); irrevocable `decimals` |
+| `ERC20MintModule` | `mint(address, uint256, bytes)`, `mint(address, uint256)`, `batchMint`, `batchTransfer` — requires `MINTER_ROLE` |
+| `ERC20BurnModule` | `burn(address, uint256, bytes)`, `burn(address, uint256)`, `batchBurn` — requires `BURNER_ROLE` |
+| `PauseModule` | `pause()` / `unpause()` (requires `PAUSER_ROLE`); `deactivateContract()` (requires `DEFAULT_ADMIN_ROLE`); `paused()` / `deactivated()` view functions |
+| `EnforcementModule` | `setAddressFrozen(address, bool)`, `batchSetAddressFrozen` (requires `ENFORCER_ROLE`); `isFrozen(address)` read |
+| `ValidationModule` / `ValidationModuleCore` | Enforces pause and freeze checks on every transfer, `transferFrom`, `approve`, mint, and burn; `canSend(address)`, `canReceive(address)`, `canTransfer(from, to, value)`, `canTransferFrom(spender, from, to, value)` |
+| `ValidationModuleAllowance` | Enforces pause and freeze checks on `approve` |
+| `AccessControlModule` | OpenZeppelin RBAC — `grantRole`, `revokeRole`, `renounceRole`, `hasRole`; `DEFAULT_ADMIN_ROLE` has all roles by default |
+| `VersionModule` | `version()` — returns the CMTAT version string |
+
+`CMTATBaseCore` also defines the following multi-module operations directly:
+
+| Function | Role | Description |
+|---|---|---|
+| `forcedBurn(address, uint256, bytes)` | `DEFAULT_ADMIN_ROLE` | Burns tokens from a frozen (blacklisted) address. The account must be frozen first via `setAddressFrozen`. Emits `ForcedTransfer(operator, account, address(0), value, data)`. |
+| `burnAndMint(address, address, uint256, uint256, bytes)` | `BURNER_ROLE` + `MINTER_ROLE` | Atomically burns from one address and mints to another in a single transaction. |
+
+### Role Summary
+
+| Role | Key operations |
+|---|---|
+| `DEFAULT_ADMIN_ROLE` | Grant/revoke all roles; `deactivateContract`; `forcedBurn`; `setName`; `setSymbol` |
+| `MINTER_ROLE` | `mint`, `batchMint`, `batchTransfer` |
+| `BURNER_ROLE` | `burn`, `batchBurn` |
+| `PAUSER_ROLE` | `pause`, `unpause` |
+| `ENFORCER_ROLE` | `setAddressFrozen`, `batchSetAddressFrozen` |
+
+### What Light Does NOT Include
+
+The following features are intentionally absent to keep the contract lean:
+
+| Feature | Missing module | Notes |
+|---|---|---|
+| Partial balance freeze | `ERC20EnforcementModule` | No `freezePartialTokens` / `unfreezePartialTokens` / `setFrozenTokens`. Address-level freeze only. |
+| Forced transfer to third party | `ERC20EnforcementModule` | Only `forcedBurn` is available. Cannot move tokens from a frozen account to another address. |
+| On-chain token metadata | `ExtraInformationModule` | No `tokenId`, `terms`, `information` fields. |
+| On-chain document management | `DocumentERC1643Module` | No ERC-1643 document storage. |
+| Snapshot engine support | `SnapshotEngineModule` | No `setSnapshotEngine` / `operateOnTransfer` hook. |
+| Gasless meta-transactions | `ERC2771Module` | No trusted forwarder / ERC-2771 support. |
+| Signature-based approvals | `ERC20PermitUpgradeable` | No ERC-2612 `permit`. |
+| Batch operations in one call | `MulticallUpgradeable` | No ERC-6357 `multicall`. |
+| Transfer rule engine | `ValidationModuleRuleEngine` | No external RuleEngine. Transfer restrictions are pause + address freeze only. |
+| ERC-1404 restricted transfer | `ValidationModuleERC1404` | No `detectTransferRestriction` / `messageForTransferRestriction`. |
+| Cross-chain mint/burn | `ERC20CrossChainModule` | No ERC-7802, no CCIP. |
+| ERC-1363 token callbacks | — | No `transferAndCall` / `approveAndCall`. |
+
+### Transfer Restriction Logic
+
+Every token movement is validated by `ValidationModule._canTransferGenericByModuleAndRevert`. The checks applied are:
+
+1. Contract must not be paused (`PauseModule.paused()` is false).
+2. Sender / spender must not be frozen (`EnforcementModule.isFrozen(account)` is false).
+3. Recipient must not be frozen.
+
+No external RuleEngine is consulted. There is no allowlist module in Light.
+
+### Blacklisting Pattern
+
+The standard stablecoin blacklisting pattern on Light:
+
+1. Call `setAddressFrozen(blacklistedAddress, true)` with `ENFORCER_ROLE`.
+2. The address is now blocked from sending and receiving tokens.
+3. To recover tokens held by the blacklisted address, call `forcedBurn(blacklistedAddress, amount, data)` with `DEFAULT_ADMIN_ROLE` (the account must be frozen before `forcedBurn` can be called).
+
+If you need to *move* the tokens to another address instead of burning them, Light cannot do this — use the Standard variant, which provides `forcedTransfer`.
+
+### Deactivation
+
+`deactivateContract()` (requires `DEFAULT_ADMIN_ROLE`, contract must be paused first) permanently disables the contract. After deactivation:
+- All state-changing operations revert.
+- Read functions still work.
+- The state is irreversible.
+
+---
+
+## When to Use the Standard Variant Instead
+
+Use **CMTAT Standard** (`CMTATStandardStandalone` / `CMTATStandardUpgradeable`) when any of the following is required:
+
+### Forced Transfer to Another Address
+
+Standard adds `ERC20EnforcementModule`, which provides:
+
+```solidity
+function forcedTransfer(address from, address to, uint256 value) external; // DEFAULT_ADMIN_ROLE
+```
+
+This moves tokens from any address to any other address without the sender's consent. Unlike `forcedBurn`, the source address does not need to be frozen, and the tokens are not destroyed — they are transferred. Frozen tokens are automatically unfrozen as needed to cover the amount.
+
+Use this for regulatory seizure scenarios where tokens must be redirected rather than destroyed.
+
+### Partial Balance Freeze
+
+Standard also adds partial-freeze functions via `ERC20EnforcementModule`:
+
+```solidity
+function freezePartialTokens(address account, uint256 value) external; // ERC20ENFORCER_ROLE
+function unfreezePartialTokens(address account, uint256 value) external; // ERC20ENFORCER_ROLE
+function setFrozenTokens(address account, uint256 value) external; // ERC20ENFORCER_ROLE
+function getFrozenTokens(address account) external view returns (uint256);
+```
+
+These lock a specific token amount on an address while leaving the rest transferable, as opposed to the full freeze in Light that blocks all transfers.
+
+### On-Chain Document Attachment
+
+Standard includes `DocumentERC1643Module` (via `CMTATBaseDocument` → `CMTATBaseAccessControl`), which stores regulatory documents directly in the token contract:
+
+```solidity
+function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external; // DOCUMENT_ROLE
+function removeDocument(bytes32 name) external; // DOCUMENT_ROLE
+function getDocument(bytes32 name) external view returns (Document memory);
+function getAllDocuments() external view returns (bytes32[] memory);
+```
+
+Useful when the regulator requires on-chain reference to a legal document (e.g., prospectus, terms of issuance).
+
+### On-Chain Token Metadata
+
+Standard includes `ExtraInformationModule`, which exposes:
+
+```solidity
+function setTokenId(string calldata tokenId_) external; // EXTRA_INFORMATION_ROLE
+function setTerms(IERC1643CMTAT.DocumentInfo calldata terms_) external; // EXTRA_INFORMATION_ROLE
+function setInformation(string calldata information_) external; // EXTRA_INFORMATION_ROLE
+```
+
+Useful for associating an ISIN or other identifier with the token, or for storing a reference to the tokenization terms.
+
+### Gasless Transactions (ERC-2771)
+
+Standard includes `ERC2771Module`, which allows a trusted forwarder to relay transactions on behalf of users. The forwarder address is set at construction time and is irrevocable.
+
+Use this if you want to sponsor gas fees for your users (e.g., the issuer pays gas for user redemptions).
+
+Note: the forwarder is fixed at deployment. Verify that the chosen forwarder is trustworthy before deploying, as it can submit arbitrary calls on behalf of any user.
+
+### External Transfer Rules (RuleEngine)
+
+Standard includes `ValidationModuleRuleEngine`, which allows plugging in an external `RuleEngine` contract:
+
+```solidity
+function setRuleEngine(IRuleEngine ruleEngine_) external; // DEFAULT_ADMIN_ROLE
+```
+
+Use this when transfer restrictions beyond pause/freeze are needed — for example, jurisdiction-based restrictions, velocity limits, or identity checks — without modifying the token contract.
+
+### Cross-Chain Transfers (ERC-7802 / Chainlink CCIP)
+
+Standard includes `ERC20CrossChainModule`, which provides:
+
+```solidity
+function crosschainMint(address to, uint256 value) external; // CROSS_CHAIN_ROLE
+function crosschainBurn(address from, uint256 value) external; // CROSS_CHAIN_ROLE
+```
+
+These functions implement the [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) interface, making CMTAT compatible with any bridge or messaging layer that expects the standardized `crosschainMint` / `crosschainBurn` entry points (such as Chainlink CCIP's Burn-and-Mint token pool, or Optimism's Superchain token standard). The `CCIPModule` additionally exposes `getCCIPAdmin()` for Chainlink CCIP registry compatibility.
+
+Note: this differs from USDC's approach. USDC cross-chain is handled by CCTP (Circle's own Cross-Chain Transfer Protocol), which reuses the standard `mint` / `burn` functions behind a privileged minter role — there are no dedicated `crosschainMint` / `crosschainBurn` entry points on the USDC contract, and USDC does not implement ERC-7802.
+
+---
+
+## When to Use the Permit Variant Instead
+
+Use **CMTAT Permit** (`CMTATStandalonePermit` / `CMTATUpgradeablePermit`) when ERC-2612 `permit` or ERC-6357 `multicall` are required. Permit shares the same module set as Standard (including ERC-7802 cross-chain) but replaces ERC-2771 with `permit` and `multicall` — see the trade-off note below.
+
+### ERC-2612 Permit — Gasless Approvals
+
+```solidity
+function permit(
+ address owner,
+ address spender,
+ uint256 value,
+ uint256 deadline,
+ uint8 v, bytes32 r, bytes32 s
+) external;
+```
+
+Allows a token owner to set an allowance using an off-chain signature instead of an on-chain `approve` transaction. The spender (or any relayer) can then submit the signature to the chain. This enables:
+
+- Gas-sponsored approval flows (spender pays gas, not the owner).
+- Single-step approve-and-use UX without a separate approve transaction.
+
+The same compliance checks that apply to `approve` also apply to `permit`: the contract must not be paused, and neither `owner` nor `spender` may be frozen.
+
+### ERC-6357 Multicall — Batched Operations
+
+```solidity
+function multicall(bytes[] calldata data) external returns (bytes[] memory results);
+```
+
+Executes multiple function calls on the token contract atomically in a single transaction. Useful for:
+
+- Minting to several addresses in one call when `batchMint` is insufficient.
+- Combining `permit` + `transferFrom` in a single transaction for a DeFi integration.
+- Performing administrative actions (pause + update metadata + batch freeze) atomically.
+
+### Trade-Off: No ERC-2771
+
+The Permit variant does **not** include `ERC2771Module`. The two features are mutually exclusive in the current deployment variants: Permit uses `MulticallUpgradeable` and `ERC20PermitUpgradeable`, which occupy contract size that ERC-2771 support would exceed.
+
+If you need both meta-transactions and permit-style approvals, consider an external gasless relayer architecture that calls `permit` directly.
+
+---
+
+## Variant Comparison
+
+| Feature | Light | Standard | Permit |
+|---|---|---|---|
+| `mint` / `batchMint` | ✓ | ✓ | ✓ |
+| `burn` / `batchBurn` | ✓ | ✓ | ✓ |
+| `batchTransfer` (minter) | ✓ | ✓ | ✓ |
+| `burnAndMint` | ✓ | ✓ | ✓ |
+| `pause` / `unpause` / `deactivateContract` | ✓ | ✓ | ✓ |
+| Address freeze (`setAddressFrozen`) | ✓ | ✓ | ✓ |
+| `canSend` / `canReceive` / `canTransfer` | ✓ | ✓ | ✓ |
+| `forcedBurn` (burn from frozen address) | ✓ | — | — |
+| `forcedTransfer` (move tokens to third party) | — | ✓ | ✓ |
+| Partial balance freeze (`freezePartialTokens`) | — | ✓ | ✓ |
+| `ExtraInformationModule` (tokenId, terms, info) | — | ✓ | ✓ |
+| `DocumentERC1643Module` (ERC-1643 documents) | — | ✓ | ✓ |
+| ERC-2771 meta-transactions (gasless) | — | ✓ | — |
+| ERC-7802 / CCIP cross-chain | — | ✓ | ✓ |
+| External RuleEngine | — | ✓ | ✓ |
+| ERC-1404 (`restrictedTransferOf`) | — | ✓ | ✓ |
+| ERC-2612 `permit` | — | — | ✓ |
+| ERC-6357 `multicall` | — | — | ✓ |
+| Deployed bytecode | 11.298 KiB | 22.243 KiB | 23.268 KiB |
+
+---
+
+## Decision Guide
+
+```
+Do you need on-chain documents, tokenId/terms,
+partial freeze, or forcedTransfer?
+ ├── No → Do you need permit or multicall?
+ │ ├── No → CMTAT Light
+ │ └── Yes → CMTAT Permit (no ERC-2771)
+ └── Yes → Do you need permit or multicall?
+ ├── No → Do you need gasless (ERC-2771)?
+ │ ├── Yes → CMTAT Standard
+ │ └── No → CMTAT Standard or Permit
+ └── Yes → CMTAT Permit (no ERC-2771)
+```
+
+---
+
+## Comparison with USDC and USDT
+
+The table below maps common stablecoin features to the relevant CMTAT variant. Sources: [USDC implementation (Ethereum)](https://etherscan.io/address/0x43506849d7c04f9138d1a2050bbf3a0c054402dd#code), [USDT (Ethereum)](https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7).
+
+### Standards
+
+| Feature | USDC | USDT | CMTAT Light | CMTAT Standard | CMTAT Permit |
+|---|---|---|---|---|---|
+| [ERC-20](https://eips.ethereum.org/EIPS/eip-20) | ✓ | ✓ | ✓ | ✓ | ✓ |
+| [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) | ✓ | — | — | — | ✓ |
+| [ERC-3009](https://eips.ethereum.org/EIPS/eip-3009) (Transfer With Authorization) | ✓ | — | — | — | — |
+| [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) (meta-transactions / gasless) | — | — | — | ✓ | — |
+| [ERC-7802](https://eips.ethereum.org/EIPS/eip-7802) (cross-chain) | — | — | — | ✓ | ✓ |
+
+### ERC-20 Operations
+
+| Feature | USDC | USDT | CMTAT Light | CMTAT Standard | CMTAT Permit |
+|---|---|---|---|---|---|
+| Mint to any address | Partial² | ✓ | ✓ | ✓ | ✓ |
+| Mint with dedicated allowance (`mintFrom`) | ✓ | — | — | — | — |
+| `batchMint` | — | — | ✓ | ✓ | ✓ |
+| `batchTransfer` (minter path) | — | — | ✓ | ✓ | ✓ |
+| Burn / redeem | ✓ | ✓ (`redeem`) | ✓ | ✓ | ✓ |
+| Set `name` after deployment | — | — | ✓ | ✓ | ✓ |
+| Set `symbol` after deployment | — | — | ✓ | ✓ | ✓ |
+
+² USDC minters hold a per-minter allowance (`minterAllowance`) that is decremented on each mint call, rather than minting directly to any address without a cap.
+
+### Compliance and Regulatory
+
+| Feature | USDC | USDT | CMTAT Light | CMTAT Standard | CMTAT Permit |
+|---|---|---|---|---|---|
+| Blacklist inside token contract | ✓ | ✓ | ✓ (`setAddressFrozen`) | ✓ | ✓ |
+| External / shared blacklist | — | — | — | ✓ (via RuleEngine) | ✓ (via RuleEngine) |
+| Forced transfer to a third party | ✓ (`instantTransfer`) | ✓ (`size`) | — | ✓ | ✓ |
+| Forced burn from blacklisted address | — | ✓ (`destroyBlackFunds`) | ✓ (`forcedBurn`) | — | — |
+| Partial balance freeze | — | — | — | ✓ | ✓ |
+| Pause all transfers | ✓ | ✓ | ✓ | ✓ | ✓ |
+| Deactivation (permanent, irreversible) | — | — | ✓ | ✓ | ✓ |
+| Fee on transfer | — | ✓ (set at 0) | — | — | — |
+| Restriction on `transferFrom` spender | ✓³ | — | ✓ (frozen spender) | ✓ (frozen spender; or full ban via RuleEngine) | ✓ (frozen spender; or full ban via RuleEngine) |
+| External rule engine (custom policies) | — | — | — | ✓ | ✓ |
+
+³ USDC allows the contract owner to disable third-party (`transferFrom`) transfers entirely via `disableERC20ThirdPartyTransfer` / `enableERC20ThirdPartyTransfer`. All CMTAT variants block `transferFrom` when the spender is frozen. Standard and Permit can additionally enforce a complete third-party transfer ban by deploying a RuleEngine rule that rejects calls where `spender != from && spender != address(0) && from != address(0) && to != address(0)` (i.e., a genuine delegated transfer, excluding mints and burns).
+
+### Access Control
+
+| Feature | USDC | USDT | CMTAT Light | CMTAT Standard | CMTAT Permit |
+|---|---|---|---|---|---|
+| Single-owner model | ✓ | ✓ | — | — | — |
+| Role-based access control (RBAC) | ✓ (Minter + Blacklister roles) | — | ✓ (5 roles) | ✓ (10+ roles) | ✓ (10+ roles) |
+| Granular per-function roles | Partial | — | ✓ | ✓ | ✓ |
+
+CMTAT replaces the single-owner pattern with `DEFAULT_ADMIN_ROLE`, which holds all roles by default. Each operational permission (mint, burn, pause, freeze, …) can be delegated to a separate address independently.
+
+### Upgradeability
+
+| Feature | USDC | USDT | CMTAT Light | CMTAT Standard | CMTAT Permit |
+|---|---|---|---|---|---|
+| Standalone (immutable) | — | ✓ | ✓ | ✓ | ✓ |
+| Upgradeable — Transparent / Beacon proxy | ✓ | — | ✓ | ✓ | ✓ |
+| Upgradeable — UUPS | — | — | — | ✓ (dedicated variant) | ✓ (dedicated variant) |
+| Migrate function (balance carry-over) | — | ✓⁴ | — | — | — |
+
+⁴ USDT includes a `migrate` function because it predates the proxy upgrade pattern and needed a manual balance migration path. CMTAT upgradeable variants use ERC-7201 namespaced storage, which makes migrations transparent.
+
+### Key Differences Versus USDC
+
+**Features USDC has that CMTAT Light lacks:**
+- **ERC-2612 Permit** — available via CMTAT Permit variant.
+- **ERC-3009 Transfer With Authorization** — not implemented in any CMTAT variant.
+- **Mint allowance per minter** (`minterAllowance`) — CMTAT uses an uncapped `MINTER_ROLE` instead. A per-minter cap could be implemented via a custom RuleEngine or a minter proxy.
+- **Forced transfer** (`instantTransfer`) — available in CMTAT Standard and Permit via `forcedTransfer`.
+
+**Features CMTAT Light has that USDC lacks:**
+- **`forcedBurn`** — burns tokens directly from a frozen (blacklisted) address in a single call. USDC has no equivalent; CMTAT Standard and Permit also lack this function (they provide `forcedTransfer` to move tokens instead).
+- **`batchMint` / `batchTransfer`** — batch operations not available in USDC.
+- **`setName` / `setSymbol`** — USDC name and symbol are fixed at deployment.
+- **Deactivation** — CMTAT provides an irreversible shutdown mechanism; USDC does not.
+- **RBAC granularity** — CMTAT separates minting, burning, pausing, and freezing into independent roles; USDC has Minter and Blacklister but the owner holds broader control.
+
+**Additional CMTAT features (Standard / Permit) that USDC also lacks:**
+- **ERC-7802 cross-chain interface** — USDC does not implement ERC-7802. USDC cross-chain transfers use CCTP (Circle's own Cross-Chain Transfer Protocol), which reuses the existing `mint` / `burn` functions behind a privileged minter role (the `TokenMinter` contract). There are no dedicated `crosschainMint` / `crosschainBurn` entry points on the USDC contract. CMTAT Standard and Permit expose these as proper ERC-7802 functions callable by `CROSS_CHAIN_ROLE`.
+- **ERC-2771 meta-transactions** — available in CMTAT Standard (not in Permit).
+- **External RuleEngine** — available in CMTAT Standard and Permit for custom per-transfer compliance logic.
+
+### Key Differences Versus USDT
+
+**Features USDT has that CMTAT lacks (across all variants):**
+- **Fee on transfer** — USDT has a configurable fee (currently 0). CMTAT has no fee mechanism.
+
+**Features USDT has that CMTAT Light lacks:**
+- **Forced transfer** (`size`) — available in CMTAT Standard and Permit via `forcedTransfer`.
+
+**Functional equivalences:**
+- **`destroyBlackFunds`** — USDT can burn from a blacklisted address without explicit role separation. CMTAT Light provides equivalent functionality via `forcedBurn` (`DEFAULT_ADMIN_ROLE`; the account must be frozen first via `setAddressFrozen`).
+- **Migrate function** — USDT includes a manual balance migration function from a previous contract. CMTAT upgradeable variants use ERC-7201 namespaced storage, making storage layout compatible across upgrades without a manual migration step.
+
+**Features CMTAT Light has that USDT lacks:**
+- **RBAC** — USDT uses a single-owner model; CMTAT provides granular role separation.
+- **Transparent proxy upgradeability** — USDT is immutable; CMTAT upgradeable variants support Transparent, Beacon, and UUPS proxies.
+- **`batchMint` / `batchBurn`** — batch operations not available in USDT.
+- **`setName` / `setSymbol`** — USDT name and symbol are fixed at deployment.
+- **Deactivation** — irreversible shutdown mechanism not present in USDT.
+
+**Additional CMTAT features (Standard / Permit) that USDT also lacks:**
+- **ERC-2612 Permit** — available via CMTAT Permit variant.
+- **ERC-2771 meta-transactions** — available in CMTAT Standard.
+- **External RuleEngine** — available in CMTAT Standard and Permit for configurable transfer policies.
+
+---
+
+## See Also
+
+- [`doc/technical/deployment.md`](./deployment.md) — full deployment model reference
+- [`doc/technical/access-control.md`](./access-control.md) — role list and function-to-role table
+- [`doc/technical/permit-multicall.md`](./permit-multicall.md) — ERC-2612 and ERC-6357 details
+- [`doc/modules/base/0_CMTATBaseCore.md`](../modules/base/0_CMTATBaseCore.md) — CMTATBaseCore module reference
diff --git a/doc/technical/upgradeable.md b/doc/technical/upgradeable.md
new file mode 100644
index 00000000..1d59117b
--- /dev/null
+++ b/doc/technical/upgradeable.md
@@ -0,0 +1,50 @@
+# Upgradeable Proxy
+
+CMTAT supports deployment via proxy contracts, which allows upgrading the contract logic after deployment using the standard proxy upgrade pattern.
+
+## Proxy Variants
+
+| Proxy type | Implementation contract |
+|---|---|
+| Transparent Proxy or Beacon Proxy | `CMTATUpgradeable` |
+| UUPS Proxy | `CMTATUpgradeableUUPS` |
+
+See [OpenZeppelin Upgrades Plugins](https://docs.openzeppelin.com/upgrades-plugins/1.x/) for deployment tooling.
+
+## Storage Layout (ERC-7201)
+
+CMTAT implements [ERC-7201](https://eips.ethereum.org/EIPS/eip-7201) for namespaced storage locations. This ensures storage slots are deterministic and do not collide across upgrades or when modules are composed.
+
+Each module stores its state under a fixed `bytes32` slot derived from a namespace string. See [`deployment.md`](./deployment.md) for the full slot table.
+
+## Initialize Functions
+
+Upgradeable contracts use `initialize` instead of a constructor. Each module exposes two initializer variants:
+
+- `__{ContractName}_init` — calls the module's own initializer **and** all parent initializers (linearized).
+- `__{ContractName}_init_unchained` — calls only the module's own initializer, **without** parent calls.
+
+When building a custom contract, call `_init_unchained` in your initializer to avoid double-initialization. Do not call two `_init` variants from the same inheritance chain.
+
+From the [OpenZeppelin documentation](https://docs.openzeppelin.com/contracts/5.x/upgradeable#multiple-inheritance):
+
+> Initializer functions are not linearized by the compiler like constructors. Each `__{ContractName}_init` function embeds the linearized calls to all parent initializers. Calling two of these `init` functions can potentially initialize the same contract twice.
+
+## UUPS Proxy
+
+The UUPS variant (`CMTATUpgradeableUUPS`) embeds the upgrade logic inside the implementation contract itself. The proxy is simpler and cheaper, but the upgrade authority is tied to the token's `DEFAULT_ADMIN_ROLE`.
+
+**Security note**: There is no segregation between the contract admin role and the proxy upgrade authority. A compromised `DEFAULT_ADMIN_ROLE` could allow an attacker to swap the implementation. Strongly consider using a multisig or a timelock for the admin account.
+
+### UUPS Proxy Key Management
+
+The admin key must be kept secure. An improvement would be to add a dedicated owner role with upgrade-only rights, separate from the token admin.
+
+## Forwarder (ERC-2771)
+
+For upgradeable deployments with `ERC2771Module`, the forwarder address is stored in the implementation contract's bytecode rather than proxy storage. This means it **can** be changed by deploying a new implementation — unlike standalone deployments where the forwarder is immutable.
+
+## Further Reading
+
+- [OpenZeppelin - Writing Upgradeable Contracts](https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable)
+- [RareSkills - ERC-7201 Namespaced Storage](https://www.rareskills.io/post/erc-7201)
diff --git a/doc/test/coverage.json b/doc/test/coverage.json
index dbe462b1..75d57a92 100644
--- a/doc/test/coverage.json
+++ b/doc/test/coverage.json
@@ -1 +1 @@
-{"contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol":{"l":{"29":295},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol","s":{"1":295},"b":{},"f":{"1":295},"fnMap":{"1":{"name":"constructor","line":27,"loc":{"start":{"line":22,"column":4},"end":{"line":34,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":1276}}},"branchMap":{}},"contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol":{"l":{"20":178},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol","s":{"1":178},"b":{},"f":{"1":178},"fnMap":{"1":{"name":"constructor","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":21,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":29}}},"branchMap":{}},"contracts/deployment/CMTATStandalone.sol":{"l":{"31":300},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandalone.sol","s":{"1":300},"b":{},"f":{"1":300},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1278}}},"branchMap":{}},"contracts/deployment/CMTATUpgradeable.sol":{"l":{"22":367},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeable.sol","s":{"1":367},"b":{},"f":{"1":367},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},"contracts/deployment/CMTATUpgradeableUUPS.sol":{"l":{"22":506},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol","s":{"1":506},"b":{"1":[2,1]},"f":{"1":506,"2":2},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}},"2":{"name":"_authorizeUpgrade","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":32,"column":131}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{"1":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":101},"end":{"line":32,"column":101}},{"start":{"line":32,"column":101},"end":{"line":32,"column":101}}]}}},"contracts/deployment/debt/CMTATStandaloneDebt.sol":{"l":{"26":360},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.sol","s":{"1":360},"b":{},"f":{"1":360},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":1027}}},"branchMap":{}},"contracts/deployment/debt/CMTATUpgradeableDebt.sol":{"l":{"16":302},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt.sol","s":{"1":302},"b":{},"f":{"1":302},"fnMap":{"1":{"name":"constructor","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":17,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":29}}},"branchMap":{}},"contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol":{"l":{"26":364},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol","s":{"1":364},"b":{},"f":{"1":364},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":1051}}},"branchMap":{}},"contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol":{"l":{"16":128},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol","s":{"1":128},"b":{},"f":{"1":128},"fnMap":{"1":{"name":"constructor","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":17,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":29}}},"branchMap":{}},"contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol":{"l":{"31":182},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol","s":{"1":182},"b":{},"f":{"1":182},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1300}}},"branchMap":{}},"contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol":{"l":{"22":257},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol","s":{"1":257},"b":{},"f":{"1":257},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},"contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol":{"l":{"30":228},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol","s":{"1":228},"b":{},"f":{"1":228},"fnMap":{"1":{"name":"constructor","line":28,"loc":{"start":{"line":22,"column":4},"end":{"line":36,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":1293}}},"branchMap":{}},"contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol":{"l":{"21":228},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol","s":{"1":228},"b":{},"f":{"1":228},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":17,"column":4},"end":{"line":22,"column":4}}}},"statementMap":{"1":{"start":{"line":21,"column":8},"end":{"line":21,"column":29}}},"branchMap":{}},"contracts/deployment/light/CMTATStandaloneLight.sol":{"l":{"23":103},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight.sol","s":{"1":103},"b":{},"f":{"1":103},"fnMap":{"1":{"name":"constructor","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":27,"column":4}}}},"statementMap":{"1":{"start":{"line":23,"column":8},"end":{"line":23,"column":790}}},"branchMap":{}},"contracts/deployment/light/CMTATUpgradeableLight.sol":{"l":{"18":99},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLight.sol","s":{"1":99},"b":{},"f":{"1":99},"fnMap":{"1":{"name":"constructor","line":16,"loc":{"start":{"line":16,"column":4},"end":{"line":19,"column":4}}}},"statementMap":{"1":{"start":{"line":18,"column":8},"end":{"line":18,"column":29}}},"branchMap":{}},"contracts/interfaces/engine/IDebtEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDebtEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/engine/IDocumentEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDocumentEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/engine/IRuleEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IRuleEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/engine/ISnapshotEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/ISnapshotEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/IAllowlistModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IAllowlistModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/IDebtEngineModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDebtEngineModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/IDebtModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDebtModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/IDocumentEngineModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDocumentEngineModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/ISnapshotEngineModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/ISnapshotEngineModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/ICMTATConstructor.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/ICMTATConstructor.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IERC20Allowance.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC20Allowance.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IERC5679.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC5679.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IERC7802.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC7802.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IGetCCIPAdmin.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IGetCCIPAdmin.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IMintBurnToken.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IMintBurnToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC1404.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1404.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC1643.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1643.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC7551.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC7551.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC7943.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC7943.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/ICMTAT.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/ICMTAT.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/IERC3643Partial.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/IERC3643Partial.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/library/ERC1404ExtendInterfaceId.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/library/ERC1404ExtendInterfaceId.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/library/RuleEngineInterfaceId.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/library/RuleEngineInterfaceId.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/modules/0_CMTATBaseCommon.sol":{"l":{"56":18,"64":56,"71":54,"77":325,"78":325,"79":199,"80":151,"95":178,"96":62,"113":90,"114":54,"121":9056,"134":5270,"136":5270,"137":277,"138":277,"139":277,"142":277,"145":277,"148":4993,"160":4179,"161":4147,"170":687,"171":648,"180":141,"181":118},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol","s":{"1":18,"2":56,"3":54,"4":325,"5":325,"6":199,"7":151,"8":178,"9":62,"10":90,"11":54,"12":9056,"13":5270,"14":5270,"15":277,"16":277,"17":277,"18":277,"19":277,"20":4993,"21":4179,"22":4147,"23":687,"24":648,"25":141,"26":118},"b":{"1":[277,4993]},"f":{"1":18,"2":56,"3":54,"4":325,"5":178,"6":90,"7":9056,"8":5270,"9":4179,"10":687,"11":141},"fnMap":{"1":{"name":"decimals","line":49,"loc":{"start":{"line":49,"column":4},"end":{"line":57,"column":4}}},"2":{"name":"name","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":4}}},"3":{"name":"symbol","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":72,"column":4}}},"4":{"name":"transfer","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":81,"column":4}}},"5":{"name":"transferFrom","line":85,"loc":{"start":{"line":85,"column":4},"end":{"line":97,"column":4}}},"6":{"name":"burnAndMint","line":111,"loc":{"start":{"line":111,"column":4},"end":{"line":115,"column":4}}},"7":{"name":"_checkTransferred","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":122,"column":4}}},"8":{"name":"_update","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":150,"column":4}}},"9":{"name":"_mintOverride","line":159,"loc":{"start":{"line":159,"column":4},"end":{"line":162,"column":4}}},"10":{"name":"_burnOverride","line":169,"loc":{"start":{"line":169,"column":4},"end":{"line":172,"column":4}}},"11":{"name":"_minterTransferOverride","line":179,"loc":{"start":{"line":179,"column":4},"end":{"line":182,"column":4}}}},"statementMap":{"1":{"start":{"line":56,"column":8},"end":{"line":56,"column":41}},"2":{"start":{"line":64,"column":8},"end":{"line":64,"column":37}},"3":{"start":{"line":71,"column":8},"end":{"line":71,"column":39}},"4":{"start":{"line":77,"column":9},"end":{"line":77,"column":36}},"5":{"start":{"line":78,"column":8},"end":{"line":78,"column":53}},"6":{"start":{"line":79,"column":8},"end":{"line":79,"column":50}},"7":{"start":{"line":80,"column":8},"end":{"line":80,"column":19}},"8":{"start":{"line":95,"column":8},"end":{"line":95,"column":55}},"9":{"start":{"line":96,"column":8},"end":{"line":96,"column":60}},"10":{"start":{"line":113,"column":8},"end":{"line":113,"column":53}},"11":{"start":{"line":114,"column":8},"end":{"line":114,"column":51}},"12":{"start":{"line":121,"column":8},"end":{"line":121,"column":79}},"13":{"start":{"line":134,"column":8},"end":{"line":134,"column":62}},"14":{"start":{"line":136,"column":8},"end":{"line":136,"column":4659}},"15":{"start":{"line":137,"column":10},"end":{"line":137,"column":53}},"16":{"start":{"line":138,"column":10},"end":{"line":138,"column":49}},"17":{"start":{"line":139,"column":10},"end":{"line":139,"column":51}},"18":{"start":{"line":142,"column":10},"end":{"line":142,"column":51}},"19":{"start":{"line":145,"column":10},"end":{"line":145,"column":111}},"20":{"start":{"line":148,"column":12},"end":{"line":148,"column":53}},"21":{"start":{"line":160,"column":8},"end":{"line":160,"column":64}},"22":{"start":{"line":161,"column":8},"end":{"line":161,"column":60}},"23":{"start":{"line":170,"column":8},"end":{"line":170,"column":65}},"24":{"start":{"line":171,"column":8},"end":{"line":171,"column":60}},"25":{"start":{"line":180,"column":8},"end":{"line":180,"column":53}},"26":{"start":{"line":181,"column":8},"end":{"line":181,"column":71}}},"branchMap":{"1":{"line":136,"type":"if","locations":[{"start":{"line":136,"column":8},"end":{"line":136,"column":8}},{"start":{"line":136,"column":8},"end":{"line":136,"column":8}}]}}},"contracts/modules/0_CMTATBaseCore.sol":{"l":{"57":4,"58":3,"74":202,"90":202,"93":202,"96":202,"99":202,"107":202,"108":202,"117":202,"118":202,"143":2,"151":6,"158":6,"169":4,"177":22,"178":22,"179":12,"180":8,"195":10,"196":6,"213":10,"214":6,"227":3,"229":2,"230":2,"239":298,"240":290,"245":70,"246":60,"253":18,"254":12},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol","s":{"1":4,"2":202,"3":202,"4":202,"5":202,"6":202,"7":202,"8":202,"9":202,"10":202,"11":2,"12":6,"13":6,"14":4,"15":22,"16":22,"17":12,"18":8,"19":10,"20":6,"21":10,"22":6,"23":3,"24":2,"25":2,"26":298,"27":290,"28":70,"29":60,"30":18,"31":12},"b":{"1":[202,0],"2":[202,0],"3":[202,0],"4":[202,0],"5":[1,1],"6":[3,1],"7":[2,1],"8":[3,1],"9":[240,6],"10":[52,8],"11":[46,4],"12":[16,2],"13":[41,6],"14":[4,4]},"f":{"1":4,"2":202,"3":202,"4":202,"5":202,"6":2,"7":6,"8":6,"9":4,"10":22,"11":10,"12":10,"13":3,"14":298,"15":70,"16":18,"17":3,"18":240,"19":52,"20":46,"21":16,"22":41,"23":4},"fnMap":{"1":{"name":"onlyERC20ForcedBurnManager","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":59,"column":4}}},"2":{"name":"initialize","line":73,"loc":{"start":{"line":70,"column":4},"end":{"line":78,"column":4}}},"3":{"name":"__CMTAT_init","line":87,"loc":{"start":{"line":84,"column":4},"end":{"line":100,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":109,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":115,"loc":{"start":{"line":115,"column":4},"end":{"line":119,"column":4}}},"6":{"name":"decimals","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":144,"column":4}}},"7":{"name":"name","line":150,"loc":{"start":{"line":150,"column":4},"end":{"line":152,"column":4}}},"8":{"name":"symbol","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":159,"column":4}}},"9":{"name":"supportsInterface","line":168,"loc":{"start":{"line":168,"column":4},"end":{"line":170,"column":4}}},"10":{"name":"transfer","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":181,"column":4}}},"11":{"name":"transferFrom","line":185,"loc":{"start":{"line":185,"column":4},"end":{"line":197,"column":4}}},"12":{"name":"burnAndMint","line":212,"loc":{"start":{"line":212,"column":4},"end":{"line":215,"column":4}}},"13":{"name":"forcedBurn","line":226,"loc":{"start":{"line":222,"column":4},"end":{"line":231,"column":4}}},"14":{"name":"_mintOverride","line":238,"loc":{"start":{"line":238,"column":4},"end":{"line":241,"column":4}}},"15":{"name":"_burnOverride","line":244,"loc":{"start":{"line":244,"column":4},"end":{"line":247,"column":4}}},"16":{"name":"_minterTransferOverride","line":252,"loc":{"start":{"line":252,"column":4},"end":{"line":255,"column":4}}},"17":{"name":"_authorizeForcedBurn","line":258,"loc":{"start":{"line":258,"column":4},"end":{"line":258,"column":82}}},"18":{"name":"_authorizeMint","line":260,"loc":{"start":{"line":260,"column":4},"end":{"line":260,"column":95}}},"19":{"name":"_authorizeBurn","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":262,"column":95}}},"20":{"name":"_authorizePause","line":264,"loc":{"start":{"line":264,"column":4},"end":{"line":264,"column":92}}},"21":{"name":"_authorizeDeactivate","line":265,"loc":{"start":{"line":265,"column":4},"end":{"line":265,"column":104}}},"22":{"name":"_authorizeFreeze","line":267,"loc":{"start":{"line":267,"column":4},"end":{"line":267,"column":101}}},"23":{"name":"_authorizeERC20AttributeManagement","line":269,"loc":{"start":{"line":269,"column":4},"end":{"line":269,"column":122}}}},"statementMap":{"1":{"start":{"line":57,"column":8},"end":{"line":57,"column":29}},"2":{"start":{"line":74,"column":8},"end":{"line":74,"column":2897}},"3":{"start":{"line":90,"column":8},"end":{"line":90,"column":33}},"4":{"start":{"line":93,"column":8},"end":{"line":93,"column":32}},"5":{"start":{"line":96,"column":8},"end":{"line":96,"column":44}},"6":{"start":{"line":99,"column":8},"end":{"line":99,"column":62}},"7":{"start":{"line":107,"column":8},"end":{"line":107,"column":39}},"8":{"start":{"line":108,"column":8},"end":{"line":108,"column":34}},"9":{"start":{"line":117,"column":8},"end":{"line":117,"column":50}},"10":{"start":{"line":118,"column":8},"end":{"line":118,"column":125}},"11":{"start":{"line":143,"column":8},"end":{"line":143,"column":41}},"12":{"start":{"line":151,"column":8},"end":{"line":151,"column":37}},"13":{"start":{"line":158,"column":8},"end":{"line":158,"column":39}},"14":{"start":{"line":169,"column":8},"end":{"line":169,"column":99}},"15":{"start":{"line":177,"column":8},"end":{"line":177,"column":35}},"16":{"start":{"line":178,"column":8},"end":{"line":178,"column":82}},"17":{"start":{"line":179,"column":8},"end":{"line":179,"column":50}},"18":{"start":{"line":180,"column":8},"end":{"line":180,"column":19}},"19":{"start":{"line":195,"column":8},"end":{"line":195,"column":84}},"20":{"start":{"line":196,"column":8},"end":{"line":196,"column":60}},"21":{"start":{"line":213,"column":8},"end":{"line":213,"column":53}},"22":{"start":{"line":214,"column":8},"end":{"line":214,"column":51}},"23":{"start":{"line":227,"column":8},"end":{"line":227,"column":95}},"24":{"start":{"line":229,"column":8},"end":{"line":229,"column":45}},"25":{"start":{"line":230,"column":8},"end":{"line":230,"column":60}},"26":{"start":{"line":239,"column":8},"end":{"line":239,"column":62}},"27":{"start":{"line":240,"column":8},"end":{"line":240,"column":60}},"28":{"start":{"line":245,"column":8},"end":{"line":245,"column":62}},"29":{"start":{"line":246,"column":8},"end":{"line":246,"column":60}},"30":{"start":{"line":253,"column":8},"end":{"line":253,"column":82}},"31":{"start":{"line":254,"column":8},"end":{"line":254,"column":71}}},"branchMap":{"1":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":21},"end":{"line":73,"column":21}},{"start":{"line":73,"column":21},"end":{"line":73,"column":21}}]},"2":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":23},"end":{"line":87,"column":23}},{"start":{"line":87,"column":23},"end":{"line":87,"column":23}}]},"3":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":68},"end":{"line":105,"column":68}},{"start":{"line":105,"column":68},"end":{"line":105,"column":68}}]},"4":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":136},"end":{"line":115,"column":136}},{"start":{"line":115,"column":136},"end":{"line":115,"column":136}}]},"5":{"line":169,"type":"cond-expr","locations":[{"start":{"line":169,"column":15},"end":{"line":169,"column":39}},{"start":{"line":169,"column":44},"end":{"line":169,"column":98}}]},"6":{"line":226,"type":"if","locations":[{"start":{"line":226,"column":48},"end":{"line":226,"column":48}},{"start":{"line":226,"column":48},"end":{"line":226,"column":48}}]},"7":{"line":227,"type":"if","locations":[{"start":{"line":227,"column":8},"end":{"line":227,"column":8}},{"start":{"line":227,"column":8},"end":{"line":227,"column":8}}]},"8":{"line":258,"type":"if","locations":[{"start":{"line":258,"column":53},"end":{"line":258,"column":53}},{"start":{"line":258,"column":53},"end":{"line":258,"column":53}}]},"9":{"line":260,"type":"if","locations":[{"start":{"line":260,"column":73},"end":{"line":260,"column":73}},{"start":{"line":260,"column":73},"end":{"line":260,"column":73}}]},"10":{"line":262,"type":"if","locations":[{"start":{"line":262,"column":73},"end":{"line":262,"column":73}},{"start":{"line":262,"column":73},"end":{"line":262,"column":73}}]},"11":{"line":264,"type":"if","locations":[{"start":{"line":264,"column":70},"end":{"line":264,"column":70}},{"start":{"line":264,"column":70},"end":{"line":264,"column":70}}]},"12":{"line":265,"type":"if","locations":[{"start":{"line":265,"column":75},"end":{"line":265,"column":75}},{"start":{"line":265,"column":75},"end":{"line":265,"column":75}}]},"13":{"line":267,"type":"if","locations":[{"start":{"line":267,"column":77},"end":{"line":267,"column":77}},{"start":{"line":267,"column":77},"end":{"line":267,"column":77}}]},"14":{"line":269,"type":"if","locations":[{"start":{"line":269,"column":93},"end":{"line":269,"column":93}},{"start":{"line":269,"column":93},"end":{"line":269,"column":93}}]}}},"contracts/modules/0_CMTATBaseGeneric.sol":{"l":{"50":51,"53":51,"56":51,"59":51,"67":51,"68":51,"76":51,"78":51},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseGeneric.sol","s":{"1":51,"2":51,"3":51,"4":51,"5":51,"6":51,"7":51,"8":51},"b":{"1":[51,0],"2":[51,0],"3":[51,0],"4":[6,0],"5":[3,3]},"f":{"1":51,"2":51,"3":51,"4":6,"5":3},"fnMap":{"1":{"name":"__CMTAT_init","line":47,"loc":{"start":{"line":44,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"__CMTAT_openzeppelin_init_unchained","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":69,"column":4}}},"3":{"name":"__CMTAT_modules_init_unchained","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":79,"column":4}}},"4":{"name":"_authorizeDocumentManagement","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":86,"column":117}}},"5":{"name":"_authorizeExtraInfoManagement","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":87,"column":129}}}},"statementMap":{"1":{"start":{"line":50,"column":8},"end":{"line":50,"column":33}},"2":{"start":{"line":53,"column":8},"end":{"line":53,"column":32}},"3":{"start":{"line":56,"column":8},"end":{"line":56,"column":44}},"4":{"start":{"line":59,"column":8},"end":{"line":59,"column":74}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":39}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":34}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":50}},"8":{"start":{"line":78,"column":8},"end":{"line":78,"column":159}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":23},"end":{"line":47,"column":23}},{"start":{"line":47,"column":23},"end":{"line":47,"column":23}}]},"2":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":68},"end":{"line":65,"column":68}},{"start":{"line":65,"column":68},"end":{"line":65,"column":68}}]},"3":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":157},"end":{"line":74,"column":157}},{"start":{"line":74,"column":157},"end":{"line":74,"column":157}}]},"4":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":93},"end":{"line":86,"column":93}},{"start":{"line":86,"column":93},"end":{"line":86,"column":93}}]},"5":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":96},"end":{"line":87,"column":96}},{"start":{"line":87,"column":96},"end":{"line":87,"column":96}}]}}},"contracts/modules/1_CMTATBaseAccessControl.sol":{"l":{"32":3692,"34":3690,"36":3690,"50":34},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/1_CMTATBaseAccessControl.sol","s":{"1":3692,"2":3690,"3":3690,"4":34},"b":{"1":[3692,0],"2":[14,2],"3":[2,4],"4":[38,36],"5":[3648,54],"6":[486,72],"7":[112,2],"8":[67,67],"9":[618,42],"10":[128,28],"11":[501,2]},"f":{"1":3692,"2":34,"3":38,"4":3648,"5":486,"6":112,"7":67,"8":618,"9":128,"10":501},"fnMap":{"1":{"name":"__CMTAT_commonModules_init_unchained","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":37,"column":4}}},"2":{"name":"supportsInterface","line":49,"loc":{"start":{"line":49,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"_authorizeERC20AttributeManagement","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":63,"column":122}}},"4":{"name":"_authorizeMint","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":69,"column":95}}},"5":{"name":"_authorizeBurn","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":75,"column":95}}},"6":{"name":"_authorizeDocumentManagement","line":81,"loc":{"start":{"line":81,"column":4},"end":{"line":81,"column":117}}},"7":{"name":"_authorizeExtraInfoManagement","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":87,"column":129}}},"8":{"name":"_authorizeERC20Enforcer","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":93,"column":118}}},"9":{"name":"_authorizeForcedTransfer","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":99,"column":119}}},"10":{"name":"_authorizeSnapshots","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":105,"column":110}}}},"statementMap":{"1":{"start":{"line":32,"column":8},"end":{"line":32,"column":50}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":125}},"3":{"start":{"line":36,"column":8},"end":{"line":36,"column":177}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":128}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":228},"end":{"line":30,"column":228}},{"start":{"line":30,"column":228},"end":{"line":30,"column":228}}]},"2":{"line":50,"type":"cond-expr","locations":[{"start":{"line":50,"column":15},"end":{"line":50,"column":39}},{"start":{"line":50,"column":44},"end":{"line":50,"column":68}}]},"3":{"line":50,"type":"cond-expr","locations":[{"start":{"line":50,"column":15},"end":{"line":50,"column":68}},{"start":{"line":50,"column":73},"end":{"line":50,"column":127}}]},"4":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":93},"end":{"line":63,"column":93}},{"start":{"line":63,"column":93},"end":{"line":63,"column":93}}]},"5":{"line":69,"type":"if","locations":[{"start":{"line":69,"column":73},"end":{"line":69,"column":73}},{"start":{"line":69,"column":73},"end":{"line":69,"column":73}}]},"6":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":73},"end":{"line":75,"column":73}},{"start":{"line":75,"column":73},"end":{"line":75,"column":73}}]},"7":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":93},"end":{"line":81,"column":93}},{"start":{"line":81,"column":93},"end":{"line":81,"column":93}}]},"8":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":96},"end":{"line":87,"column":96}},{"start":{"line":87,"column":96},"end":{"line":87,"column":96}}]},"9":{"line":93,"type":"if","locations":[{"start":{"line":93,"column":89},"end":{"line":93,"column":89}},{"start":{"line":93,"column":89},"end":{"line":93,"column":89}}]},"10":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":90},"end":{"line":99,"column":90}},{"start":{"line":99,"column":90},"end":{"line":99,"column":90}}]},"11":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":83},"end":{"line":105,"column":83}},{"start":{"line":105,"column":83},"end":{"line":105,"column":83}}]}}},"contracts/modules/2_CMTATBaseAllowlist.sol":{"l":{"54":473,"72":473,"75":473,"78":473,"81":473,"89":473,"90":473,"92":473,"99":473,"101":473,"115":52,"126":220,"127":220,"128":58,"130":162,"144":31,"145":31,"146":8,"148":23,"171":12,"177":721,"181":68,"189":173,"197":93,"201":826,"202":814,"218":5159,"227":5161,"239":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAllowlist.sol","s":{"1":473,"2":473,"3":473,"4":473,"5":473,"6":473,"7":473,"8":473,"9":473,"10":473,"11":52,"12":220,"13":220,"14":58,"15":162,"16":31,"17":31,"18":8,"19":23,"20":12,"21":721,"22":68,"23":173,"24":93,"25":826,"26":814,"27":5159,"28":5161,"29":2},"b":{"1":[473,0],"2":[473,0],"3":[473,0],"4":[473,0],"5":[52,3],"6":[58,162],"7":[8,23],"8":[72,6],"9":[24,3],"10":[60,9],"11":[761,8]},"f":{"1":473,"2":473,"3":473,"4":473,"5":52,"6":220,"7":31,"8":72,"9":24,"10":60,"11":761,"12":12,"13":721,"14":68,"15":173,"16":93,"17":826,"18":5159,"19":5161,"20":2},"fnMap":{"1":{"name":"initialize","line":53,"loc":{"start":{"line":49,"column":4},"end":{"line":59,"column":4}}},"2":{"name":"__CMTAT_init","line":69,"loc":{"start":{"line":65,"column":4},"end":{"line":82,"column":4}}},"3":{"name":"__CMTAT_openzeppelin_init_unchained","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":93,"column":4}}},"4":{"name":"__CMTAT_modules_init_unchained","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":102,"column":4}}},"5":{"name":"approve","line":114,"loc":{"start":{"line":114,"column":4},"end":{"line":116,"column":4}}},"6":{"name":"canTransfer","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":133,"column":4}}},"7":{"name":"canTransferFrom","line":138,"loc":{"start":{"line":138,"column":3},"end":{"line":150,"column":4}}},"8":{"name":"_authorizePause","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":157,"column":92}}},"9":{"name":"_authorizeDeactivate","line":158,"loc":{"start":{"line":158,"column":4},"end":{"line":158,"column":104}}},"10":{"name":"_authorizeFreeze","line":160,"loc":{"start":{"line":160,"column":4},"end":{"line":160,"column":101}}},"11":{"name":"_authorizeAllowlistManagement","line":162,"loc":{"start":{"line":162,"column":4},"end":{"line":162,"column":114}}},"12":{"name":"_canMintBurnByModule","line":168,"loc":{"start":{"line":168,"column":4},"end":{"line":172,"column":4}}},"13":{"name":"_canMintBurnByModuleAndRevert","line":174,"loc":{"start":{"line":174,"column":4},"end":{"line":178,"column":4}}},"14":{"name":"_canTransact","line":180,"loc":{"start":{"line":180,"column":2},"end":{"line":182,"column":2}}},"15":{"name":"_canTransferStandardByModule","line":184,"loc":{"start":{"line":184,"column":4},"end":{"line":190,"column":4}}},"16":{"name":"_canTransferStandardByModuleAndRevert","line":192,"loc":{"start":{"line":192,"column":4},"end":{"line":198,"column":4}}},"17":{"name":"_checkTransferred","line":200,"loc":{"start":{"line":200,"column":4},"end":{"line":203,"column":4}}},"18":{"name":"_msgSender","line":212,"loc":{"start":{"line":212,"column":4},"end":{"line":219,"column":4}}},"19":{"name":"_contextSuffixLength","line":224,"loc":{"start":{"line":224,"column":4},"end":{"line":228,"column":4}}},"20":{"name":"_msgData","line":233,"loc":{"start":{"line":233,"column":4},"end":{"line":240,"column":4}}}},"statementMap":{"1":{"start":{"line":54,"column":8},"end":{"line":54,"column":2472}},"2":{"start":{"line":72,"column":8},"end":{"line":72,"column":33}},"3":{"start":{"line":75,"column":8},"end":{"line":75,"column":32}},"4":{"start":{"line":78,"column":8},"end":{"line":78,"column":60}},"5":{"start":{"line":81,"column":8},"end":{"line":81,"column":91}},"6":{"start":{"line":89,"column":8},"end":{"line":89,"column":39}},"7":{"start":{"line":90,"column":8},"end":{"line":90,"column":34}},"8":{"start":{"line":92,"column":8},"end":{"line":92,"column":77}},"9":{"start":{"line":99,"column":9},"end":{"line":99,"column":97}},"10":{"start":{"line":101,"column":8},"end":{"line":101,"column":35}},"11":{"start":{"line":115,"column":8},"end":{"line":115,"column":55}},"12":{"start":{"line":126,"column":8},"end":{"line":126,"column":89}},"13":{"start":{"line":127,"column":8},"end":{"line":127,"column":5337}},"14":{"start":{"line":128,"column":12},"end":{"line":128,"column":24}},"15":{"start":{"line":130,"column":12},"end":{"line":130,"column":68}},"16":{"start":{"line":144,"column":8},"end":{"line":144,"column":89}},"17":{"start":{"line":145,"column":8},"end":{"line":145,"column":5836}},"18":{"start":{"line":146,"column":12},"end":{"line":146,"column":24}},"19":{"start":{"line":148,"column":12},"end":{"line":148,"column":81}},"20":{"start":{"line":171,"column":8},"end":{"line":171,"column":70}},"21":{"start":{"line":177,"column":8},"end":{"line":177,"column":71}},"22":{"start":{"line":181,"column":4},"end":{"line":181,"column":58}},"23":{"start":{"line":189,"column":8},"end":{"line":189,"column":88}},"24":{"start":{"line":197,"column":8},"end":{"line":197,"column":89}},"25":{"start":{"line":201,"column":8},"end":{"line":201,"column":66}},"26":{"start":{"line":202,"column":8},"end":{"line":202,"column":79}},"27":{"start":{"line":218,"column":8},"end":{"line":218,"column":53}},"28":{"start":{"line":227,"column":9},"end":{"line":227,"column":64}},"29":{"start":{"line":239,"column":8},"end":{"line":239,"column":51}}},"branchMap":{"1":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":21},"end":{"line":53,"column":21}},{"start":{"line":53,"column":21},"end":{"line":53,"column":21}}]},"2":{"line":69,"type":"if","locations":[{"start":{"line":69,"column":23},"end":{"line":69,"column":23}},{"start":{"line":69,"column":23},"end":{"line":69,"column":23}}]},"3":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":125},"end":{"line":87,"column":125}},{"start":{"line":87,"column":125},"end":{"line":87,"column":125}}]},"4":{"line":98,"type":"if","locations":[{"start":{"line":98,"column":217},"end":{"line":98,"column":217}},{"start":{"line":98,"column":217},"end":{"line":98,"column":217}}]},"5":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":95},"end":{"line":114,"column":95}},{"start":{"line":114,"column":95},"end":{"line":114,"column":95}}]},"6":{"line":127,"type":"if","locations":[{"start":{"line":127,"column":8},"end":{"line":127,"column":8}},{"start":{"line":127,"column":8},"end":{"line":127,"column":8}}]},"7":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":8},"end":{"line":145,"column":8}},{"start":{"line":145,"column":8},"end":{"line":145,"column":8}}]},"8":{"line":157,"type":"if","locations":[{"start":{"line":157,"column":70},"end":{"line":157,"column":70}},{"start":{"line":157,"column":70},"end":{"line":157,"column":70}}]},"9":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":75},"end":{"line":158,"column":75}},{"start":{"line":158,"column":75},"end":{"line":158,"column":75}}]},"10":{"line":160,"type":"if","locations":[{"start":{"line":160,"column":77},"end":{"line":160,"column":77}},{"start":{"line":160,"column":77},"end":{"line":160,"column":77}}]},"11":{"line":162,"type":"if","locations":[{"start":{"line":162,"column":88},"end":{"line":162,"column":88}},{"start":{"line":162,"column":88},"end":{"line":162,"column":88}}]}}},"contracts/modules/2_CMTATBaseRuleEngine.sol":{"l":{"47":3219,"64":3219,"83":3219,"86":3219,"89":3219,"91":3219,"94":3219,"102":3219,"103":3219,"105":3219,"112":3219,"119":3219,"129":462,"139":1040,"140":1040,"141":348,"143":692,"156":189,"157":189,"158":48,"160":141,"177":8230,"178":8158},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseRuleEngine.sol","s":{"1":3219,"2":3219,"3":3219,"4":3219,"5":3219,"6":3219,"7":3219,"8":3219,"9":3219,"10":3219,"11":3219,"12":3219,"13":462,"14":1040,"15":1040,"16":348,"17":692,"18":189,"19":189,"20":48,"21":141,"22":8230,"23":8158},"b":{"1":[3219,1],"2":[3219,0],"3":[3219,0],"4":[3219,0],"5":[3219,0],"6":[3219,0],"7":[462,15],"8":[348,692],"9":[48,141],"10":[440,31],"11":[160,15],"12":[352,45],"13":[87,3]},"f":{"1":3219,"2":3219,"3":3219,"4":3219,"5":3219,"6":3219,"7":462,"8":1040,"9":189,"10":440,"11":160,"12":352,"13":87,"14":8230},"fnMap":{"1":{"name":"initialize","line":46,"loc":{"start":{"line":41,"column":4},"end":{"line":53,"column":4}}},"2":{"name":"_initialize","line":63,"loc":{"start":{"line":58,"column":4},"end":{"line":70,"column":4}}},"3":{"name":"__CMTAT_init","line":80,"loc":{"start":{"line":75,"column":4},"end":{"line":95,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":106,"column":4}}},"5":{"name":"__CMTAT_internal_init_unchained","line":111,"loc":{"start":{"line":111,"column":4},"end":{"line":113,"column":4}}},"6":{"name":"__CMTAT_modules_init_unchained","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":120,"column":4}}},"7":{"name":"approve","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":130,"column":4}}},"8":{"name":"canTransfer","line":134,"loc":{"start":{"line":134,"column":4},"end":{"line":145,"column":4}}},"9":{"name":"canTransferFrom","line":150,"loc":{"start":{"line":150,"column":3},"end":{"line":162,"column":4}}},"10":{"name":"_authorizePause","line":168,"loc":{"start":{"line":168,"column":4},"end":{"line":168,"column":92}}},"11":{"name":"_authorizeDeactivate","line":169,"loc":{"start":{"line":169,"column":4},"end":{"line":169,"column":104}}},"12":{"name":"_authorizeFreeze","line":171,"loc":{"start":{"line":171,"column":4},"end":{"line":171,"column":101}}},"13":{"name":"_authorizeRuleEngineManagement","line":173,"loc":{"start":{"line":173,"column":4},"end":{"line":173,"column":129}}},"14":{"name":"_checkTransferred","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":179,"column":4}}}},"statementMap":{"1":{"start":{"line":47,"column":8},"end":{"line":47,"column":2182}},"2":{"start":{"line":64,"column":8},"end":{"line":64,"column":2689}},"3":{"start":{"line":83,"column":8},"end":{"line":83,"column":33}},"4":{"start":{"line":86,"column":8},"end":{"line":86,"column":32}},"5":{"start":{"line":89,"column":8},"end":{"line":89,"column":60}},"6":{"start":{"line":91,"column":7},"end":{"line":91,"column":47}},"7":{"start":{"line":94,"column":8},"end":{"line":94,"column":91}},"8":{"start":{"line":102,"column":8},"end":{"line":102,"column":39}},"9":{"start":{"line":103,"column":8},"end":{"line":103,"column":34}},"10":{"start":{"line":105,"column":8},"end":{"line":105,"column":77}},"11":{"start":{"line":112,"column":8},"end":{"line":112,"column":65}},"12":{"start":{"line":119,"column":8},"end":{"line":119,"column":96}},"13":{"start":{"line":129,"column":8},"end":{"line":129,"column":55}},"14":{"start":{"line":139,"column":8},"end":{"line":139,"column":90}},"15":{"start":{"line":140,"column":8},"end":{"line":140,"column":5713}},"16":{"start":{"line":141,"column":12},"end":{"line":141,"column":24}},"17":{"start":{"line":143,"column":12},"end":{"line":143,"column":74}},"18":{"start":{"line":156,"column":8},"end":{"line":156,"column":89}},"19":{"start":{"line":157,"column":8},"end":{"line":157,"column":6221}},"20":{"start":{"line":158,"column":12},"end":{"line":158,"column":24}},"21":{"start":{"line":160,"column":12},"end":{"line":160,"column":87}},"22":{"start":{"line":177,"column":8},"end":{"line":177,"column":66}},"23":{"start":{"line":178,"column":8},"end":{"line":178,"column":72}}},"branchMap":{"1":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":21},"end":{"line":46,"column":21}},{"start":{"line":46,"column":21},"end":{"line":46,"column":21}}]},"2":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":23},"end":{"line":63,"column":23}},{"start":{"line":63,"column":23},"end":{"line":63,"column":23}}]},"3":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":23},"end":{"line":80,"column":23}},{"start":{"line":80,"column":23},"end":{"line":80,"column":23}}]},"4":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":125},"end":{"line":100,"column":125}},{"start":{"line":100,"column":125},"end":{"line":100,"column":125}}]},"5":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":104},"end":{"line":111,"column":104}},{"start":{"line":111,"column":104},"end":{"line":111,"column":104}}]},"6":{"line":118,"type":"if","locations":[{"start":{"line":118,"column":216},"end":{"line":118,"column":216}},{"start":{"line":118,"column":216},"end":{"line":118,"column":216}}]},"7":{"line":128,"type":"if","locations":[{"start":{"line":128,"column":95},"end":{"line":128,"column":95}},{"start":{"line":128,"column":95},"end":{"line":128,"column":95}}]},"8":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":8},"end":{"line":140,"column":8}},{"start":{"line":140,"column":8},"end":{"line":140,"column":8}}]},"9":{"line":157,"type":"if","locations":[{"start":{"line":157,"column":8},"end":{"line":157,"column":8}},{"start":{"line":157,"column":8},"end":{"line":157,"column":8}}]},"10":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":70},"end":{"line":168,"column":70}},{"start":{"line":168,"column":70},"end":{"line":168,"column":70}}]},"11":{"line":169,"type":"if","locations":[{"start":{"line":169,"column":75},"end":{"line":169,"column":75}},{"start":{"line":169,"column":75},"end":{"line":169,"column":75}}]},"12":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":77},"end":{"line":171,"column":77}},{"start":{"line":171,"column":77},"end":{"line":171,"column":77}}]},"13":{"line":173,"type":"if","locations":[{"start":{"line":173,"column":100},"end":{"line":173,"column":100}},{"start":{"line":173,"column":100},"end":{"line":173,"column":100}}]}}},"contracts/modules/3_CMTATBaseDebt.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseDebt.sol","s":{},"b":{"1":[12,12]},"f":{"1":12},"fnMap":{"1":{"name":"_authorizeDebtManagement","line":11,"loc":{"start":{"line":11,"column":3},"end":{"line":11,"column":97}}}},"statementMap":{},"branchMap":{"1":{"line":11,"type":"if","locations":[{"start":{"line":11,"column":77},"end":{"line":11,"column":77}},{"start":{"line":11,"column":77},"end":{"line":11,"column":77}}]}}},"contracts/modules/3_CMTATBaseERC1404.sol":{"l":{"34":111,"35":42,"37":69,"50":846,"62":157,"73":251,"74":251,"75":112,"76":112,"77":84,"80":167},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseERC1404.sol","s":{"1":111,"2":42,"3":69,"4":846,"5":157,"6":251,"7":251,"8":112,"9":112,"10":84,"11":167},"b":{"1":[42,69],"2":[112,139],"3":[84,28]},"f":{"1":111,"2":846,"3":157,"4":251},"fnMap":{"1":{"name":"messageForTransferRestriction","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"canTransfer","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"canTransferFrom","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"_detectTransferRestriction","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":81,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1392}},"2":{"start":{"line":35,"column":12},"end":{"line":35,"column":74}},"3":{"start":{"line":37,"column":12},"end":{"line":37,"column":89}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":63}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":76}},"6":{"start":{"line":73,"column":8},"end":{"line":73,"column":80}},"7":{"start":{"line":74,"column":8},"end":{"line":74,"column":2875}},"8":{"start":{"line":75,"column":12},"end":{"line":75,"column":88}},"9":{"start":{"line":76,"column":12},"end":{"line":76,"column":3009}},"10":{"start":{"line":77,"column":16},"end":{"line":77,"column":114}},"11":{"start":{"line":80,"column":8},"end":{"line":80,"column":82}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":34,"column":8}},{"start":{"line":34,"column":8},"end":{"line":34,"column":8}}]},"2":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":8},"end":{"line":74,"column":8}},{"start":{"line":74,"column":8},"end":{"line":74,"column":8}}]},"3":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":12},"end":{"line":76,"column":12}},{"start":{"line":76,"column":12},"end":{"line":76,"column":12}}]}}},"contracts/modules/4_CMTATBaseERC20CrossChain.sol":{"l":{"24":417,"27":217,"42":121,"57":11,"65":35,"72":33,"76":54,"87":2921,"88":2854,"95":514,"96":429,"103":111,"104":72,"125":132,"148":3599},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC20CrossChain.sol","s":{"1":417,"2":217,"3":121,"4":11,"5":35,"6":33,"7":54,"8":2921,"9":2854,"10":514,"11":429,"12":111,"13":72,"14":132,"15":3599},"b":{"1":[20,20],"2":[24,8],"3":[132,40],"4":[50,10],"5":[30,20],"6":[60,20],"7":[40,20]},"f":{"1":417,"2":217,"3":121,"4":11,"5":35,"6":33,"7":54,"8":2921,"9":514,"10":111,"11":24,"12":132,"13":30,"14":40,"15":3599},"fnMap":{"1":{"name":"approve","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":25,"column":4}}},"2":{"name":"transfer","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":28,"column":4}}},"3":{"name":"transferFrom","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":43,"column":4}}},"4":{"name":"decimals","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":58,"column":4}}},"5":{"name":"name","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":66,"column":4}}},"6":{"name":"symbol","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":73,"column":4}}},"7":{"name":"supportsInterface","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":77,"column":4}}},"8":{"name":"_mintOverride","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":89,"column":4}}},"9":{"name":"_burnOverride","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":97,"column":4}}},"10":{"name":"_minterTransferOverride","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":105,"column":4}}},"11":{"name":"_authorizeCCIPSetAdmin","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":113,"column":106}}},"12":{"name":"_checkTokenBridge","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":126,"column":4}}},"13":{"name":"_authorizeBurnFrom","line":133,"loc":{"start":{"line":133,"column":4},"end":{"line":133,"column":124}}},"14":{"name":"_authorizeSelfBurn","line":140,"loc":{"start":{"line":140,"column":4},"end":{"line":140,"column":124}}},"15":{"name":"_update","line":143,"loc":{"start":{"line":143,"column":4},"end":{"line":149,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":58}},"2":{"start":{"line":27,"column":9},"end":{"line":27,"column":51}},"3":{"start":{"line":42,"column":8},"end":{"line":42,"column":60}},"4":{"start":{"line":57,"column":8},"end":{"line":57,"column":41}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":37}},"6":{"start":{"line":72,"column":8},"end":{"line":72,"column":39}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":127}},"8":{"start":{"line":87,"column":8},"end":{"line":87,"column":84}},"9":{"start":{"line":88,"column":8},"end":{"line":88,"column":52}},"10":{"start":{"line":95,"column":8},"end":{"line":95,"column":85}},"11":{"start":{"line":96,"column":8},"end":{"line":96,"column":52}},"12":{"start":{"line":103,"column":8},"end":{"line":103,"column":73}},"13":{"start":{"line":104,"column":8},"end":{"line":104,"column":63}},"14":{"start":{"line":125,"column":8},"end":{"line":125,"column":68}},"15":{"start":{"line":148,"column":7},"end":{"line":148,"column":55}}},"branchMap":{"1":{"line":76,"type":"cond-expr","locations":[{"start":{"line":76,"column":16},"end":{"line":76,"column":68}},{"start":{"line":76,"column":72},"end":{"line":76,"column":126}}]},"2":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":76},"end":{"line":113,"column":76}},{"start":{"line":113,"column":76},"end":{"line":113,"column":76}}]},"3":{"line":124,"type":"if","locations":[{"start":{"line":124,"column":96},"end":{"line":124,"column":96}},{"start":{"line":124,"column":96},"end":{"line":124,"column":96}}]},"4":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":83},"end":{"line":133,"column":83}},{"start":{"line":133,"column":83},"end":{"line":133,"column":83}}]},"5":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":110},"end":{"line":133,"column":110}},{"start":{"line":133,"column":110},"end":{"line":133,"column":110}}]},"6":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":83},"end":{"line":140,"column":83}},{"start":{"line":140,"column":83},"end":{"line":140,"column":83}}]},"7":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":110},"end":{"line":140,"column":110}},{"start":{"line":140,"column":110},"end":{"line":140,"column":110}}]}}},"contracts/modules/5_CMTATBaseDebtEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseDebtEngine.sol","s":{},"b":{"1":[15,3]},"f":{"1":15},"fnMap":{"1":{"name":"_authorizeDebtEngineManagement","line":11,"loc":{"start":{"line":11,"column":3},"end":{"line":11,"column":116}}}},"statementMap":{},"branchMap":{"1":{"line":11,"type":"if","locations":[{"start":{"line":11,"column":89},"end":{"line":11,"column":89}},{"start":{"line":11,"column":89},"end":{"line":11,"column":89}}]}}},"contracts/modules/5_CMTATBaseERC2771.sol":{"l":{"26":10379,"35":10383,"47":4},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC2771.sol","s":{"1":10379,"2":10383,"3":4},"b":{},"f":{"1":10379,"2":10383,"3":4},"fnMap":{"1":{"name":"_msgSender","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"_contextSuffixLength","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":36,"column":4}}},"3":{"name":"_msgData","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":48,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":53}},"2":{"start":{"line":35,"column":9},"end":{"line":35,"column":64}},"3":{"start":{"line":47,"column":8},"end":{"line":47,"column":51}}},"branchMap":{}},"contracts/modules/6_CMTATBaseERC1363.sol":{"l":{"25":439,"26":439,"38":81,"45":37,"61":24,"69":18,"83":2,"91":6,"98":6,"114":633,"129":2253,"138":2255,"150":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC1363.sol","s":{"1":439,"2":439,"3":81,"4":37,"5":24,"6":18,"7":2,"8":6,"9":6,"10":633,"11":2253,"12":2255,"13":2},"b":{"1":[439,0],"2":[6,8]},"f":{"1":439,"2":81,"3":37,"4":24,"5":18,"6":2,"7":6,"8":6,"9":633,"10":2253,"11":2255,"12":2},"fnMap":{"1":{"name":"__CMTAT_openzeppelin_init_unchained","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"approve","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":39,"column":4}}},"3":{"name":"transfer","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":4}}},"4":{"name":"transferFrom","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":62,"column":4}}},"5":{"name":"supportsInterface","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":70,"column":4}}},"6":{"name":"decimals","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":84,"column":4}}},"7":{"name":"name","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":92,"column":4}}},"8":{"name":"symbol","line":97,"loc":{"start":{"line":97,"column":4},"end":{"line":99,"column":4}}},"9":{"name":"_update","line":109,"loc":{"start":{"line":109,"column":4},"end":{"line":115,"column":4}}},"10":{"name":"_msgSender","line":123,"loc":{"start":{"line":123,"column":4},"end":{"line":130,"column":4}}},"11":{"name":"_contextSuffixLength","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":139,"column":4}}},"12":{"name":"_msgData","line":144,"loc":{"start":{"line":144,"column":4},"end":{"line":151,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":80}},"2":{"start":{"line":26,"column":8},"end":{"line":26,"column":33}},"3":{"start":{"line":38,"column":8},"end":{"line":38,"column":63}},"4":{"start":{"line":45,"column":8},"end":{"line":45,"column":59}},"5":{"start":{"line":61,"column":8},"end":{"line":61,"column":79}},"6":{"start":{"line":69,"column":8},"end":{"line":69,"column":123}},"7":{"start":{"line":83,"column":8},"end":{"line":83,"column":50}},"8":{"start":{"line":91,"column":8},"end":{"line":91,"column":46}},"9":{"start":{"line":98,"column":8},"end":{"line":98,"column":48}},"10":{"start":{"line":114,"column":8},"end":{"line":114,"column":57}},"11":{"start":{"line":129,"column":8},"end":{"line":129,"column":44}},"12":{"start":{"line":138,"column":9},"end":{"line":138,"column":55}},"13":{"start":{"line":150,"column":8},"end":{"line":150,"column":42}}},"branchMap":{"1":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":134},"end":{"line":24,"column":134}},{"start":{"line":24,"column":134},"end":{"line":24,"column":134}}]},"2":{"line":69,"type":"cond-expr","locations":[{"start":{"line":69,"column":15},"end":{"line":69,"column":63}},{"start":{"line":69,"column":68},"end":{"line":69,"column":122}}]}}},"contracts/modules/6_CMTATBaseERC7551.sol":{"l":{"19":20},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC7551.sol","s":{"1":20},"b":{},"f":{"1":20},"fnMap":{"1":{"name":"_authorizeExtraInfoManagement","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":20,"column":4}}}},"statementMap":{"1":{"start":{"line":19,"column":8},"end":{"line":19,"column":61}}},"branchMap":{}},"contracts/modules/internal/AllowlistModuleInternal.sol":{"l":{"30":473,"31":473,"40":222,"41":222,"45":1882,"49":422,"50":418,"51":418,"52":1660,"60":117,"61":117,"69":1092,"70":1092,"77":1071,"78":1071,"85":3393},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol","s":{"1":473,"2":222,"3":222,"4":422,"5":418,"6":418,"7":1660,"8":117,"9":1092,"10":1092,"11":1071,"12":1071},"b":{"1":[473,0]},"f":{"1":473,"2":222,"3":1882,"4":422,"5":117,"6":1092,"7":1071,"8":3393},"fnMap":{"1":{"name":"__Allowlist_init_unchained","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":33,"column":4}}},"2":{"name":"_addToAllowlist","line":39,"loc":{"start":{"line":39,"column":4},"end":{"line":42,"column":4}}},"3":{"name":"_addToAllowlist","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":4}}},"4":{"name":"_addToAllowlist","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":54,"column":4}}},"5":{"name":"_enableAllowlist","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":62,"column":4}}},"6":{"name":"_isAllowlisted","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":71,"column":4}}},"7":{"name":"_isAllowlistEnabled","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"8":{"name":"_getAllowlistModuleInternalStorage","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":88,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":9},"end":{"line":30,"column":88}},"2":{"start":{"line":40,"column":8},"end":{"line":40,"column":87}},"3":{"start":{"line":41,"column":8},"end":{"line":41,"column":48}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":61}},"5":{"start":{"line":50,"column":8},"end":{"line":50,"column":87}},"6":{"start":{"line":51,"column":8},"end":{"line":51,"column":2408}},"7":{"start":{"line":52,"column":12},"end":{"line":52,"column":59}},"8":{"start":{"line":60,"column":8},"end":{"line":60,"column":87}},"9":{"start":{"line":69,"column":8},"end":{"line":69,"column":87}},"10":{"start":{"line":70,"column":8},"end":{"line":70,"column":36}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":87}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":33}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":51},"end":{"line":29,"column":51}},{"start":{"line":29,"column":51},"end":{"line":29,"column":51}}]}}},"contracts/modules/internal/common/EnforcementModuleLibrary.sol":{"l":{"16":506,"19":483},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/common/EnforcementModuleLibrary.sol","s":{"1":506,"2":483},"b":{"1":[483,23],"2":[460,23]},"f":{"1":506},"fnMap":{"1":{"name":"_checkInput","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":20,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":70}},"2":{"start":{"line":19,"column":8},"end":{"line":19,"column":98}}},"branchMap":{"1":{"line":16,"type":"if","locations":[{"start":{"line":16,"column":8},"end":{"line":16,"column":8}},{"start":{"line":16,"column":8},"end":{"line":16,"column":8}}]},"2":{"line":19,"type":"if","locations":[{"start":{"line":19,"column":8},"end":{"line":19,"column":8}},{"start":{"line":19,"column":8},"end":{"line":19,"column":8}}]}}},"contracts/modules/internal/EnforcementModuleInternal.sol":{"l":{"33":385,"34":385,"38":490,"42":84,"43":42,"44":42,"45":105,"54":14098,"55":14098,"60":14525},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInternal.sol","s":{"1":385,"2":385,"3":84,"4":42,"5":42,"6":105,"7":14098,"8":14098},"b":{},"f":{"1":385,"2":490,"3":84,"4":14098,"5":14525},"fnMap":{"1":{"name":"_addAddressToTheList","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":35,"column":4}}},"2":{"name":"_addAddressToTheList","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":39,"column":4}}},"3":{"name":"_addAddressesToTheList","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":47,"column":4}}},"4":{"name":"_addressIsListed","line":53,"loc":{"start":{"line":53,"column":4},"end":{"line":56,"column":4}}},"5":{"name":"_getEnforcementModuleInternalStorage","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":63,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":91}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":53}},"3":{"start":{"line":42,"column":8},"end":{"line":42,"column":61}},"4":{"start":{"line":43,"column":8},"end":{"line":43,"column":91}},"5":{"start":{"line":44,"column":8},"end":{"line":44,"column":2008}},"6":{"start":{"line":45,"column":12},"end":{"line":45,"column":64}},"7":{"start":{"line":54,"column":8},"end":{"line":54,"column":91}},"8":{"start":{"line":55,"column":8},"end":{"line":55,"column":31}}},"branchMap":{}},"contracts/modules/internal/ERC20BurnModuleInternal.sol":{"l":{"30":223,"33":203,"34":163,"35":407,"47":708},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol","s":{"1":223,"2":203,"3":163,"4":407,"5":708},"b":{"1":[203,20],"2":[163,40]},"f":{"1":223,"2":708},"fnMap":{"1":{"name":"_batchBurn","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":37,"column":4}}},"2":{"name":"_burnOverride","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":48,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":70}},"2":{"start":{"line":33,"column":8},"end":{"line":33,"column":97}},"3":{"start":{"line":34,"column":8},"end":{"line":34,"column":1431}},"4":{"start":{"line":35,"column":13},"end":{"line":35,"column":49}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":45}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":8},"end":{"line":30,"column":8}},{"start":{"line":30,"column":8},"end":{"line":30,"column":8}}]},"2":{"line":33,"type":"if","locations":[{"start":{"line":33,"column":8},"end":{"line":33,"column":8}},{"start":{"line":33,"column":8},"end":{"line":33,"column":8}}]}}},"contracts/modules/internal/ERC20EnforcementModuleInternal.sol":{"l":{"34":154,"35":154,"37":154,"38":42,"39":42,"40":42,"43":98,"44":98,"45":98,"47":14,"49":140,"53":352,"55":352,"56":352,"58":352,"60":352,"61":352,"65":112,"66":112,"68":112,"69":112,"70":112,"77":128,"78":128,"79":14,"81":114,"83":114,"84":114,"85":28,"86":28,"87":28,"88":28,"93":128,"94":114,"95":28,"99":86,"100":86,"101":28,"102":14,"103":14,"106":14,"107":14,"112":86,"114":114,"115":114,"119":450,"120":450,"124":182,"125":182,"130":9056,"131":9056,"132":9056,"133":9056,"140":10536,"141":10536,"143":938,"144":938,"145":546,"150":9990,"154":11519,"155":11519,"159":686,"160":686,"165":12937},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol","s":{"1":154,"2":154,"3":154,"4":42,"5":42,"6":112,"7":98,"8":98,"9":140,"10":352,"11":352,"12":352,"13":352,"14":352,"15":112,"16":112,"17":112,"18":112,"19":128,"20":128,"21":114,"22":114,"23":114,"24":28,"25":28,"26":28,"27":128,"28":114,"29":28,"30":86,"31":86,"32":28,"33":14,"34":14,"35":86,"36":114,"37":114,"38":450,"39":450,"40":182,"41":182,"42":9056,"43":9056,"44":9056,"45":10536,"46":10536,"47":938,"48":546,"49":9990,"50":11519,"51":11519,"52":686,"53":686},"b":{"1":[42,112],"2":[98,14],"3":[352,0],"4":[112,0],"5":[14,114],"6":[28,86],"7":[28,86],"8":[28,58],"9":[14,14],"10":[8972,84],"11":[938,9598],"12":[546,392]},"f":{"1":154,"2":352,"3":112,"4":128,"5":128,"6":450,"7":182,"8":9056,"9":10536,"10":11519,"11":686,"12":12937},"fnMap":{"1":{"name":"_setFrozenTokens","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":50,"column":4}}},"2":{"name":"_freezePartialTokens","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":62,"column":4}}},"3":{"name":"_unfreezePartialTokens","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":71,"column":4}}},"4":{"name":"_unfreezeTokens","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":90,"column":4}}},"5":{"name":"_forcedTransfer","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":116,"column":4}}},"6":{"name":"_freezeTokensEmitEvents","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":121,"column":4}}},"7":{"name":"_unfreezeTokensEmitEvents","line":123,"loc":{"start":{"line":123,"column":4},"end":{"line":126,"column":4}}},"8":{"name":"_checkActiveBalanceAndRevert","line":129,"loc":{"start":{"line":129,"column":4},"end":{"line":134,"column":4}}},"9":{"name":"_checkActiveBalance","line":139,"loc":{"start":{"line":139,"column":4},"end":{"line":151,"column":4}}},"10":{"name":"_getFrozenTokens","line":153,"loc":{"start":{"line":153,"column":4},"end":{"line":156,"column":5}}},"11":{"name":"_getActiveBalanceOf","line":158,"loc":{"start":{"line":158,"column":4},"end":{"line":161,"column":5}}},"12":{"name":"_getEnforcementModuleStorage","line":164,"loc":{"start":{"line":164,"column":4},"end":{"line":168,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":80}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":60}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":1969}},"4":{"start":{"line":38,"column":13},"end":{"line":38,"column":59}},"5":{"start":{"line":40,"column":13},"end":{"line":40,"column":68}},"6":{"start":{"line":41,"column":15},"end":{"line":41,"column":2198}},"7":{"start":{"line":43,"column":12},"end":{"line":43,"column":58}},"8":{"start":{"line":45,"column":12},"end":{"line":45,"column":66}},"9":{"start":{"line":49,"column":8},"end":{"line":49,"column":19}},"10":{"start":{"line":53,"column":7},"end":{"line":53,"column":79}},"11":{"start":{"line":55,"column":8},"end":{"line":55,"column":61}},"12":{"start":{"line":56,"column":8},"end":{"line":56,"column":68}},"13":{"start":{"line":58,"column":8},"end":{"line":58,"column":105}},"14":{"start":{"line":61,"column":8},"end":{"line":61,"column":71}},"15":{"start":{"line":65,"column":8},"end":{"line":65,"column":80}},"16":{"start":{"line":66,"column":8},"end":{"line":66,"column":107}},"17":{"start":{"line":68,"column":8},"end":{"line":68,"column":69}},"18":{"start":{"line":70,"column":8},"end":{"line":70,"column":73}},"19":{"start":{"line":77,"column":8},"end":{"line":77,"column":61}},"20":{"start":{"line":78,"column":8},"end":{"line":78,"column":4054}},"21":{"start":{"line":81,"column":8},"end":{"line":81,"column":80}},"22":{"start":{"line":83,"column":8},"end":{"line":83,"column":66}},"23":{"start":{"line":84,"column":8},"end":{"line":84,"column":4369}},"24":{"start":{"line":85,"column":12},"end":{"line":85,"column":60}},"25":{"start":{"line":86,"column":12},"end":{"line":86,"column":84}},"26":{"start":{"line":88,"column":12},"end":{"line":88,"column":88}},"27":{"start":{"line":93,"column":8},"end":{"line":93,"column":41}},"28":{"start":{"line":94,"column":8},"end":{"line":94,"column":4872}},"29":{"start":{"line":95,"column":12},"end":{"line":95,"column":46}},"30":{"start":{"line":99,"column":12},"end":{"line":99,"column":58}},"31":{"start":{"line":100,"column":12},"end":{"line":100,"column":5160}},"32":{"start":{"line":101,"column":16},"end":{"line":101,"column":5248}},"33":{"start":{"line":103,"column":24},"end":{"line":103,"column":68}},"34":{"start":{"line":107,"column":25},"end":{"line":107,"column":92}},"35":{"start":{"line":112,"column":12},"end":{"line":112,"column":54}},"36":{"start":{"line":114,"column":8},"end":{"line":114,"column":57}},"37":{"start":{"line":115,"column":8},"end":{"line":115,"column":44}},"38":{"start":{"line":119,"column":8},"end":{"line":119,"column":52}},"39":{"start":{"line":120,"column":8},"end":{"line":120,"column":83}},"40":{"start":{"line":124,"column":8},"end":{"line":124,"column":54}},"41":{"start":{"line":125,"column":8},"end":{"line":125,"column":84}},"42":{"start":{"line":130,"column":8},"end":{"line":130,"column":20}},"43":{"start":{"line":131,"column":8},"end":{"line":131,"column":29}},"44":{"start":{"line":133,"column":8},"end":{"line":133,"column":89}},"45":{"start":{"line":140,"column":8},"end":{"line":140,"column":58}},"46":{"start":{"line":141,"column":8},"end":{"line":141,"column":7001}},"47":{"start":{"line":144,"column":12},"end":{"line":144,"column":7178}},"48":{"start":{"line":145,"column":19},"end":{"line":145,"column":48}},"49":{"start":{"line":150,"column":8},"end":{"line":150,"column":36}},"50":{"start":{"line":154,"column":8},"end":{"line":154,"column":80}},"51":{"start":{"line":155,"column":8},"end":{"line":155,"column":39}},"52":{"start":{"line":159,"column":8},"end":{"line":159,"column":80}},"53":{"start":{"line":160,"column":8},"end":{"line":160,"column":77}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":8}},{"start":{"line":37,"column":8},"end":{"line":37,"column":8}}]},"2":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":15},"end":{"line":41,"column":15}},{"start":{"line":41,"column":15},"end":{"line":41,"column":15}}]},"3":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":8},"end":{"line":58,"column":8}},{"start":{"line":58,"column":8},"end":{"line":58,"column":8}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]},"5":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":8},"end":{"line":78,"column":8}},{"start":{"line":78,"column":8},"end":{"line":78,"column":8}}]},"6":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":8},"end":{"line":84,"column":8}},{"start":{"line":84,"column":8},"end":{"line":84,"column":8}}]},"7":{"line":94,"type":"if","locations":[{"start":{"line":94,"column":8},"end":{"line":94,"column":8}},{"start":{"line":94,"column":8},"end":{"line":94,"column":8}}]},"8":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":12},"end":{"line":100,"column":12}},{"start":{"line":100,"column":12},"end":{"line":100,"column":12}}]},"9":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":16},"end":{"line":101,"column":16}},{"start":{"line":101,"column":16},"end":{"line":101,"column":16}}]},"10":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":8},"end":{"line":133,"column":8}},{"start":{"line":133,"column":8},"end":{"line":133,"column":8}}]},"11":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":8}},{"start":{"line":141,"column":8},"end":{"line":141,"column":8}}]},"12":{"line":144,"type":"if","locations":[{"start":{"line":144,"column":12},"end":{"line":144,"column":12}},{"start":{"line":144,"column":12},"end":{"line":144,"column":12}}]}}},"contracts/modules/internal/ERC20MintModuleInternal.sol":{"l":{"34":519,"37":499,"38":459,"39":1291,"47":168,"48":148,"51":148,"52":108,"53":198,"57":20,"64":4437,"70":130},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol","s":{"1":519,"2":499,"3":459,"4":1291,"5":168,"6":148,"7":148,"8":108,"9":198,"10":20,"11":4437,"12":130},"b":{"1":[499,20],"2":[459,40],"3":[148,20],"4":[108,40]},"f":{"1":519,"2":168,"3":4437,"4":130},"fnMap":{"1":{"name":"_batchMint","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"_batchTransfer","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":58,"column":4}}},"3":{"name":"_mintOverride","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"_minterTransferOverride","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":71,"column":5}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":69}},"2":{"start":{"line":37,"column":8},"end":{"line":37,"column":97}},"3":{"start":{"line":38,"column":8},"end":{"line":38,"column":1716}},"4":{"start":{"line":39,"column":12},"end":{"line":39,"column":48}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":59}},"6":{"start":{"line":48,"column":8},"end":{"line":48,"column":37}},"7":{"start":{"line":51,"column":8},"end":{"line":51,"column":87}},"8":{"start":{"line":52,"column":8},"end":{"line":52,"column":2292}},"9":{"start":{"line":53,"column":12},"end":{"line":53,"column":61}},"10":{"start":{"line":57,"column":8},"end":{"line":57,"column":19}},"11":{"start":{"line":64,"column":8},"end":{"line":64,"column":45}},"12":{"start":{"line":70,"column":12},"end":{"line":70,"column":54}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":34,"column":8}},{"start":{"line":34,"column":8},"end":{"line":34,"column":8}}]},"2":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":8}},{"start":{"line":37,"column":8},"end":{"line":37,"column":8}}]},"3":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":8},"end":{"line":47,"column":8}},{"start":{"line":47,"column":8},"end":{"line":47,"column":8}}]},"4":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":8},"end":{"line":51,"column":8}},{"start":{"line":51,"column":8},"end":{"line":51,"column":8}}]}}},"contracts/modules/internal/ValidationModuleRuleEngineInternal.sol":{"l":{"38":3219,"39":69,"53":8951,"54":8951,"68":153,"69":153,"70":153,"75":9104},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol","s":{"1":3219,"2":69,"3":8951,"4":8951,"5":153,"6":153},"b":{"1":[3219,0],"2":[69,3150]},"f":{"1":3219,"2":8951,"3":153,"4":9104},"fnMap":{"1":{"name":"__ValidationRuleEngine_init_unchained","line":37,"loc":{"start":{"line":35,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"ruleEngine","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":55,"column":4}}},"3":{"name":"_setRuleEngine","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":71,"column":4}}},"4":{"name":"_getValidationModuleRuleEngineStorage","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":78,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":1469}},"2":{"start":{"line":39,"column":12},"end":{"line":39,"column":38}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":93}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":28}},"5":{"start":{"line":68,"column":8},"end":{"line":68,"column":93}},"6":{"start":{"line":70,"column":8},"end":{"line":70,"column":36}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":15},"end":{"line":37,"column":15}},{"start":{"line":37,"column":15},"end":{"line":37,"column":15}}]},"2":{"line":38,"type":"if","locations":[{"start":{"line":38,"column":8},"end":{"line":38,"column":8}},{"start":{"line":38,"column":8},"end":{"line":38,"column":8}}]}}},"contracts/modules/wrapper/controllers/ValidationModule.sol":{"l":{"27":284,"43":1068,"44":34,"47":14,"50":1020,"60":9028,"61":7100,"64":1201,"67":727,"79":42,"83":12,"85":30,"97":8685,"100":8584,"101":121,"115":992,"118":200,"120":792,"129":584,"130":584,"131":20,"133":20,"135":42,"137":502,"139":82,"147":992,"149":320,"151":672,"165":719,"166":584,"177":266,"178":84,"180":182},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol","s":{"1":284,"2":1068,"3":34,"4":1034,"5":14,"6":1020,"7":9028,"8":7100,"9":1928,"10":1201,"11":727,"12":42,"13":12,"14":30,"15":8685,"16":8584,"17":992,"18":200,"19":792,"20":584,"21":584,"22":564,"23":544,"24":502,"25":992,"26":320,"27":672,"28":719,"29":584,"30":266,"31":84,"32":182},"b":{"1":[34,1034],"2":[14,1020],"3":[7100,1928],"4":[1201,727],"5":[12,30],"6":[0,12],"7":[121,8463],"8":[200,792],"9":[20,140],"10":[140,40],"11":[20,564],"12":[20,544],"13":[42,502],"14":[320,672],"15":[200,120],"16":[84,182]},"f":{"1":284,"2":1068,"3":9028,"4":42,"5":8685,"6":992,"7":584,"8":992,"9":719,"10":266},"fnMap":{"1":{"name":"canTransact","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"_canTransferGenericByModule","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":52,"column":4}}},"3":{"name":"_canTransferGenericByModuleAndRevert","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":69,"column":4}}},"4":{"name":"_canMintBurnByModule","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":86,"column":4}}},"5":{"name":"_canMintBurnByModuleAndRevert","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":103,"column":4}}},"6":{"name":"_canTransferisFrozen","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":122,"column":4}}},"7":{"name":"_canTransferisFrozenAndRevert","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":140,"column":4}}},"8":{"name":"_canTransferStandardByModule","line":142,"loc":{"start":{"line":142,"column":2},"end":{"line":153,"column":4}}},"9":{"name":"_canTransferStandardByModuleAndRevert","line":155,"loc":{"start":{"line":155,"column":4},"end":{"line":167,"column":4}}},"10":{"name":"_canTransact","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":182,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":36}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":1474}},"3":{"start":{"line":44,"column":12},"end":{"line":44,"column":43}},"4":{"start":{"line":46,"column":13},"end":{"line":46,"column":1574}},"5":{"start":{"line":47,"column":12},"end":{"line":47,"column":45}},"6":{"start":{"line":50,"column":12},"end":{"line":50,"column":66}},"7":{"start":{"line":60,"column":8},"end":{"line":60,"column":1945}},"8":{"start":{"line":61,"column":13},"end":{"line":61,"column":45}},"9":{"start":{"line":63,"column":13},"end":{"line":63,"column":2048}},"10":{"start":{"line":64,"column":12},"end":{"line":64,"column":46}},"11":{"start":{"line":67,"column":13},"end":{"line":67,"column":68}},"12":{"start":{"line":79,"column":8},"end":{"line":79,"column":2581}},"13":{"start":{"line":83,"column":12},"end":{"line":83,"column":24}},"14":{"start":{"line":85,"column":8},"end":{"line":85,"column":19}},"15":{"start":{"line":97,"column":8},"end":{"line":97,"column":31}},"16":{"start":{"line":100,"column":8},"end":{"line":100,"column":3466}},"17":{"start":{"line":115,"column":8},"end":{"line":115,"column":3932}},"18":{"start":{"line":118,"column":12},"end":{"line":118,"column":23}},"19":{"start":{"line":120,"column":13},"end":{"line":120,"column":25}},"20":{"start":{"line":129,"column":8},"end":{"line":129,"column":22}},"21":{"start":{"line":130,"column":8},"end":{"line":130,"column":4321}},"22":{"start":{"line":132,"column":15},"end":{"line":132,"column":4408}},"23":{"start":{"line":134,"column":15},"end":{"line":134,"column":4490}},"24":{"start":{"line":137,"column":12},"end":{"line":137,"column":18}},"25":{"start":{"line":147,"column":8},"end":{"line":147,"column":4812}},"26":{"start":{"line":149,"column":12},"end":{"line":149,"column":24}},"27":{"start":{"line":151,"column":13},"end":{"line":151,"column":24}},"28":{"start":{"line":165,"column":8},"end":{"line":165,"column":26}},"29":{"start":{"line":166,"column":8},"end":{"line":166,"column":55}},"30":{"start":{"line":177,"column":8},"end":{"line":177,"column":5822}},"31":{"start":{"line":178,"column":12},"end":{"line":178,"column":24}},"32":{"start":{"line":180,"column":12},"end":{"line":180,"column":23}}},"branchMap":{"1":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":8}},{"start":{"line":43,"column":8},"end":{"line":43,"column":8}}]},"2":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":13},"end":{"line":46,"column":13}},{"start":{"line":46,"column":13},"end":{"line":46,"column":13}}]},"3":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":8},"end":{"line":60,"column":8}},{"start":{"line":60,"column":8},"end":{"line":60,"column":8}}]},"4":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":13},"end":{"line":63,"column":13}},{"start":{"line":63,"column":13},"end":{"line":63,"column":13}}]},"5":{"line":79,"type":"if","locations":[{"start":{"line":79,"column":8},"end":{"line":79,"column":8}},{"start":{"line":79,"column":8},"end":{"line":79,"column":8}}]},"6":{"line":79,"type":"cond-expr","locations":[{"start":{"line":79,"column":11},"end":{"line":79,"column":35}},{"start":{"line":79,"column":40},"end":{"line":79,"column":73}}]},"7":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":8},"end":{"line":100,"column":8}},{"start":{"line":100,"column":8},"end":{"line":100,"column":8}}]},"8":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":8},"end":{"line":115,"column":8}},{"start":{"line":115,"column":8},"end":{"line":115,"column":8}}]},"9":{"line":115,"type":"cond-expr","locations":[{"start":{"line":115,"column":12},"end":{"line":115,"column":46}},{"start":{"line":116,"column":11},"end":{"line":116,"column":42}}]},"10":{"line":115,"type":"cond-expr","locations":[{"start":{"line":115,"column":12},"end":{"line":116,"column":42}},{"start":{"line":117,"column":11},"end":{"line":117,"column":40}}]},"11":{"line":130,"type":"if","locations":[{"start":{"line":130,"column":8},"end":{"line":130,"column":8}},{"start":{"line":130,"column":8},"end":{"line":130,"column":8}}]},"12":{"line":132,"type":"if","locations":[{"start":{"line":132,"column":15},"end":{"line":132,"column":15}},{"start":{"line":132,"column":15},"end":{"line":132,"column":15}}]},"13":{"line":134,"type":"if","locations":[{"start":{"line":134,"column":15},"end":{"line":134,"column":15}},{"start":{"line":134,"column":15},"end":{"line":134,"column":15}}]},"14":{"line":147,"type":"if","locations":[{"start":{"line":147,"column":8},"end":{"line":147,"column":8}},{"start":{"line":147,"column":8},"end":{"line":147,"column":8}}]},"15":{"line":147,"type":"cond-expr","locations":[{"start":{"line":147,"column":12},"end":{"line":147,"column":50}},{"start":{"line":148,"column":11},"end":{"line":148,"column":30}}]},"16":{"line":177,"type":"if","locations":[{"start":{"line":177,"column":8},"end":{"line":177,"column":8}},{"start":{"line":177,"column":8},"end":{"line":177,"column":8}}]}}},"contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol":{"l":{"27":12,"28":6,"30":6,"42":173,"43":148,"44":148,"45":28,"48":145,"59":173,"60":28,"62":145,"66":68,"67":18,"69":50,"77":721,"78":8,"80":713,"89":93,"90":85,"98":93,"99":93,"100":67,"101":2,"103":2,"105":4,"107":59,"110":8},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol","s":{"1":12,"2":6,"3":6,"4":173,"5":148,"6":148,"7":28,"8":145,"9":173,"10":28,"11":145,"12":68,"13":18,"14":50,"15":721,"16":713,"17":93,"18":85,"19":93,"20":93,"21":67,"22":65,"23":63,"24":59},"b":{"1":[6,6],"2":[148,25],"3":[28,120],"4":[2,14],"5":[14,12],"6":[28,145],"7":[18,50],"8":[8,713],"9":[67,26],"10":[2,65],"11":[2,63],"12":[4,59]},"f":{"1":12,"2":173,"3":173,"4":68,"5":721,"6":93,"7":93},"fnMap":{"1":{"name":"_canMintBurnByModule","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"_canTransferStandardByModuleAllowlist","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"_canTransferStandardByModule","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"_canTransact","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":71,"column":4}}},"5":{"name":"_canMintBurnByModuleAndRevert","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":82,"column":4}}},"6":{"name":"_canTransferStandardByModuleAndRevert","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":91,"column":4}}},"7":{"name":"_canTransferStandardByModuleAllowlistAndRevert","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":112,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":932}},"2":{"start":{"line":28,"column":12},"end":{"line":28,"column":24}},"3":{"start":{"line":30,"column":12},"end":{"line":30,"column":65}},"4":{"start":{"line":42,"column":8},"end":{"line":42,"column":1352}},"5":{"start":{"line":43,"column":12},"end":{"line":43,"column":80}},"6":{"start":{"line":44,"column":12},"end":{"line":44,"column":1477}},"7":{"start":{"line":45,"column":16},"end":{"line":45,"column":27}},"8":{"start":{"line":48,"column":7},"end":{"line":48,"column":19}},"9":{"start":{"line":59,"column":8},"end":{"line":59,"column":1876}},"10":{"start":{"line":60,"column":11},"end":{"line":60,"column":23}},"11":{"start":{"line":62,"column":8},"end":{"line":62,"column":79}},"12":{"start":{"line":66,"column":8},"end":{"line":66,"column":2186}},"13":{"start":{"line":67,"column":12},"end":{"line":67,"column":24}},"14":{"start":{"line":69,"column":12},"end":{"line":69,"column":57}},"15":{"start":{"line":77,"column":8},"end":{"line":77,"column":2556}},"16":{"start":{"line":80,"column":12},"end":{"line":80,"column":66}},"17":{"start":{"line":89,"column":8},"end":{"line":89,"column":72}},"18":{"start":{"line":90,"column":7},"end":{"line":90,"column":79}},"19":{"start":{"line":98,"column":8},"end":{"line":98,"column":23}},"20":{"start":{"line":99,"column":8},"end":{"line":99,"column":3293}},"21":{"start":{"line":100,"column":12},"end":{"line":100,"column":3336}},"22":{"start":{"line":102,"column":19},"end":{"line":102,"column":3445}},"23":{"start":{"line":104,"column":19},"end":{"line":104,"column":3524}},"24":{"start":{"line":107,"column":15},"end":{"line":107,"column":21}}},"branchMap":{"1":{"line":27,"type":"if","locations":[{"start":{"line":27,"column":8},"end":{"line":27,"column":8}},{"start":{"line":27,"column":8},"end":{"line":27,"column":8}}]},"2":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":8},"end":{"line":42,"column":8}},{"start":{"line":42,"column":8},"end":{"line":42,"column":8}}]},"3":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":12},"end":{"line":44,"column":12}},{"start":{"line":44,"column":12},"end":{"line":44,"column":12}}]},"4":{"line":44,"type":"cond-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":27}},{"start":{"line":44,"column":32},"end":{"line":44,"column":51}}]},"5":{"line":44,"type":"cond-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":51}},{"start":{"line":44,"column":56},"end":{"line":44,"column":73}}]},"6":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":59,"column":8}},{"start":{"line":59,"column":8},"end":{"line":59,"column":8}}]},"7":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]},"8":{"line":77,"type":"if","locations":[{"start":{"line":77,"column":8},"end":{"line":77,"column":8}},{"start":{"line":77,"column":8},"end":{"line":77,"column":8}}]},"9":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":8}},{"start":{"line":99,"column":8},"end":{"line":99,"column":8}}]},"10":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":12},"end":{"line":100,"column":12}},{"start":{"line":100,"column":12},"end":{"line":100,"column":12}}]},"11":{"line":102,"type":"if","locations":[{"start":{"line":102,"column":19},"end":{"line":102,"column":19}},{"start":{"line":102,"column":19},"end":{"line":102,"column":19}}]},"12":{"line":104,"type":"if","locations":[{"start":{"line":104,"column":19},"end":{"line":104,"column":19}},{"start":{"line":104,"column":19},"end":{"line":104,"column":19}}]}}},"contracts/modules/wrapper/core/EnforcementModule.sol":{"l":{"27":532,"28":469,"42":154,"60":231,"71":84,"79":14098,"87":490,"88":490},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol","s":{"1":532,"2":154,"3":231,"4":84,"5":14098,"6":490,"7":490},"b":{"1":[154,0],"2":[231,42],"3":[84,21]},"f":{"1":532,"2":154,"3":231,"4":84,"5":14098,"6":490},"fnMap":{"1":{"name":"onlyEnforcer","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":29,"column":4}}},"2":{"name":"setAddressFrozen","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":4}}},"3":{"name":"setAddressFrozen","line":59,"loc":{"start":{"line":57,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"batchSetAddressFrozen","line":70,"loc":{"start":{"line":68,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"isFrozen","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"_addAddressToTheList","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":89,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":25}},"2":{"start":{"line":42,"column":9},"end":{"line":42,"column":49}},"3":{"start":{"line":60,"column":9},"end":{"line":60,"column":51}},"4":{"start":{"line":71,"column":9},"end":{"line":71,"column":53}},"5":{"start":{"line":79,"column":7},"end":{"line":79,"column":39}},"6":{"start":{"line":87,"column":8},"end":{"line":87,"column":79}},"7":{"start":{"line":88,"column":8},"end":{"line":88,"column":63}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":105},"end":{"line":41,"column":105}},{"start":{"line":41,"column":105},"end":{"line":41,"column":105}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":21},"end":{"line":59,"column":21}},{"start":{"line":59,"column":21},"end":{"line":59,"column":21}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":51},"end":{"line":70,"column":51}},{"start":{"line":70,"column":51},"end":{"line":70,"column":51}}]}}},"contracts/modules/wrapper/core/ERC20BaseModule.sol":{"l":{"39":82,"40":42,"55":3892,"56":3892,"57":3892,"58":3892,"78":68,"80":28,"81":28,"84":28,"94":20,"95":20,"102":62,"103":62,"111":60,"112":60,"123":22,"124":22,"125":22,"132":20,"133":20,"134":20,"141":40,"142":40,"143":20,"145":40,"156":4076},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol","s":{"1":82,"2":3892,"3":68,"4":28,"5":28,"6":28,"7":20,"8":20,"9":62,"10":62,"11":60,"12":60,"13":22,"14":22,"15":20,"16":20,"17":40},"b":{"1":[3892,0],"2":[28,0],"3":[22,20],"4":[20,20]},"f":{"1":82,"2":3892,"3":68,"4":20,"5":62,"6":60,"7":22,"8":20,"9":40,"10":4076},"fnMap":{"1":{"name":"onlyERC20AttributeManager","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"__ERC20BaseModule_init_unchained","line":54,"loc":{"start":{"line":50,"column":4},"end":{"line":59,"column":4}}},"3":{"name":"transferFrom","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":85,"column":4}}},"4":{"name":"decimals","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":96,"column":4}}},"5":{"name":"name","line":101,"loc":{"start":{"line":101,"column":4},"end":{"line":104,"column":4}}},"6":{"name":"symbol","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":113,"column":4}}},"7":{"name":"setName","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":126,"column":4}}},"8":{"name":"setSymbol","line":131,"loc":{"start":{"line":131,"column":4},"end":{"line":135,"column":4}}},"9":{"name":"batchBalanceOf","line":140,"loc":{"start":{"line":140,"column":4},"end":{"line":146,"column":4}}},"10":{"name":"_getERC20BaseModuleStorage","line":155,"loc":{"start":{"line":155,"column":4},"end":{"line":159,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":43}},"2":{"start":{"line":55,"column":8},"end":{"line":55,"column":71}},"3":{"start":{"line":78,"column":8},"end":{"line":78,"column":68}},"4":{"start":{"line":80,"column":8},"end":{"line":80,"column":3039}},"5":{"start":{"line":81,"column":12},"end":{"line":81,"column":49}},"6":{"start":{"line":84,"column":8},"end":{"line":84,"column":21}},"7":{"start":{"line":94,"column":8},"end":{"line":94,"column":71}},"8":{"start":{"line":95,"column":8},"end":{"line":95,"column":26}},"9":{"start":{"line":102,"column":8},"end":{"line":102,"column":71}},"10":{"start":{"line":103,"column":8},"end":{"line":103,"column":22}},"11":{"start":{"line":111,"column":8},"end":{"line":111,"column":71}},"12":{"start":{"line":112,"column":8},"end":{"line":112,"column":24}},"13":{"start":{"line":123,"column":8},"end":{"line":123,"column":71}},"14":{"start":{"line":125,"column":8},"end":{"line":125,"column":31}},"15":{"start":{"line":132,"column":8},"end":{"line":132,"column":71}},"16":{"start":{"line":134,"column":8},"end":{"line":134,"column":37}},"17":{"start":{"line":142,"column":8},"end":{"line":142,"column":5157}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":23},"end":{"line":54,"column":23}},{"start":{"line":54,"column":23},"end":{"line":54,"column":23}}]},"2":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":8},"end":{"line":80,"column":8}},{"start":{"line":80,"column":8},"end":{"line":80,"column":8}}]},"3":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":87},"end":{"line":122,"column":87}},{"start":{"line":122,"column":87},"end":{"line":122,"column":87}}]},"4":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":91},"end":{"line":131,"column":91}},{"start":{"line":131,"column":91},"end":{"line":131,"column":91}}]}}},"contracts/modules/wrapper/core/ERC20BurnModule.sol":{"l":{"26":618,"27":538,"45":231,"57":84,"71":160,"72":40,"85":63,"86":61,"98":315,"99":233},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol","s":{"1":618,"2":231,"3":84,"4":160,"5":40,"6":63,"7":61,"8":315,"9":233},"b":{"1":[231,60],"2":[84,0],"3":[160,20],"4":[63,0]},"f":{"1":618,"2":231,"3":84,"4":160,"5":63,"6":315},"fnMap":{"1":{"name":"onlyBurner","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"burn","line":44,"loc":{"start":{"line":40,"column":4},"end":{"line":46,"column":4}}},"3":{"name":"burn","line":56,"loc":{"start":{"line":53,"column":4},"end":{"line":58,"column":4}}},"4":{"name":"batchBurn","line":70,"loc":{"start":{"line":66,"column":4},"end":{"line":73,"column":4}}},"5":{"name":"batchBurn","line":84,"loc":{"start":{"line":81,"column":4},"end":{"line":87,"column":4}}},"6":{"name":"_burn","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":100,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":23}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":34}},"3":{"start":{"line":57,"column":7},"end":{"line":57,"column":30}},"4":{"start":{"line":71,"column":8},"end":{"line":71,"column":35}},"5":{"start":{"line":72,"column":8},"end":{"line":72,"column":60}},"6":{"start":{"line":85,"column":8},"end":{"line":85,"column":35}},"7":{"start":{"line":86,"column":8},"end":{"line":86,"column":58}},"8":{"start":{"line":98,"column":8},"end":{"line":98,"column":36}},"9":{"start":{"line":99,"column":8},"end":{"line":99,"column":53}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":44},"end":{"line":44,"column":44}},{"start":{"line":44,"column":44},"end":{"line":44,"column":44}}]},"2":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":44},"end":{"line":56,"column":44}},{"start":{"line":56,"column":44},"end":{"line":56,"column":44}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":47},"end":{"line":70,"column":47}},{"start":{"line":70,"column":47},"end":{"line":70,"column":47}}]},"4":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":45},"end":{"line":84,"column":45}},{"start":{"line":84,"column":45},"end":{"line":84,"column":45}}]}}},"contracts/modules/wrapper/core/ERC20MintModule.sol":{"l":{"28":3948,"29":3888,"44":120,"60":3081,"76":519,"77":410,"89":168,"96":3201,"97":3153},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol","s":{"1":3948,"2":120,"3":3081,"4":519,"5":410,"6":168,"7":3201,"8":3153},"b":{"1":[120,20],"2":[3081,20],"3":[519,20],"4":[168,0]},"f":{"1":3948,"2":120,"3":3081,"4":519,"5":168,"6":3201},"fnMap":{"1":{"name":"onlyMinter","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"mint","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":4}}},"3":{"name":"mint","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"batchMint","line":75,"loc":{"start":{"line":72,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"batchTransfer","line":88,"loc":{"start":{"line":85,"column":3},"end":{"line":90,"column":4}}},"6":{"name":"_mint","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":98,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":23}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":34}},"3":{"start":{"line":60,"column":7},"end":{"line":60,"column":31}},"4":{"start":{"line":76,"column":7},"end":{"line":76,"column":34}},"5":{"start":{"line":77,"column":8},"end":{"line":77,"column":54}},"6":{"start":{"line":89,"column":8},"end":{"line":89,"column":42}},"7":{"start":{"line":96,"column":8},"end":{"line":96,"column":36}},"8":{"start":{"line":97,"column":8},"end":{"line":97,"column":53}}},"branchMap":{"1":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":109},"end":{"line":43,"column":109}},{"start":{"line":43,"column":109},"end":{"line":43,"column":109}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":88},"end":{"line":59,"column":88}},{"start":{"line":59,"column":88},"end":{"line":59,"column":88}}]},"3":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":44},"end":{"line":75,"column":44}},{"start":{"line":75,"column":44},"end":{"line":75,"column":44}}]},"4":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":53},"end":{"line":88,"column":53}},{"start":{"line":88,"column":53},"end":{"line":88,"column":53}}]}}},"contracts/modules/wrapper/core/PauseModule.sol":{"l":{"41":614,"42":571,"46":224,"47":203,"60":508,"69":63,"70":63,"71":42,"86":203,"87":182,"88":182,"89":182,"97":3329,"104":8936,"105":8936,"116":8685,"117":101,"123":9181},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol","s":{"1":614,"2":224,"3":508,"4":63,"5":63,"6":42,"7":203,"8":182,"9":182,"10":3329,"11":8936,"12":8936,"13":8685},"b":{"1":[508,22],"2":[63,21],"3":[42,21],"4":[203,21],"5":[101,8584]},"f":{"1":614,"2":224,"3":508,"4":63,"5":203,"6":3329,"7":8936,"8":8685,"9":9181},"fnMap":{"1":{"name":"onlyPauseManager","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":43,"column":4}}},"2":{"name":"onlyDeactivateContractManager","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":48,"column":4}}},"3":{"name":"pause","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"unpause","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"deactivateContract","line":83,"loc":{"start":{"line":81,"column":4},"end":{"line":90,"column":4}}},"6":{"name":"paused","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":98,"column":3}}},"7":{"name":"deactivated","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":106,"column":4}}},"8":{"name":"_requireNotDeactivated","line":115,"loc":{"start":{"line":115,"column":4},"end":{"line":119,"column":4}}},"9":{"name":"_getPauseModuleStorage","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":126,"column":4}}}},"statementMap":{"1":{"start":{"line":41,"column":8},"end":{"line":41,"column":24}},"2":{"start":{"line":46,"column":8},"end":{"line":46,"column":29}},"3":{"start":{"line":60,"column":8},"end":{"line":60,"column":35}},"4":{"start":{"line":69,"column":8},"end":{"line":69,"column":63}},"5":{"start":{"line":70,"column":8},"end":{"line":70,"column":76}},"6":{"start":{"line":71,"column":8},"end":{"line":71,"column":37}},"7":{"start":{"line":86,"column":8},"end":{"line":86,"column":43}},"8":{"start":{"line":87,"column":8},"end":{"line":87,"column":63}},"9":{"start":{"line":89,"column":7},"end":{"line":89,"column":37}},"10":{"start":{"line":97,"column":8},"end":{"line":97,"column":43}},"11":{"start":{"line":104,"column":8},"end":{"line":104,"column":63}},"12":{"start":{"line":105,"column":8},"end":{"line":105,"column":31}},"13":{"start":{"line":116,"column":8},"end":{"line":116,"column":4424}}},"branchMap":{"1":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":75},"end":{"line":59,"column":75}},{"start":{"line":59,"column":75},"end":{"line":59,"column":75}}]},"2":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":77},"end":{"line":68,"column":77}},{"start":{"line":68,"column":77},"end":{"line":68,"column":77}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":8},"end":{"line":70,"column":8}},{"start":{"line":70,"column":8},"end":{"line":70,"column":8}}]},"4":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":8},"end":{"line":83,"column":8}},{"start":{"line":83,"column":8},"end":{"line":83,"column":8}}]},"5":{"line":116,"type":"if","locations":[{"start":{"line":116,"column":8},"end":{"line":116,"column":8}},{"start":{"line":116,"column":8},"end":{"line":116,"column":8}}]}}},"contracts/modules/wrapper/core/ValidationModuleCore.sol":{"l":{"25":894,"34":174,"50":1068},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol","s":{"1":894,"2":174,"3":1068},"b":{},"f":{"1":894,"2":174,"3":1068},"fnMap":{"1":{"name":"canTransfer","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"canTransferFrom","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":35,"column":4}}},"3":{"name":"_canTransferByModule","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":51,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":64}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":61}},"3":{"start":{"line":50,"column":8},"end":{"line":50,"column":78}}},"branchMap":{}},"contracts/modules/wrapper/core/VersionModule.sol":{"l":{"28":21},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/VersionModule.sol","s":{"1":21},"b":{},"f":{"1":21},"fnMap":{"1":{"name":"version","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":29,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":7},"end":{"line":28,"column":21}}},"branchMap":{}},"contracts/modules/wrapper/extensions/DocumentEngineModule.sol":{"l":{"29":120,"30":118,"43":4,"44":2,"45":2,"57":118,"58":118,"65":78,"66":78,"67":76,"69":2,"77":21,"78":21,"79":19,"91":118,"92":118,"93":116,"103":118,"104":118,"112":337},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentEngineModule.sol","s":{"1":120,"2":4,"3":2,"4":2,"5":118,"6":118,"7":78,"8":78,"9":76,"10":2,"11":21,"12":21,"13":118,"14":118,"15":116,"16":118},"b":{"1":[4,0],"2":[2,2],"3":[76,2],"4":[19,2],"5":[118,2],"6":[116,2]},"f":{"1":120,"2":4,"3":118,"4":78,"5":21,"6":118,"7":118,"8":337},"fnMap":{"1":{"name":"onlyDocumentManager","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"__DocumentEngineModule_init_unchained","line":42,"loc":{"start":{"line":41,"column":4},"end":{"line":47,"column":4}}},"3":{"name":"documentEngine","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":59,"column":4}}},"4":{"name":"getDocument","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":71,"column":4}}},"5":{"name":"getAllDocuments","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"setDocumentEngine","line":90,"loc":{"start":{"line":88,"column":4},"end":{"line":94,"column":4}}},"7":{"name":"_setDocumentEngine","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":105,"column":4}}},"8":{"name":"_getDocumentEngineModuleStorage","line":111,"loc":{"start":{"line":111,"column":4},"end":{"line":115,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":37}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":1729}},"3":{"start":{"line":44,"column":12},"end":{"line":44,"column":85}},"4":{"start":{"line":45,"column":12},"end":{"line":45,"column":49}},"5":{"start":{"line":57,"column":8},"end":{"line":57,"column":81}},"6":{"start":{"line":58,"column":8},"end":{"line":58,"column":32}},"7":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"8":{"start":{"line":66,"column":8},"end":{"line":66,"column":2677}},"9":{"start":{"line":67,"column":12},"end":{"line":67,"column":54}},"10":{"start":{"line":69,"column":12},"end":{"line":69,"column":39}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":3098}},"13":{"start":{"line":91,"column":8},"end":{"line":91,"column":81}},"14":{"start":{"line":92,"column":8},"end":{"line":92,"column":110}},"15":{"start":{"line":93,"column":8},"end":{"line":93,"column":45}},"16":{"start":{"line":104,"column":8},"end":{"line":104,"column":44}}},"branchMap":{"1":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":21}},{"start":{"line":42,"column":21},"end":{"line":42,"column":21}}]},"2":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":8}},{"start":{"line":43,"column":8},"end":{"line":43,"column":8}}]},"3":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]},"4":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":8},"end":{"line":78,"column":8}},{"start":{"line":78,"column":8},"end":{"line":78,"column":8}}]},"5":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":53},"end":{"line":90,"column":53}},{"start":{"line":90,"column":53},"end":{"line":90,"column":53}}]},"6":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":8},"end":{"line":92,"column":8}},{"start":{"line":92,"column":8},"end":{"line":92,"column":8}}]}}},"contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol":{"l":{"24":660,"25":618,"30":156,"31":128,"43":983,"51":686,"63":100,"64":100,"75":28,"76":14,"87":324,"98":84,"110":154,"121":28,"132":28},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol","s":{"1":660,"2":156,"3":983,"4":686,"5":100,"6":100,"7":28,"8":14,"9":324,"10":84,"11":154,"12":28,"13":28},"b":{"1":[100,14],"2":[28,14],"3":[324,14],"4":[84,14],"5":[154,14],"6":[28,0],"7":[28,0]},"f":{"1":660,"2":156,"3":983,"4":686,"5":100,"6":28,"7":324,"8":84,"9":154,"10":28,"11":28},"fnMap":{"1":{"name":"onlyERC20Enforcer","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"onlyForcedTransferManager","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"3":{"name":"getFrozenTokens","line":42,"loc":{"start":{"line":42,"column":4},"end":{"line":44,"column":5}}},"4":{"name":"getActiveBalanceOf","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":52,"column":5}}},"5":{"name":"forcedTransfer","line":62,"loc":{"start":{"line":61,"column":4},"end":{"line":65,"column":4}}},"6":{"name":"forcedTransfer","line":74,"loc":{"start":{"line":73,"column":4},"end":{"line":77,"column":4}}},"7":{"name":"freezePartialTokens","line":86,"loc":{"start":{"line":85,"column":4},"end":{"line":88,"column":4}}},"8":{"name":"unfreezePartialTokens","line":97,"loc":{"start":{"line":96,"column":4},"end":{"line":99,"column":4}}},"9":{"name":"setFrozenTokens","line":108,"loc":{"start":{"line":107,"column":4},"end":{"line":111,"column":4}}},"10":{"name":"freezePartialTokens","line":120,"loc":{"start":{"line":119,"column":4},"end":{"line":122,"column":4}}},"11":{"name":"unfreezePartialTokens","line":131,"loc":{"start":{"line":130,"column":4},"end":{"line":133,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":32}},"2":{"start":{"line":30,"column":8},"end":{"line":30,"column":33}},"3":{"start":{"line":43,"column":8},"end":{"line":43,"column":40}},"4":{"start":{"line":51,"column":8},"end":{"line":51,"column":43}},"5":{"start":{"line":63,"column":7},"end":{"line":63,"column":44}},"6":{"start":{"line":64,"column":7},"end":{"line":64,"column":18}},"7":{"start":{"line":75,"column":7},"end":{"line":75,"column":42}},"8":{"start":{"line":76,"column":7},"end":{"line":76,"column":18}},"9":{"start":{"line":87,"column":8},"end":{"line":87,"column":47}},"10":{"start":{"line":98,"column":8},"end":{"line":98,"column":49}},"11":{"start":{"line":110,"column":9},"end":{"line":110,"column":48}},"12":{"start":{"line":121,"column":8},"end":{"line":121,"column":49}},"13":{"start":{"line":132,"column":8},"end":{"line":132,"column":51}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":55},"end":{"line":62,"column":55}},{"start":{"line":62,"column":55},"end":{"line":62,"column":55}}]},"2":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":57},"end":{"line":74,"column":57}},{"start":{"line":74,"column":57},"end":{"line":74,"column":57}}]},"3":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":54},"end":{"line":86,"column":54}},{"start":{"line":86,"column":54},"end":{"line":86,"column":54}}]},"4":{"line":97,"type":"if","locations":[{"start":{"line":97,"column":54},"end":{"line":97,"column":54}},{"start":{"line":97,"column":54},"end":{"line":97,"column":54}}]},"5":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":65},"end":{"line":108,"column":65}},{"start":{"line":108,"column":65},"end":{"line":108,"column":65}}]},"6":{"line":120,"type":"if","locations":[{"start":{"line":120,"column":54},"end":{"line":120,"column":54}},{"start":{"line":120,"column":54},"end":{"line":120,"column":54}}]},"7":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":54},"end":{"line":131,"column":54}},{"start":{"line":131,"column":54},"end":{"line":131,"column":54}}]}}},"contracts/modules/wrapper/extensions/ExtraInformationModule.sol":{"l":{"32":140,"33":70,"45":3741,"47":3741,"49":3741,"51":3741,"68":22,"69":22,"79":22,"92":22,"93":22,"101":110,"102":110,"109":50,"110":50,"117":88,"118":88,"125":24,"126":24,"132":3763,"133":3763,"138":3765,"140":3765,"141":3765,"142":3765,"144":3765,"148":3763,"149":3763,"157":4057},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ExtraInformationModule.sol","s":{"1":140,"2":3741,"3":3741,"4":3741,"5":3741,"6":22,"7":22,"8":22,"9":22,"10":22,"11":110,"12":110,"13":50,"14":50,"15":88,"16":88,"17":24,"18":24,"19":3763,"20":3765,"21":3763},"b":{"1":[3741,0],"2":[22,22],"3":[22,22],"4":[22,22]},"f":{"1":140,"2":3741,"3":22,"4":22,"5":22,"6":110,"7":50,"8":88,"9":24,"10":3763,"11":3765,"12":3763,"13":4057},"fnMap":{"1":{"name":"onlyExtraInfoManager","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":34,"column":4}}},"2":{"name":"__ExtraInformationModule_init_unchained","line":44,"loc":{"start":{"line":40,"column":4},"end":{"line":52,"column":4}}},"3":{"name":"setTokenId","line":67,"loc":{"start":{"line":65,"column":4},"end":{"line":70,"column":4}}},"4":{"name":"setTerms","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":80,"column":4}}},"5":{"name":"setInformation","line":91,"loc":{"start":{"line":89,"column":4},"end":{"line":94,"column":4}}},"6":{"name":"tokenId","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":103,"column":4}}},"7":{"name":"terms","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":111,"column":4}}},"8":{"name":"information","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":119,"column":4}}},"9":{"name":"_setTerms","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":127,"column":4}}},"10":{"name":"_setTokenId","line":129,"loc":{"start":{"line":129,"column":4},"end":{"line":134,"column":4}}},"11":{"name":"_setTerms","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":145,"column":4}}},"12":{"name":"_setInformation","line":147,"loc":{"start":{"line":147,"column":4},"end":{"line":150,"column":4}}},"13":{"name":"_getExtraInformationModuleStorage","line":156,"loc":{"start":{"line":156,"column":4},"end":{"line":160,"column":4}}}},"statementMap":{"1":{"start":{"line":32,"column":8},"end":{"line":32,"column":38}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":85}},"3":{"start":{"line":47,"column":8},"end":{"line":47,"column":31}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":27}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":39}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":85}},"7":{"start":{"line":69,"column":8},"end":{"line":69,"column":31}},"8":{"start":{"line":79,"column":2},"end":{"line":79,"column":18}},"9":{"start":{"line":92,"column":8},"end":{"line":92,"column":85}},"10":{"start":{"line":93,"column":8},"end":{"line":93,"column":39}},"11":{"start":{"line":101,"column":8},"end":{"line":101,"column":85}},"12":{"start":{"line":102,"column":8},"end":{"line":102,"column":25}},"13":{"start":{"line":109,"column":8},"end":{"line":109,"column":85}},"14":{"start":{"line":110,"column":8},"end":{"line":110,"column":23}},"15":{"start":{"line":117,"column":8},"end":{"line":117,"column":85}},"16":{"start":{"line":118,"column":8},"end":{"line":118,"column":29}},"17":{"start":{"line":125,"column":2},"end":{"line":125,"column":79}},"18":{"start":{"line":126,"column":8},"end":{"line":126,"column":27}},"19":{"start":{"line":133,"column":8},"end":{"line":133,"column":40}},"20":{"start":{"line":144,"column":8},"end":{"line":144,"column":28}},"21":{"start":{"line":149,"column":8},"end":{"line":149,"column":38}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":23},"end":{"line":44,"column":23}},{"start":{"line":44,"column":23},"end":{"line":44,"column":23}}]},"2":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":42},"end":{"line":67,"column":42}},{"start":{"line":67,"column":42},"end":{"line":67,"column":42}}]},"3":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":102},"end":{"line":78,"column":102}},{"start":{"line":78,"column":102},"end":{"line":78,"column":102}}]},"4":{"line":91,"type":"if","locations":[{"start":{"line":91,"column":21},"end":{"line":91,"column":21}},{"start":{"line":91,"column":21},"end":{"line":91,"column":21}}]}}},"contracts/modules/wrapper/extensions/SnapshotEngineModule.sol":{"l":{"30":503,"31":501,"45":4,"46":2,"47":2,"65":501,"66":501,"67":499,"77":5780,"78":5780,"87":501,"88":501,"95":6283},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol","s":{"1":503,"2":4,"3":2,"4":2,"5":501,"6":501,"7":499,"8":5780,"9":5780,"10":501},"b":{"1":[4,0],"2":[2,2],"3":[501,2],"4":[499,2]},"f":{"1":503,"2":4,"3":501,"4":5780,"5":501,"6":6283},"fnMap":{"1":{"name":"onlySnapshooter","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"__SnapshotEngineModule_init_unchained","line":44,"loc":{"start":{"line":43,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"setSnapshotEngine","line":64,"loc":{"start":{"line":62,"column":4},"end":{"line":68,"column":4}}},"4":{"name":"snapshotEngine","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"5":{"name":"_setSnapshotEngine","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":89,"column":4}}},"6":{"name":"_getSnapshotEngineModuleStorage","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":98,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":28}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":1821}},"3":{"start":{"line":46,"column":12},"end":{"line":46,"column":85}},"4":{"start":{"line":47,"column":12},"end":{"line":47,"column":49}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"6":{"start":{"line":66,"column":8},"end":{"line":66,"column":104}},"7":{"start":{"line":67,"column":8},"end":{"line":67,"column":45}},"8":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}},"10":{"start":{"line":88,"column":8},"end":{"line":88,"column":44}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":21},"end":{"line":44,"column":21}},{"start":{"line":44,"column":21},"end":{"line":44,"column":21}}]},"2":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]},"3":{"line":64,"type":"if","locations":[{"start":{"line":64,"column":53},"end":{"line":64,"column":53}},{"start":{"line":64,"column":53},"end":{"line":64,"column":53}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]}}},"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol":{"l":{"55":69,"56":69,"57":6,"62":14,"67":7,"72":7,"77":7,"82":7,"84":18,"86":3,"103":136,"104":136,"105":136,"106":77,"108":42,"110":17,"120":122,"121":122,"122":7,"124":115,"125":115,"126":77,"128":24,"130":14,"147":167,"148":21,"150":35,"152":7,"154":7,"157":97},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol","s":{"1":69,"2":69,"3":6,"4":63,"5":14,"6":49,"7":7,"8":42,"9":7,"10":35,"11":7,"12":28,"13":7,"14":21,"15":18,"16":3,"17":136,"18":136,"19":136,"20":77,"21":59,"22":42,"23":17,"24":122,"25":122,"26":7,"27":115,"28":115,"29":77,"30":38,"31":24,"32":14,"33":167,"34":21,"35":146,"36":35,"37":111,"38":7,"39":104,"40":7,"41":97},"b":{"1":[6,63],"2":[14,49],"3":[7,42],"4":[7,35],"5":[7,28],"6":[7,21],"7":[18,3],"8":[77,59],"9":[42,17],"10":[7,115],"11":[77,38],"12":[24,14],"13":[21,146],"14":[35,111],"15":[7,104],"16":[7,97]},"f":{"1":69,"2":136,"3":122,"4":167},"fnMap":{"1":{"name":"messageForTransferRestriction","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":88,"column":4}}},"2":{"name":"detectTransferRestriction","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":112,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":114,"loc":{"start":{"line":114,"column":4},"end":{"line":133,"column":4}}},"4":{"name":"_detectTransferRestriction","line":142,"loc":{"start":{"line":142,"column":4},"end":{"line":159,"column":4}}}},"statementMap":{"1":{"start":{"line":55,"column":10},"end":{"line":55,"column":84}},"2":{"start":{"line":56,"column":8},"end":{"line":56,"column":2157}},"3":{"start":{"line":57,"column":12},"end":{"line":57,"column":35}},"4":{"start":{"line":58,"column":15},"end":{"line":58,"column":2288}},"5":{"start":{"line":62,"column":12},"end":{"line":62,"column":48}},"6":{"start":{"line":63,"column":15},"end":{"line":63,"column":2479}},"7":{"start":{"line":67,"column":12},"end":{"line":67,"column":53}},"8":{"start":{"line":68,"column":15},"end":{"line":68,"column":2680}},"9":{"start":{"line":72,"column":12},"end":{"line":72,"column":53}},"10":{"start":{"line":73,"column":15},"end":{"line":73,"column":2881}},"11":{"start":{"line":77,"column":12},"end":{"line":77,"column":51}},"12":{"start":{"line":78,"column":16},"end":{"line":78,"column":3079}},"13":{"start":{"line":82,"column":12},"end":{"line":82,"column":56}},"14":{"start":{"line":83,"column":15},"end":{"line":83,"column":3286}},"15":{"start":{"line":84,"column":12},"end":{"line":84,"column":77}},"16":{"start":{"line":86,"column":12},"end":{"line":86,"column":36}},"17":{"start":{"line":103,"column":9},"end":{"line":103,"column":83}},"18":{"start":{"line":104,"column":9},"end":{"line":104,"column":71}},"19":{"start":{"line":105,"column":9},"end":{"line":105,"column":4192}},"20":{"start":{"line":106,"column":12},"end":{"line":106,"column":29}},"21":{"start":{"line":107,"column":16},"end":{"line":107,"column":4312}},"22":{"start":{"line":108,"column":12},"end":{"line":108,"column":73}},"23":{"start":{"line":110,"column":12},"end":{"line":110,"column":71}},"24":{"start":{"line":120,"column":8},"end":{"line":120,"column":82}},"25":{"start":{"line":121,"column":8},"end":{"line":121,"column":4834}},"26":{"start":{"line":122,"column":12},"end":{"line":122,"column":92}},"27":{"start":{"line":124,"column":12},"end":{"line":124,"column":74}},"28":{"start":{"line":125,"column":12},"end":{"line":125,"column":5062}},"29":{"start":{"line":126,"column":16},"end":{"line":126,"column":33}},"30":{"start":{"line":127,"column":19},"end":{"line":127,"column":5190}},"31":{"start":{"line":128,"column":16},"end":{"line":128,"column":90}},"32":{"start":{"line":130,"column":16},"end":{"line":130,"column":75}},"33":{"start":{"line":147,"column":8},"end":{"line":147,"column":5893}},"34":{"start":{"line":148,"column":12},"end":{"line":148,"column":89}},"35":{"start":{"line":149,"column":15},"end":{"line":149,"column":6019}},"36":{"start":{"line":150,"column":12},"end":{"line":150,"column":84}},"37":{"start":{"line":151,"column":15},"end":{"line":151,"column":6136}},"38":{"start":{"line":152,"column":12},"end":{"line":152,"column":89}},"39":{"start":{"line":153,"column":15},"end":{"line":153,"column":6264}},"40":{"start":{"line":154,"column":12},"end":{"line":154,"column":87}},"41":{"start":{"line":157,"column":12},"end":{"line":157,"column":71}}},"branchMap":{"1":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":8},"end":{"line":56,"column":8}},{"start":{"line":56,"column":8},"end":{"line":56,"column":8}}]},"2":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":15},"end":{"line":58,"column":15}},{"start":{"line":58,"column":15},"end":{"line":58,"column":15}}]},"3":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":15},"end":{"line":63,"column":15}},{"start":{"line":63,"column":15},"end":{"line":63,"column":15}}]},"4":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":15},"end":{"line":68,"column":15}},{"start":{"line":68,"column":15},"end":{"line":68,"column":15}}]},"5":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":15},"end":{"line":73,"column":15}},{"start":{"line":73,"column":15},"end":{"line":73,"column":15}}]},"6":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":16},"end":{"line":78,"column":16}},{"start":{"line":78,"column":16},"end":{"line":78,"column":16}}]},"7":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":15},"end":{"line":83,"column":15}},{"start":{"line":83,"column":15},"end":{"line":83,"column":15}}]},"8":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":9},"end":{"line":105,"column":9}},{"start":{"line":105,"column":9},"end":{"line":105,"column":9}}]},"9":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":16},"end":{"line":107,"column":16}},{"start":{"line":107,"column":16},"end":{"line":107,"column":16}}]},"10":{"line":121,"type":"if","locations":[{"start":{"line":121,"column":8},"end":{"line":121,"column":8}},{"start":{"line":121,"column":8},"end":{"line":121,"column":8}}]},"11":{"line":125,"type":"if","locations":[{"start":{"line":125,"column":12},"end":{"line":125,"column":12}},{"start":{"line":125,"column":12},"end":{"line":125,"column":12}}]},"12":{"line":127,"type":"if","locations":[{"start":{"line":127,"column":19},"end":{"line":127,"column":19}},{"start":{"line":127,"column":19},"end":{"line":127,"column":19}}]},"13":{"line":147,"type":"if","locations":[{"start":{"line":147,"column":8},"end":{"line":147,"column":8}},{"start":{"line":147,"column":8},"end":{"line":147,"column":8}}]},"14":{"line":149,"type":"if","locations":[{"start":{"line":149,"column":15},"end":{"line":149,"column":15}},{"start":{"line":149,"column":15},"end":{"line":149,"column":15}}]},"15":{"line":151,"type":"if","locations":[{"start":{"line":151,"column":15},"end":{"line":151,"column":15}},{"start":{"line":151,"column":15},"end":{"line":151,"column":15}}]},"16":{"line":153,"type":"if","locations":[{"start":{"line":153,"column":15},"end":{"line":153,"column":15}},{"start":{"line":153,"column":15},"end":{"line":153,"column":15}}]}}},"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol":{"l":{"27":90,"28":87,"49":87,"50":84,"62":692,"75":141,"87":692,"88":192,"90":500,"100":141,"101":60,"103":81,"113":81,"114":81,"115":30,"117":51,"125":500,"126":500,"127":60,"129":440,"138":8158,"139":7818,"140":7818,"141":540,"142":12,"144":528},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol","s":{"1":90,"2":87,"3":84,"4":692,"5":141,"6":692,"7":192,"8":500,"9":141,"10":60,"11":81,"12":81,"13":81,"14":30,"15":51,"16":500,"17":500,"18":60,"19":440,"20":8158,"21":7818,"22":7818,"23":540,"24":12,"25":528},"b":{"1":[87,3],"2":[84,3],"3":[192,500],"4":[60,81],"5":[30,51],"6":[60,440],"7":[540,7278],"8":[12,528]},"f":{"1":90,"2":87,"3":692,"4":141,"5":692,"6":141,"7":81,"8":500,"9":8158},"fnMap":{"1":{"name":"onlyRuleEngineManager","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":29,"column":4}}},"2":{"name":"setRuleEngine","line":48,"loc":{"start":{"line":46,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"canTransfer","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"canTransferFrom","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"_canTransfer","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":92,"column":4}}},"6":{"name":"_canTransferFrom","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":105,"column":4}}},"7":{"name":"_canTransferFromWithRuleEngine","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":119,"column":4}}},"8":{"name":"_canTransferWithRuleEngine","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":131,"column":4}}},"9":{"name":"_transferred","line":137,"loc":{"start":{"line":137,"column":4},"end":{"line":147,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":39}},"2":{"start":{"line":49,"column":9},"end":{"line":49,"column":98}},"3":{"start":{"line":50,"column":8},"end":{"line":50,"column":34}},"4":{"start":{"line":62,"column":7},"end":{"line":62,"column":43}},"5":{"start":{"line":75,"column":8},"end":{"line":75,"column":57}},"6":{"start":{"line":87,"column":7},"end":{"line":87,"column":2936}},"7":{"start":{"line":88,"column":12},"end":{"line":88,"column":24}},"8":{"start":{"line":90,"column":12},"end":{"line":90,"column":62}},"9":{"start":{"line":100,"column":8},"end":{"line":100,"column":3291}},"10":{"start":{"line":101,"column":12},"end":{"line":101,"column":24}},"11":{"start":{"line":103,"column":12},"end":{"line":103,"column":75}},"12":{"start":{"line":113,"column":8},"end":{"line":113,"column":46}},"13":{"start":{"line":114,"column":8},"end":{"line":114,"column":3734}},"14":{"start":{"line":115,"column":12},"end":{"line":115,"column":72}},"15":{"start":{"line":117,"column":12},"end":{"line":117,"column":23}},"16":{"start":{"line":125,"column":8},"end":{"line":125,"column":46}},"17":{"start":{"line":126,"column":8},"end":{"line":126,"column":4113}},"18":{"start":{"line":127,"column":12},"end":{"line":127,"column":59}},"19":{"start":{"line":129,"column":12},"end":{"line":129,"column":23}},"20":{"start":{"line":138,"column":8},"end":{"line":138,"column":62}},"21":{"start":{"line":139,"column":8},"end":{"line":139,"column":46}},"22":{"start":{"line":140,"column":8},"end":{"line":140,"column":4665}},"23":{"start":{"line":141,"column":12},"end":{"line":141,"column":4722}},"24":{"start":{"line":142,"column":16},"end":{"line":142,"column":64}},"25":{"start":{"line":144,"column":16},"end":{"line":144,"column":55}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":21},"end":{"line":48,"column":21}},{"start":{"line":48,"column":21},"end":{"line":48,"column":21}}]},"2":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":9},"end":{"line":49,"column":9}},{"start":{"line":49,"column":9},"end":{"line":49,"column":9}}]},"3":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":7},"end":{"line":87,"column":7}},{"start":{"line":87,"column":7},"end":{"line":87,"column":7}}]},"4":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":8},"end":{"line":100,"column":8}},{"start":{"line":100,"column":8},"end":{"line":100,"column":8}}]},"5":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":8},"end":{"line":114,"column":8}},{"start":{"line":114,"column":8},"end":{"line":114,"column":8}}]},"6":{"line":126,"type":"if","locations":[{"start":{"line":126,"column":8},"end":{"line":126,"column":8}},{"start":{"line":126,"column":8},"end":{"line":126,"column":8}}]},"7":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":8},"end":{"line":140,"column":8}},{"start":{"line":140,"column":8},"end":{"line":140,"column":8}}]},"8":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":12},"end":{"line":141,"column":12}},{"start":{"line":141,"column":12},"end":{"line":141,"column":12}}]}}},"contracts/modules/wrapper/options/AllowlistModule.sol":{"l":{"25":769,"26":761,"37":4,"47":218,"57":422,"67":117,"68":117,"77":4,"84":1092,"91":1882,"92":1882},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/AllowlistModule.sol","s":{"1":769,"2":4,"3":218,"4":422,"5":117,"6":117,"7":4,"8":1092,"9":1882,"10":1882},"b":{"1":[4,2],"2":[218,4],"3":[422,2],"4":[117,0]},"f":{"1":769,"2":4,"3":218,"4":422,"5":117,"6":4,"7":1092,"8":1882},"fnMap":{"1":{"name":"onlyAllowlistManager","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"setAddressAllowlist","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":38,"column":4}}},"3":{"name":"setAddressAllowlist","line":46,"loc":{"start":{"line":44,"column":4},"end":{"line":48,"column":4}}},"4":{"name":"batchSetAddressAllowlist","line":56,"loc":{"start":{"line":54,"column":4},"end":{"line":58,"column":4}}},"5":{"name":"enableAllowlist","line":66,"loc":{"start":{"line":64,"column":4},"end":{"line":69,"column":4}}},"6":{"name":"isAllowlistEnabled","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":78,"column":4}}},"7":{"name":"isAllowlisted","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":85,"column":4}}},"8":{"name":"_addToAllowlist","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":93,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":38}},"2":{"start":{"line":37,"column":9},"end":{"line":37,"column":44}},"3":{"start":{"line":47,"column":9},"end":{"line":47,"column":46}},"4":{"start":{"line":57,"column":9},"end":{"line":57,"column":45}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":31}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":56}},"7":{"start":{"line":77,"column":8},"end":{"line":77,"column":36}},"8":{"start":{"line":84,"column":7},"end":{"line":84,"column":37}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":72}},"10":{"start":{"line":92,"column":8},"end":{"line":92,"column":73}}},"branchMap":{"1":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":78},"end":{"line":36,"column":78}},{"start":{"line":36,"column":78},"end":{"line":36,"column":78}}]},"2":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":21},"end":{"line":46,"column":21}},{"start":{"line":46,"column":21},"end":{"line":46,"column":21}}]},"3":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":21},"end":{"line":56,"column":21}},{"start":{"line":56,"column":21},"end":{"line":56,"column":21}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":21},"end":{"line":66,"column":21}},{"start":{"line":66,"column":21},"end":{"line":66,"column":21}}]}}},"contracts/modules/wrapper/options/CCIPModule.sol":{"l":{"31":32,"32":24,"42":24,"43":24,"44":24,"46":16,"48":16,"55":16,"56":16,"67":40},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/CCIPModule.sol","s":{"1":32,"2":24,"3":24,"4":24,"5":16,"6":16,"7":16},"b":{"1":[24,8],"2":[16,8]},"f":{"1":32,"2":24,"3":16,"4":40},"fnMap":{"1":{"name":"onlyCCIPSetAdmin","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":33,"column":4}}},"2":{"name":"setCCIPAdmin","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":49,"column":2}}},"3":{"name":"getCCIPAdmin","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":57,"column":2}}},"4":{"name":"_getCCIPModuleStorage","line":66,"loc":{"start":{"line":66,"column":2},"end":{"line":70,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":31}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":57}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":40}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":66}},"5":{"start":{"line":48,"column":4},"end":{"line":48,"column":53}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":57}},"7":{"start":{"line":56,"column":4},"end":{"line":56,"column":24}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":57},"end":{"line":41,"column":57}},{"start":{"line":41,"column":57},"end":{"line":41,"column":57}}]},"2":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}},"contracts/modules/wrapper/options/DebtEngineModule.sol":{"l":{"28":18,"29":15,"48":15,"49":15,"50":12,"61":6,"62":6,"63":3,"74":6,"75":6,"76":3,"85":12,"86":12,"95":12,"96":12,"106":39},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtEngineModule.sol","s":{"1":18,"2":15,"3":15,"4":12,"5":6,"6":6,"7":6,"8":6,"9":12,"10":12,"11":12},"b":{"1":[15,3],"2":[12,3],"3":[3,3],"4":[3,3]},"f":{"1":18,"2":15,"3":6,"4":6,"5":12,"6":12,"7":39},"fnMap":{"1":{"name":"onlyDebtEngineManager","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"setDebtEngine","line":47,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"creditEvents","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"debt","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"debtEngine","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":87,"column":4}}},"6":{"name":"_setDebtEngine","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":97,"column":4}}},"7":{"name":"_getDebtEngineModuleStorage","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":109,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":39}},"2":{"start":{"line":48,"column":8},"end":{"line":48,"column":67}},"3":{"start":{"line":49,"column":8},"end":{"line":49,"column":98}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":37}},"5":{"start":{"line":61,"column":8},"end":{"line":61,"column":67}},"6":{"start":{"line":62,"column":8},"end":{"line":62,"column":2681}},"7":{"start":{"line":74,"column":8},"end":{"line":74,"column":67}},"8":{"start":{"line":75,"column":8},"end":{"line":75,"column":3262}},"9":{"start":{"line":85,"column":8},"end":{"line":85,"column":67}},"10":{"start":{"line":86,"column":8},"end":{"line":86,"column":28}},"11":{"start":{"line":96,"column":8},"end":{"line":96,"column":36}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":49},"end":{"line":47,"column":49}},{"start":{"line":47,"column":49},"end":{"line":47,"column":49}}]},"2":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":8},"end":{"line":49,"column":8}},{"start":{"line":49,"column":8},"end":{"line":49,"column":8}}]},"3":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":8},"end":{"line":62,"column":8}},{"start":{"line":62,"column":8},"end":{"line":62,"column":8}}]},"4":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":8},"end":{"line":75,"column":8}},{"start":{"line":75,"column":8},"end":{"line":75,"column":8}}]}}},"contracts/modules/wrapper/options/DebtModule.sol":{"l":{"30":24,"31":12,"47":4,"48":4,"49":4,"60":4,"61":4,"62":4,"73":4,"74":4,"75":4,"83":4,"84":4,"91":8,"92":8,"102":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtModule.sol","s":{"1":24,"2":4,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":8},"b":{"1":[4,4],"2":[4,4],"3":[4,4]},"f":{"1":24,"2":4,"3":4,"4":4,"5":4,"6":8,"7":24},"fnMap":{"1":{"name":"onlyDebtManager","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"setCreditEvents","line":46,"loc":{"start":{"line":44,"column":4},"end":{"line":50,"column":4}}},"3":{"name":"setDebt","line":59,"loc":{"start":{"line":57,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"setDebtInstrument","line":72,"loc":{"start":{"line":70,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"creditEvents","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":85,"column":4}}},"6":{"name":"debt","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":93,"column":4}}},"7":{"name":"_getDebtModuleStorage","line":101,"loc":{"start":{"line":101,"column":4},"end":{"line":105,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":33}},"2":{"start":{"line":47,"column":8},"end":{"line":47,"column":61}},"3":{"start":{"line":49,"column":8},"end":{"line":49,"column":35}},"4":{"start":{"line":60,"column":8},"end":{"line":60,"column":61}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":27}},"6":{"start":{"line":73,"column":8},"end":{"line":73,"column":61}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":37}},"8":{"start":{"line":83,"column":8},"end":{"line":83,"column":61}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":61}}},"branchMap":{"1":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":13},"end":{"line":46,"column":13}},{"start":{"line":46,"column":13},"end":{"line":46,"column":13}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":43},"end":{"line":59,"column":43}},{"start":{"line":59,"column":43},"end":{"line":59,"column":43}}]},"3":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":43},"end":{"line":72,"column":43}},{"start":{"line":72,"column":43},"end":{"line":72,"column":43}}]}}},"contracts/modules/wrapper/options/ERC20CrossChainModule.sol":{"l":{"33":172,"34":112,"39":60,"40":30,"45":80,"46":40,"61":52,"62":42,"74":60,"75":40,"86":30,"87":30,"99":40,"101":40,"106":68,"114":30,"117":20,"118":20,"125":60,"128":30},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol","s":{"1":172,"2":60,"3":80,"4":52,"5":42,"6":60,"7":40,"8":30,"9":30,"10":40,"11":40,"12":68,"13":30,"14":20,"15":20,"16":60,"17":30},"b":{"1":[52,30],"2":[60,30],"3":[30,30],"4":[40,40],"5":[10,10]},"f":{"1":172,"2":60,"3":80,"4":52,"5":60,"6":30,"7":40,"8":68,"9":30,"10":60},"fnMap":{"1":{"name":"onlyTokenBridge","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":35,"column":4}}},"2":{"name":"onlyBurnerFrom","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"3":{"name":"onlySelfBurn","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":47,"column":4}}},"4":{"name":"crosschainMint","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":63,"column":4}}},"5":{"name":"crosschainBurn","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":76,"column":4}}},"6":{"name":"burnFrom","line":84,"loc":{"start":{"line":83,"column":4},"end":{"line":88,"column":4}}},"7":{"name":"burn","line":97,"loc":{"start":{"line":95,"column":4},"end":{"line":102,"column":4}}},"8":{"name":"supportsInterface","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":107,"column":4}}},"9":{"name":"_burnFrom","line":112,"loc":{"start":{"line":112,"column":4},"end":{"line":119,"column":4}}},"10":{"name":"_burn","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":129,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":36}},"2":{"start":{"line":39,"column":8},"end":{"line":39,"column":27}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":27}},"4":{"start":{"line":61,"column":8},"end":{"line":61,"column":31}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":51}},"6":{"start":{"line":74,"column":8},"end":{"line":74,"column":33}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":54}},"8":{"start":{"line":86,"column":8},"end":{"line":86,"column":38}},"9":{"start":{"line":87,"column":8},"end":{"line":87,"column":40}},"10":{"start":{"line":99,"column":8},"end":{"line":99,"column":37}},"11":{"start":{"line":101,"column":8},"end":{"line":101,"column":35}},"12":{"start":{"line":106,"column":8},"end":{"line":106,"column":110}},"13":{"start":{"line":114,"column":8},"end":{"line":114,"column":64}},"14":{"start":{"line":117,"column":8},"end":{"line":117,"column":58}},"15":{"start":{"line":118,"column":8},"end":{"line":118,"column":36}},"16":{"start":{"line":125,"column":8},"end":{"line":125,"column":36}},"17":{"start":{"line":128,"column":8},"end":{"line":128,"column":53}}},"branchMap":{"1":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":89},"end":{"line":60,"column":89}},{"start":{"line":60,"column":89},"end":{"line":60,"column":89}}]},"2":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":91},"end":{"line":73,"column":91}},{"start":{"line":73,"column":91},"end":{"line":73,"column":91}}]},"3":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":48},"end":{"line":84,"column":48}},{"start":{"line":84,"column":48},"end":{"line":84,"column":48}}]},"4":{"line":97,"type":"if","locations":[{"start":{"line":97,"column":46},"end":{"line":97,"column":46}},{"start":{"line":97,"column":46},"end":{"line":97,"column":46}}]},"5":{"line":106,"type":"cond-expr","locations":[{"start":{"line":106,"column":15},"end":{"line":106,"column":56}},{"start":{"line":106,"column":61},"end":{"line":106,"column":109}}]}}},"contracts/modules/wrapper/options/ERC2771Module.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC2771Module.sol","s":{},"b":{},"f":{"1":2541},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":22,"column":4}}}},"statementMap":{},"branchMap":{}},"contracts/modules/wrapper/options/ERC7551Module.sol":{"l":{"43":2,"44":2,"53":2,"54":2,"55":2,"60":4,"61":4,"68":2,"77":2,"78":2,"83":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC7551Module.sol","s":{"1":2,"2":2,"3":2,"4":2,"5":2,"6":4,"7":4,"8":2,"9":2},"b":{"1":[2,2],"2":[2,2]},"f":{"1":2,"2":2,"3":4,"4":2,"5":2,"6":6},"fnMap":{"1":{"name":"setMetaData","line":42,"loc":{"start":{"line":40,"column":4},"end":{"line":45,"column":4}}},"2":{"name":"setTerms","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":56,"column":4}}},"3":{"name":"metaData","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":62,"column":4}}},"4":{"name":"termsHash","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":69,"column":4}}},"5":{"name":"_setMetaData","line":74,"loc":{"start":{"line":74,"column":3},"end":{"line":79,"column":4}}},"6":{"name":"_getERC7551ModuleStorage","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":86,"column":4}}}},"statementMap":{"1":{"start":{"line":43,"column":8},"end":{"line":43,"column":67}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":34}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":94}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":24}},"5":{"start":{"line":55,"column":8},"end":{"line":55,"column":31}},"6":{"start":{"line":60,"column":8},"end":{"line":60,"column":67}},"7":{"start":{"line":61,"column":8},"end":{"line":61,"column":26}},"8":{"start":{"line":68,"column":8},"end":{"line":68,"column":39}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}}},"branchMap":{"1":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":48},"end":{"line":42,"column":48}},{"start":{"line":42,"column":48},"end":{"line":42,"column":48}}]},"2":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":101},"end":{"line":52,"column":101}},{"start":{"line":52,"column":101},"end":{"line":52,"column":101}}]}}},"contracts/modules/wrapper/security/AccessControlModule.sol":{"l":{"25":3945,"26":2,"31":3943,"45":13682,"46":8159,"48":5523},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol","s":{"1":3945,"2":3943,"3":13682,"4":8159,"5":5523},"b":{"1":[3945,0],"2":[2,3943],"3":[8159,5523]},"f":{"1":3945,"2":13682},"fnMap":{"1":{"name":"__AccessControlModule_init_unchained","line":24,"loc":{"start":{"line":23,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"hasRole","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":1015}},"2":{"start":{"line":31,"column":8},"end":{"line":31,"column":44}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":1867}},"4":{"start":{"line":46,"column":12},"end":{"line":46,"column":23}},"5":{"start":{"line":48,"column":12},"end":{"line":48,"column":66}}},"branchMap":{"1":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":13},"end":{"line":24,"column":13}},{"start":{"line":24,"column":13},"end":{"line":24,"column":13}}]},"2":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":8},"end":{"line":25,"column":8}},{"start":{"line":25,"column":8},"end":{"line":25,"column":8}}]},"3":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]}}}}
\ No newline at end of file
+{"contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol":{"l":{"29":368},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol","s":{"1":368},"b":{},"f":{"1":368},"fnMap":{"1":{"name":"constructor","line":27,"loc":{"start":{"line":22,"column":4},"end":{"line":34,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":1249}}},"branchMap":{}},"contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol":{"l":{"20":226},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol","s":{"1":226},"b":{},"f":{"1":226},"fnMap":{"1":{"name":"constructor","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":21,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":29}}},"branchMap":{}},"contracts/deployment/CMTATStandardStandalone.sol":{"l":{"31":308},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardStandalone.sol","s":{"1":308},"b":{},"f":{"1":308},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1349}}},"branchMap":{}},"contracts/deployment/CMTATStandardUpgradeable.sol":{"l":{"22":336},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardUpgradeable.sol","s":{"1":336},"b":{},"f":{"1":336},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},"contracts/deployment/CMTATUpgradeableUUPS.sol":{"l":{"22":450},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol","s":{"1":450},"b":{"1":[2,1]},"f":{"1":450,"2":2},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}},"2":{"name":"_authorizeUpgrade","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":32,"column":131}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{"1":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":101},"end":{"line":32,"column":101}},{"start":{"line":32,"column":101},"end":{"line":32,"column":101}}]}}},"contracts/deployment/debt/CMTATStandaloneDebt.sol":{"l":{"26":446},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.sol","s":{"1":446},"b":{},"f":{"1":446},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":1027}}},"branchMap":{}},"contracts/deployment/debt/CMTATUpgradeableDebt.sol":{"l":{"16":456},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt.sol","s":{"1":456},"b":{},"f":{"1":456},"fnMap":{"1":{"name":"constructor","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":17,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":29}}},"branchMap":{}},"contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol":{"l":{"26":450},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol","s":{"1":450},"b":{},"f":{"1":450},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":1051}}},"branchMap":{}},"contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol":{"l":{"16":204},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol","s":{"1":204},"b":{},"f":{"1":204},"fnMap":{"1":{"name":"constructor","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":17,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":29}}},"branchMap":{}},"contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol":{"l":{"31":228},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol","s":{"1":228},"b":{},"f":{"1":228},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1273}}},"branchMap":{}},"contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol":{"l":{"22":268},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol","s":{"1":268},"b":{},"f":{"1":268},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},"contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol":{"l":{"30":230},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol","s":{"1":230},"b":{},"f":{"1":230},"fnMap":{"1":{"name":"constructor","line":28,"loc":{"start":{"line":22,"column":4},"end":{"line":36,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":1293}}},"branchMap":{}},"contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol":{"l":{"21":230},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol","s":{"1":230},"b":{},"f":{"1":230},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":17,"column":4},"end":{"line":22,"column":4}}}},"statementMap":{"1":{"start":{"line":21,"column":8},"end":{"line":21,"column":29}}},"branchMap":{}},"contracts/deployment/light/CMTATStandaloneLight.sol":{"l":{"23":125},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight.sol","s":{"1":125},"b":{},"f":{"1":125},"fnMap":{"1":{"name":"constructor","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":27,"column":4}}}},"statementMap":{"1":{"start":{"line":23,"column":8},"end":{"line":23,"column":790}}},"branchMap":{}},"contracts/deployment/light/CMTATUpgradeableLight.sol":{"l":{"18":122},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLight.sol","s":{"1":122},"b":{},"f":{"1":122},"fnMap":{"1":{"name":"constructor","line":16,"loc":{"start":{"line":16,"column":4},"end":{"line":19,"column":4}}}},"statementMap":{"1":{"start":{"line":18,"column":8},"end":{"line":18,"column":29}}},"branchMap":{}},"contracts/deployment/permit/CMTATStandalonePermit.sol":{"l":{"27":228},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATStandalonePermit.sol","s":{"1":228},"b":{},"f":{"1":228},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":33,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":1070}}},"branchMap":{}},"contracts/deployment/permit/CMTATUpgradeablePermit.sol":{"l":{"17":230},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATUpgradeablePermit.sol","s":{"1":230},"b":{},"f":{"1":230},"fnMap":{"1":{"name":"constructor","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":18,"column":4}}}},"statementMap":{"1":{"start":{"line":17,"column":8},"end":{"line":17,"column":29}}},"branchMap":{}},"contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol":{"l":{"31":327},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol","s":{"1":327},"b":{},"f":{"1":327},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1348}}},"branchMap":{}},"contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol":{"l":{"22":352},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol","s":{"1":352},"b":{},"f":{"1":352},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},"contracts/interfaces/engine/IDebtEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDebtEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/engine/IDocumentEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDocumentEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/engine/IRuleEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IRuleEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/engine/ISnapshotEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/ISnapshotEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/IAllowlistModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IAllowlistModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/IDebtEngineModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDebtEngineModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/IDebtModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDebtModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/IDocumentEngineModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDocumentEngineModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/modules/ISnapshotEngineModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/ISnapshotEngineModule.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/ICMTATConstructor.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/ICMTATConstructor.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IERC20Allowance.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC20Allowance.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IERC5679.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC5679.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IERC7802.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC7802.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IGetCCIPAdmin.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IGetCCIPAdmin.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/technical/IMintBurnToken.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IMintBurnToken.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC1404.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1404.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC1643.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1643.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC7551.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC7551.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/draft-IERC7943.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC7943.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/ICMTAT.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/ICMTAT.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/interfaces/tokenization/IERC3643Partial.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/IERC3643Partial.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/library/ERC1404ExtendInterfaceId.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/library/ERC1404ExtendInterfaceId.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/library/RuleEngineInterfaceId.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/library/RuleEngineInterfaceId.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/modules/0_CMTATBaseCommon.sol":{"l":{"51":22,"59":80,"66":68,"72":431,"73":431,"74":248,"75":197,"90":278,"91":118,"108":110,"109":66,"116":8426,"126":6250,"127":6063,"136":1175,"137":951,"146":292,"147":199},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol","s":{"1":22,"2":80,"3":68,"4":431,"5":431,"6":248,"7":197,"8":278,"9":118,"10":110,"11":66,"12":8426,"13":6250,"14":6063,"15":1175,"16":951,"17":292,"18":199},"b":{},"f":{"1":22,"2":80,"3":68,"4":431,"5":278,"6":110,"7":8426,"8":6250,"9":1175,"10":292},"fnMap":{"1":{"name":"decimals","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":52,"column":4}}},"2":{"name":"name","line":58,"loc":{"start":{"line":58,"column":4},"end":{"line":60,"column":4}}},"3":{"name":"symbol","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":67,"column":4}}},"4":{"name":"transfer","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"transferFrom","line":80,"loc":{"start":{"line":80,"column":4},"end":{"line":92,"column":4}}},"6":{"name":"burnAndMint","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":110,"column":4}}},"7":{"name":"_checkTransferred","line":115,"loc":{"start":{"line":115,"column":4},"end":{"line":117,"column":4}}},"8":{"name":"_mintOverride","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":128,"column":4}}},"9":{"name":"_burnOverride","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":138,"column":4}}},"10":{"name":"_minterTransferOverride","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":148,"column":4}}}},"statementMap":{"1":{"start":{"line":51,"column":8},"end":{"line":51,"column":41}},"2":{"start":{"line":59,"column":8},"end":{"line":59,"column":37}},"3":{"start":{"line":66,"column":8},"end":{"line":66,"column":39}},"4":{"start":{"line":72,"column":9},"end":{"line":72,"column":36}},"5":{"start":{"line":73,"column":8},"end":{"line":73,"column":53}},"6":{"start":{"line":74,"column":8},"end":{"line":74,"column":50}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":19}},"8":{"start":{"line":90,"column":8},"end":{"line":90,"column":55}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":60}},"10":{"start":{"line":108,"column":8},"end":{"line":108,"column":53}},"11":{"start":{"line":109,"column":8},"end":{"line":109,"column":51}},"12":{"start":{"line":116,"column":8},"end":{"line":116,"column":79}},"13":{"start":{"line":126,"column":8},"end":{"line":126,"column":66}},"14":{"start":{"line":127,"column":8},"end":{"line":127,"column":60}},"15":{"start":{"line":136,"column":8},"end":{"line":136,"column":67}},"16":{"start":{"line":137,"column":8},"end":{"line":137,"column":60}},"17":{"start":{"line":146,"column":8},"end":{"line":146,"column":55}},"18":{"start":{"line":147,"column":8},"end":{"line":147,"column":71}}},"branchMap":{}},"contracts/modules/0_CMTATBaseCore.sol":{"l":{"58":4,"59":3,"75":247,"91":284,"94":284,"97":284,"100":284,"108":284,"109":284,"118":284,"119":284,"144":2,"152":6,"159":6,"171":12,"179":28,"180":28,"181":18,"182":12,"189":30,"190":24,"205":14,"206":10,"223":10,"224":6,"237":3,"239":2,"240":2,"249":354,"250":346,"255":76,"256":66,"263":18,"264":12},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol","s":{"1":4,"2":247,"3":284,"4":284,"5":284,"6":284,"7":284,"8":284,"9":284,"10":284,"11":2,"12":6,"13":6,"14":12,"15":28,"16":28,"17":18,"18":12,"19":30,"20":24,"21":14,"22":10,"23":10,"24":6,"25":3,"26":2,"27":2,"28":354,"29":346,"30":76,"31":66,"32":18,"33":12},"b":{"1":[247,0],"2":[284,0],"3":[284,0],"4":[284,0],"5":[2,2],"6":[2,2],"7":[3,1],"8":[2,1],"9":[3,1],"10":[284,6],"11":[54,8],"12":[50,4],"13":[20,2],"14":[51,6],"15":[4,4]},"f":{"1":4,"2":247,"3":284,"4":284,"5":284,"6":2,"7":6,"8":6,"9":12,"10":28,"11":30,"12":14,"13":10,"14":3,"15":354,"16":76,"17":18,"18":3,"19":284,"20":54,"21":50,"22":20,"23":51,"24":4},"fnMap":{"1":{"name":"onlyERC20ForcedBurnManager","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"initialize","line":74,"loc":{"start":{"line":71,"column":4},"end":{"line":79,"column":4}}},"3":{"name":"__CMTAT_init","line":88,"loc":{"start":{"line":85,"column":4},"end":{"line":101,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":110,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":120,"column":4}}},"6":{"name":"decimals","line":137,"loc":{"start":{"line":137,"column":4},"end":{"line":145,"column":4}}},"7":{"name":"name","line":151,"loc":{"start":{"line":151,"column":4},"end":{"line":153,"column":4}}},"8":{"name":"symbol","line":158,"loc":{"start":{"line":158,"column":4},"end":{"line":160,"column":4}}},"9":{"name":"supportsInterface","line":170,"loc":{"start":{"line":170,"column":4},"end":{"line":172,"column":4}}},"10":{"name":"transfer","line":178,"loc":{"start":{"line":178,"column":4},"end":{"line":183,"column":4}}},"11":{"name":"approve","line":188,"loc":{"start":{"line":188,"column":4},"end":{"line":191,"column":4}}},"12":{"name":"transferFrom","line":195,"loc":{"start":{"line":195,"column":4},"end":{"line":207,"column":4}}},"13":{"name":"burnAndMint","line":222,"loc":{"start":{"line":222,"column":4},"end":{"line":225,"column":4}}},"14":{"name":"forcedBurn","line":236,"loc":{"start":{"line":232,"column":4},"end":{"line":241,"column":4}}},"15":{"name":"_mintOverride","line":248,"loc":{"start":{"line":248,"column":4},"end":{"line":251,"column":4}}},"16":{"name":"_burnOverride","line":254,"loc":{"start":{"line":254,"column":4},"end":{"line":257,"column":4}}},"17":{"name":"_minterTransferOverride","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":265,"column":4}}},"18":{"name":"_authorizeForcedBurn","line":268,"loc":{"start":{"line":268,"column":4},"end":{"line":268,"column":82}}},"19":{"name":"_authorizeMint","line":270,"loc":{"start":{"line":270,"column":4},"end":{"line":270,"column":95}}},"20":{"name":"_authorizeBurn","line":272,"loc":{"start":{"line":272,"column":4},"end":{"line":272,"column":95}}},"21":{"name":"_authorizePause","line":274,"loc":{"start":{"line":274,"column":4},"end":{"line":274,"column":92}}},"22":{"name":"_authorizeDeactivate","line":275,"loc":{"start":{"line":275,"column":4},"end":{"line":275,"column":104}}},"23":{"name":"_authorizeFreeze","line":277,"loc":{"start":{"line":277,"column":4},"end":{"line":277,"column":101}}},"24":{"name":"_authorizeERC20AttributeManagement","line":279,"loc":{"start":{"line":279,"column":4},"end":{"line":279,"column":122}}}},"statementMap":{"1":{"start":{"line":58,"column":8},"end":{"line":58,"column":29}},"2":{"start":{"line":75,"column":8},"end":{"line":75,"column":2991}},"3":{"start":{"line":91,"column":8},"end":{"line":91,"column":33}},"4":{"start":{"line":94,"column":8},"end":{"line":94,"column":32}},"5":{"start":{"line":97,"column":8},"end":{"line":97,"column":44}},"6":{"start":{"line":100,"column":8},"end":{"line":100,"column":62}},"7":{"start":{"line":108,"column":8},"end":{"line":108,"column":39}},"8":{"start":{"line":109,"column":8},"end":{"line":109,"column":34}},"9":{"start":{"line":118,"column":8},"end":{"line":118,"column":50}},"10":{"start":{"line":119,"column":8},"end":{"line":119,"column":125}},"11":{"start":{"line":144,"column":8},"end":{"line":144,"column":41}},"12":{"start":{"line":152,"column":8},"end":{"line":152,"column":37}},"13":{"start":{"line":159,"column":8},"end":{"line":159,"column":39}},"14":{"start":{"line":171,"column":8},"end":{"line":171,"column":128}},"15":{"start":{"line":179,"column":8},"end":{"line":179,"column":35}},"16":{"start":{"line":180,"column":8},"end":{"line":180,"column":82}},"17":{"start":{"line":181,"column":8},"end":{"line":181,"column":50}},"18":{"start":{"line":182,"column":8},"end":{"line":182,"column":19}},"19":{"start":{"line":189,"column":8},"end":{"line":189,"column":69}},"20":{"start":{"line":190,"column":8},"end":{"line":190,"column":55}},"21":{"start":{"line":205,"column":8},"end":{"line":205,"column":84}},"22":{"start":{"line":206,"column":8},"end":{"line":206,"column":60}},"23":{"start":{"line":223,"column":8},"end":{"line":223,"column":53}},"24":{"start":{"line":224,"column":8},"end":{"line":224,"column":51}},"25":{"start":{"line":237,"column":8},"end":{"line":237,"column":95}},"26":{"start":{"line":239,"column":8},"end":{"line":239,"column":45}},"27":{"start":{"line":240,"column":8},"end":{"line":240,"column":75}},"28":{"start":{"line":249,"column":8},"end":{"line":249,"column":58}},"29":{"start":{"line":250,"column":8},"end":{"line":250,"column":60}},"30":{"start":{"line":255,"column":8},"end":{"line":255,"column":58}},"31":{"start":{"line":256,"column":8},"end":{"line":256,"column":60}},"32":{"start":{"line":263,"column":8},"end":{"line":263,"column":82}},"33":{"start":{"line":264,"column":8},"end":{"line":264,"column":71}}},"branchMap":{"1":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":21},"end":{"line":74,"column":21}},{"start":{"line":74,"column":21},"end":{"line":74,"column":21}}]},"2":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":23},"end":{"line":88,"column":23}},{"start":{"line":88,"column":23},"end":{"line":88,"column":23}}]},"3":{"line":106,"type":"if","locations":[{"start":{"line":106,"column":68},"end":{"line":106,"column":68}},{"start":{"line":106,"column":68},"end":{"line":106,"column":68}}]},"4":{"line":116,"type":"if","locations":[{"start":{"line":116,"column":136},"end":{"line":116,"column":136}},{"start":{"line":116,"column":136},"end":{"line":116,"column":136}}]},"5":{"line":171,"type":"cond-expr","locations":[{"start":{"line":171,"column":15},"end":{"line":171,"column":39}},{"start":{"line":171,"column":44},"end":{"line":171,"column":68}}]},"6":{"line":171,"type":"cond-expr","locations":[{"start":{"line":171,"column":15},"end":{"line":171,"column":68}},{"start":{"line":171,"column":73},"end":{"line":171,"column":127}}]},"7":{"line":236,"type":"if","locations":[{"start":{"line":236,"column":48},"end":{"line":236,"column":48}},{"start":{"line":236,"column":48},"end":{"line":236,"column":48}}]},"8":{"line":237,"type":"if","locations":[{"start":{"line":237,"column":8},"end":{"line":237,"column":8}},{"start":{"line":237,"column":8},"end":{"line":237,"column":8}}]},"9":{"line":268,"type":"if","locations":[{"start":{"line":268,"column":53},"end":{"line":268,"column":53}},{"start":{"line":268,"column":53},"end":{"line":268,"column":53}}]},"10":{"line":270,"type":"if","locations":[{"start":{"line":270,"column":73},"end":{"line":270,"column":73}},{"start":{"line":270,"column":73},"end":{"line":270,"column":73}}]},"11":{"line":272,"type":"if","locations":[{"start":{"line":272,"column":73},"end":{"line":272,"column":73}},{"start":{"line":272,"column":73},"end":{"line":272,"column":73}}]},"12":{"line":274,"type":"if","locations":[{"start":{"line":274,"column":70},"end":{"line":274,"column":70}},{"start":{"line":274,"column":70},"end":{"line":274,"column":70}}]},"13":{"line":275,"type":"if","locations":[{"start":{"line":275,"column":75},"end":{"line":275,"column":75}},{"start":{"line":275,"column":75},"end":{"line":275,"column":75}}]},"14":{"line":277,"type":"if","locations":[{"start":{"line":277,"column":77},"end":{"line":277,"column":77}},{"start":{"line":277,"column":77},"end":{"line":277,"column":77}}]},"15":{"line":279,"type":"if","locations":[{"start":{"line":279,"column":93},"end":{"line":279,"column":93}},{"start":{"line":279,"column":93},"end":{"line":279,"column":93}}]}}},"contracts/modules/0_CMTATBaseGeneric.sol":{"l":{"50":62,"53":62,"56":62,"59":62,"67":62,"68":62,"76":62,"78":62},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseGeneric.sol","s":{"1":62,"2":62,"3":62,"4":62,"5":62,"6":62,"7":62,"8":62},"b":{"1":[62,0],"2":[62,0],"3":[62,0],"4":[11,2],"5":[3,3]},"f":{"1":62,"2":62,"3":62,"4":11,"5":3},"fnMap":{"1":{"name":"__CMTAT_init","line":47,"loc":{"start":{"line":44,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"__CMTAT_openzeppelin_init_unchained","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":69,"column":4}}},"3":{"name":"__CMTAT_modules_init_unchained","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":79,"column":4}}},"4":{"name":"_authorizeDocumentManagement","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":86,"column":118}}},"5":{"name":"_authorizeExtraInfoManagement","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":87,"column":129}}}},"statementMap":{"1":{"start":{"line":50,"column":8},"end":{"line":50,"column":33}},"2":{"start":{"line":53,"column":8},"end":{"line":53,"column":32}},"3":{"start":{"line":56,"column":8},"end":{"line":56,"column":44}},"4":{"start":{"line":59,"column":8},"end":{"line":59,"column":74}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":39}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":34}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":50}},"8":{"start":{"line":78,"column":8},"end":{"line":78,"column":159}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":23},"end":{"line":47,"column":23}},{"start":{"line":47,"column":23},"end":{"line":47,"column":23}}]},"2":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":68},"end":{"line":65,"column":68}},{"start":{"line":65,"column":68},"end":{"line":65,"column":68}}]},"3":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":157},"end":{"line":74,"column":157}},{"start":{"line":74,"column":157},"end":{"line":74,"column":157}}]},"4":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":94},"end":{"line":86,"column":94}},{"start":{"line":86,"column":94},"end":{"line":86,"column":94}}]},"5":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":96},"end":{"line":87,"column":96}},{"start":{"line":87,"column":96},"end":{"line":87,"column":96}}]}}},"contracts/modules/0_CMTATBaseSnapshot.sol":{"l":{"20":2951,"21":2951,"22":176,"23":176,"24":176,"25":176,"26":176,"28":2775},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseSnapshot.sol","s":{"1":2951,"2":2951,"3":176,"4":176,"5":176,"6":176,"7":176,"8":2775},"b":{"1":[176,2775]},"f":{"1":2951},"fnMap":{"1":{"name":"_update","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":30,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":62}},"2":{"start":{"line":21,"column":8},"end":{"line":21,"column":917}},"3":{"start":{"line":22,"column":12},"end":{"line":22,"column":55}},"4":{"start":{"line":23,"column":12},"end":{"line":23,"column":51}},"5":{"start":{"line":24,"column":12},"end":{"line":24,"column":53}},"6":{"start":{"line":25,"column":12},"end":{"line":25,"column":53}},"7":{"start":{"line":26,"column":12},"end":{"line":26,"column":113}},"8":{"start":{"line":28,"column":12},"end":{"line":28,"column":53}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":8},"end":{"line":21,"column":8}},{"start":{"line":21,"column":8},"end":{"line":21,"column":8}}]}}},"contracts/modules/1_CMTATBaseDocument.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/1_CMTATBaseDocument.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/modules/2_CMTATBaseAccessControl.sol":{"l":{"34":5342,"36":5340,"38":5340,"53":42},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAccessControl.sol","s":{"1":5342,"2":5340,"3":5340,"4":42},"b":{"1":[5342,0],"2":[16,2],"3":[2,2],"4":[2,4],"5":[46,44],"6":[5366,66],"7":[685,88],"8":[242,44],"9":[79,79],"10":[1226,63],"11":[220,42]},"f":{"1":5342,"2":42,"3":46,"4":5366,"5":685,"6":242,"7":79,"8":1226,"9":220},"fnMap":{"1":{"name":"__CMTAT_commonModules_init_unchained","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"supportsInterface","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":54,"column":4}}},"3":{"name":"_authorizeERC20AttributeManagement","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":66,"column":122}}},"4":{"name":"_authorizeMint","line":72,"loc":{"start":{"line":72,"column":4},"end":{"line":72,"column":95}}},"5":{"name":"_authorizeBurn","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":78,"column":95}}},"6":{"name":"_authorizeDocumentManagement","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":84,"column":117}}},"7":{"name":"_authorizeExtraInfoManagement","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":90,"column":129}}},"8":{"name":"_authorizeERC20Enforcer","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":96,"column":118}}},"9":{"name":"_authorizeForcedTransfer","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":102,"column":119}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":50}},"2":{"start":{"line":36,"column":8},"end":{"line":36,"column":125}},"3":{"start":{"line":38,"column":8},"end":{"line":38,"column":177}},"4":{"start":{"line":53,"column":8},"end":{"line":53,"column":157}}},"branchMap":{"1":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":228},"end":{"line":32,"column":228}},{"start":{"line":32,"column":228},"end":{"line":32,"column":228}}]},"2":{"line":53,"type":"cond-expr","locations":[{"start":{"line":53,"column":15},"end":{"line":53,"column":39}},{"start":{"line":53,"column":44},"end":{"line":53,"column":68}}]},"3":{"line":53,"type":"cond-expr","locations":[{"start":{"line":53,"column":15},"end":{"line":53,"column":68}},{"start":{"line":53,"column":73},"end":{"line":53,"column":97}}]},"4":{"line":53,"type":"cond-expr","locations":[{"start":{"line":53,"column":15},"end":{"line":53,"column":97}},{"start":{"line":53,"column":102},"end":{"line":53,"column":156}}]},"5":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":93},"end":{"line":66,"column":93}},{"start":{"line":66,"column":93},"end":{"line":66,"column":93}}]},"6":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":73},"end":{"line":72,"column":73}},{"start":{"line":72,"column":73},"end":{"line":72,"column":73}}]},"7":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":73},"end":{"line":78,"column":73}},{"start":{"line":78,"column":73},"end":{"line":78,"column":73}}]},"8":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":93},"end":{"line":84,"column":93}},{"start":{"line":84,"column":93},"end":{"line":84,"column":93}}]},"9":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":96},"end":{"line":90,"column":96}},{"start":{"line":90,"column":96},"end":{"line":90,"column":96}}]},"10":{"line":96,"type":"if","locations":[{"start":{"line":96,"column":89},"end":{"line":96,"column":89}},{"start":{"line":96,"column":89},"end":{"line":96,"column":89}}]},"11":{"line":102,"type":"if","locations":[{"start":{"line":102,"column":90},"end":{"line":102,"column":90}},{"start":{"line":102,"column":90},"end":{"line":102,"column":90}}]}}},"contracts/modules/3_CMTATBaseAllowlist.sol":{"l":{"57":594,"75":594,"78":594,"81":594,"84":594,"92":594,"93":594,"95":594,"102":594,"104":594,"123":68,"124":58,"133":54,"142":35,"152":3,"162":9,"172":9,"183":240,"184":240,"185":60,"187":180,"201":31,"202":31,"203":8,"205":23,"221":132,"224":28,"234":12,"240":740,"246":128,"250":207,"254":34,"262":191,"270":108,"274":992,"275":976,"285":116,"301":7381,"310":7383,"322":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol","s":{"1":594,"2":594,"3":594,"4":594,"5":594,"6":594,"7":594,"8":594,"9":594,"10":594,"11":68,"12":58,"13":54,"14":35,"15":3,"16":9,"17":9,"18":240,"19":240,"20":60,"21":180,"22":31,"23":31,"24":8,"25":23,"26":132,"27":28,"28":12,"29":740,"30":128,"31":207,"32":34,"33":191,"34":108,"35":992,"36":976,"37":116,"38":7381,"39":7383,"40":2},"b":{"1":[594,0],"2":[594,0],"3":[594,0],"4":[594,0],"5":[68,3],"6":[60,180],"7":[8,23],"8":[75,6],"9":[30,3],"10":[75,9],"11":[970,8]},"f":{"1":594,"2":594,"3":594,"4":594,"5":68,"6":54,"7":35,"8":3,"9":9,"10":9,"11":240,"12":31,"13":75,"14":30,"15":75,"16":970,"17":132,"18":28,"19":12,"20":740,"21":128,"22":207,"23":34,"24":191,"25":108,"26":992,"27":116,"28":7381,"29":7383,"30":2},"fnMap":{"1":{"name":"initialize","line":56,"loc":{"start":{"line":52,"column":4},"end":{"line":62,"column":4}}},"2":{"name":"__CMTAT_init","line":72,"loc":{"start":{"line":68,"column":4},"end":{"line":85,"column":4}}},"3":{"name":"__CMTAT_openzeppelin_init_unchained","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":96,"column":4}}},"4":{"name":"__CMTAT_modules_init_unchained","line":101,"loc":{"start":{"line":101,"column":4},"end":{"line":105,"column":4}}},"5":{"name":"approve","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":125,"column":4}}},"6":{"name":"transfer","line":127,"loc":{"start":{"line":127,"column":4},"end":{"line":134,"column":4}}},"7":{"name":"transferFrom","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":143,"column":4}}},"8":{"name":"decimals","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":153,"column":4}}},"9":{"name":"name","line":155,"loc":{"start":{"line":155,"column":4},"end":{"line":163,"column":4}}},"10":{"name":"symbol","line":165,"loc":{"start":{"line":165,"column":4},"end":{"line":173,"column":4}}},"11":{"name":"canTransfer","line":178,"loc":{"start":{"line":178,"column":4},"end":{"line":190,"column":4}}},"12":{"name":"canTransferFrom","line":195,"loc":{"start":{"line":195,"column":3},"end":{"line":207,"column":4}}},"13":{"name":"_authorizePause","line":214,"loc":{"start":{"line":214,"column":4},"end":{"line":214,"column":92}}},"14":{"name":"_authorizeDeactivate","line":215,"loc":{"start":{"line":215,"column":4},"end":{"line":215,"column":104}}},"15":{"name":"_authorizeFreeze","line":217,"loc":{"start":{"line":217,"column":4},"end":{"line":217,"column":101}}},"16":{"name":"_authorizeAllowlistManagement","line":219,"loc":{"start":{"line":219,"column":4},"end":{"line":219,"column":114}}},"17":{"name":"_authorizeERC20Enforcer","line":220,"loc":{"start":{"line":220,"column":4},"end":{"line":222,"column":4}}},"18":{"name":"_authorizeForcedTransfer","line":223,"loc":{"start":{"line":223,"column":4},"end":{"line":225,"column":4}}},"19":{"name":"_canMintBurnByModule","line":231,"loc":{"start":{"line":231,"column":4},"end":{"line":235,"column":4}}},"20":{"name":"_canMintByModuleAndRevert","line":237,"loc":{"start":{"line":237,"column":4},"end":{"line":241,"column":4}}},"21":{"name":"_canBurnByModuleAndRevert","line":243,"loc":{"start":{"line":243,"column":4},"end":{"line":247,"column":4}}},"22":{"name":"_canSend","line":249,"loc":{"start":{"line":249,"column":4},"end":{"line":251,"column":4}}},"23":{"name":"_canReceive","line":253,"loc":{"start":{"line":253,"column":4},"end":{"line":255,"column":4}}},"24":{"name":"_canTransferStandardByModule","line":257,"loc":{"start":{"line":257,"column":4},"end":{"line":263,"column":4}}},"25":{"name":"_canTransferStandardByModuleAndRevert","line":265,"loc":{"start":{"line":265,"column":4},"end":{"line":271,"column":4}}},"26":{"name":"_checkTransferred","line":273,"loc":{"start":{"line":273,"column":4},"end":{"line":276,"column":4}}},"27":{"name":"getFrozenTokens","line":278,"loc":{"start":{"line":278,"column":4},"end":{"line":286,"column":4}}},"28":{"name":"_msgSender","line":295,"loc":{"start":{"line":295,"column":4},"end":{"line":302,"column":4}}},"29":{"name":"_contextSuffixLength","line":307,"loc":{"start":{"line":307,"column":4},"end":{"line":311,"column":4}}},"30":{"name":"_msgData","line":316,"loc":{"start":{"line":316,"column":4},"end":{"line":323,"column":4}}}},"statementMap":{"1":{"start":{"line":57,"column":8},"end":{"line":57,"column":2722}},"2":{"start":{"line":75,"column":8},"end":{"line":75,"column":33}},"3":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}},"4":{"start":{"line":81,"column":8},"end":{"line":81,"column":60}},"5":{"start":{"line":84,"column":8},"end":{"line":84,"column":91}},"6":{"start":{"line":92,"column":8},"end":{"line":92,"column":39}},"7":{"start":{"line":93,"column":8},"end":{"line":93,"column":34}},"8":{"start":{"line":95,"column":8},"end":{"line":95,"column":77}},"9":{"start":{"line":102,"column":9},"end":{"line":102,"column":97}},"10":{"start":{"line":104,"column":8},"end":{"line":104,"column":35}},"11":{"start":{"line":123,"column":8},"end":{"line":123,"column":69}},"12":{"start":{"line":124,"column":8},"end":{"line":124,"column":55}},"13":{"start":{"line":133,"column":8},"end":{"line":133,"column":50}},"14":{"start":{"line":142,"column":8},"end":{"line":142,"column":60}},"15":{"start":{"line":152,"column":8},"end":{"line":152,"column":41}},"16":{"start":{"line":162,"column":8},"end":{"line":162,"column":37}},"17":{"start":{"line":172,"column":8},"end":{"line":172,"column":39}},"18":{"start":{"line":183,"column":8},"end":{"line":183,"column":89}},"19":{"start":{"line":184,"column":8},"end":{"line":184,"column":7166}},"20":{"start":{"line":185,"column":12},"end":{"line":185,"column":24}},"21":{"start":{"line":187,"column":12},"end":{"line":187,"column":68}},"22":{"start":{"line":201,"column":8},"end":{"line":201,"column":89}},"23":{"start":{"line":202,"column":8},"end":{"line":202,"column":7665}},"24":{"start":{"line":203,"column":12},"end":{"line":203,"column":24}},"25":{"start":{"line":205,"column":12},"end":{"line":205,"column":81}},"26":{"start":{"line":221,"column":8},"end":{"line":221,"column":55}},"27":{"start":{"line":224,"column":8},"end":{"line":224,"column":56}},"28":{"start":{"line":234,"column":8},"end":{"line":234,"column":70}},"29":{"start":{"line":240,"column":8},"end":{"line":240,"column":62}},"30":{"start":{"line":246,"column":8},"end":{"line":246,"column":64}},"31":{"start":{"line":250,"column":8},"end":{"line":250,"column":58}},"32":{"start":{"line":254,"column":8},"end":{"line":254,"column":61}},"33":{"start":{"line":262,"column":8},"end":{"line":262,"column":88}},"34":{"start":{"line":270,"column":8},"end":{"line":270,"column":89}},"35":{"start":{"line":274,"column":8},"end":{"line":274,"column":66}},"36":{"start":{"line":275,"column":8},"end":{"line":275,"column":79}},"37":{"start":{"line":285,"column":8},"end":{"line":285,"column":69}},"38":{"start":{"line":301,"column":8},"end":{"line":301,"column":53}},"39":{"start":{"line":310,"column":9},"end":{"line":310,"column":64}},"40":{"start":{"line":322,"column":8},"end":{"line":322,"column":51}}},"branchMap":{"1":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":21},"end":{"line":56,"column":21}},{"start":{"line":56,"column":21},"end":{"line":56,"column":21}}]},"2":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":23},"end":{"line":72,"column":23}},{"start":{"line":72,"column":23},"end":{"line":72,"column":23}}]},"3":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":125},"end":{"line":90,"column":125}},{"start":{"line":90,"column":125},"end":{"line":90,"column":125}}]},"4":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":217},"end":{"line":101,"column":217}},{"start":{"line":101,"column":217},"end":{"line":101,"column":217}}]},"5":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":95},"end":{"line":122,"column":95}},{"start":{"line":122,"column":95},"end":{"line":122,"column":95}}]},"6":{"line":184,"type":"if","locations":[{"start":{"line":184,"column":8},"end":{"line":184,"column":8}},{"start":{"line":184,"column":8},"end":{"line":184,"column":8}}]},"7":{"line":202,"type":"if","locations":[{"start":{"line":202,"column":8},"end":{"line":202,"column":8}},{"start":{"line":202,"column":8},"end":{"line":202,"column":8}}]},"8":{"line":214,"type":"if","locations":[{"start":{"line":214,"column":70},"end":{"line":214,"column":70}},{"start":{"line":214,"column":70},"end":{"line":214,"column":70}}]},"9":{"line":215,"type":"if","locations":[{"start":{"line":215,"column":75},"end":{"line":215,"column":75}},{"start":{"line":215,"column":75},"end":{"line":215,"column":75}}]},"10":{"line":217,"type":"if","locations":[{"start":{"line":217,"column":77},"end":{"line":217,"column":77}},{"start":{"line":217,"column":77},"end":{"line":217,"column":77}}]},"11":{"line":219,"type":"if","locations":[{"start":{"line":219,"column":88},"end":{"line":219,"column":88}},{"start":{"line":219,"column":88},"end":{"line":219,"column":88}}]}}},"contracts/modules/3_CMTATBaseRuleEngine.sol":{"l":{"47":4748,"64":4748,"83":4748,"86":4748,"89":4748,"91":4748,"94":4748,"102":4748,"103":4748,"105":4748,"112":4748,"119":4748,"129":700,"130":662,"140":1579,"141":1579,"142":570,"144":1009,"157":251,"158":251,"159":76,"161":175,"178":7434,"179":7282},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol","s":{"1":4748,"2":4748,"3":4748,"4":4748,"5":4748,"6":4748,"7":4748,"8":4748,"9":4748,"10":4748,"11":4748,"12":4748,"13":700,"14":662,"15":1579,"16":1579,"17":570,"18":1009,"19":251,"20":251,"21":76,"22":175,"23":7434,"24":7282},"b":{"1":[4748,4],"2":[4748,0],"3":[4748,0],"4":[4748,0],"5":[4748,0],"6":[4748,0],"7":[700,19],"8":[570,1009],"9":[76,175],"10":[573,39],"11":[238,19],"12":[551,57],"13":[361,3]},"f":{"1":4748,"2":4748,"3":4748,"4":4748,"5":4748,"6":4748,"7":700,"8":1579,"9":251,"10":573,"11":238,"12":551,"13":361,"14":7434},"fnMap":{"1":{"name":"initialize","line":46,"loc":{"start":{"line":41,"column":4},"end":{"line":53,"column":4}}},"2":{"name":"_initialize","line":63,"loc":{"start":{"line":58,"column":4},"end":{"line":70,"column":4}}},"3":{"name":"__CMTAT_init","line":80,"loc":{"start":{"line":75,"column":4},"end":{"line":95,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":106,"column":4}}},"5":{"name":"__CMTAT_internal_init_unchained","line":111,"loc":{"start":{"line":111,"column":4},"end":{"line":113,"column":4}}},"6":{"name":"__CMTAT_modules_init_unchained","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":120,"column":4}}},"7":{"name":"approve","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":131,"column":4}}},"8":{"name":"canTransfer","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":146,"column":4}}},"9":{"name":"canTransferFrom","line":151,"loc":{"start":{"line":151,"column":3},"end":{"line":163,"column":4}}},"10":{"name":"_authorizePause","line":169,"loc":{"start":{"line":169,"column":4},"end":{"line":169,"column":92}}},"11":{"name":"_authorizeDeactivate","line":170,"loc":{"start":{"line":170,"column":4},"end":{"line":170,"column":104}}},"12":{"name":"_authorizeFreeze","line":172,"loc":{"start":{"line":172,"column":4},"end":{"line":172,"column":101}}},"13":{"name":"_authorizeRuleEngineManagement","line":174,"loc":{"start":{"line":174,"column":4},"end":{"line":174,"column":129}}},"14":{"name":"_checkTransferred","line":177,"loc":{"start":{"line":177,"column":4},"end":{"line":180,"column":4}}}},"statementMap":{"1":{"start":{"line":47,"column":8},"end":{"line":47,"column":2158}},"2":{"start":{"line":64,"column":8},"end":{"line":64,"column":2665}},"3":{"start":{"line":83,"column":8},"end":{"line":83,"column":33}},"4":{"start":{"line":86,"column":8},"end":{"line":86,"column":32}},"5":{"start":{"line":89,"column":8},"end":{"line":89,"column":60}},"6":{"start":{"line":91,"column":7},"end":{"line":91,"column":47}},"7":{"start":{"line":94,"column":8},"end":{"line":94,"column":91}},"8":{"start":{"line":102,"column":8},"end":{"line":102,"column":39}},"9":{"start":{"line":103,"column":8},"end":{"line":103,"column":34}},"10":{"start":{"line":105,"column":8},"end":{"line":105,"column":77}},"11":{"start":{"line":112,"column":8},"end":{"line":112,"column":65}},"12":{"start":{"line":119,"column":8},"end":{"line":119,"column":96}},"13":{"start":{"line":129,"column":8},"end":{"line":129,"column":69}},"14":{"start":{"line":130,"column":8},"end":{"line":130,"column":55}},"15":{"start":{"line":140,"column":8},"end":{"line":140,"column":90}},"16":{"start":{"line":141,"column":8},"end":{"line":141,"column":5761}},"17":{"start":{"line":142,"column":12},"end":{"line":142,"column":24}},"18":{"start":{"line":144,"column":12},"end":{"line":144,"column":74}},"19":{"start":{"line":157,"column":8},"end":{"line":157,"column":89}},"20":{"start":{"line":158,"column":8},"end":{"line":158,"column":6269}},"21":{"start":{"line":159,"column":12},"end":{"line":159,"column":24}},"22":{"start":{"line":161,"column":12},"end":{"line":161,"column":87}},"23":{"start":{"line":178,"column":8},"end":{"line":178,"column":66}},"24":{"start":{"line":179,"column":8},"end":{"line":179,"column":72}}},"branchMap":{"1":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":21},"end":{"line":46,"column":21}},{"start":{"line":46,"column":21},"end":{"line":46,"column":21}}]},"2":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":23},"end":{"line":63,"column":23}},{"start":{"line":63,"column":23},"end":{"line":63,"column":23}}]},"3":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":23},"end":{"line":80,"column":23}},{"start":{"line":80,"column":23},"end":{"line":80,"column":23}}]},"4":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":125},"end":{"line":100,"column":125}},{"start":{"line":100,"column":125},"end":{"line":100,"column":125}}]},"5":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":104},"end":{"line":111,"column":104}},{"start":{"line":111,"column":104},"end":{"line":111,"column":104}}]},"6":{"line":118,"type":"if","locations":[{"start":{"line":118,"column":216},"end":{"line":118,"column":216}},{"start":{"line":118,"column":216},"end":{"line":118,"column":216}}]},"7":{"line":128,"type":"if","locations":[{"start":{"line":128,"column":95},"end":{"line":128,"column":95}},{"start":{"line":128,"column":95},"end":{"line":128,"column":95}}]},"8":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":8}},{"start":{"line":141,"column":8},"end":{"line":141,"column":8}}]},"9":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":8},"end":{"line":158,"column":8}},{"start":{"line":158,"column":8},"end":{"line":158,"column":8}}]},"10":{"line":169,"type":"if","locations":[{"start":{"line":169,"column":70},"end":{"line":169,"column":70}},{"start":{"line":169,"column":70},"end":{"line":169,"column":70}}]},"11":{"line":170,"type":"if","locations":[{"start":{"line":170,"column":75},"end":{"line":170,"column":75}},{"start":{"line":170,"column":75},"end":{"line":170,"column":75}}]},"12":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":77},"end":{"line":172,"column":77}},{"start":{"line":172,"column":77},"end":{"line":172,"column":77}}]},"13":{"line":174,"type":"if","locations":[{"start":{"line":174,"column":100},"end":{"line":174,"column":100}},{"start":{"line":174,"column":100},"end":{"line":174,"column":100}}]}}},"contracts/modules/4_CMTATBaseDebt.sol":{"l":{"19":92,"25":82,"31":44,"37":4,"43":12,"49":12,"55":1250},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseDebt.sol","s":{"1":92,"2":82,"3":44,"4":4,"5":12,"6":12,"7":1250},"b":{"1":[12,12],"2":[96,3]},"f":{"1":92,"2":82,"3":44,"4":4,"5":12,"6":12,"7":1250,"8":12,"9":96},"fnMap":{"1":{"name":"approve","line":16,"loc":{"start":{"line":16,"column":3},"end":{"line":20,"column":3}}},"2":{"name":"transfer","line":22,"loc":{"start":{"line":22,"column":3},"end":{"line":26,"column":3}}},"3":{"name":"transferFrom","line":28,"loc":{"start":{"line":28,"column":3},"end":{"line":32,"column":3}}},"4":{"name":"decimals","line":34,"loc":{"start":{"line":34,"column":3},"end":{"line":38,"column":3}}},"5":{"name":"name","line":40,"loc":{"start":{"line":40,"column":3},"end":{"line":44,"column":3}}},"6":{"name":"symbol","line":46,"loc":{"start":{"line":46,"column":3},"end":{"line":50,"column":3}}},"7":{"name":"_update","line":52,"loc":{"start":{"line":52,"column":3},"end":{"line":56,"column":3}}},"8":{"name":"_authorizeDebtManagement","line":58,"loc":{"start":{"line":58,"column":3},"end":{"line":58,"column":97}}},"9":{"name":"_authorizeSnapshots","line":60,"loc":{"start":{"line":60,"column":3},"end":{"line":60,"column":110}}}},"statementMap":{"1":{"start":{"line":19,"column":6},"end":{"line":19,"column":56}},"2":{"start":{"line":25,"column":6},"end":{"line":25,"column":48}},"3":{"start":{"line":31,"column":6},"end":{"line":31,"column":58}},"4":{"start":{"line":37,"column":6},"end":{"line":37,"column":39}},"5":{"start":{"line":43,"column":6},"end":{"line":43,"column":35}},"6":{"start":{"line":49,"column":6},"end":{"line":49,"column":37}},"7":{"start":{"line":55,"column":6},"end":{"line":55,"column":48}}},"branchMap":{"1":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":77},"end":{"line":58,"column":77}},{"start":{"line":58,"column":77},"end":{"line":58,"column":77}}]},"2":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":82},"end":{"line":60,"column":82}},{"start":{"line":60,"column":82},"end":{"line":60,"column":82}}]}}},"contracts/modules/4_CMTATBaseERC1404.sol":{"l":{"34":159,"35":66,"37":93,"50":1255,"62":207,"73":377,"74":377,"75":198,"76":198,"77":22,"79":176,"80":176,"81":132,"84":223},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC1404.sol","s":{"1":159,"2":66,"3":93,"4":1255,"5":207,"6":377,"7":377,"8":198,"9":198,"10":22,"11":176,"12":176,"13":132,"14":223},"b":{"1":[66,93],"2":[198,179],"3":[22,176],"4":[132,44]},"f":{"1":159,"2":1255,"3":207,"4":377},"fnMap":{"1":{"name":"messageForTransferRestriction","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"canTransfer","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"canTransferFrom","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"_detectTransferRestriction","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":85,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1333}},"2":{"start":{"line":35,"column":12},"end":{"line":35,"column":74}},"3":{"start":{"line":37,"column":12},"end":{"line":37,"column":89}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":63}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":76}},"6":{"start":{"line":73,"column":8},"end":{"line":73,"column":80}},"7":{"start":{"line":74,"column":8},"end":{"line":74,"column":2816}},"8":{"start":{"line":75,"column":12},"end":{"line":75,"column":62}},"9":{"start":{"line":76,"column":12},"end":{"line":76,"column":2924}},"10":{"start":{"line":77,"column":16},"end":{"line":77,"column":114}},"11":{"start":{"line":79,"column":12},"end":{"line":79,"column":63}},"12":{"start":{"line":80,"column":12},"end":{"line":80,"column":3167}},"13":{"start":{"line":81,"column":16},"end":{"line":81,"column":114}},"14":{"start":{"line":84,"column":8},"end":{"line":84,"column":82}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":34,"column":8}},{"start":{"line":34,"column":8},"end":{"line":34,"column":8}}]},"2":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":8},"end":{"line":74,"column":8}},{"start":{"line":74,"column":8},"end":{"line":74,"column":8}}]},"3":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":12},"end":{"line":76,"column":12}},{"start":{"line":76,"column":12},"end":{"line":76,"column":12}}]},"4":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":12},"end":{"line":80,"column":12}},{"start":{"line":80,"column":12},"end":{"line":80,"column":12}}]}}},"contracts/modules/5_CMTATBaseERC20CrossChain.sol":{"l":{"24":627,"27":295,"42":199,"57":15,"65":59,"72":47,"76":66,"88":4518,"96":869,"104":207,"125":218},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol","s":{"1":627,"2":295,"3":199,"4":15,"5":59,"6":47,"7":66,"8":4518,"9":869,"10":207,"11":218},"b":{"1":[24,24],"2":[36,12],"3":[218,48],"4":[84,12],"5":[60,24],"6":[72,24],"7":[48,24]},"f":{"1":627,"2":295,"3":199,"4":15,"5":59,"6":47,"7":66,"8":4518,"9":869,"10":207,"11":36,"12":218,"13":60,"14":48},"fnMap":{"1":{"name":"approve","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":25,"column":4}}},"2":{"name":"transfer","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":28,"column":4}}},"3":{"name":"transferFrom","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":43,"column":4}}},"4":{"name":"decimals","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":58,"column":4}}},"5":{"name":"name","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":66,"column":4}}},"6":{"name":"symbol","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":73,"column":4}}},"7":{"name":"supportsInterface","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":77,"column":4}}},"8":{"name":"_mintOverride","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":89,"column":4}}},"9":{"name":"_burnOverride","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":97,"column":4}}},"10":{"name":"_minterTransferOverride","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":105,"column":4}}},"11":{"name":"_authorizeCCIPSetAdmin","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":113,"column":106}}},"12":{"name":"_checkTokenBridge","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":126,"column":4}}},"13":{"name":"_authorizeBurnFrom","line":133,"loc":{"start":{"line":133,"column":4},"end":{"line":133,"column":124}}},"14":{"name":"_authorizeSelfBurn","line":140,"loc":{"start":{"line":140,"column":4},"end":{"line":140,"column":124}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":58}},"2":{"start":{"line":27,"column":9},"end":{"line":27,"column":51}},"3":{"start":{"line":42,"column":8},"end":{"line":42,"column":60}},"4":{"start":{"line":57,"column":8},"end":{"line":57,"column":41}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":37}},"6":{"start":{"line":72,"column":8},"end":{"line":72,"column":39}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":127}},"8":{"start":{"line":88,"column":8},"end":{"line":88,"column":52}},"9":{"start":{"line":96,"column":8},"end":{"line":96,"column":52}},"10":{"start":{"line":104,"column":8},"end":{"line":104,"column":63}},"11":{"start":{"line":125,"column":8},"end":{"line":125,"column":68}}},"branchMap":{"1":{"line":76,"type":"cond-expr","locations":[{"start":{"line":76,"column":16},"end":{"line":76,"column":68}},{"start":{"line":76,"column":72},"end":{"line":76,"column":126}}]},"2":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":76},"end":{"line":113,"column":76}},{"start":{"line":113,"column":76},"end":{"line":113,"column":76}}]},"3":{"line":124,"type":"if","locations":[{"start":{"line":124,"column":96},"end":{"line":124,"column":96}},{"start":{"line":124,"column":96},"end":{"line":124,"column":96}}]},"4":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":83},"end":{"line":133,"column":83}},{"start":{"line":133,"column":83},"end":{"line":133,"column":83}}]},"5":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":110},"end":{"line":133,"column":110}},{"start":{"line":133,"column":110},"end":{"line":133,"column":110}}]},"6":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":83},"end":{"line":140,"column":83}},{"start":{"line":140,"column":83},"end":{"line":140,"column":83}}]},"7":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":110},"end":{"line":140,"column":110}},{"start":{"line":140,"column":110},"end":{"line":140,"column":110}}]}}},"contracts/modules/6_CMTATBaseDebtEngine.sol":{"l":{"25":923,"31":60,"37":33,"43":69,"49":3,"55":9,"61":9},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseDebtEngine.sol","s":{"1":923,"2":60,"3":33,"4":69,"5":3,"6":9,"7":9},"b":{"1":[15,3],"2":[49,2]},"f":{"1":923,"2":60,"3":33,"4":69,"5":3,"6":9,"7":9,"8":15,"9":49},"fnMap":{"1":{"name":"_update","line":22,"loc":{"start":{"line":22,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"transfer","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":32,"column":4}}},"3":{"name":"transferFrom","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":38,"column":4}}},"4":{"name":"approve","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":44,"column":4}}},"5":{"name":"decimals","line":46,"loc":{"start":{"line":46,"column":4},"end":{"line":50,"column":4}}},"6":{"name":"name","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":56,"column":4}}},"7":{"name":"symbol","line":58,"loc":{"start":{"line":58,"column":4},"end":{"line":62,"column":4}}},"8":{"name":"_authorizeDebtEngineManagement","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":68,"column":118}}},"9":{"name":"_authorizeSnapshots","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":70,"column":111}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":50}},"2":{"start":{"line":31,"column":8},"end":{"line":31,"column":59}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":69}},"4":{"start":{"line":43,"column":8},"end":{"line":43,"column":63}},"5":{"start":{"line":49,"column":8},"end":{"line":49,"column":50}},"6":{"start":{"line":55,"column":8},"end":{"line":55,"column":46}},"7":{"start":{"line":61,"column":8},"end":{"line":61,"column":48}}},"branchMap":{"1":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":90},"end":{"line":68,"column":90}},{"start":{"line":68,"column":90},"end":{"line":68,"column":90}}]},"2":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":83},"end":{"line":70,"column":83}},{"start":{"line":70,"column":83},"end":{"line":70,"column":83}}]}}},"contracts/modules/6_CMTATBaseERC2612.sol":{"l":{"27":460,"28":460,"29":460,"30":460,"49":10,"50":4,"61":92,"71":31,"87":26,"101":2,"114":18,"127":8},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol","s":{"1":460,"2":460,"3":460,"4":460,"5":10,"6":4,"7":92,"8":31,"9":26,"10":2,"11":18,"12":8},"b":{"1":[460,0]},"f":{"1":460,"2":10,"3":92,"4":31,"5":26,"6":2,"7":18,"8":8},"fnMap":{"1":{"name":"__CMTAT_openzeppelin_init_unchained","line":26,"loc":{"start":{"line":24,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"permit","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"approve","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":62,"column":4}}},"4":{"name":"transfer","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"transferFrom","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":88,"column":4}}},"6":{"name":"decimals","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":102,"column":4}}},"7":{"name":"name","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":115,"column":4}}},"8":{"name":"symbol","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":128,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":80}},"2":{"start":{"line":28,"column":8},"end":{"line":28,"column":58}},"3":{"start":{"line":29,"column":8},"end":{"line":29,"column":58}},"4":{"start":{"line":30,"column":8},"end":{"line":30,"column":35}},"5":{"start":{"line":49,"column":8},"end":{"line":49,"column":62}},"6":{"start":{"line":50,"column":8},"end":{"line":50,"column":78}},"7":{"start":{"line":61,"column":8},"end":{"line":61,"column":63}},"8":{"start":{"line":71,"column":8},"end":{"line":71,"column":59}},"9":{"start":{"line":87,"column":8},"end":{"line":87,"column":79}},"10":{"start":{"line":101,"column":8},"end":{"line":101,"column":50}},"11":{"start":{"line":114,"column":8},"end":{"line":114,"column":46}},"12":{"start":{"line":127,"column":8},"end":{"line":127,"column":48}}},"branchMap":{"1":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":32},"end":{"line":26,"column":32}},{"start":{"line":26,"column":32},"end":{"line":26,"column":32}}]}}},"contracts/modules/6_CMTATBaseERC2771.sol":{"l":{"26":18475,"35":18481,"47":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2771.sol","s":{"1":18475,"2":18481,"3":6},"b":{},"f":{"1":18475,"2":18481,"3":6},"fnMap":{"1":{"name":"_msgSender","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"_contextSuffixLength","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":36,"column":4}}},"3":{"name":"_msgData","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":48,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":53}},"2":{"start":{"line":35,"column":9},"end":{"line":35,"column":64}},"3":{"start":{"line":47,"column":8},"end":{"line":47,"column":51}}},"branchMap":{}},"contracts/modules/7_CMTATBaseERC2771Snapshot.sol":{"l":{"24":778,"30":58,"36":26,"42":92,"48":2,"54":6,"60":6,"70":3814,"76":2,"82":3816},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC2771Snapshot.sol","s":{"1":778,"2":58,"3":26,"4":92,"5":2,"6":6,"7":6,"8":3814,"9":2,"10":3816},"b":{"1":[189,4]},"f":{"1":778,"2":58,"3":26,"4":92,"5":2,"6":6,"7":6,"8":3814,"9":2,"10":3816,"11":189},"fnMap":{"1":{"name":"_update","line":21,"loc":{"start":{"line":21,"column":4},"end":{"line":25,"column":4}}},"2":{"name":"transfer","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":31,"column":4}}},"3":{"name":"transferFrom","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":37,"column":4}}},"4":{"name":"approve","line":39,"loc":{"start":{"line":39,"column":4},"end":{"line":43,"column":4}}},"5":{"name":"decimals","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":49,"column":4}}},"6":{"name":"name","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":55,"column":4}}},"7":{"name":"symbol","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":61,"column":4}}},"8":{"name":"_msgSender","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":71,"column":4}}},"9":{"name":"_msgData","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":77,"column":4}}},"10":{"name":"_contextSuffixLength","line":79,"loc":{"start":{"line":79,"column":4},"end":{"line":83,"column":4}}},"11":{"name":"_authorizeSnapshots","line":89,"loc":{"start":{"line":89,"column":4},"end":{"line":89,"column":111}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":50}},"2":{"start":{"line":30,"column":8},"end":{"line":30,"column":59}},"3":{"start":{"line":36,"column":8},"end":{"line":36,"column":69}},"4":{"start":{"line":42,"column":8},"end":{"line":42,"column":63}},"5":{"start":{"line":48,"column":8},"end":{"line":48,"column":50}},"6":{"start":{"line":54,"column":8},"end":{"line":54,"column":46}},"7":{"start":{"line":60,"column":8},"end":{"line":60,"column":48}},"8":{"start":{"line":70,"column":8},"end":{"line":70,"column":44}},"9":{"start":{"line":76,"column":8},"end":{"line":76,"column":42}},"10":{"start":{"line":82,"column":8},"end":{"line":82,"column":54}}},"branchMap":{"1":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":83},"end":{"line":89,"column":83}},{"start":{"line":89,"column":83},"end":{"line":89,"column":83}}]}}},"contracts/modules/7_CMTATBaseERC7551Enforcement.sol":{"l":{"22":390,"26":78,"37":11591,"45":4,"53":11595,"64":114,"72":90,"80":282,"88":20,"96":18,"104":6,"112":336},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC7551Enforcement.sol","s":{"1":390,"2":78,"3":11591,"4":4,"5":11595,"6":114,"7":90,"8":282,"9":20,"10":18,"11":6,"12":336},"b":{},"f":{"1":390,"2":78,"3":11591,"4":4,"5":11595,"6":114,"7":90,"8":282,"9":20,"10":18,"11":6,"12":336},"fnMap":{"1":{"name":"_authorizeERC20Enforcer","line":21,"loc":{"start":{"line":21,"column":4},"end":{"line":23,"column":4}}},"2":{"name":"_authorizeForcedTransfer","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":27,"column":4}}},"3":{"name":"_msgSender","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":38,"column":4}}},"4":{"name":"_msgData","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":46,"column":4}}},"5":{"name":"_contextSuffixLength","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":54,"column":4}}},"6":{"name":"transfer","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":65,"column":4}}},"7":{"name":"transferFrom","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":73,"column":4}}},"8":{"name":"approve","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":81,"column":4}}},"9":{"name":"name","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":89,"column":4}}},"10":{"name":"symbol","line":91,"loc":{"start":{"line":91,"column":4},"end":{"line":97,"column":4}}},"11":{"name":"decimals","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":105,"column":4}}},"12":{"name":"getFrozenTokens","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":113,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":55}},"2":{"start":{"line":26,"column":8},"end":{"line":26,"column":56}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":44}},"4":{"start":{"line":45,"column":8},"end":{"line":45,"column":42}},"5":{"start":{"line":53,"column":8},"end":{"line":53,"column":54}},"6":{"start":{"line":64,"column":8},"end":{"line":64,"column":59}},"7":{"start":{"line":72,"column":8},"end":{"line":72,"column":69}},"8":{"start":{"line":80,"column":8},"end":{"line":80,"column":63}},"9":{"start":{"line":88,"column":8},"end":{"line":88,"column":46}},"10":{"start":{"line":96,"column":8},"end":{"line":96,"column":48}},"11":{"start":{"line":104,"column":8},"end":{"line":104,"column":50}},"12":{"start":{"line":112,"column":8},"end":{"line":112,"column":69}}},"branchMap":{}},"contracts/modules/8_CMTATBaseERC1363.sol":{"l":{"26":499,"27":499,"39":93,"46":39,"62":28,"70":18,"84":2,"92":6,"99":6,"119":3508,"128":3510,"140":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol","s":{"1":499,"2":499,"3":93,"4":39,"5":28,"6":18,"7":2,"8":6,"9":6,"10":3508,"11":3510,"12":2},"b":{"1":[499,0],"2":[6,8]},"f":{"1":499,"2":93,"3":39,"4":28,"5":18,"6":2,"7":6,"8":6,"9":3508,"10":3510,"11":2},"fnMap":{"1":{"name":"__CMTAT_openzeppelin_init_unchained","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"approve","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":40,"column":4}}},"3":{"name":"transfer","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":47,"column":4}}},"4":{"name":"transferFrom","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":63,"column":4}}},"5":{"name":"supportsInterface","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":71,"column":4}}},"6":{"name":"decimals","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":85,"column":4}}},"7":{"name":"name","line":91,"loc":{"start":{"line":91,"column":4},"end":{"line":93,"column":4}}},"8":{"name":"symbol","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":100,"column":4}}},"9":{"name":"_msgSender","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":120,"column":4}}},"10":{"name":"_contextSuffixLength","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":129,"column":4}}},"11":{"name":"_msgData","line":134,"loc":{"start":{"line":134,"column":4},"end":{"line":141,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":80}},"2":{"start":{"line":27,"column":8},"end":{"line":27,"column":33}},"3":{"start":{"line":39,"column":8},"end":{"line":39,"column":66}},"4":{"start":{"line":46,"column":8},"end":{"line":46,"column":62}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":82}},"6":{"start":{"line":70,"column":8},"end":{"line":70,"column":123}},"7":{"start":{"line":84,"column":8},"end":{"line":84,"column":53}},"8":{"start":{"line":92,"column":8},"end":{"line":92,"column":49}},"9":{"start":{"line":99,"column":8},"end":{"line":99,"column":51}},"10":{"start":{"line":119,"column":8},"end":{"line":119,"column":55}},"11":{"start":{"line":128,"column":9},"end":{"line":128,"column":66}},"12":{"start":{"line":140,"column":8},"end":{"line":140,"column":53}}},"branchMap":{"1":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":134},"end":{"line":25,"column":134}},{"start":{"line":25,"column":134},"end":{"line":25,"column":134}}]},"2":{"line":70,"type":"cond-expr","locations":[{"start":{"line":70,"column":15},"end":{"line":70,"column":63}},{"start":{"line":70,"column":68},"end":{"line":70,"column":122}}]}}},"contracts/modules/8_CMTATBaseERC7551.sol":{"l":{"20":20},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC7551.sol","s":{"1":20},"b":{},"f":{"1":20},"fnMap":{"1":{"name":"_authorizeExtraInfoManagement","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":21,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":61}}},"branchMap":{}},"contracts/modules/internal/AllowlistModuleInternal.sol":{"l":{"30":594,"31":594,"40":296,"41":296,"45":2396,"49":532,"50":528,"51":528,"52":2100,"60":142,"61":142,"69":1438,"70":1438,"77":1424,"78":1424,"85":4422},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol","s":{"1":594,"2":296,"3":296,"4":532,"5":528,"6":528,"7":2100,"8":142,"9":1438,"10":1438,"11":1424,"12":1424},"b":{"1":[594,0]},"f":{"1":594,"2":296,"3":2396,"4":532,"5":142,"6":1438,"7":1424,"8":4422},"fnMap":{"1":{"name":"__Allowlist_init_unchained","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":33,"column":4}}},"2":{"name":"_addToAllowlist","line":39,"loc":{"start":{"line":39,"column":4},"end":{"line":42,"column":4}}},"3":{"name":"_addToAllowlist","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":4}}},"4":{"name":"_addToAllowlist","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":54,"column":4}}},"5":{"name":"_enableAllowlist","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":62,"column":4}}},"6":{"name":"_isAllowlisted","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":71,"column":4}}},"7":{"name":"_isAllowlistEnabled","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"8":{"name":"_getAllowlistModuleInternalStorage","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":88,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":9},"end":{"line":30,"column":88}},"2":{"start":{"line":40,"column":8},"end":{"line":40,"column":87}},"3":{"start":{"line":41,"column":8},"end":{"line":41,"column":48}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":61}},"5":{"start":{"line":50,"column":8},"end":{"line":50,"column":87}},"6":{"start":{"line":51,"column":8},"end":{"line":51,"column":2408}},"7":{"start":{"line":52,"column":12},"end":{"line":52,"column":59}},"8":{"start":{"line":60,"column":8},"end":{"line":60,"column":87}},"9":{"start":{"line":69,"column":8},"end":{"line":69,"column":87}},"10":{"start":{"line":70,"column":8},"end":{"line":70,"column":36}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":87}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":33}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":51},"end":{"line":29,"column":51}},{"start":{"line":29,"column":51},"end":{"line":29,"column":51}}]}}},"contracts/modules/internal/common/EnforcementModuleLibrary.sol":{"l":{"16":657,"19":630},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/common/EnforcementModuleLibrary.sol","s":{"1":657,"2":630},"b":{"1":[630,27],"2":[603,27]},"f":{"1":657},"fnMap":{"1":{"name":"_checkInput","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":20,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":70}},"2":{"start":{"line":19,"column":8},"end":{"line":19,"column":98}}},"branchMap":{"1":{"line":16,"type":"if","locations":[{"start":{"line":16,"column":8},"end":{"line":16,"column":8}},{"start":{"line":16,"column":8},"end":{"line":16,"column":8}}]},"2":{"line":19,"type":"if","locations":[{"start":{"line":19,"column":8},"end":{"line":19,"column":8}},{"start":{"line":19,"column":8},"end":{"line":19,"column":8}}]}}},"contracts/modules/internal/EnforcementModuleInternal.sol":{"l":{"34":571,"35":571,"39":721,"40":75,"42":646,"46":125,"47":75,"48":75,"49":150,"58":16612,"59":16612,"64":17258},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInternal.sol","s":{"1":571,"2":571,"3":721,"4":125,"5":75,"6":75,"7":150,"8":16612,"9":16612},"b":{"1":[75,646]},"f":{"1":571,"2":721,"3":125,"4":16612,"5":17258},"fnMap":{"1":{"name":"_addAddressToTheList","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":36,"column":4}}},"2":{"name":"_addAddressToTheList","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":43,"column":4}}},"3":{"name":"_addAddressesToTheList","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":51,"column":4}}},"4":{"name":"_addressIsListed","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":60,"column":4}}},"5":{"name":"_getEnforcementModuleInternalStorage","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":67,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":91}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":53}},"3":{"start":{"line":39,"column":8},"end":{"line":39,"column":1738}},"4":{"start":{"line":46,"column":8},"end":{"line":46,"column":61}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":91}},"6":{"start":{"line":48,"column":8},"end":{"line":48,"column":2170}},"7":{"start":{"line":49,"column":12},"end":{"line":49,"column":64}},"8":{"start":{"line":58,"column":8},"end":{"line":58,"column":91}},"9":{"start":{"line":59,"column":8},"end":{"line":59,"column":31}}},"branchMap":{"1":{"line":39,"type":"if","locations":[{"start":{"line":39,"column":8},"end":{"line":39,"column":8}},{"start":{"line":39,"column":8},"end":{"line":39,"column":8}}]}}},"contracts/modules/internal/ERC20BurnModuleInternal.sol":{"l":{"30":330,"33":306,"34":258,"35":638,"47":1017},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol","s":{"1":330,"2":306,"3":258,"4":638,"5":1017},"b":{"1":[306,24],"2":[258,48]},"f":{"1":330,"2":1017},"fnMap":{"1":{"name":"_batchBurn","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":37,"column":4}}},"2":{"name":"_burnOverride","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":48,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":70}},"2":{"start":{"line":33,"column":8},"end":{"line":33,"column":97}},"3":{"start":{"line":34,"column":8},"end":{"line":34,"column":1431}},"4":{"start":{"line":35,"column":13},"end":{"line":35,"column":49}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":45}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":8},"end":{"line":30,"column":8}},{"start":{"line":30,"column":8},"end":{"line":30,"column":8}}]},"2":{"line":33,"type":"if","locations":[{"start":{"line":33,"column":8},"end":{"line":33,"column":8}},{"start":{"line":33,"column":8},"end":{"line":33,"column":8}}]}}},"contracts/modules/internal/ERC20EnforcementModuleInternal.sol":{"l":{"34":378,"35":378,"37":378,"38":84,"39":84,"40":84,"43":273,"44":273,"45":273,"47":21,"49":357,"53":622,"54":29,"56":593,"58":593,"59":593,"61":593,"63":572,"64":572,"68":226,"69":29,"71":197,"72":197,"74":176,"75":176,"76":176,"83":220,"84":220,"85":21,"87":199,"88":199,"90":199,"92":199,"93":178,"95":199,"96":63,"97":63,"98":63,"99":63,"104":220,"105":199,"106":42,"110":157,"111":157,"112":42,"113":21,"114":21,"117":21,"118":21,"123":157,"125":199,"129":845,"133":323,"138":8426,"139":8426,"140":8426,"141":8426,"148":10527,"149":10527,"150":1533,"152":1533,"153":105,"154":42,"156":63,"158":1428,"159":1428,"160":819,"165":9603,"169":12921,"170":12921,"174":432,"175":432,"176":432,"178":432,"179":32,"181":400,"186":14720},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol","s":{"1":378,"2":378,"3":378,"4":84,"5":84,"6":294,"7":273,"8":273,"9":357,"10":622,"11":593,"12":593,"13":593,"14":593,"15":572,"16":226,"17":197,"18":197,"19":176,"20":176,"21":220,"22":220,"23":199,"24":199,"25":199,"26":199,"27":199,"28":63,"29":63,"30":220,"31":199,"32":42,"33":157,"34":157,"35":42,"36":21,"37":21,"38":157,"39":199,"40":845,"41":323,"42":8426,"43":8426,"44":8426,"45":10527,"46":10527,"47":1533,"48":1533,"49":105,"50":42,"51":63,"52":1428,"53":819,"54":9603,"55":12921,"56":12921,"57":432,"58":432,"59":432,"60":432,"61":32,"62":400},"b":{"1":[84,294],"2":[273,21],"3":[29,593],"4":[572,21],"5":[29,197],"6":[176,21],"7":[21,199],"8":[178,21],"9":[63,136],"10":[42,157],"11":[42,115],"12":[21,21],"13":[8258,168],"14":[1533,8994],"15":[105,1428],"16":[42,63],"17":[819,609],"18":[32,400]},"f":{"1":378,"2":622,"3":226,"4":220,"5":220,"6":845,"7":323,"8":8426,"9":10527,"10":12921,"11":432,"12":14720},"fnMap":{"1":{"name":"_setFrozenTokens","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":50,"column":4}}},"2":{"name":"_freezePartialTokens","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":65,"column":4}}},"3":{"name":"_unfreezePartialTokens","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":77,"column":4}}},"4":{"name":"_unfreezeTokens","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":101,"column":4}}},"5":{"name":"_forcedTransfer","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":126,"column":4}}},"6":{"name":"_freezeTokensEmitEvents","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":130,"column":4}}},"7":{"name":"_unfreezeTokensEmitEvents","line":132,"loc":{"start":{"line":132,"column":4},"end":{"line":134,"column":4}}},"8":{"name":"_checkActiveBalanceAndRevert","line":137,"loc":{"start":{"line":137,"column":4},"end":{"line":142,"column":4}}},"9":{"name":"_checkActiveBalance","line":147,"loc":{"start":{"line":147,"column":4},"end":{"line":166,"column":4}}},"10":{"name":"_getFrozenTokens","line":168,"loc":{"start":{"line":168,"column":4},"end":{"line":171,"column":5}}},"11":{"name":"_getActiveBalanceOf","line":173,"loc":{"start":{"line":173,"column":4},"end":{"line":182,"column":5}}},"12":{"name":"_getEnforcementModuleStorage","line":185,"loc":{"start":{"line":185,"column":4},"end":{"line":189,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":80}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":60}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":1822}},"4":{"start":{"line":38,"column":13},"end":{"line":38,"column":59}},"5":{"start":{"line":40,"column":13},"end":{"line":40,"column":65}},"6":{"start":{"line":41,"column":15},"end":{"line":41,"column":2048}},"7":{"start":{"line":43,"column":12},"end":{"line":43,"column":58}},"8":{"start":{"line":45,"column":12},"end":{"line":45,"column":62}},"9":{"start":{"line":49,"column":8},"end":{"line":49,"column":19}},"10":{"start":{"line":53,"column":7},"end":{"line":53,"column":2570}},"11":{"start":{"line":56,"column":7},"end":{"line":56,"column":79}},"12":{"start":{"line":58,"column":8},"end":{"line":58,"column":61}},"13":{"start":{"line":59,"column":8},"end":{"line":59,"column":68}},"14":{"start":{"line":61,"column":8},"end":{"line":61,"column":105}},"15":{"start":{"line":64,"column":8},"end":{"line":64,"column":65}},"16":{"start":{"line":68,"column":8},"end":{"line":68,"column":3309}},"17":{"start":{"line":71,"column":8},"end":{"line":71,"column":80}},"18":{"start":{"line":72,"column":8},"end":{"line":72,"column":107}},"19":{"start":{"line":74,"column":8},"end":{"line":74,"column":69}},"20":{"start":{"line":76,"column":8},"end":{"line":76,"column":68}},"21":{"start":{"line":83,"column":8},"end":{"line":83,"column":61}},"22":{"start":{"line":84,"column":8},"end":{"line":84,"column":4071}},"23":{"start":{"line":87,"column":8},"end":{"line":87,"column":80}},"24":{"start":{"line":88,"column":8},"end":{"line":88,"column":60}},"25":{"start":{"line":90,"column":8},"end":{"line":90,"column":29}},"26":{"start":{"line":92,"column":8},"end":{"line":92,"column":4490}},"27":{"start":{"line":95,"column":8},"end":{"line":95,"column":4600}},"28":{"start":{"line":96,"column":12},"end":{"line":96,"column":60}},"29":{"start":{"line":99,"column":12},"end":{"line":99,"column":83}},"30":{"start":{"line":104,"column":8},"end":{"line":104,"column":35}},"31":{"start":{"line":105,"column":8},"end":{"line":105,"column":5058}},"32":{"start":{"line":106,"column":12},"end":{"line":106,"column":46}},"33":{"start":{"line":110,"column":12},"end":{"line":110,"column":58}},"34":{"start":{"line":111,"column":12},"end":{"line":111,"column":5346}},"35":{"start":{"line":112,"column":16},"end":{"line":112,"column":5434}},"36":{"start":{"line":114,"column":24},"end":{"line":114,"column":68}},"37":{"start":{"line":118,"column":25},"end":{"line":118,"column":92}},"38":{"start":{"line":123,"column":12},"end":{"line":123,"column":54}},"39":{"start":{"line":125,"column":8},"end":{"line":125,"column":44}},"40":{"start":{"line":129,"column":8},"end":{"line":129,"column":83}},"41":{"start":{"line":133,"column":8},"end":{"line":133,"column":84}},"42":{"start":{"line":138,"column":8},"end":{"line":138,"column":20}},"43":{"start":{"line":139,"column":8},"end":{"line":139,"column":29}},"44":{"start":{"line":141,"column":8},"end":{"line":141,"column":89}},"45":{"start":{"line":148,"column":8},"end":{"line":148,"column":58}},"46":{"start":{"line":149,"column":8},"end":{"line":149,"column":6991}},"47":{"start":{"line":150,"column":12},"end":{"line":150,"column":62}},"48":{"start":{"line":152,"column":12},"end":{"line":152,"column":7171}},"49":{"start":{"line":153,"column":16},"end":{"line":153,"column":7227}},"50":{"start":{"line":154,"column":20},"end":{"line":154,"column":36}},"51":{"start":{"line":156,"column":16},"end":{"line":156,"column":33}},"52":{"start":{"line":159,"column":12},"end":{"line":159,"column":7415}},"53":{"start":{"line":160,"column":19},"end":{"line":160,"column":48}},"54":{"start":{"line":165,"column":8},"end":{"line":165,"column":36}},"55":{"start":{"line":169,"column":8},"end":{"line":169,"column":80}},"56":{"start":{"line":170,"column":8},"end":{"line":170,"column":39}},"57":{"start":{"line":174,"column":8},"end":{"line":174,"column":80}},"58":{"start":{"line":175,"column":8},"end":{"line":175,"column":61}},"59":{"start":{"line":176,"column":8},"end":{"line":176,"column":55}},"60":{"start":{"line":178,"column":8},"end":{"line":178,"column":8335}},"61":{"start":{"line":179,"column":12},"end":{"line":179,"column":20}},"62":{"start":{"line":181,"column":8},"end":{"line":181,"column":37}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":8}},{"start":{"line":37,"column":8},"end":{"line":37,"column":8}}]},"2":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":15},"end":{"line":41,"column":15}},{"start":{"line":41,"column":15},"end":{"line":41,"column":15}}]},"3":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":7},"end":{"line":53,"column":7}},{"start":{"line":53,"column":7},"end":{"line":53,"column":7}}]},"4":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":8},"end":{"line":61,"column":8}},{"start":{"line":61,"column":8},"end":{"line":61,"column":8}}]},"5":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":8},"end":{"line":68,"column":8}},{"start":{"line":68,"column":8},"end":{"line":68,"column":8}}]},"6":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":8}},{"start":{"line":72,"column":8},"end":{"line":72,"column":8}}]},"7":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":8},"end":{"line":84,"column":8}},{"start":{"line":84,"column":8},"end":{"line":84,"column":8}}]},"8":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":8},"end":{"line":92,"column":8}},{"start":{"line":92,"column":8},"end":{"line":92,"column":8}}]},"9":{"line":95,"type":"if","locations":[{"start":{"line":95,"column":8},"end":{"line":95,"column":8}},{"start":{"line":95,"column":8},"end":{"line":95,"column":8}}]},"10":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":8},"end":{"line":105,"column":8}},{"start":{"line":105,"column":8},"end":{"line":105,"column":8}}]},"11":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":12},"end":{"line":111,"column":12}},{"start":{"line":111,"column":12},"end":{"line":111,"column":12}}]},"12":{"line":112,"type":"if","locations":[{"start":{"line":112,"column":16},"end":{"line":112,"column":16}},{"start":{"line":112,"column":16},"end":{"line":112,"column":16}}]},"13":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":8}},{"start":{"line":141,"column":8},"end":{"line":141,"column":8}}]},"14":{"line":149,"type":"if","locations":[{"start":{"line":149,"column":8},"end":{"line":149,"column":8}},{"start":{"line":149,"column":8},"end":{"line":149,"column":8}}]},"15":{"line":152,"type":"if","locations":[{"start":{"line":152,"column":12},"end":{"line":152,"column":12}},{"start":{"line":152,"column":12},"end":{"line":152,"column":12}}]},"16":{"line":153,"type":"if","locations":[{"start":{"line":153,"column":16},"end":{"line":153,"column":16}},{"start":{"line":153,"column":16},"end":{"line":153,"column":16}}]},"17":{"line":159,"type":"if","locations":[{"start":{"line":159,"column":12},"end":{"line":159,"column":12}},{"start":{"line":159,"column":12},"end":{"line":159,"column":12}}]},"18":{"line":178,"type":"if","locations":[{"start":{"line":178,"column":8},"end":{"line":178,"column":8}},{"start":{"line":178,"column":8},"end":{"line":178,"column":8}}]}}},"contracts/modules/internal/ERC20MintModuleInternal.sol":{"l":{"34":730,"37":706,"38":658,"39":1836,"47":238,"48":214,"51":214,"52":166,"53":310,"57":43,"64":6409,"70":211},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol","s":{"1":730,"2":706,"3":658,"4":1836,"5":238,"6":214,"7":214,"8":166,"9":310,"10":43,"11":6409,"12":211},"b":{"1":[706,24],"2":[658,48],"3":[214,24],"4":[166,48]},"f":{"1":730,"2":238,"3":6409,"4":211},"fnMap":{"1":{"name":"_batchMint","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"_batchTransfer","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":58,"column":4}}},"3":{"name":"_mintOverride","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"_minterTransferOverride","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":71,"column":5}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":69}},"2":{"start":{"line":37,"column":8},"end":{"line":37,"column":97}},"3":{"start":{"line":38,"column":8},"end":{"line":38,"column":1716}},"4":{"start":{"line":39,"column":12},"end":{"line":39,"column":48}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":59}},"6":{"start":{"line":48,"column":8},"end":{"line":48,"column":37}},"7":{"start":{"line":51,"column":8},"end":{"line":51,"column":87}},"8":{"start":{"line":52,"column":8},"end":{"line":52,"column":2292}},"9":{"start":{"line":53,"column":12},"end":{"line":53,"column":61}},"10":{"start":{"line":57,"column":8},"end":{"line":57,"column":19}},"11":{"start":{"line":64,"column":8},"end":{"line":64,"column":45}},"12":{"start":{"line":70,"column":12},"end":{"line":70,"column":54}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":34,"column":8}},{"start":{"line":34,"column":8},"end":{"line":34,"column":8}}]},"2":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":8}},{"start":{"line":37,"column":8},"end":{"line":37,"column":8}}]},"3":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":8},"end":{"line":47,"column":8}},{"start":{"line":47,"column":8},"end":{"line":47,"column":8}}]},"4":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":8},"end":{"line":51,"column":8}},{"start":{"line":51,"column":8},"end":{"line":51,"column":8}}]}}},"contracts/modules/internal/ValidationModuleRuleEngineInternal.sol":{"l":{"38":4748,"39":83,"53":8704,"54":8704,"68":441,"69":441,"70":441,"75":9145},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol","s":{"1":4748,"2":83,"3":8704,"4":8704,"5":441,"6":441},"b":{"1":[4748,0],"2":[83,4665]},"f":{"1":4748,"2":8704,"3":441,"4":9145},"fnMap":{"1":{"name":"__ValidationRuleEngine_init_unchained","line":37,"loc":{"start":{"line":35,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"ruleEngine","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":55,"column":4}}},"3":{"name":"_setRuleEngine","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":71,"column":4}}},"4":{"name":"_getValidationModuleRuleEngineStorage","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":78,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":1469}},"2":{"start":{"line":39,"column":12},"end":{"line":39,"column":38}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":93}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":28}},"5":{"start":{"line":68,"column":8},"end":{"line":68,"column":93}},"6":{"start":{"line":70,"column":8},"end":{"line":70,"column":36}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":15},"end":{"line":37,"column":15}},{"start":{"line":37,"column":15},"end":{"line":37,"column":15}}]},"2":{"line":38,"type":"if","locations":[{"start":{"line":38,"column":8},"end":{"line":38,"column":8}},{"start":{"line":38,"column":8},"end":{"line":38,"column":8}}]}}},"contracts/modules/wrapper/controllers/ValidationModule.sol":{"l":{"27":352,"32":46,"48":1437,"49":34,"52":14,"55":1389,"65":8325,"66":6229,"69":1175,"72":921,"84":42,"88":12,"90":30,"100":6606,"101":6557,"102":60,"113":1247,"114":1175,"115":84,"129":1353,"132":240,"134":1113,"143":744,"144":24,"146":24,"148":50,"157":1353,"159":384,"161":969,"175":911,"176":744,"186":1906,"195":28},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol","s":{"1":352,"2":46,"3":1437,"4":34,"5":1403,"6":14,"7":1389,"8":8325,"9":6229,"10":2096,"11":1175,"12":921,"13":42,"14":12,"15":30,"16":6606,"17":6557,"18":1247,"19":1175,"20":1353,"21":240,"22":1113,"23":744,"24":720,"25":696,"26":1353,"27":384,"28":969,"29":911,"30":744,"31":1906,"32":28},"b":{"1":[34,1403],"2":[14,1389],"3":[6229,2096],"4":[1175,921],"5":[12,30],"6":[0,12],"7":[60,6497],"8":[84,1091],"9":[240,1113],"10":[24,168],"11":[168,48],"12":[24,720],"13":[24,696],"14":[50,646],"15":[384,969],"16":[240,144]},"f":{"1":352,"2":46,"3":1437,"4":8325,"5":42,"6":6606,"7":1247,"8":1353,"9":744,"10":1353,"11":911,"12":1906,"13":28},"fnMap":{"1":{"name":"canSend","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"canReceive","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":33,"column":4}}},"3":{"name":"_canTransferGenericByModule","line":42,"loc":{"start":{"line":42,"column":4},"end":{"line":57,"column":4}}},"4":{"name":"_canTransferGenericByModuleAndRevert","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":74,"column":4}}},"5":{"name":"_canMintBurnByModule","line":81,"loc":{"start":{"line":81,"column":4},"end":{"line":91,"column":4}}},"6":{"name":"_canMintByModuleAndRevert","line":97,"loc":{"start":{"line":97,"column":4},"end":{"line":104,"column":4}}},"7":{"name":"_canBurnByModuleAndRevert","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":117,"column":4}}},"8":{"name":"_canTransferisFrozen","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":136,"column":4}}},"9":{"name":"_canTransferisFrozenAndRevert","line":138,"loc":{"start":{"line":138,"column":4},"end":{"line":150,"column":4}}},"10":{"name":"_canTransferStandardByModule","line":152,"loc":{"start":{"line":152,"column":2},"end":{"line":163,"column":4}}},"11":{"name":"_canTransferStandardByModuleAndRevert","line":165,"loc":{"start":{"line":165,"column":4},"end":{"line":177,"column":4}}},"12":{"name":"_canSend","line":185,"loc":{"start":{"line":185,"column":4},"end":{"line":187,"column":4}}},"13":{"name":"_canReceive","line":194,"loc":{"start":{"line":194,"column":4},"end":{"line":196,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":32}},"2":{"start":{"line":32,"column":8},"end":{"line":32,"column":35}},"3":{"start":{"line":48,"column":8},"end":{"line":48,"column":1732}},"4":{"start":{"line":49,"column":12},"end":{"line":49,"column":43}},"5":{"start":{"line":51,"column":13},"end":{"line":51,"column":1832}},"6":{"start":{"line":52,"column":12},"end":{"line":52,"column":45}},"7":{"start":{"line":55,"column":12},"end":{"line":55,"column":66}},"8":{"start":{"line":65,"column":8},"end":{"line":65,"column":2203}},"9":{"start":{"line":66,"column":13},"end":{"line":66,"column":41}},"10":{"start":{"line":68,"column":13},"end":{"line":68,"column":2302}},"11":{"start":{"line":69,"column":12},"end":{"line":69,"column":42}},"12":{"start":{"line":72,"column":13},"end":{"line":72,"column":68}},"13":{"start":{"line":84,"column":8},"end":{"line":84,"column":2831}},"14":{"start":{"line":88,"column":12},"end":{"line":88,"column":24}},"15":{"start":{"line":90,"column":8},"end":{"line":90,"column":19}},"16":{"start":{"line":100,"column":8},"end":{"line":100,"column":31}},"17":{"start":{"line":101,"column":8},"end":{"line":101,"column":3428}},"18":{"start":{"line":113,"column":8},"end":{"line":113,"column":31}},"19":{"start":{"line":114,"column":8},"end":{"line":114,"column":3793}},"20":{"start":{"line":129,"column":8},"end":{"line":129,"column":4251}},"21":{"start":{"line":132,"column":12},"end":{"line":132,"column":23}},"22":{"start":{"line":134,"column":13},"end":{"line":134,"column":25}},"23":{"start":{"line":143,"column":8},"end":{"line":143,"column":4616}},"24":{"start":{"line":145,"column":15},"end":{"line":145,"column":4720}},"25":{"start":{"line":147,"column":15},"end":{"line":147,"column":4819}},"26":{"start":{"line":157,"column":8},"end":{"line":157,"column":5078}},"27":{"start":{"line":159,"column":12},"end":{"line":159,"column":24}},"28":{"start":{"line":161,"column":13},"end":{"line":161,"column":24}},"29":{"start":{"line":175,"column":8},"end":{"line":175,"column":26}},"30":{"start":{"line":176,"column":8},"end":{"line":176,"column":55}},"31":{"start":{"line":186,"column":8},"end":{"line":186,"column":51}},"32":{"start":{"line":195,"column":8},"end":{"line":195,"column":51}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":8},"end":{"line":48,"column":8}},{"start":{"line":48,"column":8},"end":{"line":48,"column":8}}]},"2":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":13},"end":{"line":51,"column":13}},{"start":{"line":51,"column":13},"end":{"line":51,"column":13}}]},"3":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":8},"end":{"line":65,"column":8}},{"start":{"line":65,"column":8},"end":{"line":65,"column":8}}]},"4":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":13},"end":{"line":68,"column":13}},{"start":{"line":68,"column":13},"end":{"line":68,"column":13}}]},"5":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":8},"end":{"line":84,"column":8}},{"start":{"line":84,"column":8},"end":{"line":84,"column":8}}]},"6":{"line":84,"type":"cond-expr","locations":[{"start":{"line":84,"column":11},"end":{"line":84,"column":35}},{"start":{"line":84,"column":40},"end":{"line":84,"column":73}}]},"7":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":8},"end":{"line":101,"column":8}},{"start":{"line":101,"column":8},"end":{"line":101,"column":8}}]},"8":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":8},"end":{"line":114,"column":8}},{"start":{"line":114,"column":8},"end":{"line":114,"column":8}}]},"9":{"line":129,"type":"if","locations":[{"start":{"line":129,"column":8},"end":{"line":129,"column":8}},{"start":{"line":129,"column":8},"end":{"line":129,"column":8}}]},"10":{"line":129,"type":"cond-expr","locations":[{"start":{"line":129,"column":12},"end":{"line":129,"column":46}},{"start":{"line":130,"column":11},"end":{"line":130,"column":42}}]},"11":{"line":129,"type":"cond-expr","locations":[{"start":{"line":129,"column":12},"end":{"line":130,"column":42}},{"start":{"line":131,"column":11},"end":{"line":131,"column":40}}]},"12":{"line":143,"type":"if","locations":[{"start":{"line":143,"column":8},"end":{"line":143,"column":8}},{"start":{"line":143,"column":8},"end":{"line":143,"column":8}}]},"13":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":15},"end":{"line":145,"column":15}},{"start":{"line":145,"column":15},"end":{"line":145,"column":15}}]},"14":{"line":147,"type":"if","locations":[{"start":{"line":147,"column":15},"end":{"line":147,"column":15}},{"start":{"line":147,"column":15},"end":{"line":147,"column":15}}]},"15":{"line":157,"type":"if","locations":[{"start":{"line":157,"column":8},"end":{"line":157,"column":8}},{"start":{"line":157,"column":8},"end":{"line":157,"column":8}}]},"16":{"line":157,"type":"cond-expr","locations":[{"start":{"line":157,"column":12},"end":{"line":157,"column":50}},{"start":{"line":158,"column":11},"end":{"line":158,"column":30}}]}}},"contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol":{"l":{"27":12,"28":6,"30":6,"42":191,"43":166,"44":166,"45":36,"48":155,"59":191,"60":36,"62":155,"67":207,"68":26,"70":181,"76":34,"77":18,"79":16,"88":740,"89":4,"91":736,"99":128,"100":4,"102":124,"111":108,"112":98,"120":108,"121":79,"122":2,"124":2,"126":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol","s":{"1":12,"2":6,"3":6,"4":191,"5":166,"6":166,"7":36,"8":155,"9":191,"10":36,"11":155,"12":207,"13":26,"14":181,"15":34,"16":18,"17":16,"18":740,"19":736,"20":128,"21":124,"22":108,"23":98,"24":108,"25":79,"26":77,"27":75},"b":{"1":[6,6],"2":[166,25],"3":[36,130],"4":[2,18],"5":[18,16],"6":[36,155],"7":[26,181],"8":[18,16],"9":[4,736],"10":[4,124],"11":[79,29],"12":[2,77],"13":[2,75],"14":[6,69]},"f":{"1":12,"2":191,"3":191,"4":207,"5":34,"6":740,"7":128,"8":108,"9":108},"fnMap":{"1":{"name":"_canMintBurnByModule","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"_canTransferStandardByModuleAllowlist","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"_canTransferStandardByModule","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"_canSend","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"_canReceive","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"_canMintByModuleAndRevert","line":85,"loc":{"start":{"line":85,"column":4},"end":{"line":93,"column":4}}},"7":{"name":"_canBurnByModuleAndRevert","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":104,"column":4}}},"8":{"name":"_canTransferStandardByModuleAndRevert","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":113,"column":4}}},"9":{"name":"_canTransferStandardByModuleAllowlistAndRevert","line":115,"loc":{"start":{"line":115,"column":4},"end":{"line":129,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":932}},"2":{"start":{"line":28,"column":12},"end":{"line":28,"column":24}},"3":{"start":{"line":30,"column":12},"end":{"line":30,"column":65}},"4":{"start":{"line":42,"column":8},"end":{"line":42,"column":1352}},"5":{"start":{"line":43,"column":12},"end":{"line":43,"column":80}},"6":{"start":{"line":44,"column":12},"end":{"line":44,"column":1477}},"7":{"start":{"line":45,"column":16},"end":{"line":45,"column":27}},"8":{"start":{"line":48,"column":7},"end":{"line":48,"column":19}},"9":{"start":{"line":59,"column":8},"end":{"line":59,"column":1876}},"10":{"start":{"line":60,"column":11},"end":{"line":60,"column":23}},"11":{"start":{"line":62,"column":8},"end":{"line":62,"column":79}},"12":{"start":{"line":67,"column":8},"end":{"line":67,"column":2219}},"13":{"start":{"line":68,"column":12},"end":{"line":68,"column":24}},"14":{"start":{"line":70,"column":12},"end":{"line":70,"column":53}},"15":{"start":{"line":76,"column":8},"end":{"line":76,"column":2549}},"16":{"start":{"line":77,"column":12},"end":{"line":77,"column":24}},"17":{"start":{"line":79,"column":12},"end":{"line":79,"column":56}},"18":{"start":{"line":88,"column":8},"end":{"line":88,"column":2946}},"19":{"start":{"line":91,"column":12},"end":{"line":91,"column":57}},"20":{"start":{"line":99,"column":8},"end":{"line":99,"column":3297}},"21":{"start":{"line":102,"column":12},"end":{"line":102,"column":59}},"22":{"start":{"line":111,"column":8},"end":{"line":111,"column":72}},"23":{"start":{"line":112,"column":8},"end":{"line":112,"column":80}},"24":{"start":{"line":120,"column":8},"end":{"line":120,"column":3993}},"25":{"start":{"line":121,"column":12},"end":{"line":121,"column":4036}},"26":{"start":{"line":123,"column":19},"end":{"line":123,"column":4161}},"27":{"start":{"line":125,"column":19},"end":{"line":125,"column":4256}}},"branchMap":{"1":{"line":27,"type":"if","locations":[{"start":{"line":27,"column":8},"end":{"line":27,"column":8}},{"start":{"line":27,"column":8},"end":{"line":27,"column":8}}]},"2":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":8},"end":{"line":42,"column":8}},{"start":{"line":42,"column":8},"end":{"line":42,"column":8}}]},"3":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":12},"end":{"line":44,"column":12}},{"start":{"line":44,"column":12},"end":{"line":44,"column":12}}]},"4":{"line":44,"type":"cond-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":27}},{"start":{"line":44,"column":32},"end":{"line":44,"column":51}}]},"5":{"line":44,"type":"cond-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":51}},{"start":{"line":44,"column":56},"end":{"line":44,"column":73}}]},"6":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":59,"column":8}},{"start":{"line":59,"column":8},"end":{"line":59,"column":8}}]},"7":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":8},"end":{"line":67,"column":8}},{"start":{"line":67,"column":8},"end":{"line":67,"column":8}}]},"8":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":8},"end":{"line":76,"column":8}},{"start":{"line":76,"column":8},"end":{"line":76,"column":8}}]},"9":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":8},"end":{"line":88,"column":8}},{"start":{"line":88,"column":8},"end":{"line":88,"column":8}}]},"10":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":8}},{"start":{"line":99,"column":8},"end":{"line":99,"column":8}}]},"11":{"line":120,"type":"if","locations":[{"start":{"line":120,"column":8},"end":{"line":120,"column":8}},{"start":{"line":120,"column":8},"end":{"line":120,"column":8}}]},"12":{"line":121,"type":"if","locations":[{"start":{"line":121,"column":12},"end":{"line":121,"column":12}},{"start":{"line":121,"column":12},"end":{"line":121,"column":12}}]},"13":{"line":123,"type":"if","locations":[{"start":{"line":123,"column":19},"end":{"line":123,"column":19}},{"start":{"line":123,"column":19},"end":{"line":123,"column":19}}]},"14":{"line":125,"type":"if","locations":[{"start":{"line":125,"column":19},"end":{"line":125,"column":19}},{"start":{"line":125,"column":19},"end":{"line":125,"column":19}}]}}},"contracts/modules/wrapper/core/EnforcementModule.sol":{"l":{"27":771,"28":696,"42":271,"60":300,"71":125,"79":16612,"87":721,"88":646},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol","s":{"1":771,"2":271,"3":300,"4":125,"5":16612,"6":721,"7":646},"b":{"1":[271,0],"2":[300,50],"3":[125,25]},"f":{"1":771,"2":271,"3":300,"4":125,"5":16612,"6":721},"fnMap":{"1":{"name":"onlyEnforcer","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":29,"column":4}}},"2":{"name":"setAddressFrozen","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":4}}},"3":{"name":"setAddressFrozen","line":59,"loc":{"start":{"line":57,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"batchSetAddressFrozen","line":70,"loc":{"start":{"line":68,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"isFrozen","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"_addAddressToTheList","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":89,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":25}},"2":{"start":{"line":42,"column":9},"end":{"line":42,"column":49}},"3":{"start":{"line":60,"column":9},"end":{"line":60,"column":51}},"4":{"start":{"line":71,"column":9},"end":{"line":71,"column":53}},"5":{"start":{"line":79,"column":7},"end":{"line":79,"column":39}},"6":{"start":{"line":87,"column":8},"end":{"line":87,"column":79}},"7":{"start":{"line":88,"column":8},"end":{"line":88,"column":63}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":105},"end":{"line":41,"column":105}},{"start":{"line":41,"column":105},"end":{"line":41,"column":105}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":21},"end":{"line":59,"column":21}},{"start":{"line":59,"column":21},"end":{"line":59,"column":21}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":51},"end":{"line":70,"column":51}},{"start":{"line":70,"column":51},"end":{"line":70,"column":51}}]}}},"contracts/modules/wrapper/core/ERC20BaseModule.sol":{"l":{"39":98,"40":50,"55":5624,"56":5624,"57":5624,"58":5624,"78":128,"80":80,"83":80,"86":80,"96":24,"97":24,"104":86,"105":86,"113":74,"114":74,"125":26,"126":26,"127":26,"134":24,"135":24,"136":24,"143":48,"144":48,"145":24,"147":48,"158":5858},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol","s":{"1":98,"2":5624,"3":128,"4":80,"5":80,"6":80,"7":24,"8":24,"9":86,"10":86,"11":74,"12":74,"13":26,"14":26,"15":24,"16":24,"17":48},"b":{"1":[5624,0],"2":[80,0],"3":[26,24],"4":[24,24]},"f":{"1":98,"2":5624,"3":128,"4":24,"5":86,"6":74,"7":26,"8":24,"9":48,"10":5858},"fnMap":{"1":{"name":"onlyERC20AttributeManager","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"__ERC20BaseModule_init_unchained","line":54,"loc":{"start":{"line":50,"column":4},"end":{"line":59,"column":4}}},"3":{"name":"transferFrom","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":87,"column":4}}},"4":{"name":"decimals","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":98,"column":4}}},"5":{"name":"name","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":106,"column":4}}},"6":{"name":"symbol","line":112,"loc":{"start":{"line":112,"column":4},"end":{"line":115,"column":4}}},"7":{"name":"setName","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":128,"column":4}}},"8":{"name":"setSymbol","line":133,"loc":{"start":{"line":133,"column":4},"end":{"line":137,"column":4}}},"9":{"name":"batchBalanceOf","line":142,"loc":{"start":{"line":142,"column":4},"end":{"line":148,"column":4}}},"10":{"name":"_getERC20BaseModuleStorage","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":161,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":43}},"2":{"start":{"line":55,"column":8},"end":{"line":55,"column":71}},"3":{"start":{"line":78,"column":8},"end":{"line":78,"column":68}},"4":{"start":{"line":80,"column":8},"end":{"line":80,"column":3039}},"5":{"start":{"line":83,"column":12},"end":{"line":83,"column":49}},"6":{"start":{"line":86,"column":8},"end":{"line":86,"column":21}},"7":{"start":{"line":96,"column":8},"end":{"line":96,"column":71}},"8":{"start":{"line":97,"column":8},"end":{"line":97,"column":26}},"9":{"start":{"line":104,"column":8},"end":{"line":104,"column":71}},"10":{"start":{"line":105,"column":8},"end":{"line":105,"column":22}},"11":{"start":{"line":113,"column":8},"end":{"line":113,"column":71}},"12":{"start":{"line":114,"column":8},"end":{"line":114,"column":24}},"13":{"start":{"line":125,"column":8},"end":{"line":125,"column":71}},"14":{"start":{"line":127,"column":8},"end":{"line":127,"column":31}},"15":{"start":{"line":134,"column":8},"end":{"line":134,"column":71}},"16":{"start":{"line":136,"column":8},"end":{"line":136,"column":37}},"17":{"start":{"line":144,"column":8},"end":{"line":144,"column":5304}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":23},"end":{"line":54,"column":23}},{"start":{"line":54,"column":23},"end":{"line":54,"column":23}}]},"2":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":8},"end":{"line":80,"column":8}},{"start":{"line":80,"column":8},"end":{"line":80,"column":8}}]},"3":{"line":124,"type":"if","locations":[{"start":{"line":124,"column":87},"end":{"line":124,"column":87}},{"start":{"line":124,"column":87},"end":{"line":124,"column":87}}]},"4":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":91},"end":{"line":133,"column":91}},{"start":{"line":133,"column":91},"end":{"line":133,"column":91}}]}}},"contracts/modules/wrapper/core/ERC20BurnModule.sol":{"l":{"26":835,"27":739,"45":271,"57":138,"73":254,"74":91,"87":76,"88":74,"100":409,"101":292},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol","s":{"1":835,"2":271,"3":138,"4":254,"5":91,"6":76,"7":74,"8":409,"9":292},"b":{"1":[271,72],"2":[138,0],"3":[254,24],"4":[76,0]},"f":{"1":835,"2":271,"3":138,"4":254,"5":76,"6":409},"fnMap":{"1":{"name":"onlyBurner","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"burn","line":44,"loc":{"start":{"line":40,"column":4},"end":{"line":46,"column":4}}},"3":{"name":"burn","line":56,"loc":{"start":{"line":53,"column":4},"end":{"line":58,"column":4}}},"4":{"name":"batchBurn","line":72,"loc":{"start":{"line":68,"column":4},"end":{"line":75,"column":4}}},"5":{"name":"batchBurn","line":86,"loc":{"start":{"line":83,"column":4},"end":{"line":89,"column":4}}},"6":{"name":"_burn","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":102,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":23}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":34}},"3":{"start":{"line":57,"column":7},"end":{"line":57,"column":30}},"4":{"start":{"line":73,"column":8},"end":{"line":73,"column":35}},"5":{"start":{"line":74,"column":8},"end":{"line":74,"column":60}},"6":{"start":{"line":87,"column":8},"end":{"line":87,"column":35}},"7":{"start":{"line":88,"column":8},"end":{"line":88,"column":58}},"8":{"start":{"line":100,"column":8},"end":{"line":100,"column":36}},"9":{"start":{"line":101,"column":8},"end":{"line":101,"column":53}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":44},"end":{"line":44,"column":44}},{"start":{"line":44,"column":44},"end":{"line":44,"column":44}}]},"2":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":44},"end":{"line":56,"column":44}},{"start":{"line":56,"column":44},"end":{"line":56,"column":44}}]},"3":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":47},"end":{"line":72,"column":47}},{"start":{"line":72,"column":47},"end":{"line":72,"column":47}}]},"4":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":45},"end":{"line":86,"column":45}},{"start":{"line":86,"column":45},"end":{"line":86,"column":45}}]}}},"contracts/modules/wrapper/core/ERC20MintModule.sol":{"l":{"28":5722,"29":5650,"44":148,"60":4534,"76":730,"77":583,"89":238,"96":4682,"97":4586},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol","s":{"1":5722,"2":148,"3":4534,"4":730,"5":583,"6":238,"7":4682,"8":4586},"b":{"1":[148,24],"2":[4534,24],"3":[730,24],"4":[238,0]},"f":{"1":5722,"2":148,"3":4534,"4":730,"5":238,"6":4682},"fnMap":{"1":{"name":"onlyMinter","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"mint","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":4}}},"3":{"name":"mint","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"batchMint","line":75,"loc":{"start":{"line":72,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"batchTransfer","line":88,"loc":{"start":{"line":85,"column":3},"end":{"line":90,"column":4}}},"6":{"name":"_mint","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":98,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":23}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":34}},"3":{"start":{"line":60,"column":7},"end":{"line":60,"column":31}},"4":{"start":{"line":76,"column":7},"end":{"line":76,"column":34}},"5":{"start":{"line":77,"column":8},"end":{"line":77,"column":54}},"6":{"start":{"line":89,"column":8},"end":{"line":89,"column":42}},"7":{"start":{"line":96,"column":8},"end":{"line":96,"column":36}},"8":{"start":{"line":97,"column":8},"end":{"line":97,"column":53}}},"branchMap":{"1":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":109},"end":{"line":43,"column":109}},{"start":{"line":43,"column":109},"end":{"line":43,"column":109}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":88},"end":{"line":59,"column":88}},{"start":{"line":59,"column":88},"end":{"line":59,"column":88}}]},"3":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":44},"end":{"line":75,"column":44}},{"start":{"line":75,"column":44},"end":{"line":75,"column":44}}]},"4":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":53},"end":{"line":88,"column":53}},{"start":{"line":88,"column":53},"end":{"line":88,"column":53}}]}}},"contracts/modules/wrapper/core/PauseModule.sol":{"l":{"41":763,"42":712,"46":318,"47":293,"60":637,"69":75,"70":75,"71":50,"86":293,"87":268,"88":268,"89":25,"91":243,"92":243,"100":5339,"107":8168,"108":8168,"119":7853,"120":121,"126":8511},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol","s":{"1":763,"2":318,"3":637,"4":75,"5":75,"6":50,"7":293,"8":268,"9":268,"10":243,"11":5339,"12":8168,"13":8168,"14":7853},"b":{"1":[637,26],"2":[75,25],"3":[50,25],"4":[293,25],"5":[25,243],"6":[121,7732]},"f":{"1":763,"2":318,"3":637,"4":75,"5":293,"6":5339,"7":8168,"8":7853,"9":8511},"fnMap":{"1":{"name":"onlyPauseManager","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":43,"column":4}}},"2":{"name":"onlyDeactivateContractManager","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":48,"column":4}}},"3":{"name":"pause","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"unpause","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"deactivateContract","line":83,"loc":{"start":{"line":81,"column":4},"end":{"line":93,"column":4}}},"6":{"name":"paused","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":101,"column":3}}},"7":{"name":"deactivated","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":109,"column":4}}},"8":{"name":"_requireNotDeactivated","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":122,"column":4}}},"9":{"name":"_getPauseModuleStorage","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":129,"column":4}}}},"statementMap":{"1":{"start":{"line":41,"column":8},"end":{"line":41,"column":24}},"2":{"start":{"line":46,"column":8},"end":{"line":46,"column":29}},"3":{"start":{"line":60,"column":8},"end":{"line":60,"column":35}},"4":{"start":{"line":69,"column":8},"end":{"line":69,"column":63}},"5":{"start":{"line":70,"column":8},"end":{"line":70,"column":76}},"6":{"start":{"line":71,"column":8},"end":{"line":71,"column":37}},"7":{"start":{"line":86,"column":8},"end":{"line":86,"column":43}},"8":{"start":{"line":87,"column":8},"end":{"line":87,"column":63}},"9":{"start":{"line":88,"column":8},"end":{"line":88,"column":3423}},"10":{"start":{"line":92,"column":7},"end":{"line":92,"column":37}},"11":{"start":{"line":100,"column":8},"end":{"line":100,"column":43}},"12":{"start":{"line":107,"column":8},"end":{"line":107,"column":63}},"13":{"start":{"line":108,"column":8},"end":{"line":108,"column":31}},"14":{"start":{"line":119,"column":8},"end":{"line":119,"column":4507}}},"branchMap":{"1":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":75},"end":{"line":59,"column":75}},{"start":{"line":59,"column":75},"end":{"line":59,"column":75}}]},"2":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":77},"end":{"line":68,"column":77}},{"start":{"line":68,"column":77},"end":{"line":68,"column":77}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":8},"end":{"line":70,"column":8}},{"start":{"line":70,"column":8},"end":{"line":70,"column":8}}]},"4":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":8},"end":{"line":83,"column":8}},{"start":{"line":83,"column":8},"end":{"line":83,"column":8}}]},"5":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":8},"end":{"line":88,"column":8}},{"start":{"line":88,"column":8},"end":{"line":88,"column":8}}]},"6":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":8},"end":{"line":119,"column":8}},{"start":{"line":119,"column":8},"end":{"line":119,"column":8}}]}}},"contracts/modules/wrapper/core/ValidationModuleCore.sol":{"l":{"25":1229,"34":208,"50":1437},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol","s":{"1":1229,"2":208,"3":1437},"b":{},"f":{"1":1229,"2":208,"3":1437},"fnMap":{"1":{"name":"canTransfer","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"canTransferFrom","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":35,"column":4}}},"3":{"name":"_canTransferByModule","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":51,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":64}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":61}},"3":{"start":{"line":50,"column":8},"end":{"line":50,"column":78}}},"branchMap":{}},"contracts/modules/wrapper/core/VersionModule.sol":{"l":{"28":25},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/VersionModule.sol","s":{"1":25},"b":{},"f":{"1":25},"fnMap":{"1":{"name":"version","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":29,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":7},"end":{"line":28,"column":21}}},"branchMap":{}},"contracts/modules/wrapper/extensions/DocumentERC1643Module.sol":{"l":{"24":299,"25":253,"29":138,"33":46,"37":207,"38":207,"39":207,"40":207,"41":207,"43":207,"44":184,"45":184,"48":207,"52":46,"53":46,"54":46,"56":46,"57":46,"58":46,"60":46,"61":23,"62":23,"63":23,"66":46,"67":46,"68":46,"70":46,"76":437},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol","s":{"1":299,"2":138,"3":46,"4":207,"5":207,"6":207,"7":184,"8":207,"9":46,"10":46,"11":46,"12":46,"13":46,"14":46,"15":46,"16":23,"17":46,"18":46},"b":{"1":[207,23],"2":[184,23],"3":[46,23],"4":[46,0],"5":[23,23]},"f":{"1":299,"2":138,"3":46,"4":207,"5":46,"6":437},"fnMap":{"1":{"name":"onlyDocumentManager","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"getDocument","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":30,"column":4}}},"3":{"name":"getAllDocuments","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":34,"column":4}}},"4":{"name":"setDocument","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":49,"column":4}}},"5":{"name":"removeDocument","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":71,"column":4}}},"6":{"name":"_getDocumentERC1643ModuleStorage","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":79,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":37}},"2":{"start":{"line":29,"column":8},"end":{"line":29,"column":66}},"3":{"start":{"line":33,"column":8},"end":{"line":33,"column":64}},"4":{"start":{"line":37,"column":8},"end":{"line":37,"column":83}},"5":{"start":{"line":38,"column":8},"end":{"line":38,"column":54}},"6":{"start":{"line":43,"column":8},"end":{"line":43,"column":1758}},"7":{"start":{"line":44,"column":12},"end":{"line":44,"column":38}},"8":{"start":{"line":48,"column":8},"end":{"line":48,"column":53}},"9":{"start":{"line":52,"column":8},"end":{"line":52,"column":83}},"10":{"start":{"line":53,"column":8},"end":{"line":53,"column":42}},"11":{"start":{"line":54,"column":8},"end":{"line":54,"column":58}},"12":{"start":{"line":56,"column":8},"end":{"line":56,"column":53}},"13":{"start":{"line":57,"column":8},"end":{"line":57,"column":31}},"14":{"start":{"line":58,"column":8},"end":{"line":58,"column":55}},"15":{"start":{"line":60,"column":8},"end":{"line":60,"column":2398}},"16":{"start":{"line":61,"column":12},"end":{"line":61,"column":59}},"17":{"start":{"line":66,"column":8},"end":{"line":66,"column":29}},"18":{"start":{"line":70,"column":8},"end":{"line":70,"column":71}}},"branchMap":{"1":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":106},"end":{"line":36,"column":106}},{"start":{"line":36,"column":106},"end":{"line":36,"column":106}}]},"2":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":8}},{"start":{"line":43,"column":8},"end":{"line":43,"column":8}}]},"3":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":66},"end":{"line":51,"column":66}},{"start":{"line":51,"column":66},"end":{"line":51,"column":66}}]},"4":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":8},"end":{"line":54,"column":8}},{"start":{"line":54,"column":8},"end":{"line":54,"column":8}}]},"5":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":8},"end":{"line":60,"column":8}},{"start":{"line":60,"column":8},"end":{"line":60,"column":8}}]}}},"contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol":{"l":{"26":1289,"27":1226,"32":262,"33":220,"44":2246,"55":146,"56":125,"66":574,"76":194,"87":378,"95":845,"96":845,"100":323,"101":323},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol","s":{"1":1289,"2":262,"3":2246,"4":146,"5":125,"6":574,"7":194,"8":378,"9":845,"10":845,"11":323,"12":323},"b":{"1":[146,42],"2":[574,21],"3":[194,21],"4":[378,21]},"f":{"1":1289,"2":262,"3":2246,"4":146,"5":574,"6":194,"7":378,"8":845,"9":323},"fnMap":{"1":{"name":"onlyERC20Enforcer","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"onlyForcedTransferManager","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":34,"column":4}}},"3":{"name":"getFrozenTokens","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":4}}},"4":{"name":"forcedTransfer","line":54,"loc":{"start":{"line":53,"column":4},"end":{"line":57,"column":4}}},"5":{"name":"freezePartialTokens","line":65,"loc":{"start":{"line":64,"column":4},"end":{"line":67,"column":4}}},"6":{"name":"unfreezePartialTokens","line":75,"loc":{"start":{"line":74,"column":4},"end":{"line":77,"column":4}}},"7":{"name":"setFrozenTokens","line":85,"loc":{"start":{"line":84,"column":4},"end":{"line":88,"column":4}}},"8":{"name":"_freezeTokensEmitEvents","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":97,"column":4}}},"9":{"name":"_unfreezeTokensEmitEvents","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":102,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":32}},"2":{"start":{"line":32,"column":8},"end":{"line":32,"column":33}},"3":{"start":{"line":44,"column":8},"end":{"line":44,"column":40}},"4":{"start":{"line":55,"column":8},"end":{"line":55,"column":39}},"5":{"start":{"line":56,"column":8},"end":{"line":56,"column":19}},"6":{"start":{"line":66,"column":8},"end":{"line":66,"column":43}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":45}},"8":{"start":{"line":87,"column":8},"end":{"line":87,"column":47}},"9":{"start":{"line":95,"column":8},"end":{"line":95,"column":71}},"10":{"start":{"line":96,"column":8},"end":{"line":96,"column":71}},"11":{"start":{"line":100,"column":8},"end":{"line":100,"column":73}},"12":{"start":{"line":101,"column":8},"end":{"line":101,"column":73}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":57},"end":{"line":54,"column":57}},{"start":{"line":54,"column":57},"end":{"line":54,"column":57}}]},"2":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":54},"end":{"line":65,"column":54}},{"start":{"line":65,"column":54},"end":{"line":65,"column":54}}]},"3":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":54},"end":{"line":75,"column":54}},{"start":{"line":75,"column":54},"end":{"line":75,"column":54}}]},"4":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":65},"end":{"line":85,"column":65}},{"start":{"line":85,"column":65},"end":{"line":85,"column":65}}]}}},"contracts/modules/wrapper/extensions/ExtraInformationModule.sol":{"l":{"32":164,"33":82,"45":5402,"47":5402,"49":5402,"51":5402,"68":26,"69":26,"79":26,"92":26,"93":26,"101":130,"102":130,"109":58,"110":58,"117":104,"118":104,"125":28,"126":28,"132":5428,"133":5428,"138":5430,"140":5430,"141":5430,"142":5430,"144":5430,"148":5428,"149":5428,"157":5774},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ExtraInformationModule.sol","s":{"1":164,"2":5402,"3":5402,"4":5402,"5":5402,"6":26,"7":26,"8":26,"9":26,"10":26,"11":130,"12":130,"13":58,"14":58,"15":104,"16":104,"17":28,"18":28,"19":5428,"20":5430,"21":5428},"b":{"1":[5402,0],"2":[26,26],"3":[26,26],"4":[26,26]},"f":{"1":164,"2":5402,"3":26,"4":26,"5":26,"6":130,"7":58,"8":104,"9":28,"10":5428,"11":5430,"12":5428,"13":5774},"fnMap":{"1":{"name":"onlyExtraInfoManager","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":34,"column":4}}},"2":{"name":"__ExtraInformationModule_init_unchained","line":44,"loc":{"start":{"line":40,"column":4},"end":{"line":52,"column":4}}},"3":{"name":"setTokenId","line":67,"loc":{"start":{"line":65,"column":4},"end":{"line":70,"column":4}}},"4":{"name":"setTerms","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":80,"column":4}}},"5":{"name":"setInformation","line":91,"loc":{"start":{"line":89,"column":4},"end":{"line":94,"column":4}}},"6":{"name":"tokenId","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":103,"column":4}}},"7":{"name":"terms","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":111,"column":4}}},"8":{"name":"information","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":119,"column":4}}},"9":{"name":"_setTerms","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":127,"column":4}}},"10":{"name":"_setTokenId","line":129,"loc":{"start":{"line":129,"column":4},"end":{"line":134,"column":4}}},"11":{"name":"_setTerms","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":145,"column":4}}},"12":{"name":"_setInformation","line":147,"loc":{"start":{"line":147,"column":4},"end":{"line":150,"column":4}}},"13":{"name":"_getExtraInformationModuleStorage","line":156,"loc":{"start":{"line":156,"column":4},"end":{"line":160,"column":4}}}},"statementMap":{"1":{"start":{"line":32,"column":8},"end":{"line":32,"column":38}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":85}},"3":{"start":{"line":47,"column":8},"end":{"line":47,"column":31}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":27}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":39}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":85}},"7":{"start":{"line":69,"column":8},"end":{"line":69,"column":31}},"8":{"start":{"line":79,"column":2},"end":{"line":79,"column":18}},"9":{"start":{"line":92,"column":8},"end":{"line":92,"column":85}},"10":{"start":{"line":93,"column":8},"end":{"line":93,"column":39}},"11":{"start":{"line":101,"column":8},"end":{"line":101,"column":85}},"12":{"start":{"line":102,"column":8},"end":{"line":102,"column":25}},"13":{"start":{"line":109,"column":8},"end":{"line":109,"column":85}},"14":{"start":{"line":110,"column":8},"end":{"line":110,"column":23}},"15":{"start":{"line":117,"column":8},"end":{"line":117,"column":85}},"16":{"start":{"line":118,"column":8},"end":{"line":118,"column":29}},"17":{"start":{"line":125,"column":2},"end":{"line":125,"column":79}},"18":{"start":{"line":126,"column":8},"end":{"line":126,"column":27}},"19":{"start":{"line":133,"column":8},"end":{"line":133,"column":40}},"20":{"start":{"line":144,"column":8},"end":{"line":144,"column":28}},"21":{"start":{"line":149,"column":8},"end":{"line":149,"column":38}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":23},"end":{"line":44,"column":23}},{"start":{"line":44,"column":23},"end":{"line":44,"column":23}}]},"2":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":42},"end":{"line":67,"column":42}},{"start":{"line":67,"column":42},"end":{"line":67,"column":42}}]},"3":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":102},"end":{"line":78,"column":102}},{"start":{"line":78,"column":102},"end":{"line":78,"column":102}}]},"4":{"line":91,"type":"if","locations":[{"start":{"line":91,"column":21},"end":{"line":91,"column":21}},{"start":{"line":91,"column":21},"end":{"line":91,"column":21}}]}}},"contracts/modules/wrapper/extensions/SnapshotEngineModule.sol":{"l":{"30":343,"31":334,"45":27,"46":18,"47":18,"65":334,"66":334,"67":325,"77":3300,"78":3300,"87":343,"88":343,"95":3652},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol","s":{"1":343,"2":27,"3":18,"4":18,"5":334,"6":334,"7":325,"8":3300,"9":3300,"10":343},"b":{"1":[27,0],"2":[18,9],"3":[334,9],"4":[325,9]},"f":{"1":343,"2":27,"3":334,"4":3300,"5":343,"6":3652},"fnMap":{"1":{"name":"onlySnapshooter","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"__SnapshotEngineModule_init_unchained","line":44,"loc":{"start":{"line":43,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"setSnapshotEngine","line":64,"loc":{"start":{"line":62,"column":4},"end":{"line":68,"column":4}}},"4":{"name":"snapshotEngine","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"5":{"name":"_setSnapshotEngine","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":89,"column":4}}},"6":{"name":"_getSnapshotEngineModuleStorage","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":98,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":28}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":1821}},"3":{"start":{"line":46,"column":12},"end":{"line":46,"column":85}},"4":{"start":{"line":47,"column":12},"end":{"line":47,"column":49}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"6":{"start":{"line":66,"column":8},"end":{"line":66,"column":104}},"7":{"start":{"line":67,"column":8},"end":{"line":67,"column":45}},"8":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}},"10":{"start":{"line":88,"column":8},"end":{"line":88,"column":44}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":21},"end":{"line":44,"column":21}},{"start":{"line":44,"column":21},"end":{"line":44,"column":21}}]},"2":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]},"3":{"line":64,"type":"if","locations":[{"start":{"line":64,"column":53},"end":{"line":64,"column":53}},{"start":{"line":64,"column":53},"end":{"line":64,"column":53}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]}}},"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol":{"l":{"27":808,"28":804,"29":28,"31":776,"32":28},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol","s":{"1":808,"2":804,"3":776},"b":{"1":[28,776],"2":[28,748]},"f":{"1":808},"fnMap":{"1":{"name":"_canAuthorizeAllowanceByModuleAndRevert","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":34,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":26}},"2":{"start":{"line":28,"column":8},"end":{"line":28,"column":917}},"3":{"start":{"line":31,"column":8},"end":{"line":31,"column":1004}}},"branchMap":{"1":{"line":28,"type":"if","locations":[{"start":{"line":28,"column":8},"end":{"line":28,"column":8}},{"start":{"line":28,"column":8},"end":{"line":28,"column":8}}]},"2":{"line":31,"type":"if","locations":[{"start":{"line":31,"column":8},"end":{"line":31,"column":8}},{"start":{"line":31,"column":8},"end":{"line":31,"column":8}}]}}},"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol":{"l":{"55":93,"56":93,"57":6,"62":22,"67":11,"72":11,"77":11,"82":11,"84":18,"86":3,"103":199,"104":199,"105":199,"106":132,"108":42,"110":25,"120":189,"121":189,"122":11,"124":178,"125":178,"126":132,"128":24,"130":22,"147":223,"148":33,"150":55,"152":11,"154":11,"157":113},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol","s":{"1":93,"2":93,"3":6,"4":87,"5":22,"6":65,"7":11,"8":54,"9":11,"10":43,"11":11,"12":32,"13":11,"14":21,"15":18,"16":3,"17":199,"18":199,"19":199,"20":132,"21":67,"22":42,"23":25,"24":189,"25":189,"26":11,"27":178,"28":178,"29":132,"30":46,"31":24,"32":22,"33":223,"34":33,"35":190,"36":55,"37":135,"38":11,"39":124,"40":11,"41":113},"b":{"1":[6,87],"2":[22,65],"3":[11,54],"4":[11,43],"5":[11,32],"6":[11,21],"7":[18,3],"8":[132,67],"9":[42,25],"10":[11,178],"11":[132,46],"12":[24,22],"13":[33,190],"14":[55,135],"15":[11,124],"16":[11,113]},"f":{"1":93,"2":199,"3":189,"4":223},"fnMap":{"1":{"name":"messageForTransferRestriction","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":88,"column":4}}},"2":{"name":"detectTransferRestriction","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":112,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":114,"loc":{"start":{"line":114,"column":4},"end":{"line":133,"column":4}}},"4":{"name":"_detectTransferRestriction","line":142,"loc":{"start":{"line":142,"column":4},"end":{"line":159,"column":4}}}},"statementMap":{"1":{"start":{"line":55,"column":10},"end":{"line":55,"column":84}},"2":{"start":{"line":56,"column":8},"end":{"line":56,"column":2157}},"3":{"start":{"line":57,"column":12},"end":{"line":57,"column":35}},"4":{"start":{"line":58,"column":15},"end":{"line":58,"column":2288}},"5":{"start":{"line":62,"column":12},"end":{"line":62,"column":48}},"6":{"start":{"line":63,"column":15},"end":{"line":63,"column":2479}},"7":{"start":{"line":67,"column":12},"end":{"line":67,"column":53}},"8":{"start":{"line":68,"column":15},"end":{"line":68,"column":2680}},"9":{"start":{"line":72,"column":12},"end":{"line":72,"column":53}},"10":{"start":{"line":73,"column":15},"end":{"line":73,"column":2881}},"11":{"start":{"line":77,"column":12},"end":{"line":77,"column":51}},"12":{"start":{"line":78,"column":16},"end":{"line":78,"column":3079}},"13":{"start":{"line":82,"column":12},"end":{"line":82,"column":56}},"14":{"start":{"line":83,"column":15},"end":{"line":83,"column":3286}},"15":{"start":{"line":84,"column":12},"end":{"line":84,"column":77}},"16":{"start":{"line":86,"column":12},"end":{"line":86,"column":36}},"17":{"start":{"line":103,"column":9},"end":{"line":103,"column":83}},"18":{"start":{"line":104,"column":9},"end":{"line":104,"column":71}},"19":{"start":{"line":105,"column":9},"end":{"line":105,"column":4192}},"20":{"start":{"line":106,"column":12},"end":{"line":106,"column":29}},"21":{"start":{"line":107,"column":16},"end":{"line":107,"column":4312}},"22":{"start":{"line":108,"column":12},"end":{"line":108,"column":73}},"23":{"start":{"line":110,"column":12},"end":{"line":110,"column":71}},"24":{"start":{"line":120,"column":8},"end":{"line":120,"column":82}},"25":{"start":{"line":121,"column":8},"end":{"line":121,"column":4834}},"26":{"start":{"line":122,"column":12},"end":{"line":122,"column":92}},"27":{"start":{"line":124,"column":12},"end":{"line":124,"column":74}},"28":{"start":{"line":125,"column":12},"end":{"line":125,"column":5062}},"29":{"start":{"line":126,"column":16},"end":{"line":126,"column":33}},"30":{"start":{"line":127,"column":19},"end":{"line":127,"column":5190}},"31":{"start":{"line":128,"column":16},"end":{"line":128,"column":90}},"32":{"start":{"line":130,"column":16},"end":{"line":130,"column":75}},"33":{"start":{"line":147,"column":8},"end":{"line":147,"column":5893}},"34":{"start":{"line":148,"column":12},"end":{"line":148,"column":89}},"35":{"start":{"line":149,"column":15},"end":{"line":149,"column":6019}},"36":{"start":{"line":150,"column":12},"end":{"line":150,"column":84}},"37":{"start":{"line":151,"column":15},"end":{"line":151,"column":6136}},"38":{"start":{"line":152,"column":12},"end":{"line":152,"column":89}},"39":{"start":{"line":153,"column":15},"end":{"line":153,"column":6264}},"40":{"start":{"line":154,"column":12},"end":{"line":154,"column":87}},"41":{"start":{"line":157,"column":12},"end":{"line":157,"column":71}}},"branchMap":{"1":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":8},"end":{"line":56,"column":8}},{"start":{"line":56,"column":8},"end":{"line":56,"column":8}}]},"2":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":15},"end":{"line":58,"column":15}},{"start":{"line":58,"column":15},"end":{"line":58,"column":15}}]},"3":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":15},"end":{"line":63,"column":15}},{"start":{"line":63,"column":15},"end":{"line":63,"column":15}}]},"4":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":15},"end":{"line":68,"column":15}},{"start":{"line":68,"column":15},"end":{"line":68,"column":15}}]},"5":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":15},"end":{"line":73,"column":15}},{"start":{"line":73,"column":15},"end":{"line":73,"column":15}}]},"6":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":16},"end":{"line":78,"column":16}},{"start":{"line":78,"column":16},"end":{"line":78,"column":16}}]},"7":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":15},"end":{"line":83,"column":15}},{"start":{"line":83,"column":15},"end":{"line":83,"column":15}}]},"8":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":9},"end":{"line":105,"column":9}},{"start":{"line":105,"column":9},"end":{"line":105,"column":9}}]},"9":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":16},"end":{"line":107,"column":16}},{"start":{"line":107,"column":16},"end":{"line":107,"column":16}}]},"10":{"line":121,"type":"if","locations":[{"start":{"line":121,"column":8},"end":{"line":121,"column":8}},{"start":{"line":121,"column":8},"end":{"line":121,"column":8}}]},"11":{"line":125,"type":"if","locations":[{"start":{"line":125,"column":12},"end":{"line":125,"column":12}},{"start":{"line":125,"column":12},"end":{"line":125,"column":12}}]},"12":{"line":127,"type":"if","locations":[{"start":{"line":127,"column":19},"end":{"line":127,"column":19}},{"start":{"line":127,"column":19},"end":{"line":127,"column":19}}]},"13":{"line":147,"type":"if","locations":[{"start":{"line":147,"column":8},"end":{"line":147,"column":8}},{"start":{"line":147,"column":8},"end":{"line":147,"column":8}}]},"14":{"line":149,"type":"if","locations":[{"start":{"line":149,"column":15},"end":{"line":149,"column":15}},{"start":{"line":149,"column":15},"end":{"line":149,"column":15}}]},"15":{"line":151,"type":"if","locations":[{"start":{"line":151,"column":15},"end":{"line":151,"column":15}},{"start":{"line":151,"column":15},"end":{"line":151,"column":15}}]},"16":{"line":153,"type":"if","locations":[{"start":{"line":153,"column":15},"end":{"line":153,"column":15}},{"start":{"line":153,"column":15},"end":{"line":153,"column":15}}]}}},"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol":{"l":{"28":364,"29":361,"50":361,"51":358,"63":1009,"76":175,"88":1009,"89":240,"91":769,"101":175,"102":76,"104":99,"114":99,"115":99,"116":30,"118":69,"126":769,"127":769,"128":60,"130":709,"139":7282,"140":6851,"141":6851,"142":715,"143":703,"145":12},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol","s":{"1":364,"2":361,"3":358,"4":1009,"5":175,"6":1009,"7":240,"8":769,"9":175,"10":76,"11":99,"12":99,"13":99,"14":30,"15":69,"16":769,"17":769,"18":60,"19":709,"20":7282,"21":6851,"22":6851,"23":715,"24":703,"25":12},"b":{"1":[361,3],"2":[358,3],"3":[240,769],"4":[76,99],"5":[30,69],"6":[60,709],"7":[715,6136],"8":[703,12]},"f":{"1":364,"2":361,"3":1009,"4":175,"5":1009,"6":175,"7":99,"8":769,"9":7282},"fnMap":{"1":{"name":"onlyRuleEngineManager","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"setRuleEngine","line":49,"loc":{"start":{"line":47,"column":4},"end":{"line":52,"column":4}}},"3":{"name":"canTransfer","line":58,"loc":{"start":{"line":58,"column":4},"end":{"line":64,"column":4}}},"4":{"name":"canTransferFrom","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":77,"column":4}}},"5":{"name":"_canTransfer","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":93,"column":4}}},"6":{"name":"_canTransferFrom","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":106,"column":4}}},"7":{"name":"_canTransferFromWithRuleEngine","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":120,"column":4}}},"8":{"name":"_canTransferWithRuleEngine","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":132,"column":4}}},"9":{"name":"_transferred","line":138,"loc":{"start":{"line":138,"column":4},"end":{"line":148,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":39}},"2":{"start":{"line":50,"column":9},"end":{"line":50,"column":98}},"3":{"start":{"line":51,"column":8},"end":{"line":51,"column":34}},"4":{"start":{"line":63,"column":7},"end":{"line":63,"column":43}},"5":{"start":{"line":76,"column":8},"end":{"line":76,"column":57}},"6":{"start":{"line":88,"column":7},"end":{"line":88,"column":3016}},"7":{"start":{"line":89,"column":12},"end":{"line":89,"column":24}},"8":{"start":{"line":91,"column":12},"end":{"line":91,"column":62}},"9":{"start":{"line":101,"column":8},"end":{"line":101,"column":3371}},"10":{"start":{"line":102,"column":12},"end":{"line":102,"column":24}},"11":{"start":{"line":104,"column":12},"end":{"line":104,"column":75}},"12":{"start":{"line":114,"column":8},"end":{"line":114,"column":46}},"13":{"start":{"line":115,"column":8},"end":{"line":115,"column":3814}},"14":{"start":{"line":116,"column":12},"end":{"line":116,"column":72}},"15":{"start":{"line":118,"column":12},"end":{"line":118,"column":23}},"16":{"start":{"line":126,"column":8},"end":{"line":126,"column":46}},"17":{"start":{"line":127,"column":8},"end":{"line":127,"column":4193}},"18":{"start":{"line":128,"column":12},"end":{"line":128,"column":59}},"19":{"start":{"line":130,"column":12},"end":{"line":130,"column":23}},"20":{"start":{"line":139,"column":8},"end":{"line":139,"column":62}},"21":{"start":{"line":140,"column":8},"end":{"line":140,"column":46}},"22":{"start":{"line":141,"column":8},"end":{"line":141,"column":4745}},"23":{"start":{"line":142,"column":12},"end":{"line":142,"column":4802}},"24":{"start":{"line":143,"column":16},"end":{"line":143,"column":64}},"25":{"start":{"line":145,"column":16},"end":{"line":145,"column":55}}},"branchMap":{"1":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":21},"end":{"line":49,"column":21}},{"start":{"line":49,"column":21},"end":{"line":49,"column":21}}]},"2":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":9},"end":{"line":50,"column":9}},{"start":{"line":50,"column":9},"end":{"line":50,"column":9}}]},"3":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":7},"end":{"line":88,"column":7}},{"start":{"line":88,"column":7},"end":{"line":88,"column":7}}]},"4":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":8},"end":{"line":101,"column":8}},{"start":{"line":101,"column":8},"end":{"line":101,"column":8}}]},"5":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":8},"end":{"line":115,"column":8}},{"start":{"line":115,"column":8},"end":{"line":115,"column":8}}]},"6":{"line":127,"type":"if","locations":[{"start":{"line":127,"column":8},"end":{"line":127,"column":8}},{"start":{"line":127,"column":8},"end":{"line":127,"column":8}}]},"7":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":8}},{"start":{"line":141,"column":8},"end":{"line":141,"column":8}}]},"8":{"line":142,"type":"if","locations":[{"start":{"line":142,"column":12},"end":{"line":142,"column":12}},{"start":{"line":142,"column":12},"end":{"line":142,"column":12}}]}}},"contracts/modules/wrapper/options/AllowlistModule.sol":{"l":{"25":978,"26":970,"37":4,"47":292,"57":532,"67":142,"68":142,"77":4,"84":1438,"91":2396,"92":2396},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/AllowlistModule.sol","s":{"1":978,"2":4,"3":292,"4":532,"5":142,"6":142,"7":4,"8":1438,"9":2396,"10":2396},"b":{"1":[4,2],"2":[292,4],"3":[532,2],"4":[142,0]},"f":{"1":978,"2":4,"3":292,"4":532,"5":142,"6":4,"7":1438,"8":2396},"fnMap":{"1":{"name":"onlyAllowlistManager","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"setAddressAllowlist","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":38,"column":4}}},"3":{"name":"setAddressAllowlist","line":46,"loc":{"start":{"line":44,"column":4},"end":{"line":48,"column":4}}},"4":{"name":"batchSetAddressAllowlist","line":56,"loc":{"start":{"line":54,"column":4},"end":{"line":58,"column":4}}},"5":{"name":"enableAllowlist","line":66,"loc":{"start":{"line":64,"column":4},"end":{"line":69,"column":4}}},"6":{"name":"isAllowlistEnabled","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":78,"column":4}}},"7":{"name":"isAllowlisted","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":85,"column":4}}},"8":{"name":"_addToAllowlist","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":93,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":38}},"2":{"start":{"line":37,"column":9},"end":{"line":37,"column":44}},"3":{"start":{"line":47,"column":9},"end":{"line":47,"column":46}},"4":{"start":{"line":57,"column":9},"end":{"line":57,"column":45}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":31}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":56}},"7":{"start":{"line":77,"column":8},"end":{"line":77,"column":36}},"8":{"start":{"line":84,"column":7},"end":{"line":84,"column":37}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":72}},"10":{"start":{"line":92,"column":8},"end":{"line":92,"column":73}}},"branchMap":{"1":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":78},"end":{"line":36,"column":78}},{"start":{"line":36,"column":78},"end":{"line":36,"column":78}}]},"2":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":21},"end":{"line":46,"column":21}},{"start":{"line":46,"column":21},"end":{"line":46,"column":21}}]},"3":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":21},"end":{"line":56,"column":21}},{"start":{"line":56,"column":21},"end":{"line":56,"column":21}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":21},"end":{"line":66,"column":21}},{"start":{"line":66,"column":21},"end":{"line":66,"column":21}}]}}},"contracts/modules/wrapper/options/CCIPModule.sol":{"l":{"31":48,"32":36,"42":36,"43":36,"44":36,"46":24,"48":24,"55":24,"56":24,"67":60},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/CCIPModule.sol","s":{"1":48,"2":36,"3":36,"4":36,"5":24,"6":24,"7":24},"b":{"1":[36,12],"2":[24,12]},"f":{"1":48,"2":36,"3":24,"4":60},"fnMap":{"1":{"name":"onlyCCIPSetAdmin","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":33,"column":4}}},"2":{"name":"setCCIPAdmin","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":49,"column":2}}},"3":{"name":"getCCIPAdmin","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":57,"column":2}}},"4":{"name":"_getCCIPModuleStorage","line":66,"loc":{"start":{"line":66,"column":2},"end":{"line":70,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":31}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":57}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":40}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":66}},"5":{"start":{"line":48,"column":4},"end":{"line":48,"column":53}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":57}},"7":{"start":{"line":56,"column":4},"end":{"line":56,"column":24}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":57},"end":{"line":41,"column":57}},{"start":{"line":41,"column":57},"end":{"line":41,"column":57}}]},"2":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}},"contracts/modules/wrapper/options/DebtEngineModule.sol":{"l":{"28":18,"29":15,"48":15,"49":15,"50":12,"61":6,"62":6,"63":3,"74":6,"75":6,"76":3,"85":12,"86":12,"95":12,"96":12,"106":39},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtEngineModule.sol","s":{"1":18,"2":15,"3":15,"4":12,"5":6,"6":6,"7":6,"8":6,"9":12,"10":12,"11":12},"b":{"1":[15,3],"2":[12,3],"3":[3,3],"4":[3,3]},"f":{"1":18,"2":15,"3":6,"4":6,"5":12,"6":12,"7":39},"fnMap":{"1":{"name":"onlyDebtEngineManager","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"setDebtEngine","line":47,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"creditEvents","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"debt","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"debtEngine","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":87,"column":4}}},"6":{"name":"_setDebtEngine","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":97,"column":4}}},"7":{"name":"_getDebtEngineModuleStorage","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":109,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":39}},"2":{"start":{"line":48,"column":8},"end":{"line":48,"column":67}},"3":{"start":{"line":49,"column":8},"end":{"line":49,"column":98}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":37}},"5":{"start":{"line":61,"column":8},"end":{"line":61,"column":67}},"6":{"start":{"line":62,"column":8},"end":{"line":62,"column":2681}},"7":{"start":{"line":74,"column":8},"end":{"line":74,"column":67}},"8":{"start":{"line":75,"column":8},"end":{"line":75,"column":3262}},"9":{"start":{"line":85,"column":8},"end":{"line":85,"column":67}},"10":{"start":{"line":86,"column":8},"end":{"line":86,"column":28}},"11":{"start":{"line":96,"column":8},"end":{"line":96,"column":36}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":49},"end":{"line":47,"column":49}},{"start":{"line":47,"column":49},"end":{"line":47,"column":49}}]},"2":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":8},"end":{"line":49,"column":8}},{"start":{"line":49,"column":8},"end":{"line":49,"column":8}}]},"3":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":8},"end":{"line":62,"column":8}},{"start":{"line":62,"column":8},"end":{"line":62,"column":8}}]},"4":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":8},"end":{"line":75,"column":8}},{"start":{"line":75,"column":8},"end":{"line":75,"column":8}}]}}},"contracts/modules/wrapper/options/DebtModule.sol":{"l":{"30":24,"31":12,"47":4,"48":4,"49":4,"60":4,"61":4,"62":4,"73":4,"74":4,"75":4,"83":4,"84":4,"91":8,"92":8,"102":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtModule.sol","s":{"1":24,"2":4,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":8},"b":{"1":[4,4],"2":[4,4],"3":[4,4]},"f":{"1":24,"2":4,"3":4,"4":4,"5":4,"6":8,"7":24},"fnMap":{"1":{"name":"onlyDebtManager","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"setCreditEvents","line":46,"loc":{"start":{"line":44,"column":4},"end":{"line":50,"column":4}}},"3":{"name":"setDebt","line":59,"loc":{"start":{"line":57,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"setDebtInstrument","line":72,"loc":{"start":{"line":70,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"creditEvents","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":85,"column":4}}},"6":{"name":"debt","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":93,"column":4}}},"7":{"name":"_getDebtModuleStorage","line":101,"loc":{"start":{"line":101,"column":4},"end":{"line":105,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":33}},"2":{"start":{"line":47,"column":8},"end":{"line":47,"column":61}},"3":{"start":{"line":49,"column":8},"end":{"line":49,"column":35}},"4":{"start":{"line":60,"column":8},"end":{"line":60,"column":61}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":27}},"6":{"start":{"line":73,"column":8},"end":{"line":73,"column":61}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":37}},"8":{"start":{"line":83,"column":8},"end":{"line":83,"column":61}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":61}}},"branchMap":{"1":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":13},"end":{"line":46,"column":13}},{"start":{"line":46,"column":13},"end":{"line":46,"column":13}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":43},"end":{"line":59,"column":43}},{"start":{"line":59,"column":43},"end":{"line":59,"column":43}}]},"3":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":43},"end":{"line":72,"column":43}},{"start":{"line":72,"column":43},"end":{"line":72,"column":43}}]}}},"contracts/modules/wrapper/options/DocumentEngineModule.sol":{"l":{"29":34,"30":29,"43":37,"44":6,"45":6,"57":15,"58":15,"65":9,"66":9,"67":6,"69":3,"77":5,"78":5,"79":2,"84":9,"85":9,"89":2,"90":2,"101":18,"102":18,"103":15,"113":21,"114":21,"122":64},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DocumentEngineModule.sol","s":{"1":34,"2":37,"3":6,"4":6,"5":15,"6":15,"7":9,"8":9,"9":6,"10":3,"11":5,"12":5,"13":9,"14":9,"15":2,"16":2,"17":18,"18":18,"19":15,"20":21},"b":{"1":[37,0],"2":[6,31],"3":[6,3],"4":[2,3],"5":[9,1],"6":[2,1],"7":[18,3],"8":[15,3]},"f":{"1":34,"2":37,"3":15,"4":9,"5":5,"6":9,"7":2,"8":18,"9":21,"10":64},"fnMap":{"1":{"name":"onlyDocumentManager","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"__DocumentEngineModule_init_unchained","line":42,"loc":{"start":{"line":41,"column":4},"end":{"line":47,"column":4}}},"3":{"name":"documentEngine","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":59,"column":4}}},"4":{"name":"getDocument","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":71,"column":4}}},"5":{"name":"getAllDocuments","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"setDocument","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":86,"column":4}}},"7":{"name":"removeDocument","line":88,"loc":{"start":{"line":88,"column":4},"end":{"line":91,"column":4}}},"8":{"name":"setDocumentEngine","line":100,"loc":{"start":{"line":98,"column":4},"end":{"line":104,"column":4}}},"9":{"name":"_setDocumentEngine","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":115,"column":4}}},"10":{"name":"_getDocumentEngineModuleStorage","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":125,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":37}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":1712}},"3":{"start":{"line":44,"column":12},"end":{"line":44,"column":85}},"4":{"start":{"line":45,"column":12},"end":{"line":45,"column":49}},"5":{"start":{"line":57,"column":8},"end":{"line":57,"column":81}},"6":{"start":{"line":58,"column":8},"end":{"line":58,"column":32}},"7":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"8":{"start":{"line":66,"column":8},"end":{"line":66,"column":2654}},"9":{"start":{"line":67,"column":12},"end":{"line":67,"column":54}},"10":{"start":{"line":69,"column":12},"end":{"line":69,"column":39}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":3076}},"13":{"start":{"line":84,"column":8},"end":{"line":84,"column":81}},"14":{"start":{"line":85,"column":8},"end":{"line":85,"column":61}},"15":{"start":{"line":89,"column":8},"end":{"line":89,"column":81}},"16":{"start":{"line":90,"column":8},"end":{"line":90,"column":45}},"17":{"start":{"line":101,"column":8},"end":{"line":101,"column":81}},"18":{"start":{"line":102,"column":8},"end":{"line":102,"column":110}},"19":{"start":{"line":103,"column":8},"end":{"line":103,"column":45}},"20":{"start":{"line":114,"column":8},"end":{"line":114,"column":44}}},"branchMap":{"1":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":21}},{"start":{"line":42,"column":21},"end":{"line":42,"column":21}}]},"2":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":8}},{"start":{"line":43,"column":8},"end":{"line":43,"column":8}}]},"3":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]},"4":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":8},"end":{"line":78,"column":8}},{"start":{"line":78,"column":8},"end":{"line":78,"column":8}}]},"5":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":116},"end":{"line":83,"column":116}},{"start":{"line":83,"column":116},"end":{"line":83,"column":116}}]},"6":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":76},"end":{"line":88,"column":76}},{"start":{"line":88,"column":76},"end":{"line":88,"column":76}}]},"7":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":53},"end":{"line":100,"column":53}},{"start":{"line":100,"column":53},"end":{"line":100,"column":53}}]},"8":{"line":102,"type":"if","locations":[{"start":{"line":102,"column":8},"end":{"line":102,"column":8}},{"start":{"line":102,"column":8},"end":{"line":102,"column":8}}]}}},"contracts/modules/wrapper/options/ERC20CrossChainModule.sol":{"l":{"33":266,"34":194,"39":96,"40":60,"45":96,"46":48,"61":86,"62":62,"74":108,"75":60,"86":60,"87":60,"98":48,"99":48,"104":84,"112":60,"115":48,"116":48,"120":96,"121":48},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol","s":{"1":266,"2":96,"3":96,"4":86,"5":62,"6":108,"7":60,"8":60,"9":60,"10":48,"11":48,"12":84,"13":60,"14":48,"15":48,"16":96,"17":48},"b":{"1":[86,36],"2":[108,36],"3":[60,36],"4":[48,48],"5":[12,12]},"f":{"1":266,"2":96,"3":96,"4":86,"5":108,"6":60,"7":48,"8":84,"9":60,"10":96},"fnMap":{"1":{"name":"onlyTokenBridge","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":35,"column":4}}},"2":{"name":"onlyBurnerFrom","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"3":{"name":"onlySelfBurn","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":47,"column":4}}},"4":{"name":"crosschainMint","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":63,"column":4}}},"5":{"name":"crosschainBurn","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":76,"column":4}}},"6":{"name":"burnFrom","line":84,"loc":{"start":{"line":83,"column":4},"end":{"line":88,"column":4}}},"7":{"name":"burn","line":97,"loc":{"start":{"line":95,"column":4},"end":{"line":100,"column":4}}},"8":{"name":"supportsInterface","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":105,"column":4}}},"9":{"name":"_burnFrom","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":117,"column":4}}},"10":{"name":"_burnFromOperator","line":119,"loc":{"start":{"line":119,"column":4},"end":{"line":122,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":36}},"2":{"start":{"line":39,"column":8},"end":{"line":39,"column":27}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":27}},"4":{"start":{"line":61,"column":8},"end":{"line":61,"column":31}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":51}},"6":{"start":{"line":74,"column":8},"end":{"line":74,"column":33}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":54}},"8":{"start":{"line":86,"column":8},"end":{"line":86,"column":38}},"9":{"start":{"line":87,"column":8},"end":{"line":87,"column":40}},"10":{"start":{"line":98,"column":8},"end":{"line":98,"column":37}},"11":{"start":{"line":99,"column":8},"end":{"line":99,"column":47}},"12":{"start":{"line":104,"column":8},"end":{"line":104,"column":110}},"13":{"start":{"line":112,"column":8},"end":{"line":112,"column":64}},"14":{"start":{"line":115,"column":8},"end":{"line":115,"column":58}},"15":{"start":{"line":116,"column":8},"end":{"line":116,"column":48}},"16":{"start":{"line":120,"column":8},"end":{"line":120,"column":36}},"17":{"start":{"line":121,"column":8},"end":{"line":121,"column":53}}},"branchMap":{"1":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":89},"end":{"line":60,"column":89}},{"start":{"line":60,"column":89},"end":{"line":60,"column":89}}]},"2":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":91},"end":{"line":73,"column":91}},{"start":{"line":73,"column":91},"end":{"line":73,"column":91}}]},"3":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":48},"end":{"line":84,"column":48}},{"start":{"line":84,"column":48},"end":{"line":84,"column":48}}]},"4":{"line":97,"type":"if","locations":[{"start":{"line":97,"column":46},"end":{"line":97,"column":46}},{"start":{"line":97,"column":46},"end":{"line":97,"column":46}}]},"5":{"line":104,"type":"cond-expr","locations":[{"start":{"line":104,"column":15},"end":{"line":104,"column":56}},{"start":{"line":104,"column":61},"end":{"line":104,"column":109}}]}}},"contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol":{"l":{"30":452,"39":432,"49":74,"50":74,"51":74,"52":74,"53":24,"55":74,"56":74,"66":48,"67":40,"77":32,"78":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol","s":{"1":452,"2":432,"3":74,"4":74,"5":74,"6":74,"7":24,"8":74,"9":74,"10":48,"11":40,"12":32,"13":24},"b":{"1":[74,0],"2":[24,50],"3":[48,0],"4":[32,0]},"f":{"1":452,"2":432,"3":74,"4":48,"5":32},"fnMap":{"1":{"name":"getFrozenTokens","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"getActiveBalanceOf","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":40,"column":4}}},"3":{"name":"forcedTransfer","line":48,"loc":{"start":{"line":47,"column":4},"end":{"line":57,"column":4}}},"4":{"name":"freezePartialTokens","line":65,"loc":{"start":{"line":64,"column":4},"end":{"line":68,"column":4}}},"5":{"name":"unfreezePartialTokens","line":76,"loc":{"start":{"line":75,"column":4},"end":{"line":79,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":62}},"2":{"start":{"line":39,"column":8},"end":{"line":39,"column":43}},"3":{"start":{"line":49,"column":8},"end":{"line":49,"column":59}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":39}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":58}},"6":{"start":{"line":52,"column":8},"end":{"line":52,"column":1980}},"7":{"start":{"line":53,"column":12},"end":{"line":53,"column":124}},"8":{"start":{"line":55,"column":8},"end":{"line":55,"column":94}},"9":{"start":{"line":56,"column":8},"end":{"line":56,"column":19}},"10":{"start":{"line":66,"column":8},"end":{"line":66,"column":43}},"11":{"start":{"line":67,"column":8},"end":{"line":67,"column":88}},"12":{"start":{"line":77,"column":8},"end":{"line":77,"column":45}},"13":{"start":{"line":78,"column":8},"end":{"line":78,"column":90}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":54},"end":{"line":48,"column":54}},{"start":{"line":48,"column":54},"end":{"line":48,"column":54}}]},"2":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":8},"end":{"line":52,"column":8}},{"start":{"line":52,"column":8},"end":{"line":52,"column":8}}]},"3":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":54},"end":{"line":65,"column":54}},{"start":{"line":65,"column":54},"end":{"line":65,"column":54}}]},"4":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":54},"end":{"line":76,"column":54}},{"start":{"line":76,"column":54},"end":{"line":76,"column":54}}]}}},"contracts/modules/wrapper/options/ERC2771Module.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC2771Module.sol","s":{},"b":{},"f":{"1":3323},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":22,"column":4}}}},"statementMap":{},"branchMap":{}},"contracts/modules/wrapper/options/ERC7551Module.sol":{"l":{"43":2,"44":2,"53":2,"54":2,"55":2,"60":4,"61":4,"68":2,"77":2,"78":2,"83":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC7551Module.sol","s":{"1":2,"2":2,"3":2,"4":2,"5":2,"6":4,"7":4,"8":2,"9":2},"b":{"1":[2,2],"2":[2,2]},"f":{"1":2,"2":2,"3":4,"4":2,"5":2,"6":6},"fnMap":{"1":{"name":"setMetaData","line":42,"loc":{"start":{"line":40,"column":4},"end":{"line":45,"column":4}}},"2":{"name":"setTerms","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":56,"column":4}}},"3":{"name":"metaData","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":62,"column":4}}},"4":{"name":"termsHash","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":69,"column":4}}},"5":{"name":"_setMetaData","line":74,"loc":{"start":{"line":74,"column":3},"end":{"line":79,"column":4}}},"6":{"name":"_getERC7551ModuleStorage","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":86,"column":4}}}},"statementMap":{"1":{"start":{"line":43,"column":8},"end":{"line":43,"column":67}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":34}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":94}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":24}},"5":{"start":{"line":55,"column":8},"end":{"line":55,"column":31}},"6":{"start":{"line":60,"column":8},"end":{"line":60,"column":67}},"7":{"start":{"line":61,"column":8},"end":{"line":61,"column":26}},"8":{"start":{"line":68,"column":8},"end":{"line":68,"column":39}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}}},"branchMap":{"1":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":48},"end":{"line":42,"column":48}},{"start":{"line":42,"column":48},"end":{"line":42,"column":48}}]},"2":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":101},"end":{"line":52,"column":101}},{"start":{"line":52,"column":101},"end":{"line":52,"column":101}}]}}},"contracts/modules/wrapper/security/AccessControlModule.sol":{"l":{"25":5688,"26":2,"31":5686,"45":20013,"46":12061,"48":7952},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol","s":{"1":5688,"2":5686,"3":20013,"4":12061,"5":7952},"b":{"1":[5688,0],"2":[2,5686],"3":[12061,7952]},"f":{"1":5688,"2":20013},"fnMap":{"1":{"name":"__AccessControlModule_init_unchained","line":24,"loc":{"start":{"line":23,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"hasRole","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":1015}},"2":{"start":{"line":31,"column":8},"end":{"line":31,"column":44}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":1867}},"4":{"start":{"line":46,"column":12},"end":{"line":46,"column":23}},"5":{"start":{"line":48,"column":12},"end":{"line":48,"column":66}}},"branchMap":{"1":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":13},"end":{"line":24,"column":13}},{"start":{"line":24,"column":13},"end":{"line":24,"column":13}}]},"2":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":8},"end":{"line":25,"column":8}},{"start":{"line":25,"column":8},"end":{"line":25,"column":8}}]},"3":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]}}}}
\ No newline at end of file
diff --git a/doc/test/coverage/coverage-final.json b/doc/test/coverage/coverage-final.json
index 373fe938..4a2a2822 100644
--- a/doc/test/coverage/coverage-final.json
+++ b/doc/test/coverage/coverage-final.json
@@ -1,19 +1,23 @@
{
-"contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol":{"l":{"29":295},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol","s":{"1":295},"b":{},"f":{"1":295},"fnMap":{"1":{"name":"constructor","line":27,"loc":{"start":{"line":22,"column":4},"end":{"line":34,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":1276}}},"branchMap":{}},
-"contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol":{"l":{"20":178},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol","s":{"1":178},"b":{},"f":{"1":178},"fnMap":{"1":{"name":"constructor","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":21,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":29}}},"branchMap":{}},
-"contracts/deployment/CMTATStandalone.sol":{"l":{"31":300},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandalone.sol","s":{"1":300},"b":{},"f":{"1":300},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1278}}},"branchMap":{}},
-"contracts/deployment/CMTATUpgradeable.sol":{"l":{"22":367},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeable.sol","s":{"1":367},"b":{},"f":{"1":367},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},
-"contracts/deployment/CMTATUpgradeableUUPS.sol":{"l":{"22":506},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol","s":{"1":506},"b":{"1":[2,1]},"f":{"1":506,"2":2},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}},"2":{"name":"_authorizeUpgrade","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":32,"column":131}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{"1":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":101},"end":{"line":32,"column":101}},{"start":{"line":32,"column":101},"end":{"line":32,"column":101}}]}}},
-"contracts/deployment/debt/CMTATStandaloneDebt.sol":{"l":{"26":360},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.sol","s":{"1":360},"b":{},"f":{"1":360},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":1027}}},"branchMap":{}},
-"contracts/deployment/debt/CMTATUpgradeableDebt.sol":{"l":{"16":302},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt.sol","s":{"1":302},"b":{},"f":{"1":302},"fnMap":{"1":{"name":"constructor","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":17,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":29}}},"branchMap":{}},
-"contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol":{"l":{"26":364},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol","s":{"1":364},"b":{},"f":{"1":364},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":1051}}},"branchMap":{}},
-"contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol":{"l":{"16":128},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol","s":{"1":128},"b":{},"f":{"1":128},"fnMap":{"1":{"name":"constructor","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":17,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":29}}},"branchMap":{}},
-"contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol":{"l":{"31":182},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol","s":{"1":182},"b":{},"f":{"1":182},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1300}}},"branchMap":{}},
-"contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol":{"l":{"22":257},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol","s":{"1":257},"b":{},"f":{"1":257},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},
-"contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol":{"l":{"30":228},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol","s":{"1":228},"b":{},"f":{"1":228},"fnMap":{"1":{"name":"constructor","line":28,"loc":{"start":{"line":22,"column":4},"end":{"line":36,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":1293}}},"branchMap":{}},
-"contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol":{"l":{"21":228},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol","s":{"1":228},"b":{},"f":{"1":228},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":17,"column":4},"end":{"line":22,"column":4}}}},"statementMap":{"1":{"start":{"line":21,"column":8},"end":{"line":21,"column":29}}},"branchMap":{}},
-"contracts/deployment/light/CMTATStandaloneLight.sol":{"l":{"23":103},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight.sol","s":{"1":103},"b":{},"f":{"1":103},"fnMap":{"1":{"name":"constructor","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":27,"column":4}}}},"statementMap":{"1":{"start":{"line":23,"column":8},"end":{"line":23,"column":790}}},"branchMap":{}},
-"contracts/deployment/light/CMTATUpgradeableLight.sol":{"l":{"18":99},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLight.sol","s":{"1":99},"b":{},"f":{"1":99},"fnMap":{"1":{"name":"constructor","line":16,"loc":{"start":{"line":16,"column":4},"end":{"line":19,"column":4}}}},"statementMap":{"1":{"start":{"line":18,"column":8},"end":{"line":18,"column":29}}},"branchMap":{}},
+"contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol":{"l":{"29":368},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol","s":{"1":368},"b":{},"f":{"1":368},"fnMap":{"1":{"name":"constructor","line":27,"loc":{"start":{"line":22,"column":4},"end":{"line":34,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":1249}}},"branchMap":{}},
+"contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol":{"l":{"20":226},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol","s":{"1":226},"b":{},"f":{"1":226},"fnMap":{"1":{"name":"constructor","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":21,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":29}}},"branchMap":{}},
+"contracts/deployment/CMTATStandardStandalone.sol":{"l":{"31":308},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardStandalone.sol","s":{"1":308},"b":{},"f":{"1":308},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1349}}},"branchMap":{}},
+"contracts/deployment/CMTATStandardUpgradeable.sol":{"l":{"22":336},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardUpgradeable.sol","s":{"1":336},"b":{},"f":{"1":336},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},
+"contracts/deployment/CMTATUpgradeableUUPS.sol":{"l":{"22":450},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol","s":{"1":450},"b":{"1":[2,1]},"f":{"1":450,"2":2},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}},"2":{"name":"_authorizeUpgrade","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":32,"column":131}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{"1":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":101},"end":{"line":32,"column":101}},{"start":{"line":32,"column":101},"end":{"line":32,"column":101}}]}}},
+"contracts/deployment/debt/CMTATStandaloneDebt.sol":{"l":{"26":446},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.sol","s":{"1":446},"b":{},"f":{"1":446},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":1027}}},"branchMap":{}},
+"contracts/deployment/debt/CMTATUpgradeableDebt.sol":{"l":{"16":456},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt.sol","s":{"1":456},"b":{},"f":{"1":456},"fnMap":{"1":{"name":"constructor","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":17,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":29}}},"branchMap":{}},
+"contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol":{"l":{"26":450},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol","s":{"1":450},"b":{},"f":{"1":450},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":32,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":1051}}},"branchMap":{}},
+"contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol":{"l":{"16":204},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol","s":{"1":204},"b":{},"f":{"1":204},"fnMap":{"1":{"name":"constructor","line":14,"loc":{"start":{"line":14,"column":4},"end":{"line":17,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":29}}},"branchMap":{}},
+"contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol":{"l":{"31":228},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol","s":{"1":228},"b":{},"f":{"1":228},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1273}}},"branchMap":{}},
+"contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol":{"l":{"22":268},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol","s":{"1":268},"b":{},"f":{"1":268},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},
+"contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol":{"l":{"30":230},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol","s":{"1":230},"b":{},"f":{"1":230},"fnMap":{"1":{"name":"constructor","line":28,"loc":{"start":{"line":22,"column":4},"end":{"line":36,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":1293}}},"branchMap":{}},
+"contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol":{"l":{"21":230},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol","s":{"1":230},"b":{},"f":{"1":230},"fnMap":{"1":{"name":"constructor","line":19,"loc":{"start":{"line":17,"column":4},"end":{"line":22,"column":4}}}},"statementMap":{"1":{"start":{"line":21,"column":8},"end":{"line":21,"column":29}}},"branchMap":{}},
+"contracts/deployment/light/CMTATStandaloneLight.sol":{"l":{"23":125},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight.sol","s":{"1":125},"b":{},"f":{"1":125},"fnMap":{"1":{"name":"constructor","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":27,"column":4}}}},"statementMap":{"1":{"start":{"line":23,"column":8},"end":{"line":23,"column":790}}},"branchMap":{}},
+"contracts/deployment/light/CMTATUpgradeableLight.sol":{"l":{"18":122},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLight.sol","s":{"1":122},"b":{},"f":{"1":122},"fnMap":{"1":{"name":"constructor","line":16,"loc":{"start":{"line":16,"column":4},"end":{"line":19,"column":4}}}},"statementMap":{"1":{"start":{"line":18,"column":8},"end":{"line":18,"column":29}}},"branchMap":{}},
+"contracts/deployment/permit/CMTATStandalonePermit.sol":{"l":{"27":228},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATStandalonePermit.sol","s":{"1":228},"b":{},"f":{"1":228},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":33,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":1070}}},"branchMap":{}},
+"contracts/deployment/permit/CMTATUpgradeablePermit.sol":{"l":{"17":230},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATUpgradeablePermit.sol","s":{"1":230},"b":{},"f":{"1":230},"fnMap":{"1":{"name":"constructor","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":18,"column":4}}}},"statementMap":{"1":{"start":{"line":17,"column":8},"end":{"line":17,"column":29}}},"branchMap":{}},
+"contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol":{"l":{"31":327},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol","s":{"1":327},"b":{},"f":{"1":327},"fnMap":{"1":{"name":"constructor","line":29,"loc":{"start":{"line":23,"column":4},"end":{"line":37,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1348}}},"branchMap":{}},
+"contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol":{"l":{"22":352},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol","s":{"1":352},"b":{},"f":{"1":352},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":23,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":29}}},"branchMap":{}},
"contracts/interfaces/engine/IDebtEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDebtEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},
"contracts/interfaces/engine/IDocumentEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDocumentEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},
"contracts/interfaces/engine/IRuleEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IRuleEngine.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},
@@ -38,46 +42,54 @@
"contracts/interfaces/tokenization/IERC3643Partial.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/IERC3643Partial.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},
"contracts/library/ERC1404ExtendInterfaceId.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/library/ERC1404ExtendInterfaceId.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},
"contracts/library/RuleEngineInterfaceId.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/library/RuleEngineInterfaceId.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},
-"contracts/modules/0_CMTATBaseCommon.sol":{"l":{"56":18,"64":56,"71":54,"77":325,"78":325,"79":199,"80":151,"95":178,"96":62,"113":90,"114":54,"121":9056,"134":5270,"136":5270,"137":277,"138":277,"139":277,"142":277,"145":277,"148":4993,"160":4179,"161":4147,"170":687,"171":648,"180":141,"181":118},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol","s":{"1":18,"2":56,"3":54,"4":325,"5":325,"6":199,"7":151,"8":178,"9":62,"10":90,"11":54,"12":9056,"13":5270,"14":5270,"15":277,"16":277,"17":277,"18":277,"19":277,"20":4993,"21":4179,"22":4147,"23":687,"24":648,"25":141,"26":118},"b":{"1":[277,4993]},"f":{"1":18,"2":56,"3":54,"4":325,"5":178,"6":90,"7":9056,"8":5270,"9":4179,"10":687,"11":141},"fnMap":{"1":{"name":"decimals","line":49,"loc":{"start":{"line":49,"column":4},"end":{"line":57,"column":4}}},"2":{"name":"name","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":4}}},"3":{"name":"symbol","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":72,"column":4}}},"4":{"name":"transfer","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":81,"column":4}}},"5":{"name":"transferFrom","line":85,"loc":{"start":{"line":85,"column":4},"end":{"line":97,"column":4}}},"6":{"name":"burnAndMint","line":111,"loc":{"start":{"line":111,"column":4},"end":{"line":115,"column":4}}},"7":{"name":"_checkTransferred","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":122,"column":4}}},"8":{"name":"_update","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":150,"column":4}}},"9":{"name":"_mintOverride","line":159,"loc":{"start":{"line":159,"column":4},"end":{"line":162,"column":4}}},"10":{"name":"_burnOverride","line":169,"loc":{"start":{"line":169,"column":4},"end":{"line":172,"column":4}}},"11":{"name":"_minterTransferOverride","line":179,"loc":{"start":{"line":179,"column":4},"end":{"line":182,"column":4}}}},"statementMap":{"1":{"start":{"line":56,"column":8},"end":{"line":56,"column":41}},"2":{"start":{"line":64,"column":8},"end":{"line":64,"column":37}},"3":{"start":{"line":71,"column":8},"end":{"line":71,"column":39}},"4":{"start":{"line":77,"column":9},"end":{"line":77,"column":36}},"5":{"start":{"line":78,"column":8},"end":{"line":78,"column":53}},"6":{"start":{"line":79,"column":8},"end":{"line":79,"column":50}},"7":{"start":{"line":80,"column":8},"end":{"line":80,"column":19}},"8":{"start":{"line":95,"column":8},"end":{"line":95,"column":55}},"9":{"start":{"line":96,"column":8},"end":{"line":96,"column":60}},"10":{"start":{"line":113,"column":8},"end":{"line":113,"column":53}},"11":{"start":{"line":114,"column":8},"end":{"line":114,"column":51}},"12":{"start":{"line":121,"column":8},"end":{"line":121,"column":79}},"13":{"start":{"line":134,"column":8},"end":{"line":134,"column":62}},"14":{"start":{"line":136,"column":8},"end":{"line":136,"column":4659}},"15":{"start":{"line":137,"column":10},"end":{"line":137,"column":53}},"16":{"start":{"line":138,"column":10},"end":{"line":138,"column":49}},"17":{"start":{"line":139,"column":10},"end":{"line":139,"column":51}},"18":{"start":{"line":142,"column":10},"end":{"line":142,"column":51}},"19":{"start":{"line":145,"column":10},"end":{"line":145,"column":111}},"20":{"start":{"line":148,"column":12},"end":{"line":148,"column":53}},"21":{"start":{"line":160,"column":8},"end":{"line":160,"column":64}},"22":{"start":{"line":161,"column":8},"end":{"line":161,"column":60}},"23":{"start":{"line":170,"column":8},"end":{"line":170,"column":65}},"24":{"start":{"line":171,"column":8},"end":{"line":171,"column":60}},"25":{"start":{"line":180,"column":8},"end":{"line":180,"column":53}},"26":{"start":{"line":181,"column":8},"end":{"line":181,"column":71}}},"branchMap":{"1":{"line":136,"type":"if","locations":[{"start":{"line":136,"column":8},"end":{"line":136,"column":8}},{"start":{"line":136,"column":8},"end":{"line":136,"column":8}}]}}},
-"contracts/modules/0_CMTATBaseCore.sol":{"l":{"57":4,"58":3,"74":202,"90":202,"93":202,"96":202,"99":202,"107":202,"108":202,"117":202,"118":202,"143":2,"151":6,"158":6,"169":4,"177":22,"178":22,"179":12,"180":8,"195":10,"196":6,"213":10,"214":6,"227":3,"229":2,"230":2,"239":298,"240":290,"245":70,"246":60,"253":18,"254":12},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol","s":{"1":4,"2":202,"3":202,"4":202,"5":202,"6":202,"7":202,"8":202,"9":202,"10":202,"11":2,"12":6,"13":6,"14":4,"15":22,"16":22,"17":12,"18":8,"19":10,"20":6,"21":10,"22":6,"23":3,"24":2,"25":2,"26":298,"27":290,"28":70,"29":60,"30":18,"31":12},"b":{"1":[202,0],"2":[202,0],"3":[202,0],"4":[202,0],"5":[1,1],"6":[3,1],"7":[2,1],"8":[3,1],"9":[240,6],"10":[52,8],"11":[46,4],"12":[16,2],"13":[41,6],"14":[4,4]},"f":{"1":4,"2":202,"3":202,"4":202,"5":202,"6":2,"7":6,"8":6,"9":4,"10":22,"11":10,"12":10,"13":3,"14":298,"15":70,"16":18,"17":3,"18":240,"19":52,"20":46,"21":16,"22":41,"23":4},"fnMap":{"1":{"name":"onlyERC20ForcedBurnManager","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":59,"column":4}}},"2":{"name":"initialize","line":73,"loc":{"start":{"line":70,"column":4},"end":{"line":78,"column":4}}},"3":{"name":"__CMTAT_init","line":87,"loc":{"start":{"line":84,"column":4},"end":{"line":100,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":109,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":115,"loc":{"start":{"line":115,"column":4},"end":{"line":119,"column":4}}},"6":{"name":"decimals","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":144,"column":4}}},"7":{"name":"name","line":150,"loc":{"start":{"line":150,"column":4},"end":{"line":152,"column":4}}},"8":{"name":"symbol","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":159,"column":4}}},"9":{"name":"supportsInterface","line":168,"loc":{"start":{"line":168,"column":4},"end":{"line":170,"column":4}}},"10":{"name":"transfer","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":181,"column":4}}},"11":{"name":"transferFrom","line":185,"loc":{"start":{"line":185,"column":4},"end":{"line":197,"column":4}}},"12":{"name":"burnAndMint","line":212,"loc":{"start":{"line":212,"column":4},"end":{"line":215,"column":4}}},"13":{"name":"forcedBurn","line":226,"loc":{"start":{"line":222,"column":4},"end":{"line":231,"column":4}}},"14":{"name":"_mintOverride","line":238,"loc":{"start":{"line":238,"column":4},"end":{"line":241,"column":4}}},"15":{"name":"_burnOverride","line":244,"loc":{"start":{"line":244,"column":4},"end":{"line":247,"column":4}}},"16":{"name":"_minterTransferOverride","line":252,"loc":{"start":{"line":252,"column":4},"end":{"line":255,"column":4}}},"17":{"name":"_authorizeForcedBurn","line":258,"loc":{"start":{"line":258,"column":4},"end":{"line":258,"column":82}}},"18":{"name":"_authorizeMint","line":260,"loc":{"start":{"line":260,"column":4},"end":{"line":260,"column":95}}},"19":{"name":"_authorizeBurn","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":262,"column":95}}},"20":{"name":"_authorizePause","line":264,"loc":{"start":{"line":264,"column":4},"end":{"line":264,"column":92}}},"21":{"name":"_authorizeDeactivate","line":265,"loc":{"start":{"line":265,"column":4},"end":{"line":265,"column":104}}},"22":{"name":"_authorizeFreeze","line":267,"loc":{"start":{"line":267,"column":4},"end":{"line":267,"column":101}}},"23":{"name":"_authorizeERC20AttributeManagement","line":269,"loc":{"start":{"line":269,"column":4},"end":{"line":269,"column":122}}}},"statementMap":{"1":{"start":{"line":57,"column":8},"end":{"line":57,"column":29}},"2":{"start":{"line":74,"column":8},"end":{"line":74,"column":2897}},"3":{"start":{"line":90,"column":8},"end":{"line":90,"column":33}},"4":{"start":{"line":93,"column":8},"end":{"line":93,"column":32}},"5":{"start":{"line":96,"column":8},"end":{"line":96,"column":44}},"6":{"start":{"line":99,"column":8},"end":{"line":99,"column":62}},"7":{"start":{"line":107,"column":8},"end":{"line":107,"column":39}},"8":{"start":{"line":108,"column":8},"end":{"line":108,"column":34}},"9":{"start":{"line":117,"column":8},"end":{"line":117,"column":50}},"10":{"start":{"line":118,"column":8},"end":{"line":118,"column":125}},"11":{"start":{"line":143,"column":8},"end":{"line":143,"column":41}},"12":{"start":{"line":151,"column":8},"end":{"line":151,"column":37}},"13":{"start":{"line":158,"column":8},"end":{"line":158,"column":39}},"14":{"start":{"line":169,"column":8},"end":{"line":169,"column":99}},"15":{"start":{"line":177,"column":8},"end":{"line":177,"column":35}},"16":{"start":{"line":178,"column":8},"end":{"line":178,"column":82}},"17":{"start":{"line":179,"column":8},"end":{"line":179,"column":50}},"18":{"start":{"line":180,"column":8},"end":{"line":180,"column":19}},"19":{"start":{"line":195,"column":8},"end":{"line":195,"column":84}},"20":{"start":{"line":196,"column":8},"end":{"line":196,"column":60}},"21":{"start":{"line":213,"column":8},"end":{"line":213,"column":53}},"22":{"start":{"line":214,"column":8},"end":{"line":214,"column":51}},"23":{"start":{"line":227,"column":8},"end":{"line":227,"column":95}},"24":{"start":{"line":229,"column":8},"end":{"line":229,"column":45}},"25":{"start":{"line":230,"column":8},"end":{"line":230,"column":60}},"26":{"start":{"line":239,"column":8},"end":{"line":239,"column":62}},"27":{"start":{"line":240,"column":8},"end":{"line":240,"column":60}},"28":{"start":{"line":245,"column":8},"end":{"line":245,"column":62}},"29":{"start":{"line":246,"column":8},"end":{"line":246,"column":60}},"30":{"start":{"line":253,"column":8},"end":{"line":253,"column":82}},"31":{"start":{"line":254,"column":8},"end":{"line":254,"column":71}}},"branchMap":{"1":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":21},"end":{"line":73,"column":21}},{"start":{"line":73,"column":21},"end":{"line":73,"column":21}}]},"2":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":23},"end":{"line":87,"column":23}},{"start":{"line":87,"column":23},"end":{"line":87,"column":23}}]},"3":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":68},"end":{"line":105,"column":68}},{"start":{"line":105,"column":68},"end":{"line":105,"column":68}}]},"4":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":136},"end":{"line":115,"column":136}},{"start":{"line":115,"column":136},"end":{"line":115,"column":136}}]},"5":{"line":169,"type":"cond-expr","locations":[{"start":{"line":169,"column":15},"end":{"line":169,"column":39}},{"start":{"line":169,"column":44},"end":{"line":169,"column":98}}]},"6":{"line":226,"type":"if","locations":[{"start":{"line":226,"column":48},"end":{"line":226,"column":48}},{"start":{"line":226,"column":48},"end":{"line":226,"column":48}}]},"7":{"line":227,"type":"if","locations":[{"start":{"line":227,"column":8},"end":{"line":227,"column":8}},{"start":{"line":227,"column":8},"end":{"line":227,"column":8}}]},"8":{"line":258,"type":"if","locations":[{"start":{"line":258,"column":53},"end":{"line":258,"column":53}},{"start":{"line":258,"column":53},"end":{"line":258,"column":53}}]},"9":{"line":260,"type":"if","locations":[{"start":{"line":260,"column":73},"end":{"line":260,"column":73}},{"start":{"line":260,"column":73},"end":{"line":260,"column":73}}]},"10":{"line":262,"type":"if","locations":[{"start":{"line":262,"column":73},"end":{"line":262,"column":73}},{"start":{"line":262,"column":73},"end":{"line":262,"column":73}}]},"11":{"line":264,"type":"if","locations":[{"start":{"line":264,"column":70},"end":{"line":264,"column":70}},{"start":{"line":264,"column":70},"end":{"line":264,"column":70}}]},"12":{"line":265,"type":"if","locations":[{"start":{"line":265,"column":75},"end":{"line":265,"column":75}},{"start":{"line":265,"column":75},"end":{"line":265,"column":75}}]},"13":{"line":267,"type":"if","locations":[{"start":{"line":267,"column":77},"end":{"line":267,"column":77}},{"start":{"line":267,"column":77},"end":{"line":267,"column":77}}]},"14":{"line":269,"type":"if","locations":[{"start":{"line":269,"column":93},"end":{"line":269,"column":93}},{"start":{"line":269,"column":93},"end":{"line":269,"column":93}}]}}},
-"contracts/modules/0_CMTATBaseGeneric.sol":{"l":{"50":51,"53":51,"56":51,"59":51,"67":51,"68":51,"76":51,"78":51},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseGeneric.sol","s":{"1":51,"2":51,"3":51,"4":51,"5":51,"6":51,"7":51,"8":51},"b":{"1":[51,0],"2":[51,0],"3":[51,0],"4":[6,0],"5":[3,3]},"f":{"1":51,"2":51,"3":51,"4":6,"5":3},"fnMap":{"1":{"name":"__CMTAT_init","line":47,"loc":{"start":{"line":44,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"__CMTAT_openzeppelin_init_unchained","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":69,"column":4}}},"3":{"name":"__CMTAT_modules_init_unchained","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":79,"column":4}}},"4":{"name":"_authorizeDocumentManagement","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":86,"column":117}}},"5":{"name":"_authorizeExtraInfoManagement","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":87,"column":129}}}},"statementMap":{"1":{"start":{"line":50,"column":8},"end":{"line":50,"column":33}},"2":{"start":{"line":53,"column":8},"end":{"line":53,"column":32}},"3":{"start":{"line":56,"column":8},"end":{"line":56,"column":44}},"4":{"start":{"line":59,"column":8},"end":{"line":59,"column":74}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":39}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":34}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":50}},"8":{"start":{"line":78,"column":8},"end":{"line":78,"column":159}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":23},"end":{"line":47,"column":23}},{"start":{"line":47,"column":23},"end":{"line":47,"column":23}}]},"2":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":68},"end":{"line":65,"column":68}},{"start":{"line":65,"column":68},"end":{"line":65,"column":68}}]},"3":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":157},"end":{"line":74,"column":157}},{"start":{"line":74,"column":157},"end":{"line":74,"column":157}}]},"4":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":93},"end":{"line":86,"column":93}},{"start":{"line":86,"column":93},"end":{"line":86,"column":93}}]},"5":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":96},"end":{"line":87,"column":96}},{"start":{"line":87,"column":96},"end":{"line":87,"column":96}}]}}},
-"contracts/modules/1_CMTATBaseAccessControl.sol":{"l":{"32":3692,"34":3690,"36":3690,"50":34},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/1_CMTATBaseAccessControl.sol","s":{"1":3692,"2":3690,"3":3690,"4":34},"b":{"1":[3692,0],"2":[14,2],"3":[2,4],"4":[38,36],"5":[3648,54],"6":[486,72],"7":[112,2],"8":[67,67],"9":[618,42],"10":[128,28],"11":[501,2]},"f":{"1":3692,"2":34,"3":38,"4":3648,"5":486,"6":112,"7":67,"8":618,"9":128,"10":501},"fnMap":{"1":{"name":"__CMTAT_commonModules_init_unchained","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":37,"column":4}}},"2":{"name":"supportsInterface","line":49,"loc":{"start":{"line":49,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"_authorizeERC20AttributeManagement","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":63,"column":122}}},"4":{"name":"_authorizeMint","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":69,"column":95}}},"5":{"name":"_authorizeBurn","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":75,"column":95}}},"6":{"name":"_authorizeDocumentManagement","line":81,"loc":{"start":{"line":81,"column":4},"end":{"line":81,"column":117}}},"7":{"name":"_authorizeExtraInfoManagement","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":87,"column":129}}},"8":{"name":"_authorizeERC20Enforcer","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":93,"column":118}}},"9":{"name":"_authorizeForcedTransfer","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":99,"column":119}}},"10":{"name":"_authorizeSnapshots","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":105,"column":110}}}},"statementMap":{"1":{"start":{"line":32,"column":8},"end":{"line":32,"column":50}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":125}},"3":{"start":{"line":36,"column":8},"end":{"line":36,"column":177}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":128}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":228},"end":{"line":30,"column":228}},{"start":{"line":30,"column":228},"end":{"line":30,"column":228}}]},"2":{"line":50,"type":"cond-expr","locations":[{"start":{"line":50,"column":15},"end":{"line":50,"column":39}},{"start":{"line":50,"column":44},"end":{"line":50,"column":68}}]},"3":{"line":50,"type":"cond-expr","locations":[{"start":{"line":50,"column":15},"end":{"line":50,"column":68}},{"start":{"line":50,"column":73},"end":{"line":50,"column":127}}]},"4":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":93},"end":{"line":63,"column":93}},{"start":{"line":63,"column":93},"end":{"line":63,"column":93}}]},"5":{"line":69,"type":"if","locations":[{"start":{"line":69,"column":73},"end":{"line":69,"column":73}},{"start":{"line":69,"column":73},"end":{"line":69,"column":73}}]},"6":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":73},"end":{"line":75,"column":73}},{"start":{"line":75,"column":73},"end":{"line":75,"column":73}}]},"7":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":93},"end":{"line":81,"column":93}},{"start":{"line":81,"column":93},"end":{"line":81,"column":93}}]},"8":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":96},"end":{"line":87,"column":96}},{"start":{"line":87,"column":96},"end":{"line":87,"column":96}}]},"9":{"line":93,"type":"if","locations":[{"start":{"line":93,"column":89},"end":{"line":93,"column":89}},{"start":{"line":93,"column":89},"end":{"line":93,"column":89}}]},"10":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":90},"end":{"line":99,"column":90}},{"start":{"line":99,"column":90},"end":{"line":99,"column":90}}]},"11":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":83},"end":{"line":105,"column":83}},{"start":{"line":105,"column":83},"end":{"line":105,"column":83}}]}}},
-"contracts/modules/2_CMTATBaseAllowlist.sol":{"l":{"54":473,"72":473,"75":473,"78":473,"81":473,"89":473,"90":473,"92":473,"99":473,"101":473,"115":52,"126":220,"127":220,"128":58,"130":162,"144":31,"145":31,"146":8,"148":23,"171":12,"177":721,"181":68,"189":173,"197":93,"201":826,"202":814,"218":5159,"227":5161,"239":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAllowlist.sol","s":{"1":473,"2":473,"3":473,"4":473,"5":473,"6":473,"7":473,"8":473,"9":473,"10":473,"11":52,"12":220,"13":220,"14":58,"15":162,"16":31,"17":31,"18":8,"19":23,"20":12,"21":721,"22":68,"23":173,"24":93,"25":826,"26":814,"27":5159,"28":5161,"29":2},"b":{"1":[473,0],"2":[473,0],"3":[473,0],"4":[473,0],"5":[52,3],"6":[58,162],"7":[8,23],"8":[72,6],"9":[24,3],"10":[60,9],"11":[761,8]},"f":{"1":473,"2":473,"3":473,"4":473,"5":52,"6":220,"7":31,"8":72,"9":24,"10":60,"11":761,"12":12,"13":721,"14":68,"15":173,"16":93,"17":826,"18":5159,"19":5161,"20":2},"fnMap":{"1":{"name":"initialize","line":53,"loc":{"start":{"line":49,"column":4},"end":{"line":59,"column":4}}},"2":{"name":"__CMTAT_init","line":69,"loc":{"start":{"line":65,"column":4},"end":{"line":82,"column":4}}},"3":{"name":"__CMTAT_openzeppelin_init_unchained","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":93,"column":4}}},"4":{"name":"__CMTAT_modules_init_unchained","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":102,"column":4}}},"5":{"name":"approve","line":114,"loc":{"start":{"line":114,"column":4},"end":{"line":116,"column":4}}},"6":{"name":"canTransfer","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":133,"column":4}}},"7":{"name":"canTransferFrom","line":138,"loc":{"start":{"line":138,"column":3},"end":{"line":150,"column":4}}},"8":{"name":"_authorizePause","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":157,"column":92}}},"9":{"name":"_authorizeDeactivate","line":158,"loc":{"start":{"line":158,"column":4},"end":{"line":158,"column":104}}},"10":{"name":"_authorizeFreeze","line":160,"loc":{"start":{"line":160,"column":4},"end":{"line":160,"column":101}}},"11":{"name":"_authorizeAllowlistManagement","line":162,"loc":{"start":{"line":162,"column":4},"end":{"line":162,"column":114}}},"12":{"name":"_canMintBurnByModule","line":168,"loc":{"start":{"line":168,"column":4},"end":{"line":172,"column":4}}},"13":{"name":"_canMintBurnByModuleAndRevert","line":174,"loc":{"start":{"line":174,"column":4},"end":{"line":178,"column":4}}},"14":{"name":"_canTransact","line":180,"loc":{"start":{"line":180,"column":2},"end":{"line":182,"column":2}}},"15":{"name":"_canTransferStandardByModule","line":184,"loc":{"start":{"line":184,"column":4},"end":{"line":190,"column":4}}},"16":{"name":"_canTransferStandardByModuleAndRevert","line":192,"loc":{"start":{"line":192,"column":4},"end":{"line":198,"column":4}}},"17":{"name":"_checkTransferred","line":200,"loc":{"start":{"line":200,"column":4},"end":{"line":203,"column":4}}},"18":{"name":"_msgSender","line":212,"loc":{"start":{"line":212,"column":4},"end":{"line":219,"column":4}}},"19":{"name":"_contextSuffixLength","line":224,"loc":{"start":{"line":224,"column":4},"end":{"line":228,"column":4}}},"20":{"name":"_msgData","line":233,"loc":{"start":{"line":233,"column":4},"end":{"line":240,"column":4}}}},"statementMap":{"1":{"start":{"line":54,"column":8},"end":{"line":54,"column":2472}},"2":{"start":{"line":72,"column":8},"end":{"line":72,"column":33}},"3":{"start":{"line":75,"column":8},"end":{"line":75,"column":32}},"4":{"start":{"line":78,"column":8},"end":{"line":78,"column":60}},"5":{"start":{"line":81,"column":8},"end":{"line":81,"column":91}},"6":{"start":{"line":89,"column":8},"end":{"line":89,"column":39}},"7":{"start":{"line":90,"column":8},"end":{"line":90,"column":34}},"8":{"start":{"line":92,"column":8},"end":{"line":92,"column":77}},"9":{"start":{"line":99,"column":9},"end":{"line":99,"column":97}},"10":{"start":{"line":101,"column":8},"end":{"line":101,"column":35}},"11":{"start":{"line":115,"column":8},"end":{"line":115,"column":55}},"12":{"start":{"line":126,"column":8},"end":{"line":126,"column":89}},"13":{"start":{"line":127,"column":8},"end":{"line":127,"column":5337}},"14":{"start":{"line":128,"column":12},"end":{"line":128,"column":24}},"15":{"start":{"line":130,"column":12},"end":{"line":130,"column":68}},"16":{"start":{"line":144,"column":8},"end":{"line":144,"column":89}},"17":{"start":{"line":145,"column":8},"end":{"line":145,"column":5836}},"18":{"start":{"line":146,"column":12},"end":{"line":146,"column":24}},"19":{"start":{"line":148,"column":12},"end":{"line":148,"column":81}},"20":{"start":{"line":171,"column":8},"end":{"line":171,"column":70}},"21":{"start":{"line":177,"column":8},"end":{"line":177,"column":71}},"22":{"start":{"line":181,"column":4},"end":{"line":181,"column":58}},"23":{"start":{"line":189,"column":8},"end":{"line":189,"column":88}},"24":{"start":{"line":197,"column":8},"end":{"line":197,"column":89}},"25":{"start":{"line":201,"column":8},"end":{"line":201,"column":66}},"26":{"start":{"line":202,"column":8},"end":{"line":202,"column":79}},"27":{"start":{"line":218,"column":8},"end":{"line":218,"column":53}},"28":{"start":{"line":227,"column":9},"end":{"line":227,"column":64}},"29":{"start":{"line":239,"column":8},"end":{"line":239,"column":51}}},"branchMap":{"1":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":21},"end":{"line":53,"column":21}},{"start":{"line":53,"column":21},"end":{"line":53,"column":21}}]},"2":{"line":69,"type":"if","locations":[{"start":{"line":69,"column":23},"end":{"line":69,"column":23}},{"start":{"line":69,"column":23},"end":{"line":69,"column":23}}]},"3":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":125},"end":{"line":87,"column":125}},{"start":{"line":87,"column":125},"end":{"line":87,"column":125}}]},"4":{"line":98,"type":"if","locations":[{"start":{"line":98,"column":217},"end":{"line":98,"column":217}},{"start":{"line":98,"column":217},"end":{"line":98,"column":217}}]},"5":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":95},"end":{"line":114,"column":95}},{"start":{"line":114,"column":95},"end":{"line":114,"column":95}}]},"6":{"line":127,"type":"if","locations":[{"start":{"line":127,"column":8},"end":{"line":127,"column":8}},{"start":{"line":127,"column":8},"end":{"line":127,"column":8}}]},"7":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":8},"end":{"line":145,"column":8}},{"start":{"line":145,"column":8},"end":{"line":145,"column":8}}]},"8":{"line":157,"type":"if","locations":[{"start":{"line":157,"column":70},"end":{"line":157,"column":70}},{"start":{"line":157,"column":70},"end":{"line":157,"column":70}}]},"9":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":75},"end":{"line":158,"column":75}},{"start":{"line":158,"column":75},"end":{"line":158,"column":75}}]},"10":{"line":160,"type":"if","locations":[{"start":{"line":160,"column":77},"end":{"line":160,"column":77}},{"start":{"line":160,"column":77},"end":{"line":160,"column":77}}]},"11":{"line":162,"type":"if","locations":[{"start":{"line":162,"column":88},"end":{"line":162,"column":88}},{"start":{"line":162,"column":88},"end":{"line":162,"column":88}}]}}},
-"contracts/modules/2_CMTATBaseRuleEngine.sol":{"l":{"47":3219,"64":3219,"83":3219,"86":3219,"89":3219,"91":3219,"94":3219,"102":3219,"103":3219,"105":3219,"112":3219,"119":3219,"129":462,"139":1040,"140":1040,"141":348,"143":692,"156":189,"157":189,"158":48,"160":141,"177":8230,"178":8158},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseRuleEngine.sol","s":{"1":3219,"2":3219,"3":3219,"4":3219,"5":3219,"6":3219,"7":3219,"8":3219,"9":3219,"10":3219,"11":3219,"12":3219,"13":462,"14":1040,"15":1040,"16":348,"17":692,"18":189,"19":189,"20":48,"21":141,"22":8230,"23":8158},"b":{"1":[3219,1],"2":[3219,0],"3":[3219,0],"4":[3219,0],"5":[3219,0],"6":[3219,0],"7":[462,15],"8":[348,692],"9":[48,141],"10":[440,31],"11":[160,15],"12":[352,45],"13":[87,3]},"f":{"1":3219,"2":3219,"3":3219,"4":3219,"5":3219,"6":3219,"7":462,"8":1040,"9":189,"10":440,"11":160,"12":352,"13":87,"14":8230},"fnMap":{"1":{"name":"initialize","line":46,"loc":{"start":{"line":41,"column":4},"end":{"line":53,"column":4}}},"2":{"name":"_initialize","line":63,"loc":{"start":{"line":58,"column":4},"end":{"line":70,"column":4}}},"3":{"name":"__CMTAT_init","line":80,"loc":{"start":{"line":75,"column":4},"end":{"line":95,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":106,"column":4}}},"5":{"name":"__CMTAT_internal_init_unchained","line":111,"loc":{"start":{"line":111,"column":4},"end":{"line":113,"column":4}}},"6":{"name":"__CMTAT_modules_init_unchained","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":120,"column":4}}},"7":{"name":"approve","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":130,"column":4}}},"8":{"name":"canTransfer","line":134,"loc":{"start":{"line":134,"column":4},"end":{"line":145,"column":4}}},"9":{"name":"canTransferFrom","line":150,"loc":{"start":{"line":150,"column":3},"end":{"line":162,"column":4}}},"10":{"name":"_authorizePause","line":168,"loc":{"start":{"line":168,"column":4},"end":{"line":168,"column":92}}},"11":{"name":"_authorizeDeactivate","line":169,"loc":{"start":{"line":169,"column":4},"end":{"line":169,"column":104}}},"12":{"name":"_authorizeFreeze","line":171,"loc":{"start":{"line":171,"column":4},"end":{"line":171,"column":101}}},"13":{"name":"_authorizeRuleEngineManagement","line":173,"loc":{"start":{"line":173,"column":4},"end":{"line":173,"column":129}}},"14":{"name":"_checkTransferred","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":179,"column":4}}}},"statementMap":{"1":{"start":{"line":47,"column":8},"end":{"line":47,"column":2182}},"2":{"start":{"line":64,"column":8},"end":{"line":64,"column":2689}},"3":{"start":{"line":83,"column":8},"end":{"line":83,"column":33}},"4":{"start":{"line":86,"column":8},"end":{"line":86,"column":32}},"5":{"start":{"line":89,"column":8},"end":{"line":89,"column":60}},"6":{"start":{"line":91,"column":7},"end":{"line":91,"column":47}},"7":{"start":{"line":94,"column":8},"end":{"line":94,"column":91}},"8":{"start":{"line":102,"column":8},"end":{"line":102,"column":39}},"9":{"start":{"line":103,"column":8},"end":{"line":103,"column":34}},"10":{"start":{"line":105,"column":8},"end":{"line":105,"column":77}},"11":{"start":{"line":112,"column":8},"end":{"line":112,"column":65}},"12":{"start":{"line":119,"column":8},"end":{"line":119,"column":96}},"13":{"start":{"line":129,"column":8},"end":{"line":129,"column":55}},"14":{"start":{"line":139,"column":8},"end":{"line":139,"column":90}},"15":{"start":{"line":140,"column":8},"end":{"line":140,"column":5713}},"16":{"start":{"line":141,"column":12},"end":{"line":141,"column":24}},"17":{"start":{"line":143,"column":12},"end":{"line":143,"column":74}},"18":{"start":{"line":156,"column":8},"end":{"line":156,"column":89}},"19":{"start":{"line":157,"column":8},"end":{"line":157,"column":6221}},"20":{"start":{"line":158,"column":12},"end":{"line":158,"column":24}},"21":{"start":{"line":160,"column":12},"end":{"line":160,"column":87}},"22":{"start":{"line":177,"column":8},"end":{"line":177,"column":66}},"23":{"start":{"line":178,"column":8},"end":{"line":178,"column":72}}},"branchMap":{"1":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":21},"end":{"line":46,"column":21}},{"start":{"line":46,"column":21},"end":{"line":46,"column":21}}]},"2":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":23},"end":{"line":63,"column":23}},{"start":{"line":63,"column":23},"end":{"line":63,"column":23}}]},"3":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":23},"end":{"line":80,"column":23}},{"start":{"line":80,"column":23},"end":{"line":80,"column":23}}]},"4":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":125},"end":{"line":100,"column":125}},{"start":{"line":100,"column":125},"end":{"line":100,"column":125}}]},"5":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":104},"end":{"line":111,"column":104}},{"start":{"line":111,"column":104},"end":{"line":111,"column":104}}]},"6":{"line":118,"type":"if","locations":[{"start":{"line":118,"column":216},"end":{"line":118,"column":216}},{"start":{"line":118,"column":216},"end":{"line":118,"column":216}}]},"7":{"line":128,"type":"if","locations":[{"start":{"line":128,"column":95},"end":{"line":128,"column":95}},{"start":{"line":128,"column":95},"end":{"line":128,"column":95}}]},"8":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":8},"end":{"line":140,"column":8}},{"start":{"line":140,"column":8},"end":{"line":140,"column":8}}]},"9":{"line":157,"type":"if","locations":[{"start":{"line":157,"column":8},"end":{"line":157,"column":8}},{"start":{"line":157,"column":8},"end":{"line":157,"column":8}}]},"10":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":70},"end":{"line":168,"column":70}},{"start":{"line":168,"column":70},"end":{"line":168,"column":70}}]},"11":{"line":169,"type":"if","locations":[{"start":{"line":169,"column":75},"end":{"line":169,"column":75}},{"start":{"line":169,"column":75},"end":{"line":169,"column":75}}]},"12":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":77},"end":{"line":171,"column":77}},{"start":{"line":171,"column":77},"end":{"line":171,"column":77}}]},"13":{"line":173,"type":"if","locations":[{"start":{"line":173,"column":100},"end":{"line":173,"column":100}},{"start":{"line":173,"column":100},"end":{"line":173,"column":100}}]}}},
-"contracts/modules/3_CMTATBaseDebt.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseDebt.sol","s":{},"b":{"1":[12,12]},"f":{"1":12},"fnMap":{"1":{"name":"_authorizeDebtManagement","line":11,"loc":{"start":{"line":11,"column":3},"end":{"line":11,"column":97}}}},"statementMap":{},"branchMap":{"1":{"line":11,"type":"if","locations":[{"start":{"line":11,"column":77},"end":{"line":11,"column":77}},{"start":{"line":11,"column":77},"end":{"line":11,"column":77}}]}}},
-"contracts/modules/3_CMTATBaseERC1404.sol":{"l":{"34":111,"35":42,"37":69,"50":846,"62":157,"73":251,"74":251,"75":112,"76":112,"77":84,"80":167},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseERC1404.sol","s":{"1":111,"2":42,"3":69,"4":846,"5":157,"6":251,"7":251,"8":112,"9":112,"10":84,"11":167},"b":{"1":[42,69],"2":[112,139],"3":[84,28]},"f":{"1":111,"2":846,"3":157,"4":251},"fnMap":{"1":{"name":"messageForTransferRestriction","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"canTransfer","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"canTransferFrom","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"_detectTransferRestriction","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":81,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1392}},"2":{"start":{"line":35,"column":12},"end":{"line":35,"column":74}},"3":{"start":{"line":37,"column":12},"end":{"line":37,"column":89}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":63}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":76}},"6":{"start":{"line":73,"column":8},"end":{"line":73,"column":80}},"7":{"start":{"line":74,"column":8},"end":{"line":74,"column":2875}},"8":{"start":{"line":75,"column":12},"end":{"line":75,"column":88}},"9":{"start":{"line":76,"column":12},"end":{"line":76,"column":3009}},"10":{"start":{"line":77,"column":16},"end":{"line":77,"column":114}},"11":{"start":{"line":80,"column":8},"end":{"line":80,"column":82}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":34,"column":8}},{"start":{"line":34,"column":8},"end":{"line":34,"column":8}}]},"2":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":8},"end":{"line":74,"column":8}},{"start":{"line":74,"column":8},"end":{"line":74,"column":8}}]},"3":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":12},"end":{"line":76,"column":12}},{"start":{"line":76,"column":12},"end":{"line":76,"column":12}}]}}},
-"contracts/modules/4_CMTATBaseERC20CrossChain.sol":{"l":{"24":417,"27":217,"42":121,"57":11,"65":35,"72":33,"76":54,"87":2921,"88":2854,"95":514,"96":429,"103":111,"104":72,"125":132,"148":3599},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC20CrossChain.sol","s":{"1":417,"2":217,"3":121,"4":11,"5":35,"6":33,"7":54,"8":2921,"9":2854,"10":514,"11":429,"12":111,"13":72,"14":132,"15":3599},"b":{"1":[20,20],"2":[24,8],"3":[132,40],"4":[50,10],"5":[30,20],"6":[60,20],"7":[40,20]},"f":{"1":417,"2":217,"3":121,"4":11,"5":35,"6":33,"7":54,"8":2921,"9":514,"10":111,"11":24,"12":132,"13":30,"14":40,"15":3599},"fnMap":{"1":{"name":"approve","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":25,"column":4}}},"2":{"name":"transfer","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":28,"column":4}}},"3":{"name":"transferFrom","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":43,"column":4}}},"4":{"name":"decimals","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":58,"column":4}}},"5":{"name":"name","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":66,"column":4}}},"6":{"name":"symbol","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":73,"column":4}}},"7":{"name":"supportsInterface","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":77,"column":4}}},"8":{"name":"_mintOverride","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":89,"column":4}}},"9":{"name":"_burnOverride","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":97,"column":4}}},"10":{"name":"_minterTransferOverride","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":105,"column":4}}},"11":{"name":"_authorizeCCIPSetAdmin","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":113,"column":106}}},"12":{"name":"_checkTokenBridge","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":126,"column":4}}},"13":{"name":"_authorizeBurnFrom","line":133,"loc":{"start":{"line":133,"column":4},"end":{"line":133,"column":124}}},"14":{"name":"_authorizeSelfBurn","line":140,"loc":{"start":{"line":140,"column":4},"end":{"line":140,"column":124}}},"15":{"name":"_update","line":143,"loc":{"start":{"line":143,"column":4},"end":{"line":149,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":58}},"2":{"start":{"line":27,"column":9},"end":{"line":27,"column":51}},"3":{"start":{"line":42,"column":8},"end":{"line":42,"column":60}},"4":{"start":{"line":57,"column":8},"end":{"line":57,"column":41}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":37}},"6":{"start":{"line":72,"column":8},"end":{"line":72,"column":39}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":127}},"8":{"start":{"line":87,"column":8},"end":{"line":87,"column":84}},"9":{"start":{"line":88,"column":8},"end":{"line":88,"column":52}},"10":{"start":{"line":95,"column":8},"end":{"line":95,"column":85}},"11":{"start":{"line":96,"column":8},"end":{"line":96,"column":52}},"12":{"start":{"line":103,"column":8},"end":{"line":103,"column":73}},"13":{"start":{"line":104,"column":8},"end":{"line":104,"column":63}},"14":{"start":{"line":125,"column":8},"end":{"line":125,"column":68}},"15":{"start":{"line":148,"column":7},"end":{"line":148,"column":55}}},"branchMap":{"1":{"line":76,"type":"cond-expr","locations":[{"start":{"line":76,"column":16},"end":{"line":76,"column":68}},{"start":{"line":76,"column":72},"end":{"line":76,"column":126}}]},"2":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":76},"end":{"line":113,"column":76}},{"start":{"line":113,"column":76},"end":{"line":113,"column":76}}]},"3":{"line":124,"type":"if","locations":[{"start":{"line":124,"column":96},"end":{"line":124,"column":96}},{"start":{"line":124,"column":96},"end":{"line":124,"column":96}}]},"4":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":83},"end":{"line":133,"column":83}},{"start":{"line":133,"column":83},"end":{"line":133,"column":83}}]},"5":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":110},"end":{"line":133,"column":110}},{"start":{"line":133,"column":110},"end":{"line":133,"column":110}}]},"6":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":83},"end":{"line":140,"column":83}},{"start":{"line":140,"column":83},"end":{"line":140,"column":83}}]},"7":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":110},"end":{"line":140,"column":110}},{"start":{"line":140,"column":110},"end":{"line":140,"column":110}}]}}},
-"contracts/modules/5_CMTATBaseDebtEngine.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseDebtEngine.sol","s":{},"b":{"1":[15,3]},"f":{"1":15},"fnMap":{"1":{"name":"_authorizeDebtEngineManagement","line":11,"loc":{"start":{"line":11,"column":3},"end":{"line":11,"column":116}}}},"statementMap":{},"branchMap":{"1":{"line":11,"type":"if","locations":[{"start":{"line":11,"column":89},"end":{"line":11,"column":89}},{"start":{"line":11,"column":89},"end":{"line":11,"column":89}}]}}},
-"contracts/modules/5_CMTATBaseERC2771.sol":{"l":{"26":10379,"35":10383,"47":4},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC2771.sol","s":{"1":10379,"2":10383,"3":4},"b":{},"f":{"1":10379,"2":10383,"3":4},"fnMap":{"1":{"name":"_msgSender","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"_contextSuffixLength","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":36,"column":4}}},"3":{"name":"_msgData","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":48,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":53}},"2":{"start":{"line":35,"column":9},"end":{"line":35,"column":64}},"3":{"start":{"line":47,"column":8},"end":{"line":47,"column":51}}},"branchMap":{}},
-"contracts/modules/6_CMTATBaseERC1363.sol":{"l":{"25":439,"26":439,"38":81,"45":37,"61":24,"69":18,"83":2,"91":6,"98":6,"114":633,"129":2253,"138":2255,"150":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC1363.sol","s":{"1":439,"2":439,"3":81,"4":37,"5":24,"6":18,"7":2,"8":6,"9":6,"10":633,"11":2253,"12":2255,"13":2},"b":{"1":[439,0],"2":[6,8]},"f":{"1":439,"2":81,"3":37,"4":24,"5":18,"6":2,"7":6,"8":6,"9":633,"10":2253,"11":2255,"12":2},"fnMap":{"1":{"name":"__CMTAT_openzeppelin_init_unchained","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"approve","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":39,"column":4}}},"3":{"name":"transfer","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":4}}},"4":{"name":"transferFrom","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":62,"column":4}}},"5":{"name":"supportsInterface","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":70,"column":4}}},"6":{"name":"decimals","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":84,"column":4}}},"7":{"name":"name","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":92,"column":4}}},"8":{"name":"symbol","line":97,"loc":{"start":{"line":97,"column":4},"end":{"line":99,"column":4}}},"9":{"name":"_update","line":109,"loc":{"start":{"line":109,"column":4},"end":{"line":115,"column":4}}},"10":{"name":"_msgSender","line":123,"loc":{"start":{"line":123,"column":4},"end":{"line":130,"column":4}}},"11":{"name":"_contextSuffixLength","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":139,"column":4}}},"12":{"name":"_msgData","line":144,"loc":{"start":{"line":144,"column":4},"end":{"line":151,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":80}},"2":{"start":{"line":26,"column":8},"end":{"line":26,"column":33}},"3":{"start":{"line":38,"column":8},"end":{"line":38,"column":63}},"4":{"start":{"line":45,"column":8},"end":{"line":45,"column":59}},"5":{"start":{"line":61,"column":8},"end":{"line":61,"column":79}},"6":{"start":{"line":69,"column":8},"end":{"line":69,"column":123}},"7":{"start":{"line":83,"column":8},"end":{"line":83,"column":50}},"8":{"start":{"line":91,"column":8},"end":{"line":91,"column":46}},"9":{"start":{"line":98,"column":8},"end":{"line":98,"column":48}},"10":{"start":{"line":114,"column":8},"end":{"line":114,"column":57}},"11":{"start":{"line":129,"column":8},"end":{"line":129,"column":44}},"12":{"start":{"line":138,"column":9},"end":{"line":138,"column":55}},"13":{"start":{"line":150,"column":8},"end":{"line":150,"column":42}}},"branchMap":{"1":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":134},"end":{"line":24,"column":134}},{"start":{"line":24,"column":134},"end":{"line":24,"column":134}}]},"2":{"line":69,"type":"cond-expr","locations":[{"start":{"line":69,"column":15},"end":{"line":69,"column":63}},{"start":{"line":69,"column":68},"end":{"line":69,"column":122}}]}}},
-"contracts/modules/6_CMTATBaseERC7551.sol":{"l":{"19":20},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC7551.sol","s":{"1":20},"b":{},"f":{"1":20},"fnMap":{"1":{"name":"_authorizeExtraInfoManagement","line":18,"loc":{"start":{"line":18,"column":4},"end":{"line":20,"column":4}}}},"statementMap":{"1":{"start":{"line":19,"column":8},"end":{"line":19,"column":61}}},"branchMap":{}},
-"contracts/modules/internal/AllowlistModuleInternal.sol":{"l":{"30":473,"31":473,"40":222,"41":222,"45":1882,"49":422,"50":418,"51":418,"52":1660,"60":117,"61":117,"69":1092,"70":1092,"77":1071,"78":1071,"85":3393},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol","s":{"1":473,"2":222,"3":222,"4":422,"5":418,"6":418,"7":1660,"8":117,"9":1092,"10":1092,"11":1071,"12":1071},"b":{"1":[473,0]},"f":{"1":473,"2":222,"3":1882,"4":422,"5":117,"6":1092,"7":1071,"8":3393},"fnMap":{"1":{"name":"__Allowlist_init_unchained","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":33,"column":4}}},"2":{"name":"_addToAllowlist","line":39,"loc":{"start":{"line":39,"column":4},"end":{"line":42,"column":4}}},"3":{"name":"_addToAllowlist","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":4}}},"4":{"name":"_addToAllowlist","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":54,"column":4}}},"5":{"name":"_enableAllowlist","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":62,"column":4}}},"6":{"name":"_isAllowlisted","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":71,"column":4}}},"7":{"name":"_isAllowlistEnabled","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"8":{"name":"_getAllowlistModuleInternalStorage","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":88,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":9},"end":{"line":30,"column":88}},"2":{"start":{"line":40,"column":8},"end":{"line":40,"column":87}},"3":{"start":{"line":41,"column":8},"end":{"line":41,"column":48}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":61}},"5":{"start":{"line":50,"column":8},"end":{"line":50,"column":87}},"6":{"start":{"line":51,"column":8},"end":{"line":51,"column":2408}},"7":{"start":{"line":52,"column":12},"end":{"line":52,"column":59}},"8":{"start":{"line":60,"column":8},"end":{"line":60,"column":87}},"9":{"start":{"line":69,"column":8},"end":{"line":69,"column":87}},"10":{"start":{"line":70,"column":8},"end":{"line":70,"column":36}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":87}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":33}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":51},"end":{"line":29,"column":51}},{"start":{"line":29,"column":51},"end":{"line":29,"column":51}}]}}},
-"contracts/modules/internal/common/EnforcementModuleLibrary.sol":{"l":{"16":506,"19":483},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/common/EnforcementModuleLibrary.sol","s":{"1":506,"2":483},"b":{"1":[483,23],"2":[460,23]},"f":{"1":506},"fnMap":{"1":{"name":"_checkInput","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":20,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":70}},"2":{"start":{"line":19,"column":8},"end":{"line":19,"column":98}}},"branchMap":{"1":{"line":16,"type":"if","locations":[{"start":{"line":16,"column":8},"end":{"line":16,"column":8}},{"start":{"line":16,"column":8},"end":{"line":16,"column":8}}]},"2":{"line":19,"type":"if","locations":[{"start":{"line":19,"column":8},"end":{"line":19,"column":8}},{"start":{"line":19,"column":8},"end":{"line":19,"column":8}}]}}},
-"contracts/modules/internal/EnforcementModuleInternal.sol":{"l":{"33":385,"34":385,"38":490,"42":84,"43":42,"44":42,"45":105,"54":14098,"55":14098,"60":14525},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInternal.sol","s":{"1":385,"2":385,"3":84,"4":42,"5":42,"6":105,"7":14098,"8":14098},"b":{},"f":{"1":385,"2":490,"3":84,"4":14098,"5":14525},"fnMap":{"1":{"name":"_addAddressToTheList","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":35,"column":4}}},"2":{"name":"_addAddressToTheList","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":39,"column":4}}},"3":{"name":"_addAddressesToTheList","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":47,"column":4}}},"4":{"name":"_addressIsListed","line":53,"loc":{"start":{"line":53,"column":4},"end":{"line":56,"column":4}}},"5":{"name":"_getEnforcementModuleInternalStorage","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":63,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":91}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":53}},"3":{"start":{"line":42,"column":8},"end":{"line":42,"column":61}},"4":{"start":{"line":43,"column":8},"end":{"line":43,"column":91}},"5":{"start":{"line":44,"column":8},"end":{"line":44,"column":2008}},"6":{"start":{"line":45,"column":12},"end":{"line":45,"column":64}},"7":{"start":{"line":54,"column":8},"end":{"line":54,"column":91}},"8":{"start":{"line":55,"column":8},"end":{"line":55,"column":31}}},"branchMap":{}},
-"contracts/modules/internal/ERC20BurnModuleInternal.sol":{"l":{"30":223,"33":203,"34":163,"35":407,"47":708},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol","s":{"1":223,"2":203,"3":163,"4":407,"5":708},"b":{"1":[203,20],"2":[163,40]},"f":{"1":223,"2":708},"fnMap":{"1":{"name":"_batchBurn","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":37,"column":4}}},"2":{"name":"_burnOverride","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":48,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":70}},"2":{"start":{"line":33,"column":8},"end":{"line":33,"column":97}},"3":{"start":{"line":34,"column":8},"end":{"line":34,"column":1431}},"4":{"start":{"line":35,"column":13},"end":{"line":35,"column":49}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":45}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":8},"end":{"line":30,"column":8}},{"start":{"line":30,"column":8},"end":{"line":30,"column":8}}]},"2":{"line":33,"type":"if","locations":[{"start":{"line":33,"column":8},"end":{"line":33,"column":8}},{"start":{"line":33,"column":8},"end":{"line":33,"column":8}}]}}},
-"contracts/modules/internal/ERC20EnforcementModuleInternal.sol":{"l":{"34":154,"35":154,"37":154,"38":42,"39":42,"40":42,"43":98,"44":98,"45":98,"47":14,"49":140,"53":352,"55":352,"56":352,"58":352,"60":352,"61":352,"65":112,"66":112,"68":112,"69":112,"70":112,"77":128,"78":128,"79":14,"81":114,"83":114,"84":114,"85":28,"86":28,"87":28,"88":28,"93":128,"94":114,"95":28,"99":86,"100":86,"101":28,"102":14,"103":14,"106":14,"107":14,"112":86,"114":114,"115":114,"119":450,"120":450,"124":182,"125":182,"130":9056,"131":9056,"132":9056,"133":9056,"140":10536,"141":10536,"143":938,"144":938,"145":546,"150":9990,"154":11519,"155":11519,"159":686,"160":686,"165":12937},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol","s":{"1":154,"2":154,"3":154,"4":42,"5":42,"6":112,"7":98,"8":98,"9":140,"10":352,"11":352,"12":352,"13":352,"14":352,"15":112,"16":112,"17":112,"18":112,"19":128,"20":128,"21":114,"22":114,"23":114,"24":28,"25":28,"26":28,"27":128,"28":114,"29":28,"30":86,"31":86,"32":28,"33":14,"34":14,"35":86,"36":114,"37":114,"38":450,"39":450,"40":182,"41":182,"42":9056,"43":9056,"44":9056,"45":10536,"46":10536,"47":938,"48":546,"49":9990,"50":11519,"51":11519,"52":686,"53":686},"b":{"1":[42,112],"2":[98,14],"3":[352,0],"4":[112,0],"5":[14,114],"6":[28,86],"7":[28,86],"8":[28,58],"9":[14,14],"10":[8972,84],"11":[938,9598],"12":[546,392]},"f":{"1":154,"2":352,"3":112,"4":128,"5":128,"6":450,"7":182,"8":9056,"9":10536,"10":11519,"11":686,"12":12937},"fnMap":{"1":{"name":"_setFrozenTokens","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":50,"column":4}}},"2":{"name":"_freezePartialTokens","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":62,"column":4}}},"3":{"name":"_unfreezePartialTokens","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":71,"column":4}}},"4":{"name":"_unfreezeTokens","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":90,"column":4}}},"5":{"name":"_forcedTransfer","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":116,"column":4}}},"6":{"name":"_freezeTokensEmitEvents","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":121,"column":4}}},"7":{"name":"_unfreezeTokensEmitEvents","line":123,"loc":{"start":{"line":123,"column":4},"end":{"line":126,"column":4}}},"8":{"name":"_checkActiveBalanceAndRevert","line":129,"loc":{"start":{"line":129,"column":4},"end":{"line":134,"column":4}}},"9":{"name":"_checkActiveBalance","line":139,"loc":{"start":{"line":139,"column":4},"end":{"line":151,"column":4}}},"10":{"name":"_getFrozenTokens","line":153,"loc":{"start":{"line":153,"column":4},"end":{"line":156,"column":5}}},"11":{"name":"_getActiveBalanceOf","line":158,"loc":{"start":{"line":158,"column":4},"end":{"line":161,"column":5}}},"12":{"name":"_getEnforcementModuleStorage","line":164,"loc":{"start":{"line":164,"column":4},"end":{"line":168,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":80}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":60}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":1969}},"4":{"start":{"line":38,"column":13},"end":{"line":38,"column":59}},"5":{"start":{"line":40,"column":13},"end":{"line":40,"column":68}},"6":{"start":{"line":41,"column":15},"end":{"line":41,"column":2198}},"7":{"start":{"line":43,"column":12},"end":{"line":43,"column":58}},"8":{"start":{"line":45,"column":12},"end":{"line":45,"column":66}},"9":{"start":{"line":49,"column":8},"end":{"line":49,"column":19}},"10":{"start":{"line":53,"column":7},"end":{"line":53,"column":79}},"11":{"start":{"line":55,"column":8},"end":{"line":55,"column":61}},"12":{"start":{"line":56,"column":8},"end":{"line":56,"column":68}},"13":{"start":{"line":58,"column":8},"end":{"line":58,"column":105}},"14":{"start":{"line":61,"column":8},"end":{"line":61,"column":71}},"15":{"start":{"line":65,"column":8},"end":{"line":65,"column":80}},"16":{"start":{"line":66,"column":8},"end":{"line":66,"column":107}},"17":{"start":{"line":68,"column":8},"end":{"line":68,"column":69}},"18":{"start":{"line":70,"column":8},"end":{"line":70,"column":73}},"19":{"start":{"line":77,"column":8},"end":{"line":77,"column":61}},"20":{"start":{"line":78,"column":8},"end":{"line":78,"column":4054}},"21":{"start":{"line":81,"column":8},"end":{"line":81,"column":80}},"22":{"start":{"line":83,"column":8},"end":{"line":83,"column":66}},"23":{"start":{"line":84,"column":8},"end":{"line":84,"column":4369}},"24":{"start":{"line":85,"column":12},"end":{"line":85,"column":60}},"25":{"start":{"line":86,"column":12},"end":{"line":86,"column":84}},"26":{"start":{"line":88,"column":12},"end":{"line":88,"column":88}},"27":{"start":{"line":93,"column":8},"end":{"line":93,"column":41}},"28":{"start":{"line":94,"column":8},"end":{"line":94,"column":4872}},"29":{"start":{"line":95,"column":12},"end":{"line":95,"column":46}},"30":{"start":{"line":99,"column":12},"end":{"line":99,"column":58}},"31":{"start":{"line":100,"column":12},"end":{"line":100,"column":5160}},"32":{"start":{"line":101,"column":16},"end":{"line":101,"column":5248}},"33":{"start":{"line":103,"column":24},"end":{"line":103,"column":68}},"34":{"start":{"line":107,"column":25},"end":{"line":107,"column":92}},"35":{"start":{"line":112,"column":12},"end":{"line":112,"column":54}},"36":{"start":{"line":114,"column":8},"end":{"line":114,"column":57}},"37":{"start":{"line":115,"column":8},"end":{"line":115,"column":44}},"38":{"start":{"line":119,"column":8},"end":{"line":119,"column":52}},"39":{"start":{"line":120,"column":8},"end":{"line":120,"column":83}},"40":{"start":{"line":124,"column":8},"end":{"line":124,"column":54}},"41":{"start":{"line":125,"column":8},"end":{"line":125,"column":84}},"42":{"start":{"line":130,"column":8},"end":{"line":130,"column":20}},"43":{"start":{"line":131,"column":8},"end":{"line":131,"column":29}},"44":{"start":{"line":133,"column":8},"end":{"line":133,"column":89}},"45":{"start":{"line":140,"column":8},"end":{"line":140,"column":58}},"46":{"start":{"line":141,"column":8},"end":{"line":141,"column":7001}},"47":{"start":{"line":144,"column":12},"end":{"line":144,"column":7178}},"48":{"start":{"line":145,"column":19},"end":{"line":145,"column":48}},"49":{"start":{"line":150,"column":8},"end":{"line":150,"column":36}},"50":{"start":{"line":154,"column":8},"end":{"line":154,"column":80}},"51":{"start":{"line":155,"column":8},"end":{"line":155,"column":39}},"52":{"start":{"line":159,"column":8},"end":{"line":159,"column":80}},"53":{"start":{"line":160,"column":8},"end":{"line":160,"column":77}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":8}},{"start":{"line":37,"column":8},"end":{"line":37,"column":8}}]},"2":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":15},"end":{"line":41,"column":15}},{"start":{"line":41,"column":15},"end":{"line":41,"column":15}}]},"3":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":8},"end":{"line":58,"column":8}},{"start":{"line":58,"column":8},"end":{"line":58,"column":8}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]},"5":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":8},"end":{"line":78,"column":8}},{"start":{"line":78,"column":8},"end":{"line":78,"column":8}}]},"6":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":8},"end":{"line":84,"column":8}},{"start":{"line":84,"column":8},"end":{"line":84,"column":8}}]},"7":{"line":94,"type":"if","locations":[{"start":{"line":94,"column":8},"end":{"line":94,"column":8}},{"start":{"line":94,"column":8},"end":{"line":94,"column":8}}]},"8":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":12},"end":{"line":100,"column":12}},{"start":{"line":100,"column":12},"end":{"line":100,"column":12}}]},"9":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":16},"end":{"line":101,"column":16}},{"start":{"line":101,"column":16},"end":{"line":101,"column":16}}]},"10":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":8},"end":{"line":133,"column":8}},{"start":{"line":133,"column":8},"end":{"line":133,"column":8}}]},"11":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":8}},{"start":{"line":141,"column":8},"end":{"line":141,"column":8}}]},"12":{"line":144,"type":"if","locations":[{"start":{"line":144,"column":12},"end":{"line":144,"column":12}},{"start":{"line":144,"column":12},"end":{"line":144,"column":12}}]}}},
-"contracts/modules/internal/ERC20MintModuleInternal.sol":{"l":{"34":519,"37":499,"38":459,"39":1291,"47":168,"48":148,"51":148,"52":108,"53":198,"57":20,"64":4437,"70":130},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol","s":{"1":519,"2":499,"3":459,"4":1291,"5":168,"6":148,"7":148,"8":108,"9":198,"10":20,"11":4437,"12":130},"b":{"1":[499,20],"2":[459,40],"3":[148,20],"4":[108,40]},"f":{"1":519,"2":168,"3":4437,"4":130},"fnMap":{"1":{"name":"_batchMint","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"_batchTransfer","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":58,"column":4}}},"3":{"name":"_mintOverride","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"_minterTransferOverride","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":71,"column":5}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":69}},"2":{"start":{"line":37,"column":8},"end":{"line":37,"column":97}},"3":{"start":{"line":38,"column":8},"end":{"line":38,"column":1716}},"4":{"start":{"line":39,"column":12},"end":{"line":39,"column":48}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":59}},"6":{"start":{"line":48,"column":8},"end":{"line":48,"column":37}},"7":{"start":{"line":51,"column":8},"end":{"line":51,"column":87}},"8":{"start":{"line":52,"column":8},"end":{"line":52,"column":2292}},"9":{"start":{"line":53,"column":12},"end":{"line":53,"column":61}},"10":{"start":{"line":57,"column":8},"end":{"line":57,"column":19}},"11":{"start":{"line":64,"column":8},"end":{"line":64,"column":45}},"12":{"start":{"line":70,"column":12},"end":{"line":70,"column":54}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":34,"column":8}},{"start":{"line":34,"column":8},"end":{"line":34,"column":8}}]},"2":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":8}},{"start":{"line":37,"column":8},"end":{"line":37,"column":8}}]},"3":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":8},"end":{"line":47,"column":8}},{"start":{"line":47,"column":8},"end":{"line":47,"column":8}}]},"4":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":8},"end":{"line":51,"column":8}},{"start":{"line":51,"column":8},"end":{"line":51,"column":8}}]}}},
-"contracts/modules/internal/ValidationModuleRuleEngineInternal.sol":{"l":{"38":3219,"39":69,"53":8951,"54":8951,"68":153,"69":153,"70":153,"75":9104},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol","s":{"1":3219,"2":69,"3":8951,"4":8951,"5":153,"6":153},"b":{"1":[3219,0],"2":[69,3150]},"f":{"1":3219,"2":8951,"3":153,"4":9104},"fnMap":{"1":{"name":"__ValidationRuleEngine_init_unchained","line":37,"loc":{"start":{"line":35,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"ruleEngine","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":55,"column":4}}},"3":{"name":"_setRuleEngine","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":71,"column":4}}},"4":{"name":"_getValidationModuleRuleEngineStorage","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":78,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":1469}},"2":{"start":{"line":39,"column":12},"end":{"line":39,"column":38}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":93}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":28}},"5":{"start":{"line":68,"column":8},"end":{"line":68,"column":93}},"6":{"start":{"line":70,"column":8},"end":{"line":70,"column":36}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":15},"end":{"line":37,"column":15}},{"start":{"line":37,"column":15},"end":{"line":37,"column":15}}]},"2":{"line":38,"type":"if","locations":[{"start":{"line":38,"column":8},"end":{"line":38,"column":8}},{"start":{"line":38,"column":8},"end":{"line":38,"column":8}}]}}},
-"contracts/modules/wrapper/controllers/ValidationModule.sol":{"l":{"27":284,"43":1068,"44":34,"47":14,"50":1020,"60":9028,"61":7100,"64":1201,"67":727,"79":42,"83":12,"85":30,"97":8685,"100":8584,"101":121,"115":992,"118":200,"120":792,"129":584,"130":584,"131":20,"133":20,"135":42,"137":502,"139":82,"147":992,"149":320,"151":672,"165":719,"166":584,"177":266,"178":84,"180":182},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol","s":{"1":284,"2":1068,"3":34,"4":1034,"5":14,"6":1020,"7":9028,"8":7100,"9":1928,"10":1201,"11":727,"12":42,"13":12,"14":30,"15":8685,"16":8584,"17":992,"18":200,"19":792,"20":584,"21":584,"22":564,"23":544,"24":502,"25":992,"26":320,"27":672,"28":719,"29":584,"30":266,"31":84,"32":182},"b":{"1":[34,1034],"2":[14,1020],"3":[7100,1928],"4":[1201,727],"5":[12,30],"6":[0,12],"7":[121,8463],"8":[200,792],"9":[20,140],"10":[140,40],"11":[20,564],"12":[20,544],"13":[42,502],"14":[320,672],"15":[200,120],"16":[84,182]},"f":{"1":284,"2":1068,"3":9028,"4":42,"5":8685,"6":992,"7":584,"8":992,"9":719,"10":266},"fnMap":{"1":{"name":"canTransact","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"_canTransferGenericByModule","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":52,"column":4}}},"3":{"name":"_canTransferGenericByModuleAndRevert","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":69,"column":4}}},"4":{"name":"_canMintBurnByModule","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":86,"column":4}}},"5":{"name":"_canMintBurnByModuleAndRevert","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":103,"column":4}}},"6":{"name":"_canTransferisFrozen","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":122,"column":4}}},"7":{"name":"_canTransferisFrozenAndRevert","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":140,"column":4}}},"8":{"name":"_canTransferStandardByModule","line":142,"loc":{"start":{"line":142,"column":2},"end":{"line":153,"column":4}}},"9":{"name":"_canTransferStandardByModuleAndRevert","line":155,"loc":{"start":{"line":155,"column":4},"end":{"line":167,"column":4}}},"10":{"name":"_canTransact","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":182,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":36}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":1474}},"3":{"start":{"line":44,"column":12},"end":{"line":44,"column":43}},"4":{"start":{"line":46,"column":13},"end":{"line":46,"column":1574}},"5":{"start":{"line":47,"column":12},"end":{"line":47,"column":45}},"6":{"start":{"line":50,"column":12},"end":{"line":50,"column":66}},"7":{"start":{"line":60,"column":8},"end":{"line":60,"column":1945}},"8":{"start":{"line":61,"column":13},"end":{"line":61,"column":45}},"9":{"start":{"line":63,"column":13},"end":{"line":63,"column":2048}},"10":{"start":{"line":64,"column":12},"end":{"line":64,"column":46}},"11":{"start":{"line":67,"column":13},"end":{"line":67,"column":68}},"12":{"start":{"line":79,"column":8},"end":{"line":79,"column":2581}},"13":{"start":{"line":83,"column":12},"end":{"line":83,"column":24}},"14":{"start":{"line":85,"column":8},"end":{"line":85,"column":19}},"15":{"start":{"line":97,"column":8},"end":{"line":97,"column":31}},"16":{"start":{"line":100,"column":8},"end":{"line":100,"column":3466}},"17":{"start":{"line":115,"column":8},"end":{"line":115,"column":3932}},"18":{"start":{"line":118,"column":12},"end":{"line":118,"column":23}},"19":{"start":{"line":120,"column":13},"end":{"line":120,"column":25}},"20":{"start":{"line":129,"column":8},"end":{"line":129,"column":22}},"21":{"start":{"line":130,"column":8},"end":{"line":130,"column":4321}},"22":{"start":{"line":132,"column":15},"end":{"line":132,"column":4408}},"23":{"start":{"line":134,"column":15},"end":{"line":134,"column":4490}},"24":{"start":{"line":137,"column":12},"end":{"line":137,"column":18}},"25":{"start":{"line":147,"column":8},"end":{"line":147,"column":4812}},"26":{"start":{"line":149,"column":12},"end":{"line":149,"column":24}},"27":{"start":{"line":151,"column":13},"end":{"line":151,"column":24}},"28":{"start":{"line":165,"column":8},"end":{"line":165,"column":26}},"29":{"start":{"line":166,"column":8},"end":{"line":166,"column":55}},"30":{"start":{"line":177,"column":8},"end":{"line":177,"column":5822}},"31":{"start":{"line":178,"column":12},"end":{"line":178,"column":24}},"32":{"start":{"line":180,"column":12},"end":{"line":180,"column":23}}},"branchMap":{"1":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":8}},{"start":{"line":43,"column":8},"end":{"line":43,"column":8}}]},"2":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":13},"end":{"line":46,"column":13}},{"start":{"line":46,"column":13},"end":{"line":46,"column":13}}]},"3":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":8},"end":{"line":60,"column":8}},{"start":{"line":60,"column":8},"end":{"line":60,"column":8}}]},"4":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":13},"end":{"line":63,"column":13}},{"start":{"line":63,"column":13},"end":{"line":63,"column":13}}]},"5":{"line":79,"type":"if","locations":[{"start":{"line":79,"column":8},"end":{"line":79,"column":8}},{"start":{"line":79,"column":8},"end":{"line":79,"column":8}}]},"6":{"line":79,"type":"cond-expr","locations":[{"start":{"line":79,"column":11},"end":{"line":79,"column":35}},{"start":{"line":79,"column":40},"end":{"line":79,"column":73}}]},"7":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":8},"end":{"line":100,"column":8}},{"start":{"line":100,"column":8},"end":{"line":100,"column":8}}]},"8":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":8},"end":{"line":115,"column":8}},{"start":{"line":115,"column":8},"end":{"line":115,"column":8}}]},"9":{"line":115,"type":"cond-expr","locations":[{"start":{"line":115,"column":12},"end":{"line":115,"column":46}},{"start":{"line":116,"column":11},"end":{"line":116,"column":42}}]},"10":{"line":115,"type":"cond-expr","locations":[{"start":{"line":115,"column":12},"end":{"line":116,"column":42}},{"start":{"line":117,"column":11},"end":{"line":117,"column":40}}]},"11":{"line":130,"type":"if","locations":[{"start":{"line":130,"column":8},"end":{"line":130,"column":8}},{"start":{"line":130,"column":8},"end":{"line":130,"column":8}}]},"12":{"line":132,"type":"if","locations":[{"start":{"line":132,"column":15},"end":{"line":132,"column":15}},{"start":{"line":132,"column":15},"end":{"line":132,"column":15}}]},"13":{"line":134,"type":"if","locations":[{"start":{"line":134,"column":15},"end":{"line":134,"column":15}},{"start":{"line":134,"column":15},"end":{"line":134,"column":15}}]},"14":{"line":147,"type":"if","locations":[{"start":{"line":147,"column":8},"end":{"line":147,"column":8}},{"start":{"line":147,"column":8},"end":{"line":147,"column":8}}]},"15":{"line":147,"type":"cond-expr","locations":[{"start":{"line":147,"column":12},"end":{"line":147,"column":50}},{"start":{"line":148,"column":11},"end":{"line":148,"column":30}}]},"16":{"line":177,"type":"if","locations":[{"start":{"line":177,"column":8},"end":{"line":177,"column":8}},{"start":{"line":177,"column":8},"end":{"line":177,"column":8}}]}}},
-"contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol":{"l":{"27":12,"28":6,"30":6,"42":173,"43":148,"44":148,"45":28,"48":145,"59":173,"60":28,"62":145,"66":68,"67":18,"69":50,"77":721,"78":8,"80":713,"89":93,"90":85,"98":93,"99":93,"100":67,"101":2,"103":2,"105":4,"107":59,"110":8},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol","s":{"1":12,"2":6,"3":6,"4":173,"5":148,"6":148,"7":28,"8":145,"9":173,"10":28,"11":145,"12":68,"13":18,"14":50,"15":721,"16":713,"17":93,"18":85,"19":93,"20":93,"21":67,"22":65,"23":63,"24":59},"b":{"1":[6,6],"2":[148,25],"3":[28,120],"4":[2,14],"5":[14,12],"6":[28,145],"7":[18,50],"8":[8,713],"9":[67,26],"10":[2,65],"11":[2,63],"12":[4,59]},"f":{"1":12,"2":173,"3":173,"4":68,"5":721,"6":93,"7":93},"fnMap":{"1":{"name":"_canMintBurnByModule","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"_canTransferStandardByModuleAllowlist","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"_canTransferStandardByModule","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"_canTransact","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":71,"column":4}}},"5":{"name":"_canMintBurnByModuleAndRevert","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":82,"column":4}}},"6":{"name":"_canTransferStandardByModuleAndRevert","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":91,"column":4}}},"7":{"name":"_canTransferStandardByModuleAllowlistAndRevert","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":112,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":932}},"2":{"start":{"line":28,"column":12},"end":{"line":28,"column":24}},"3":{"start":{"line":30,"column":12},"end":{"line":30,"column":65}},"4":{"start":{"line":42,"column":8},"end":{"line":42,"column":1352}},"5":{"start":{"line":43,"column":12},"end":{"line":43,"column":80}},"6":{"start":{"line":44,"column":12},"end":{"line":44,"column":1477}},"7":{"start":{"line":45,"column":16},"end":{"line":45,"column":27}},"8":{"start":{"line":48,"column":7},"end":{"line":48,"column":19}},"9":{"start":{"line":59,"column":8},"end":{"line":59,"column":1876}},"10":{"start":{"line":60,"column":11},"end":{"line":60,"column":23}},"11":{"start":{"line":62,"column":8},"end":{"line":62,"column":79}},"12":{"start":{"line":66,"column":8},"end":{"line":66,"column":2186}},"13":{"start":{"line":67,"column":12},"end":{"line":67,"column":24}},"14":{"start":{"line":69,"column":12},"end":{"line":69,"column":57}},"15":{"start":{"line":77,"column":8},"end":{"line":77,"column":2556}},"16":{"start":{"line":80,"column":12},"end":{"line":80,"column":66}},"17":{"start":{"line":89,"column":8},"end":{"line":89,"column":72}},"18":{"start":{"line":90,"column":7},"end":{"line":90,"column":79}},"19":{"start":{"line":98,"column":8},"end":{"line":98,"column":23}},"20":{"start":{"line":99,"column":8},"end":{"line":99,"column":3293}},"21":{"start":{"line":100,"column":12},"end":{"line":100,"column":3336}},"22":{"start":{"line":102,"column":19},"end":{"line":102,"column":3445}},"23":{"start":{"line":104,"column":19},"end":{"line":104,"column":3524}},"24":{"start":{"line":107,"column":15},"end":{"line":107,"column":21}}},"branchMap":{"1":{"line":27,"type":"if","locations":[{"start":{"line":27,"column":8},"end":{"line":27,"column":8}},{"start":{"line":27,"column":8},"end":{"line":27,"column":8}}]},"2":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":8},"end":{"line":42,"column":8}},{"start":{"line":42,"column":8},"end":{"line":42,"column":8}}]},"3":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":12},"end":{"line":44,"column":12}},{"start":{"line":44,"column":12},"end":{"line":44,"column":12}}]},"4":{"line":44,"type":"cond-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":27}},{"start":{"line":44,"column":32},"end":{"line":44,"column":51}}]},"5":{"line":44,"type":"cond-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":51}},{"start":{"line":44,"column":56},"end":{"line":44,"column":73}}]},"6":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":59,"column":8}},{"start":{"line":59,"column":8},"end":{"line":59,"column":8}}]},"7":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]},"8":{"line":77,"type":"if","locations":[{"start":{"line":77,"column":8},"end":{"line":77,"column":8}},{"start":{"line":77,"column":8},"end":{"line":77,"column":8}}]},"9":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":8}},{"start":{"line":99,"column":8},"end":{"line":99,"column":8}}]},"10":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":12},"end":{"line":100,"column":12}},{"start":{"line":100,"column":12},"end":{"line":100,"column":12}}]},"11":{"line":102,"type":"if","locations":[{"start":{"line":102,"column":19},"end":{"line":102,"column":19}},{"start":{"line":102,"column":19},"end":{"line":102,"column":19}}]},"12":{"line":104,"type":"if","locations":[{"start":{"line":104,"column":19},"end":{"line":104,"column":19}},{"start":{"line":104,"column":19},"end":{"line":104,"column":19}}]}}},
-"contracts/modules/wrapper/core/EnforcementModule.sol":{"l":{"27":532,"28":469,"42":154,"60":231,"71":84,"79":14098,"87":490,"88":490},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol","s":{"1":532,"2":154,"3":231,"4":84,"5":14098,"6":490,"7":490},"b":{"1":[154,0],"2":[231,42],"3":[84,21]},"f":{"1":532,"2":154,"3":231,"4":84,"5":14098,"6":490},"fnMap":{"1":{"name":"onlyEnforcer","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":29,"column":4}}},"2":{"name":"setAddressFrozen","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":4}}},"3":{"name":"setAddressFrozen","line":59,"loc":{"start":{"line":57,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"batchSetAddressFrozen","line":70,"loc":{"start":{"line":68,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"isFrozen","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"_addAddressToTheList","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":89,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":25}},"2":{"start":{"line":42,"column":9},"end":{"line":42,"column":49}},"3":{"start":{"line":60,"column":9},"end":{"line":60,"column":51}},"4":{"start":{"line":71,"column":9},"end":{"line":71,"column":53}},"5":{"start":{"line":79,"column":7},"end":{"line":79,"column":39}},"6":{"start":{"line":87,"column":8},"end":{"line":87,"column":79}},"7":{"start":{"line":88,"column":8},"end":{"line":88,"column":63}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":105},"end":{"line":41,"column":105}},{"start":{"line":41,"column":105},"end":{"line":41,"column":105}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":21},"end":{"line":59,"column":21}},{"start":{"line":59,"column":21},"end":{"line":59,"column":21}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":51},"end":{"line":70,"column":51}},{"start":{"line":70,"column":51},"end":{"line":70,"column":51}}]}}},
-"contracts/modules/wrapper/core/ERC20BaseModule.sol":{"l":{"39":82,"40":42,"55":3892,"56":3892,"57":3892,"58":3892,"78":68,"80":28,"81":28,"84":28,"94":20,"95":20,"102":62,"103":62,"111":60,"112":60,"123":22,"124":22,"125":22,"132":20,"133":20,"134":20,"141":40,"142":40,"143":20,"145":40,"156":4076},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol","s":{"1":82,"2":3892,"3":68,"4":28,"5":28,"6":28,"7":20,"8":20,"9":62,"10":62,"11":60,"12":60,"13":22,"14":22,"15":20,"16":20,"17":40},"b":{"1":[3892,0],"2":[28,0],"3":[22,20],"4":[20,20]},"f":{"1":82,"2":3892,"3":68,"4":20,"5":62,"6":60,"7":22,"8":20,"9":40,"10":4076},"fnMap":{"1":{"name":"onlyERC20AttributeManager","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"__ERC20BaseModule_init_unchained","line":54,"loc":{"start":{"line":50,"column":4},"end":{"line":59,"column":4}}},"3":{"name":"transferFrom","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":85,"column":4}}},"4":{"name":"decimals","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":96,"column":4}}},"5":{"name":"name","line":101,"loc":{"start":{"line":101,"column":4},"end":{"line":104,"column":4}}},"6":{"name":"symbol","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":113,"column":4}}},"7":{"name":"setName","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":126,"column":4}}},"8":{"name":"setSymbol","line":131,"loc":{"start":{"line":131,"column":4},"end":{"line":135,"column":4}}},"9":{"name":"batchBalanceOf","line":140,"loc":{"start":{"line":140,"column":4},"end":{"line":146,"column":4}}},"10":{"name":"_getERC20BaseModuleStorage","line":155,"loc":{"start":{"line":155,"column":4},"end":{"line":159,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":43}},"2":{"start":{"line":55,"column":8},"end":{"line":55,"column":71}},"3":{"start":{"line":78,"column":8},"end":{"line":78,"column":68}},"4":{"start":{"line":80,"column":8},"end":{"line":80,"column":3039}},"5":{"start":{"line":81,"column":12},"end":{"line":81,"column":49}},"6":{"start":{"line":84,"column":8},"end":{"line":84,"column":21}},"7":{"start":{"line":94,"column":8},"end":{"line":94,"column":71}},"8":{"start":{"line":95,"column":8},"end":{"line":95,"column":26}},"9":{"start":{"line":102,"column":8},"end":{"line":102,"column":71}},"10":{"start":{"line":103,"column":8},"end":{"line":103,"column":22}},"11":{"start":{"line":111,"column":8},"end":{"line":111,"column":71}},"12":{"start":{"line":112,"column":8},"end":{"line":112,"column":24}},"13":{"start":{"line":123,"column":8},"end":{"line":123,"column":71}},"14":{"start":{"line":125,"column":8},"end":{"line":125,"column":31}},"15":{"start":{"line":132,"column":8},"end":{"line":132,"column":71}},"16":{"start":{"line":134,"column":8},"end":{"line":134,"column":37}},"17":{"start":{"line":142,"column":8},"end":{"line":142,"column":5157}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":23},"end":{"line":54,"column":23}},{"start":{"line":54,"column":23},"end":{"line":54,"column":23}}]},"2":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":8},"end":{"line":80,"column":8}},{"start":{"line":80,"column":8},"end":{"line":80,"column":8}}]},"3":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":87},"end":{"line":122,"column":87}},{"start":{"line":122,"column":87},"end":{"line":122,"column":87}}]},"4":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":91},"end":{"line":131,"column":91}},{"start":{"line":131,"column":91},"end":{"line":131,"column":91}}]}}},
-"contracts/modules/wrapper/core/ERC20BurnModule.sol":{"l":{"26":618,"27":538,"45":231,"57":84,"71":160,"72":40,"85":63,"86":61,"98":315,"99":233},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol","s":{"1":618,"2":231,"3":84,"4":160,"5":40,"6":63,"7":61,"8":315,"9":233},"b":{"1":[231,60],"2":[84,0],"3":[160,20],"4":[63,0]},"f":{"1":618,"2":231,"3":84,"4":160,"5":63,"6":315},"fnMap":{"1":{"name":"onlyBurner","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"burn","line":44,"loc":{"start":{"line":40,"column":4},"end":{"line":46,"column":4}}},"3":{"name":"burn","line":56,"loc":{"start":{"line":53,"column":4},"end":{"line":58,"column":4}}},"4":{"name":"batchBurn","line":70,"loc":{"start":{"line":66,"column":4},"end":{"line":73,"column":4}}},"5":{"name":"batchBurn","line":84,"loc":{"start":{"line":81,"column":4},"end":{"line":87,"column":4}}},"6":{"name":"_burn","line":93,"loc":{"start":{"line":93,"column":4},"end":{"line":100,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":23}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":34}},"3":{"start":{"line":57,"column":7},"end":{"line":57,"column":30}},"4":{"start":{"line":71,"column":8},"end":{"line":71,"column":35}},"5":{"start":{"line":72,"column":8},"end":{"line":72,"column":60}},"6":{"start":{"line":85,"column":8},"end":{"line":85,"column":35}},"7":{"start":{"line":86,"column":8},"end":{"line":86,"column":58}},"8":{"start":{"line":98,"column":8},"end":{"line":98,"column":36}},"9":{"start":{"line":99,"column":8},"end":{"line":99,"column":53}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":44},"end":{"line":44,"column":44}},{"start":{"line":44,"column":44},"end":{"line":44,"column":44}}]},"2":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":44},"end":{"line":56,"column":44}},{"start":{"line":56,"column":44},"end":{"line":56,"column":44}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":47},"end":{"line":70,"column":47}},{"start":{"line":70,"column":47},"end":{"line":70,"column":47}}]},"4":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":45},"end":{"line":84,"column":45}},{"start":{"line":84,"column":45},"end":{"line":84,"column":45}}]}}},
-"contracts/modules/wrapper/core/ERC20MintModule.sol":{"l":{"28":3948,"29":3888,"44":120,"60":3081,"76":519,"77":410,"89":168,"96":3201,"97":3153},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol","s":{"1":3948,"2":120,"3":3081,"4":519,"5":410,"6":168,"7":3201,"8":3153},"b":{"1":[120,20],"2":[3081,20],"3":[519,20],"4":[168,0]},"f":{"1":3948,"2":120,"3":3081,"4":519,"5":168,"6":3201},"fnMap":{"1":{"name":"onlyMinter","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"mint","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":4}}},"3":{"name":"mint","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"batchMint","line":75,"loc":{"start":{"line":72,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"batchTransfer","line":88,"loc":{"start":{"line":85,"column":3},"end":{"line":90,"column":4}}},"6":{"name":"_mint","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":98,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":23}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":34}},"3":{"start":{"line":60,"column":7},"end":{"line":60,"column":31}},"4":{"start":{"line":76,"column":7},"end":{"line":76,"column":34}},"5":{"start":{"line":77,"column":8},"end":{"line":77,"column":54}},"6":{"start":{"line":89,"column":8},"end":{"line":89,"column":42}},"7":{"start":{"line":96,"column":8},"end":{"line":96,"column":36}},"8":{"start":{"line":97,"column":8},"end":{"line":97,"column":53}}},"branchMap":{"1":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":109},"end":{"line":43,"column":109}},{"start":{"line":43,"column":109},"end":{"line":43,"column":109}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":88},"end":{"line":59,"column":88}},{"start":{"line":59,"column":88},"end":{"line":59,"column":88}}]},"3":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":44},"end":{"line":75,"column":44}},{"start":{"line":75,"column":44},"end":{"line":75,"column":44}}]},"4":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":53},"end":{"line":88,"column":53}},{"start":{"line":88,"column":53},"end":{"line":88,"column":53}}]}}},
-"contracts/modules/wrapper/core/PauseModule.sol":{"l":{"41":614,"42":571,"46":224,"47":203,"60":508,"69":63,"70":63,"71":42,"86":203,"87":182,"88":182,"89":182,"97":3329,"104":8936,"105":8936,"116":8685,"117":101,"123":9181},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol","s":{"1":614,"2":224,"3":508,"4":63,"5":63,"6":42,"7":203,"8":182,"9":182,"10":3329,"11":8936,"12":8936,"13":8685},"b":{"1":[508,22],"2":[63,21],"3":[42,21],"4":[203,21],"5":[101,8584]},"f":{"1":614,"2":224,"3":508,"4":63,"5":203,"6":3329,"7":8936,"8":8685,"9":9181},"fnMap":{"1":{"name":"onlyPauseManager","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":43,"column":4}}},"2":{"name":"onlyDeactivateContractManager","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":48,"column":4}}},"3":{"name":"pause","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"unpause","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"deactivateContract","line":83,"loc":{"start":{"line":81,"column":4},"end":{"line":90,"column":4}}},"6":{"name":"paused","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":98,"column":3}}},"7":{"name":"deactivated","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":106,"column":4}}},"8":{"name":"_requireNotDeactivated","line":115,"loc":{"start":{"line":115,"column":4},"end":{"line":119,"column":4}}},"9":{"name":"_getPauseModuleStorage","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":126,"column":4}}}},"statementMap":{"1":{"start":{"line":41,"column":8},"end":{"line":41,"column":24}},"2":{"start":{"line":46,"column":8},"end":{"line":46,"column":29}},"3":{"start":{"line":60,"column":8},"end":{"line":60,"column":35}},"4":{"start":{"line":69,"column":8},"end":{"line":69,"column":63}},"5":{"start":{"line":70,"column":8},"end":{"line":70,"column":76}},"6":{"start":{"line":71,"column":8},"end":{"line":71,"column":37}},"7":{"start":{"line":86,"column":8},"end":{"line":86,"column":43}},"8":{"start":{"line":87,"column":8},"end":{"line":87,"column":63}},"9":{"start":{"line":89,"column":7},"end":{"line":89,"column":37}},"10":{"start":{"line":97,"column":8},"end":{"line":97,"column":43}},"11":{"start":{"line":104,"column":8},"end":{"line":104,"column":63}},"12":{"start":{"line":105,"column":8},"end":{"line":105,"column":31}},"13":{"start":{"line":116,"column":8},"end":{"line":116,"column":4424}}},"branchMap":{"1":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":75},"end":{"line":59,"column":75}},{"start":{"line":59,"column":75},"end":{"line":59,"column":75}}]},"2":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":77},"end":{"line":68,"column":77}},{"start":{"line":68,"column":77},"end":{"line":68,"column":77}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":8},"end":{"line":70,"column":8}},{"start":{"line":70,"column":8},"end":{"line":70,"column":8}}]},"4":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":8},"end":{"line":83,"column":8}},{"start":{"line":83,"column":8},"end":{"line":83,"column":8}}]},"5":{"line":116,"type":"if","locations":[{"start":{"line":116,"column":8},"end":{"line":116,"column":8}},{"start":{"line":116,"column":8},"end":{"line":116,"column":8}}]}}},
-"contracts/modules/wrapper/core/ValidationModuleCore.sol":{"l":{"25":894,"34":174,"50":1068},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol","s":{"1":894,"2":174,"3":1068},"b":{},"f":{"1":894,"2":174,"3":1068},"fnMap":{"1":{"name":"canTransfer","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"canTransferFrom","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":35,"column":4}}},"3":{"name":"_canTransferByModule","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":51,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":64}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":61}},"3":{"start":{"line":50,"column":8},"end":{"line":50,"column":78}}},"branchMap":{}},
-"contracts/modules/wrapper/core/VersionModule.sol":{"l":{"28":21},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/VersionModule.sol","s":{"1":21},"b":{},"f":{"1":21},"fnMap":{"1":{"name":"version","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":29,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":7},"end":{"line":28,"column":21}}},"branchMap":{}},
-"contracts/modules/wrapper/extensions/DocumentEngineModule.sol":{"l":{"29":120,"30":118,"43":4,"44":2,"45":2,"57":118,"58":118,"65":78,"66":78,"67":76,"69":2,"77":21,"78":21,"79":19,"91":118,"92":118,"93":116,"103":118,"104":118,"112":337},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentEngineModule.sol","s":{"1":120,"2":4,"3":2,"4":2,"5":118,"6":118,"7":78,"8":78,"9":76,"10":2,"11":21,"12":21,"13":118,"14":118,"15":116,"16":118},"b":{"1":[4,0],"2":[2,2],"3":[76,2],"4":[19,2],"5":[118,2],"6":[116,2]},"f":{"1":120,"2":4,"3":118,"4":78,"5":21,"6":118,"7":118,"8":337},"fnMap":{"1":{"name":"onlyDocumentManager","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"__DocumentEngineModule_init_unchained","line":42,"loc":{"start":{"line":41,"column":4},"end":{"line":47,"column":4}}},"3":{"name":"documentEngine","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":59,"column":4}}},"4":{"name":"getDocument","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":71,"column":4}}},"5":{"name":"getAllDocuments","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"setDocumentEngine","line":90,"loc":{"start":{"line":88,"column":4},"end":{"line":94,"column":4}}},"7":{"name":"_setDocumentEngine","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":105,"column":4}}},"8":{"name":"_getDocumentEngineModuleStorage","line":111,"loc":{"start":{"line":111,"column":4},"end":{"line":115,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":37}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":1729}},"3":{"start":{"line":44,"column":12},"end":{"line":44,"column":85}},"4":{"start":{"line":45,"column":12},"end":{"line":45,"column":49}},"5":{"start":{"line":57,"column":8},"end":{"line":57,"column":81}},"6":{"start":{"line":58,"column":8},"end":{"line":58,"column":32}},"7":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"8":{"start":{"line":66,"column":8},"end":{"line":66,"column":2677}},"9":{"start":{"line":67,"column":12},"end":{"line":67,"column":54}},"10":{"start":{"line":69,"column":12},"end":{"line":69,"column":39}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":3098}},"13":{"start":{"line":91,"column":8},"end":{"line":91,"column":81}},"14":{"start":{"line":92,"column":8},"end":{"line":92,"column":110}},"15":{"start":{"line":93,"column":8},"end":{"line":93,"column":45}},"16":{"start":{"line":104,"column":8},"end":{"line":104,"column":44}}},"branchMap":{"1":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":21}},{"start":{"line":42,"column":21},"end":{"line":42,"column":21}}]},"2":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":8}},{"start":{"line":43,"column":8},"end":{"line":43,"column":8}}]},"3":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]},"4":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":8},"end":{"line":78,"column":8}},{"start":{"line":78,"column":8},"end":{"line":78,"column":8}}]},"5":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":53},"end":{"line":90,"column":53}},{"start":{"line":90,"column":53},"end":{"line":90,"column":53}}]},"6":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":8},"end":{"line":92,"column":8}},{"start":{"line":92,"column":8},"end":{"line":92,"column":8}}]}}},
-"contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol":{"l":{"24":660,"25":618,"30":156,"31":128,"43":983,"51":686,"63":100,"64":100,"75":28,"76":14,"87":324,"98":84,"110":154,"121":28,"132":28},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol","s":{"1":660,"2":156,"3":983,"4":686,"5":100,"6":100,"7":28,"8":14,"9":324,"10":84,"11":154,"12":28,"13":28},"b":{"1":[100,14],"2":[28,14],"3":[324,14],"4":[84,14],"5":[154,14],"6":[28,0],"7":[28,0]},"f":{"1":660,"2":156,"3":983,"4":686,"5":100,"6":28,"7":324,"8":84,"9":154,"10":28,"11":28},"fnMap":{"1":{"name":"onlyERC20Enforcer","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"onlyForcedTransferManager","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"3":{"name":"getFrozenTokens","line":42,"loc":{"start":{"line":42,"column":4},"end":{"line":44,"column":5}}},"4":{"name":"getActiveBalanceOf","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":52,"column":5}}},"5":{"name":"forcedTransfer","line":62,"loc":{"start":{"line":61,"column":4},"end":{"line":65,"column":4}}},"6":{"name":"forcedTransfer","line":74,"loc":{"start":{"line":73,"column":4},"end":{"line":77,"column":4}}},"7":{"name":"freezePartialTokens","line":86,"loc":{"start":{"line":85,"column":4},"end":{"line":88,"column":4}}},"8":{"name":"unfreezePartialTokens","line":97,"loc":{"start":{"line":96,"column":4},"end":{"line":99,"column":4}}},"9":{"name":"setFrozenTokens","line":108,"loc":{"start":{"line":107,"column":4},"end":{"line":111,"column":4}}},"10":{"name":"freezePartialTokens","line":120,"loc":{"start":{"line":119,"column":4},"end":{"line":122,"column":4}}},"11":{"name":"unfreezePartialTokens","line":131,"loc":{"start":{"line":130,"column":4},"end":{"line":133,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":32}},"2":{"start":{"line":30,"column":8},"end":{"line":30,"column":33}},"3":{"start":{"line":43,"column":8},"end":{"line":43,"column":40}},"4":{"start":{"line":51,"column":8},"end":{"line":51,"column":43}},"5":{"start":{"line":63,"column":7},"end":{"line":63,"column":44}},"6":{"start":{"line":64,"column":7},"end":{"line":64,"column":18}},"7":{"start":{"line":75,"column":7},"end":{"line":75,"column":42}},"8":{"start":{"line":76,"column":7},"end":{"line":76,"column":18}},"9":{"start":{"line":87,"column":8},"end":{"line":87,"column":47}},"10":{"start":{"line":98,"column":8},"end":{"line":98,"column":49}},"11":{"start":{"line":110,"column":9},"end":{"line":110,"column":48}},"12":{"start":{"line":121,"column":8},"end":{"line":121,"column":49}},"13":{"start":{"line":132,"column":8},"end":{"line":132,"column":51}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":55},"end":{"line":62,"column":55}},{"start":{"line":62,"column":55},"end":{"line":62,"column":55}}]},"2":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":57},"end":{"line":74,"column":57}},{"start":{"line":74,"column":57},"end":{"line":74,"column":57}}]},"3":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":54},"end":{"line":86,"column":54}},{"start":{"line":86,"column":54},"end":{"line":86,"column":54}}]},"4":{"line":97,"type":"if","locations":[{"start":{"line":97,"column":54},"end":{"line":97,"column":54}},{"start":{"line":97,"column":54},"end":{"line":97,"column":54}}]},"5":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":65},"end":{"line":108,"column":65}},{"start":{"line":108,"column":65},"end":{"line":108,"column":65}}]},"6":{"line":120,"type":"if","locations":[{"start":{"line":120,"column":54},"end":{"line":120,"column":54}},{"start":{"line":120,"column":54},"end":{"line":120,"column":54}}]},"7":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":54},"end":{"line":131,"column":54}},{"start":{"line":131,"column":54},"end":{"line":131,"column":54}}]}}},
-"contracts/modules/wrapper/extensions/ExtraInformationModule.sol":{"l":{"32":140,"33":70,"45":3741,"47":3741,"49":3741,"51":3741,"68":22,"69":22,"79":22,"92":22,"93":22,"101":110,"102":110,"109":50,"110":50,"117":88,"118":88,"125":24,"126":24,"132":3763,"133":3763,"138":3765,"140":3765,"141":3765,"142":3765,"144":3765,"148":3763,"149":3763,"157":4057},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ExtraInformationModule.sol","s":{"1":140,"2":3741,"3":3741,"4":3741,"5":3741,"6":22,"7":22,"8":22,"9":22,"10":22,"11":110,"12":110,"13":50,"14":50,"15":88,"16":88,"17":24,"18":24,"19":3763,"20":3765,"21":3763},"b":{"1":[3741,0],"2":[22,22],"3":[22,22],"4":[22,22]},"f":{"1":140,"2":3741,"3":22,"4":22,"5":22,"6":110,"7":50,"8":88,"9":24,"10":3763,"11":3765,"12":3763,"13":4057},"fnMap":{"1":{"name":"onlyExtraInfoManager","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":34,"column":4}}},"2":{"name":"__ExtraInformationModule_init_unchained","line":44,"loc":{"start":{"line":40,"column":4},"end":{"line":52,"column":4}}},"3":{"name":"setTokenId","line":67,"loc":{"start":{"line":65,"column":4},"end":{"line":70,"column":4}}},"4":{"name":"setTerms","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":80,"column":4}}},"5":{"name":"setInformation","line":91,"loc":{"start":{"line":89,"column":4},"end":{"line":94,"column":4}}},"6":{"name":"tokenId","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":103,"column":4}}},"7":{"name":"terms","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":111,"column":4}}},"8":{"name":"information","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":119,"column":4}}},"9":{"name":"_setTerms","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":127,"column":4}}},"10":{"name":"_setTokenId","line":129,"loc":{"start":{"line":129,"column":4},"end":{"line":134,"column":4}}},"11":{"name":"_setTerms","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":145,"column":4}}},"12":{"name":"_setInformation","line":147,"loc":{"start":{"line":147,"column":4},"end":{"line":150,"column":4}}},"13":{"name":"_getExtraInformationModuleStorage","line":156,"loc":{"start":{"line":156,"column":4},"end":{"line":160,"column":4}}}},"statementMap":{"1":{"start":{"line":32,"column":8},"end":{"line":32,"column":38}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":85}},"3":{"start":{"line":47,"column":8},"end":{"line":47,"column":31}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":27}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":39}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":85}},"7":{"start":{"line":69,"column":8},"end":{"line":69,"column":31}},"8":{"start":{"line":79,"column":2},"end":{"line":79,"column":18}},"9":{"start":{"line":92,"column":8},"end":{"line":92,"column":85}},"10":{"start":{"line":93,"column":8},"end":{"line":93,"column":39}},"11":{"start":{"line":101,"column":8},"end":{"line":101,"column":85}},"12":{"start":{"line":102,"column":8},"end":{"line":102,"column":25}},"13":{"start":{"line":109,"column":8},"end":{"line":109,"column":85}},"14":{"start":{"line":110,"column":8},"end":{"line":110,"column":23}},"15":{"start":{"line":117,"column":8},"end":{"line":117,"column":85}},"16":{"start":{"line":118,"column":8},"end":{"line":118,"column":29}},"17":{"start":{"line":125,"column":2},"end":{"line":125,"column":79}},"18":{"start":{"line":126,"column":8},"end":{"line":126,"column":27}},"19":{"start":{"line":133,"column":8},"end":{"line":133,"column":40}},"20":{"start":{"line":144,"column":8},"end":{"line":144,"column":28}},"21":{"start":{"line":149,"column":8},"end":{"line":149,"column":38}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":23},"end":{"line":44,"column":23}},{"start":{"line":44,"column":23},"end":{"line":44,"column":23}}]},"2":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":42},"end":{"line":67,"column":42}},{"start":{"line":67,"column":42},"end":{"line":67,"column":42}}]},"3":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":102},"end":{"line":78,"column":102}},{"start":{"line":78,"column":102},"end":{"line":78,"column":102}}]},"4":{"line":91,"type":"if","locations":[{"start":{"line":91,"column":21},"end":{"line":91,"column":21}},{"start":{"line":91,"column":21},"end":{"line":91,"column":21}}]}}},
-"contracts/modules/wrapper/extensions/SnapshotEngineModule.sol":{"l":{"30":503,"31":501,"45":4,"46":2,"47":2,"65":501,"66":501,"67":499,"77":5780,"78":5780,"87":501,"88":501,"95":6283},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol","s":{"1":503,"2":4,"3":2,"4":2,"5":501,"6":501,"7":499,"8":5780,"9":5780,"10":501},"b":{"1":[4,0],"2":[2,2],"3":[501,2],"4":[499,2]},"f":{"1":503,"2":4,"3":501,"4":5780,"5":501,"6":6283},"fnMap":{"1":{"name":"onlySnapshooter","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"__SnapshotEngineModule_init_unchained","line":44,"loc":{"start":{"line":43,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"setSnapshotEngine","line":64,"loc":{"start":{"line":62,"column":4},"end":{"line":68,"column":4}}},"4":{"name":"snapshotEngine","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"5":{"name":"_setSnapshotEngine","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":89,"column":4}}},"6":{"name":"_getSnapshotEngineModuleStorage","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":98,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":28}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":1821}},"3":{"start":{"line":46,"column":12},"end":{"line":46,"column":85}},"4":{"start":{"line":47,"column":12},"end":{"line":47,"column":49}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"6":{"start":{"line":66,"column":8},"end":{"line":66,"column":104}},"7":{"start":{"line":67,"column":8},"end":{"line":67,"column":45}},"8":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}},"10":{"start":{"line":88,"column":8},"end":{"line":88,"column":44}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":21},"end":{"line":44,"column":21}},{"start":{"line":44,"column":21},"end":{"line":44,"column":21}}]},"2":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]},"3":{"line":64,"type":"if","locations":[{"start":{"line":64,"column":53},"end":{"line":64,"column":53}},{"start":{"line":64,"column":53},"end":{"line":64,"column":53}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]}}},
-"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol":{"l":{"55":69,"56":69,"57":6,"62":14,"67":7,"72":7,"77":7,"82":7,"84":18,"86":3,"103":136,"104":136,"105":136,"106":77,"108":42,"110":17,"120":122,"121":122,"122":7,"124":115,"125":115,"126":77,"128":24,"130":14,"147":167,"148":21,"150":35,"152":7,"154":7,"157":97},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol","s":{"1":69,"2":69,"3":6,"4":63,"5":14,"6":49,"7":7,"8":42,"9":7,"10":35,"11":7,"12":28,"13":7,"14":21,"15":18,"16":3,"17":136,"18":136,"19":136,"20":77,"21":59,"22":42,"23":17,"24":122,"25":122,"26":7,"27":115,"28":115,"29":77,"30":38,"31":24,"32":14,"33":167,"34":21,"35":146,"36":35,"37":111,"38":7,"39":104,"40":7,"41":97},"b":{"1":[6,63],"2":[14,49],"3":[7,42],"4":[7,35],"5":[7,28],"6":[7,21],"7":[18,3],"8":[77,59],"9":[42,17],"10":[7,115],"11":[77,38],"12":[24,14],"13":[21,146],"14":[35,111],"15":[7,104],"16":[7,97]},"f":{"1":69,"2":136,"3":122,"4":167},"fnMap":{"1":{"name":"messageForTransferRestriction","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":88,"column":4}}},"2":{"name":"detectTransferRestriction","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":112,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":114,"loc":{"start":{"line":114,"column":4},"end":{"line":133,"column":4}}},"4":{"name":"_detectTransferRestriction","line":142,"loc":{"start":{"line":142,"column":4},"end":{"line":159,"column":4}}}},"statementMap":{"1":{"start":{"line":55,"column":10},"end":{"line":55,"column":84}},"2":{"start":{"line":56,"column":8},"end":{"line":56,"column":2157}},"3":{"start":{"line":57,"column":12},"end":{"line":57,"column":35}},"4":{"start":{"line":58,"column":15},"end":{"line":58,"column":2288}},"5":{"start":{"line":62,"column":12},"end":{"line":62,"column":48}},"6":{"start":{"line":63,"column":15},"end":{"line":63,"column":2479}},"7":{"start":{"line":67,"column":12},"end":{"line":67,"column":53}},"8":{"start":{"line":68,"column":15},"end":{"line":68,"column":2680}},"9":{"start":{"line":72,"column":12},"end":{"line":72,"column":53}},"10":{"start":{"line":73,"column":15},"end":{"line":73,"column":2881}},"11":{"start":{"line":77,"column":12},"end":{"line":77,"column":51}},"12":{"start":{"line":78,"column":16},"end":{"line":78,"column":3079}},"13":{"start":{"line":82,"column":12},"end":{"line":82,"column":56}},"14":{"start":{"line":83,"column":15},"end":{"line":83,"column":3286}},"15":{"start":{"line":84,"column":12},"end":{"line":84,"column":77}},"16":{"start":{"line":86,"column":12},"end":{"line":86,"column":36}},"17":{"start":{"line":103,"column":9},"end":{"line":103,"column":83}},"18":{"start":{"line":104,"column":9},"end":{"line":104,"column":71}},"19":{"start":{"line":105,"column":9},"end":{"line":105,"column":4192}},"20":{"start":{"line":106,"column":12},"end":{"line":106,"column":29}},"21":{"start":{"line":107,"column":16},"end":{"line":107,"column":4312}},"22":{"start":{"line":108,"column":12},"end":{"line":108,"column":73}},"23":{"start":{"line":110,"column":12},"end":{"line":110,"column":71}},"24":{"start":{"line":120,"column":8},"end":{"line":120,"column":82}},"25":{"start":{"line":121,"column":8},"end":{"line":121,"column":4834}},"26":{"start":{"line":122,"column":12},"end":{"line":122,"column":92}},"27":{"start":{"line":124,"column":12},"end":{"line":124,"column":74}},"28":{"start":{"line":125,"column":12},"end":{"line":125,"column":5062}},"29":{"start":{"line":126,"column":16},"end":{"line":126,"column":33}},"30":{"start":{"line":127,"column":19},"end":{"line":127,"column":5190}},"31":{"start":{"line":128,"column":16},"end":{"line":128,"column":90}},"32":{"start":{"line":130,"column":16},"end":{"line":130,"column":75}},"33":{"start":{"line":147,"column":8},"end":{"line":147,"column":5893}},"34":{"start":{"line":148,"column":12},"end":{"line":148,"column":89}},"35":{"start":{"line":149,"column":15},"end":{"line":149,"column":6019}},"36":{"start":{"line":150,"column":12},"end":{"line":150,"column":84}},"37":{"start":{"line":151,"column":15},"end":{"line":151,"column":6136}},"38":{"start":{"line":152,"column":12},"end":{"line":152,"column":89}},"39":{"start":{"line":153,"column":15},"end":{"line":153,"column":6264}},"40":{"start":{"line":154,"column":12},"end":{"line":154,"column":87}},"41":{"start":{"line":157,"column":12},"end":{"line":157,"column":71}}},"branchMap":{"1":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":8},"end":{"line":56,"column":8}},{"start":{"line":56,"column":8},"end":{"line":56,"column":8}}]},"2":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":15},"end":{"line":58,"column":15}},{"start":{"line":58,"column":15},"end":{"line":58,"column":15}}]},"3":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":15},"end":{"line":63,"column":15}},{"start":{"line":63,"column":15},"end":{"line":63,"column":15}}]},"4":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":15},"end":{"line":68,"column":15}},{"start":{"line":68,"column":15},"end":{"line":68,"column":15}}]},"5":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":15},"end":{"line":73,"column":15}},{"start":{"line":73,"column":15},"end":{"line":73,"column":15}}]},"6":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":16},"end":{"line":78,"column":16}},{"start":{"line":78,"column":16},"end":{"line":78,"column":16}}]},"7":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":15},"end":{"line":83,"column":15}},{"start":{"line":83,"column":15},"end":{"line":83,"column":15}}]},"8":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":9},"end":{"line":105,"column":9}},{"start":{"line":105,"column":9},"end":{"line":105,"column":9}}]},"9":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":16},"end":{"line":107,"column":16}},{"start":{"line":107,"column":16},"end":{"line":107,"column":16}}]},"10":{"line":121,"type":"if","locations":[{"start":{"line":121,"column":8},"end":{"line":121,"column":8}},{"start":{"line":121,"column":8},"end":{"line":121,"column":8}}]},"11":{"line":125,"type":"if","locations":[{"start":{"line":125,"column":12},"end":{"line":125,"column":12}},{"start":{"line":125,"column":12},"end":{"line":125,"column":12}}]},"12":{"line":127,"type":"if","locations":[{"start":{"line":127,"column":19},"end":{"line":127,"column":19}},{"start":{"line":127,"column":19},"end":{"line":127,"column":19}}]},"13":{"line":147,"type":"if","locations":[{"start":{"line":147,"column":8},"end":{"line":147,"column":8}},{"start":{"line":147,"column":8},"end":{"line":147,"column":8}}]},"14":{"line":149,"type":"if","locations":[{"start":{"line":149,"column":15},"end":{"line":149,"column":15}},{"start":{"line":149,"column":15},"end":{"line":149,"column":15}}]},"15":{"line":151,"type":"if","locations":[{"start":{"line":151,"column":15},"end":{"line":151,"column":15}},{"start":{"line":151,"column":15},"end":{"line":151,"column":15}}]},"16":{"line":153,"type":"if","locations":[{"start":{"line":153,"column":15},"end":{"line":153,"column":15}},{"start":{"line":153,"column":15},"end":{"line":153,"column":15}}]}}},
-"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol":{"l":{"27":90,"28":87,"49":87,"50":84,"62":692,"75":141,"87":692,"88":192,"90":500,"100":141,"101":60,"103":81,"113":81,"114":81,"115":30,"117":51,"125":500,"126":500,"127":60,"129":440,"138":8158,"139":7818,"140":7818,"141":540,"142":12,"144":528},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol","s":{"1":90,"2":87,"3":84,"4":692,"5":141,"6":692,"7":192,"8":500,"9":141,"10":60,"11":81,"12":81,"13":81,"14":30,"15":51,"16":500,"17":500,"18":60,"19":440,"20":8158,"21":7818,"22":7818,"23":540,"24":12,"25":528},"b":{"1":[87,3],"2":[84,3],"3":[192,500],"4":[60,81],"5":[30,51],"6":[60,440],"7":[540,7278],"8":[12,528]},"f":{"1":90,"2":87,"3":692,"4":141,"5":692,"6":141,"7":81,"8":500,"9":8158},"fnMap":{"1":{"name":"onlyRuleEngineManager","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":29,"column":4}}},"2":{"name":"setRuleEngine","line":48,"loc":{"start":{"line":46,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"canTransfer","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"canTransferFrom","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"_canTransfer","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":92,"column":4}}},"6":{"name":"_canTransferFrom","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":105,"column":4}}},"7":{"name":"_canTransferFromWithRuleEngine","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":119,"column":4}}},"8":{"name":"_canTransferWithRuleEngine","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":131,"column":4}}},"9":{"name":"_transferred","line":137,"loc":{"start":{"line":137,"column":4},"end":{"line":147,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":39}},"2":{"start":{"line":49,"column":9},"end":{"line":49,"column":98}},"3":{"start":{"line":50,"column":8},"end":{"line":50,"column":34}},"4":{"start":{"line":62,"column":7},"end":{"line":62,"column":43}},"5":{"start":{"line":75,"column":8},"end":{"line":75,"column":57}},"6":{"start":{"line":87,"column":7},"end":{"line":87,"column":2936}},"7":{"start":{"line":88,"column":12},"end":{"line":88,"column":24}},"8":{"start":{"line":90,"column":12},"end":{"line":90,"column":62}},"9":{"start":{"line":100,"column":8},"end":{"line":100,"column":3291}},"10":{"start":{"line":101,"column":12},"end":{"line":101,"column":24}},"11":{"start":{"line":103,"column":12},"end":{"line":103,"column":75}},"12":{"start":{"line":113,"column":8},"end":{"line":113,"column":46}},"13":{"start":{"line":114,"column":8},"end":{"line":114,"column":3734}},"14":{"start":{"line":115,"column":12},"end":{"line":115,"column":72}},"15":{"start":{"line":117,"column":12},"end":{"line":117,"column":23}},"16":{"start":{"line":125,"column":8},"end":{"line":125,"column":46}},"17":{"start":{"line":126,"column":8},"end":{"line":126,"column":4113}},"18":{"start":{"line":127,"column":12},"end":{"line":127,"column":59}},"19":{"start":{"line":129,"column":12},"end":{"line":129,"column":23}},"20":{"start":{"line":138,"column":8},"end":{"line":138,"column":62}},"21":{"start":{"line":139,"column":8},"end":{"line":139,"column":46}},"22":{"start":{"line":140,"column":8},"end":{"line":140,"column":4665}},"23":{"start":{"line":141,"column":12},"end":{"line":141,"column":4722}},"24":{"start":{"line":142,"column":16},"end":{"line":142,"column":64}},"25":{"start":{"line":144,"column":16},"end":{"line":144,"column":55}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":21},"end":{"line":48,"column":21}},{"start":{"line":48,"column":21},"end":{"line":48,"column":21}}]},"2":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":9},"end":{"line":49,"column":9}},{"start":{"line":49,"column":9},"end":{"line":49,"column":9}}]},"3":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":7},"end":{"line":87,"column":7}},{"start":{"line":87,"column":7},"end":{"line":87,"column":7}}]},"4":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":8},"end":{"line":100,"column":8}},{"start":{"line":100,"column":8},"end":{"line":100,"column":8}}]},"5":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":8},"end":{"line":114,"column":8}},{"start":{"line":114,"column":8},"end":{"line":114,"column":8}}]},"6":{"line":126,"type":"if","locations":[{"start":{"line":126,"column":8},"end":{"line":126,"column":8}},{"start":{"line":126,"column":8},"end":{"line":126,"column":8}}]},"7":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":8},"end":{"line":140,"column":8}},{"start":{"line":140,"column":8},"end":{"line":140,"column":8}}]},"8":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":12},"end":{"line":141,"column":12}},{"start":{"line":141,"column":12},"end":{"line":141,"column":12}}]}}},
-"contracts/modules/wrapper/options/AllowlistModule.sol":{"l":{"25":769,"26":761,"37":4,"47":218,"57":422,"67":117,"68":117,"77":4,"84":1092,"91":1882,"92":1882},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/AllowlistModule.sol","s":{"1":769,"2":4,"3":218,"4":422,"5":117,"6":117,"7":4,"8":1092,"9":1882,"10":1882},"b":{"1":[4,2],"2":[218,4],"3":[422,2],"4":[117,0]},"f":{"1":769,"2":4,"3":218,"4":422,"5":117,"6":4,"7":1092,"8":1882},"fnMap":{"1":{"name":"onlyAllowlistManager","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"setAddressAllowlist","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":38,"column":4}}},"3":{"name":"setAddressAllowlist","line":46,"loc":{"start":{"line":44,"column":4},"end":{"line":48,"column":4}}},"4":{"name":"batchSetAddressAllowlist","line":56,"loc":{"start":{"line":54,"column":4},"end":{"line":58,"column":4}}},"5":{"name":"enableAllowlist","line":66,"loc":{"start":{"line":64,"column":4},"end":{"line":69,"column":4}}},"6":{"name":"isAllowlistEnabled","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":78,"column":4}}},"7":{"name":"isAllowlisted","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":85,"column":4}}},"8":{"name":"_addToAllowlist","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":93,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":38}},"2":{"start":{"line":37,"column":9},"end":{"line":37,"column":44}},"3":{"start":{"line":47,"column":9},"end":{"line":47,"column":46}},"4":{"start":{"line":57,"column":9},"end":{"line":57,"column":45}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":31}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":56}},"7":{"start":{"line":77,"column":8},"end":{"line":77,"column":36}},"8":{"start":{"line":84,"column":7},"end":{"line":84,"column":37}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":72}},"10":{"start":{"line":92,"column":8},"end":{"line":92,"column":73}}},"branchMap":{"1":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":78},"end":{"line":36,"column":78}},{"start":{"line":36,"column":78},"end":{"line":36,"column":78}}]},"2":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":21},"end":{"line":46,"column":21}},{"start":{"line":46,"column":21},"end":{"line":46,"column":21}}]},"3":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":21},"end":{"line":56,"column":21}},{"start":{"line":56,"column":21},"end":{"line":56,"column":21}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":21},"end":{"line":66,"column":21}},{"start":{"line":66,"column":21},"end":{"line":66,"column":21}}]}}},
-"contracts/modules/wrapper/options/CCIPModule.sol":{"l":{"31":32,"32":24,"42":24,"43":24,"44":24,"46":16,"48":16,"55":16,"56":16,"67":40},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/CCIPModule.sol","s":{"1":32,"2":24,"3":24,"4":24,"5":16,"6":16,"7":16},"b":{"1":[24,8],"2":[16,8]},"f":{"1":32,"2":24,"3":16,"4":40},"fnMap":{"1":{"name":"onlyCCIPSetAdmin","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":33,"column":4}}},"2":{"name":"setCCIPAdmin","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":49,"column":2}}},"3":{"name":"getCCIPAdmin","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":57,"column":2}}},"4":{"name":"_getCCIPModuleStorage","line":66,"loc":{"start":{"line":66,"column":2},"end":{"line":70,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":31}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":57}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":40}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":66}},"5":{"start":{"line":48,"column":4},"end":{"line":48,"column":53}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":57}},"7":{"start":{"line":56,"column":4},"end":{"line":56,"column":24}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":57},"end":{"line":41,"column":57}},{"start":{"line":41,"column":57},"end":{"line":41,"column":57}}]},"2":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}},
+"contracts/modules/0_CMTATBaseCommon.sol":{"l":{"51":22,"59":80,"66":68,"72":431,"73":431,"74":248,"75":197,"90":278,"91":118,"108":110,"109":66,"116":8426,"126":6250,"127":6063,"136":1175,"137":951,"146":292,"147":199},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol","s":{"1":22,"2":80,"3":68,"4":431,"5":431,"6":248,"7":197,"8":278,"9":118,"10":110,"11":66,"12":8426,"13":6250,"14":6063,"15":1175,"16":951,"17":292,"18":199},"b":{},"f":{"1":22,"2":80,"3":68,"4":431,"5":278,"6":110,"7":8426,"8":6250,"9":1175,"10":292},"fnMap":{"1":{"name":"decimals","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":52,"column":4}}},"2":{"name":"name","line":58,"loc":{"start":{"line":58,"column":4},"end":{"line":60,"column":4}}},"3":{"name":"symbol","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":67,"column":4}}},"4":{"name":"transfer","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"transferFrom","line":80,"loc":{"start":{"line":80,"column":4},"end":{"line":92,"column":4}}},"6":{"name":"burnAndMint","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":110,"column":4}}},"7":{"name":"_checkTransferred","line":115,"loc":{"start":{"line":115,"column":4},"end":{"line":117,"column":4}}},"8":{"name":"_mintOverride","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":128,"column":4}}},"9":{"name":"_burnOverride","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":138,"column":4}}},"10":{"name":"_minterTransferOverride","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":148,"column":4}}}},"statementMap":{"1":{"start":{"line":51,"column":8},"end":{"line":51,"column":41}},"2":{"start":{"line":59,"column":8},"end":{"line":59,"column":37}},"3":{"start":{"line":66,"column":8},"end":{"line":66,"column":39}},"4":{"start":{"line":72,"column":9},"end":{"line":72,"column":36}},"5":{"start":{"line":73,"column":8},"end":{"line":73,"column":53}},"6":{"start":{"line":74,"column":8},"end":{"line":74,"column":50}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":19}},"8":{"start":{"line":90,"column":8},"end":{"line":90,"column":55}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":60}},"10":{"start":{"line":108,"column":8},"end":{"line":108,"column":53}},"11":{"start":{"line":109,"column":8},"end":{"line":109,"column":51}},"12":{"start":{"line":116,"column":8},"end":{"line":116,"column":79}},"13":{"start":{"line":126,"column":8},"end":{"line":126,"column":66}},"14":{"start":{"line":127,"column":8},"end":{"line":127,"column":60}},"15":{"start":{"line":136,"column":8},"end":{"line":136,"column":67}},"16":{"start":{"line":137,"column":8},"end":{"line":137,"column":60}},"17":{"start":{"line":146,"column":8},"end":{"line":146,"column":55}},"18":{"start":{"line":147,"column":8},"end":{"line":147,"column":71}}},"branchMap":{}},
+"contracts/modules/0_CMTATBaseCore.sol":{"l":{"58":4,"59":3,"75":247,"91":284,"94":284,"97":284,"100":284,"108":284,"109":284,"118":284,"119":284,"144":2,"152":6,"159":6,"171":12,"179":28,"180":28,"181":18,"182":12,"189":30,"190":24,"205":14,"206":10,"223":10,"224":6,"237":3,"239":2,"240":2,"249":354,"250":346,"255":76,"256":66,"263":18,"264":12},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol","s":{"1":4,"2":247,"3":284,"4":284,"5":284,"6":284,"7":284,"8":284,"9":284,"10":284,"11":2,"12":6,"13":6,"14":12,"15":28,"16":28,"17":18,"18":12,"19":30,"20":24,"21":14,"22":10,"23":10,"24":6,"25":3,"26":2,"27":2,"28":354,"29":346,"30":76,"31":66,"32":18,"33":12},"b":{"1":[247,0],"2":[284,0],"3":[284,0],"4":[284,0],"5":[2,2],"6":[2,2],"7":[3,1],"8":[2,1],"9":[3,1],"10":[284,6],"11":[54,8],"12":[50,4],"13":[20,2],"14":[51,6],"15":[4,4]},"f":{"1":4,"2":247,"3":284,"4":284,"5":284,"6":2,"7":6,"8":6,"9":12,"10":28,"11":30,"12":14,"13":10,"14":3,"15":354,"16":76,"17":18,"18":3,"19":284,"20":54,"21":50,"22":20,"23":51,"24":4},"fnMap":{"1":{"name":"onlyERC20ForcedBurnManager","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"initialize","line":74,"loc":{"start":{"line":71,"column":4},"end":{"line":79,"column":4}}},"3":{"name":"__CMTAT_init","line":88,"loc":{"start":{"line":85,"column":4},"end":{"line":101,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":110,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":120,"column":4}}},"6":{"name":"decimals","line":137,"loc":{"start":{"line":137,"column":4},"end":{"line":145,"column":4}}},"7":{"name":"name","line":151,"loc":{"start":{"line":151,"column":4},"end":{"line":153,"column":4}}},"8":{"name":"symbol","line":158,"loc":{"start":{"line":158,"column":4},"end":{"line":160,"column":4}}},"9":{"name":"supportsInterface","line":170,"loc":{"start":{"line":170,"column":4},"end":{"line":172,"column":4}}},"10":{"name":"transfer","line":178,"loc":{"start":{"line":178,"column":4},"end":{"line":183,"column":4}}},"11":{"name":"approve","line":188,"loc":{"start":{"line":188,"column":4},"end":{"line":191,"column":4}}},"12":{"name":"transferFrom","line":195,"loc":{"start":{"line":195,"column":4},"end":{"line":207,"column":4}}},"13":{"name":"burnAndMint","line":222,"loc":{"start":{"line":222,"column":4},"end":{"line":225,"column":4}}},"14":{"name":"forcedBurn","line":236,"loc":{"start":{"line":232,"column":4},"end":{"line":241,"column":4}}},"15":{"name":"_mintOverride","line":248,"loc":{"start":{"line":248,"column":4},"end":{"line":251,"column":4}}},"16":{"name":"_burnOverride","line":254,"loc":{"start":{"line":254,"column":4},"end":{"line":257,"column":4}}},"17":{"name":"_minterTransferOverride","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":265,"column":4}}},"18":{"name":"_authorizeForcedBurn","line":268,"loc":{"start":{"line":268,"column":4},"end":{"line":268,"column":82}}},"19":{"name":"_authorizeMint","line":270,"loc":{"start":{"line":270,"column":4},"end":{"line":270,"column":95}}},"20":{"name":"_authorizeBurn","line":272,"loc":{"start":{"line":272,"column":4},"end":{"line":272,"column":95}}},"21":{"name":"_authorizePause","line":274,"loc":{"start":{"line":274,"column":4},"end":{"line":274,"column":92}}},"22":{"name":"_authorizeDeactivate","line":275,"loc":{"start":{"line":275,"column":4},"end":{"line":275,"column":104}}},"23":{"name":"_authorizeFreeze","line":277,"loc":{"start":{"line":277,"column":4},"end":{"line":277,"column":101}}},"24":{"name":"_authorizeERC20AttributeManagement","line":279,"loc":{"start":{"line":279,"column":4},"end":{"line":279,"column":122}}}},"statementMap":{"1":{"start":{"line":58,"column":8},"end":{"line":58,"column":29}},"2":{"start":{"line":75,"column":8},"end":{"line":75,"column":2991}},"3":{"start":{"line":91,"column":8},"end":{"line":91,"column":33}},"4":{"start":{"line":94,"column":8},"end":{"line":94,"column":32}},"5":{"start":{"line":97,"column":8},"end":{"line":97,"column":44}},"6":{"start":{"line":100,"column":8},"end":{"line":100,"column":62}},"7":{"start":{"line":108,"column":8},"end":{"line":108,"column":39}},"8":{"start":{"line":109,"column":8},"end":{"line":109,"column":34}},"9":{"start":{"line":118,"column":8},"end":{"line":118,"column":50}},"10":{"start":{"line":119,"column":8},"end":{"line":119,"column":125}},"11":{"start":{"line":144,"column":8},"end":{"line":144,"column":41}},"12":{"start":{"line":152,"column":8},"end":{"line":152,"column":37}},"13":{"start":{"line":159,"column":8},"end":{"line":159,"column":39}},"14":{"start":{"line":171,"column":8},"end":{"line":171,"column":128}},"15":{"start":{"line":179,"column":8},"end":{"line":179,"column":35}},"16":{"start":{"line":180,"column":8},"end":{"line":180,"column":82}},"17":{"start":{"line":181,"column":8},"end":{"line":181,"column":50}},"18":{"start":{"line":182,"column":8},"end":{"line":182,"column":19}},"19":{"start":{"line":189,"column":8},"end":{"line":189,"column":69}},"20":{"start":{"line":190,"column":8},"end":{"line":190,"column":55}},"21":{"start":{"line":205,"column":8},"end":{"line":205,"column":84}},"22":{"start":{"line":206,"column":8},"end":{"line":206,"column":60}},"23":{"start":{"line":223,"column":8},"end":{"line":223,"column":53}},"24":{"start":{"line":224,"column":8},"end":{"line":224,"column":51}},"25":{"start":{"line":237,"column":8},"end":{"line":237,"column":95}},"26":{"start":{"line":239,"column":8},"end":{"line":239,"column":45}},"27":{"start":{"line":240,"column":8},"end":{"line":240,"column":75}},"28":{"start":{"line":249,"column":8},"end":{"line":249,"column":58}},"29":{"start":{"line":250,"column":8},"end":{"line":250,"column":60}},"30":{"start":{"line":255,"column":8},"end":{"line":255,"column":58}},"31":{"start":{"line":256,"column":8},"end":{"line":256,"column":60}},"32":{"start":{"line":263,"column":8},"end":{"line":263,"column":82}},"33":{"start":{"line":264,"column":8},"end":{"line":264,"column":71}}},"branchMap":{"1":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":21},"end":{"line":74,"column":21}},{"start":{"line":74,"column":21},"end":{"line":74,"column":21}}]},"2":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":23},"end":{"line":88,"column":23}},{"start":{"line":88,"column":23},"end":{"line":88,"column":23}}]},"3":{"line":106,"type":"if","locations":[{"start":{"line":106,"column":68},"end":{"line":106,"column":68}},{"start":{"line":106,"column":68},"end":{"line":106,"column":68}}]},"4":{"line":116,"type":"if","locations":[{"start":{"line":116,"column":136},"end":{"line":116,"column":136}},{"start":{"line":116,"column":136},"end":{"line":116,"column":136}}]},"5":{"line":171,"type":"cond-expr","locations":[{"start":{"line":171,"column":15},"end":{"line":171,"column":39}},{"start":{"line":171,"column":44},"end":{"line":171,"column":68}}]},"6":{"line":171,"type":"cond-expr","locations":[{"start":{"line":171,"column":15},"end":{"line":171,"column":68}},{"start":{"line":171,"column":73},"end":{"line":171,"column":127}}]},"7":{"line":236,"type":"if","locations":[{"start":{"line":236,"column":48},"end":{"line":236,"column":48}},{"start":{"line":236,"column":48},"end":{"line":236,"column":48}}]},"8":{"line":237,"type":"if","locations":[{"start":{"line":237,"column":8},"end":{"line":237,"column":8}},{"start":{"line":237,"column":8},"end":{"line":237,"column":8}}]},"9":{"line":268,"type":"if","locations":[{"start":{"line":268,"column":53},"end":{"line":268,"column":53}},{"start":{"line":268,"column":53},"end":{"line":268,"column":53}}]},"10":{"line":270,"type":"if","locations":[{"start":{"line":270,"column":73},"end":{"line":270,"column":73}},{"start":{"line":270,"column":73},"end":{"line":270,"column":73}}]},"11":{"line":272,"type":"if","locations":[{"start":{"line":272,"column":73},"end":{"line":272,"column":73}},{"start":{"line":272,"column":73},"end":{"line":272,"column":73}}]},"12":{"line":274,"type":"if","locations":[{"start":{"line":274,"column":70},"end":{"line":274,"column":70}},{"start":{"line":274,"column":70},"end":{"line":274,"column":70}}]},"13":{"line":275,"type":"if","locations":[{"start":{"line":275,"column":75},"end":{"line":275,"column":75}},{"start":{"line":275,"column":75},"end":{"line":275,"column":75}}]},"14":{"line":277,"type":"if","locations":[{"start":{"line":277,"column":77},"end":{"line":277,"column":77}},{"start":{"line":277,"column":77},"end":{"line":277,"column":77}}]},"15":{"line":279,"type":"if","locations":[{"start":{"line":279,"column":93},"end":{"line":279,"column":93}},{"start":{"line":279,"column":93},"end":{"line":279,"column":93}}]}}},
+"contracts/modules/0_CMTATBaseGeneric.sol":{"l":{"50":62,"53":62,"56":62,"59":62,"67":62,"68":62,"76":62,"78":62},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseGeneric.sol","s":{"1":62,"2":62,"3":62,"4":62,"5":62,"6":62,"7":62,"8":62},"b":{"1":[62,0],"2":[62,0],"3":[62,0],"4":[11,2],"5":[3,3]},"f":{"1":62,"2":62,"3":62,"4":11,"5":3},"fnMap":{"1":{"name":"__CMTAT_init","line":47,"loc":{"start":{"line":44,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"__CMTAT_openzeppelin_init_unchained","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":69,"column":4}}},"3":{"name":"__CMTAT_modules_init_unchained","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":79,"column":4}}},"4":{"name":"_authorizeDocumentManagement","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":86,"column":118}}},"5":{"name":"_authorizeExtraInfoManagement","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":87,"column":129}}}},"statementMap":{"1":{"start":{"line":50,"column":8},"end":{"line":50,"column":33}},"2":{"start":{"line":53,"column":8},"end":{"line":53,"column":32}},"3":{"start":{"line":56,"column":8},"end":{"line":56,"column":44}},"4":{"start":{"line":59,"column":8},"end":{"line":59,"column":74}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":39}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":34}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":50}},"8":{"start":{"line":78,"column":8},"end":{"line":78,"column":159}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":23},"end":{"line":47,"column":23}},{"start":{"line":47,"column":23},"end":{"line":47,"column":23}}]},"2":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":68},"end":{"line":65,"column":68}},{"start":{"line":65,"column":68},"end":{"line":65,"column":68}}]},"3":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":157},"end":{"line":74,"column":157}},{"start":{"line":74,"column":157},"end":{"line":74,"column":157}}]},"4":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":94},"end":{"line":86,"column":94}},{"start":{"line":86,"column":94},"end":{"line":86,"column":94}}]},"5":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":96},"end":{"line":87,"column":96}},{"start":{"line":87,"column":96},"end":{"line":87,"column":96}}]}}},
+"contracts/modules/0_CMTATBaseSnapshot.sol":{"l":{"20":2951,"21":2951,"22":176,"23":176,"24":176,"25":176,"26":176,"28":2775},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseSnapshot.sol","s":{"1":2951,"2":2951,"3":176,"4":176,"5":176,"6":176,"7":176,"8":2775},"b":{"1":[176,2775]},"f":{"1":2951},"fnMap":{"1":{"name":"_update","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":30,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":62}},"2":{"start":{"line":21,"column":8},"end":{"line":21,"column":917}},"3":{"start":{"line":22,"column":12},"end":{"line":22,"column":55}},"4":{"start":{"line":23,"column":12},"end":{"line":23,"column":51}},"5":{"start":{"line":24,"column":12},"end":{"line":24,"column":53}},"6":{"start":{"line":25,"column":12},"end":{"line":25,"column":53}},"7":{"start":{"line":26,"column":12},"end":{"line":26,"column":113}},"8":{"start":{"line":28,"column":12},"end":{"line":28,"column":53}}},"branchMap":{"1":{"line":21,"type":"if","locations":[{"start":{"line":21,"column":8},"end":{"line":21,"column":8}},{"start":{"line":21,"column":8},"end":{"line":21,"column":8}}]}}},
+"contracts/modules/1_CMTATBaseDocument.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/1_CMTATBaseDocument.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},
+"contracts/modules/2_CMTATBaseAccessControl.sol":{"l":{"34":5342,"36":5340,"38":5340,"53":42},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAccessControl.sol","s":{"1":5342,"2":5340,"3":5340,"4":42},"b":{"1":[5342,0],"2":[16,2],"3":[2,2],"4":[2,4],"5":[46,44],"6":[5366,66],"7":[685,88],"8":[242,44],"9":[79,79],"10":[1226,63],"11":[220,42]},"f":{"1":5342,"2":42,"3":46,"4":5366,"5":685,"6":242,"7":79,"8":1226,"9":220},"fnMap":{"1":{"name":"__CMTAT_commonModules_init_unchained","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"supportsInterface","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":54,"column":4}}},"3":{"name":"_authorizeERC20AttributeManagement","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":66,"column":122}}},"4":{"name":"_authorizeMint","line":72,"loc":{"start":{"line":72,"column":4},"end":{"line":72,"column":95}}},"5":{"name":"_authorizeBurn","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":78,"column":95}}},"6":{"name":"_authorizeDocumentManagement","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":84,"column":117}}},"7":{"name":"_authorizeExtraInfoManagement","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":90,"column":129}}},"8":{"name":"_authorizeERC20Enforcer","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":96,"column":118}}},"9":{"name":"_authorizeForcedTransfer","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":102,"column":119}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":50}},"2":{"start":{"line":36,"column":8},"end":{"line":36,"column":125}},"3":{"start":{"line":38,"column":8},"end":{"line":38,"column":177}},"4":{"start":{"line":53,"column":8},"end":{"line":53,"column":157}}},"branchMap":{"1":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":228},"end":{"line":32,"column":228}},{"start":{"line":32,"column":228},"end":{"line":32,"column":228}}]},"2":{"line":53,"type":"cond-expr","locations":[{"start":{"line":53,"column":15},"end":{"line":53,"column":39}},{"start":{"line":53,"column":44},"end":{"line":53,"column":68}}]},"3":{"line":53,"type":"cond-expr","locations":[{"start":{"line":53,"column":15},"end":{"line":53,"column":68}},{"start":{"line":53,"column":73},"end":{"line":53,"column":97}}]},"4":{"line":53,"type":"cond-expr","locations":[{"start":{"line":53,"column":15},"end":{"line":53,"column":97}},{"start":{"line":53,"column":102},"end":{"line":53,"column":156}}]},"5":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":93},"end":{"line":66,"column":93}},{"start":{"line":66,"column":93},"end":{"line":66,"column":93}}]},"6":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":73},"end":{"line":72,"column":73}},{"start":{"line":72,"column":73},"end":{"line":72,"column":73}}]},"7":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":73},"end":{"line":78,"column":73}},{"start":{"line":78,"column":73},"end":{"line":78,"column":73}}]},"8":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":93},"end":{"line":84,"column":93}},{"start":{"line":84,"column":93},"end":{"line":84,"column":93}}]},"9":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":96},"end":{"line":90,"column":96}},{"start":{"line":90,"column":96},"end":{"line":90,"column":96}}]},"10":{"line":96,"type":"if","locations":[{"start":{"line":96,"column":89},"end":{"line":96,"column":89}},{"start":{"line":96,"column":89},"end":{"line":96,"column":89}}]},"11":{"line":102,"type":"if","locations":[{"start":{"line":102,"column":90},"end":{"line":102,"column":90}},{"start":{"line":102,"column":90},"end":{"line":102,"column":90}}]}}},
+"contracts/modules/3_CMTATBaseAllowlist.sol":{"l":{"57":594,"75":594,"78":594,"81":594,"84":594,"92":594,"93":594,"95":594,"102":594,"104":594,"123":68,"124":58,"133":54,"142":35,"152":3,"162":9,"172":9,"183":240,"184":240,"185":60,"187":180,"201":31,"202":31,"203":8,"205":23,"221":132,"224":28,"234":12,"240":740,"246":128,"250":207,"254":34,"262":191,"270":108,"274":992,"275":976,"285":116,"301":7381,"310":7383,"322":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol","s":{"1":594,"2":594,"3":594,"4":594,"5":594,"6":594,"7":594,"8":594,"9":594,"10":594,"11":68,"12":58,"13":54,"14":35,"15":3,"16":9,"17":9,"18":240,"19":240,"20":60,"21":180,"22":31,"23":31,"24":8,"25":23,"26":132,"27":28,"28":12,"29":740,"30":128,"31":207,"32":34,"33":191,"34":108,"35":992,"36":976,"37":116,"38":7381,"39":7383,"40":2},"b":{"1":[594,0],"2":[594,0],"3":[594,0],"4":[594,0],"5":[68,3],"6":[60,180],"7":[8,23],"8":[75,6],"9":[30,3],"10":[75,9],"11":[970,8]},"f":{"1":594,"2":594,"3":594,"4":594,"5":68,"6":54,"7":35,"8":3,"9":9,"10":9,"11":240,"12":31,"13":75,"14":30,"15":75,"16":970,"17":132,"18":28,"19":12,"20":740,"21":128,"22":207,"23":34,"24":191,"25":108,"26":992,"27":116,"28":7381,"29":7383,"30":2},"fnMap":{"1":{"name":"initialize","line":56,"loc":{"start":{"line":52,"column":4},"end":{"line":62,"column":4}}},"2":{"name":"__CMTAT_init","line":72,"loc":{"start":{"line":68,"column":4},"end":{"line":85,"column":4}}},"3":{"name":"__CMTAT_openzeppelin_init_unchained","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":96,"column":4}}},"4":{"name":"__CMTAT_modules_init_unchained","line":101,"loc":{"start":{"line":101,"column":4},"end":{"line":105,"column":4}}},"5":{"name":"approve","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":125,"column":4}}},"6":{"name":"transfer","line":127,"loc":{"start":{"line":127,"column":4},"end":{"line":134,"column":4}}},"7":{"name":"transferFrom","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":143,"column":4}}},"8":{"name":"decimals","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":153,"column":4}}},"9":{"name":"name","line":155,"loc":{"start":{"line":155,"column":4},"end":{"line":163,"column":4}}},"10":{"name":"symbol","line":165,"loc":{"start":{"line":165,"column":4},"end":{"line":173,"column":4}}},"11":{"name":"canTransfer","line":178,"loc":{"start":{"line":178,"column":4},"end":{"line":190,"column":4}}},"12":{"name":"canTransferFrom","line":195,"loc":{"start":{"line":195,"column":3},"end":{"line":207,"column":4}}},"13":{"name":"_authorizePause","line":214,"loc":{"start":{"line":214,"column":4},"end":{"line":214,"column":92}}},"14":{"name":"_authorizeDeactivate","line":215,"loc":{"start":{"line":215,"column":4},"end":{"line":215,"column":104}}},"15":{"name":"_authorizeFreeze","line":217,"loc":{"start":{"line":217,"column":4},"end":{"line":217,"column":101}}},"16":{"name":"_authorizeAllowlistManagement","line":219,"loc":{"start":{"line":219,"column":4},"end":{"line":219,"column":114}}},"17":{"name":"_authorizeERC20Enforcer","line":220,"loc":{"start":{"line":220,"column":4},"end":{"line":222,"column":4}}},"18":{"name":"_authorizeForcedTransfer","line":223,"loc":{"start":{"line":223,"column":4},"end":{"line":225,"column":4}}},"19":{"name":"_canMintBurnByModule","line":231,"loc":{"start":{"line":231,"column":4},"end":{"line":235,"column":4}}},"20":{"name":"_canMintByModuleAndRevert","line":237,"loc":{"start":{"line":237,"column":4},"end":{"line":241,"column":4}}},"21":{"name":"_canBurnByModuleAndRevert","line":243,"loc":{"start":{"line":243,"column":4},"end":{"line":247,"column":4}}},"22":{"name":"_canSend","line":249,"loc":{"start":{"line":249,"column":4},"end":{"line":251,"column":4}}},"23":{"name":"_canReceive","line":253,"loc":{"start":{"line":253,"column":4},"end":{"line":255,"column":4}}},"24":{"name":"_canTransferStandardByModule","line":257,"loc":{"start":{"line":257,"column":4},"end":{"line":263,"column":4}}},"25":{"name":"_canTransferStandardByModuleAndRevert","line":265,"loc":{"start":{"line":265,"column":4},"end":{"line":271,"column":4}}},"26":{"name":"_checkTransferred","line":273,"loc":{"start":{"line":273,"column":4},"end":{"line":276,"column":4}}},"27":{"name":"getFrozenTokens","line":278,"loc":{"start":{"line":278,"column":4},"end":{"line":286,"column":4}}},"28":{"name":"_msgSender","line":295,"loc":{"start":{"line":295,"column":4},"end":{"line":302,"column":4}}},"29":{"name":"_contextSuffixLength","line":307,"loc":{"start":{"line":307,"column":4},"end":{"line":311,"column":4}}},"30":{"name":"_msgData","line":316,"loc":{"start":{"line":316,"column":4},"end":{"line":323,"column":4}}}},"statementMap":{"1":{"start":{"line":57,"column":8},"end":{"line":57,"column":2722}},"2":{"start":{"line":75,"column":8},"end":{"line":75,"column":33}},"3":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}},"4":{"start":{"line":81,"column":8},"end":{"line":81,"column":60}},"5":{"start":{"line":84,"column":8},"end":{"line":84,"column":91}},"6":{"start":{"line":92,"column":8},"end":{"line":92,"column":39}},"7":{"start":{"line":93,"column":8},"end":{"line":93,"column":34}},"8":{"start":{"line":95,"column":8},"end":{"line":95,"column":77}},"9":{"start":{"line":102,"column":9},"end":{"line":102,"column":97}},"10":{"start":{"line":104,"column":8},"end":{"line":104,"column":35}},"11":{"start":{"line":123,"column":8},"end":{"line":123,"column":69}},"12":{"start":{"line":124,"column":8},"end":{"line":124,"column":55}},"13":{"start":{"line":133,"column":8},"end":{"line":133,"column":50}},"14":{"start":{"line":142,"column":8},"end":{"line":142,"column":60}},"15":{"start":{"line":152,"column":8},"end":{"line":152,"column":41}},"16":{"start":{"line":162,"column":8},"end":{"line":162,"column":37}},"17":{"start":{"line":172,"column":8},"end":{"line":172,"column":39}},"18":{"start":{"line":183,"column":8},"end":{"line":183,"column":89}},"19":{"start":{"line":184,"column":8},"end":{"line":184,"column":7166}},"20":{"start":{"line":185,"column":12},"end":{"line":185,"column":24}},"21":{"start":{"line":187,"column":12},"end":{"line":187,"column":68}},"22":{"start":{"line":201,"column":8},"end":{"line":201,"column":89}},"23":{"start":{"line":202,"column":8},"end":{"line":202,"column":7665}},"24":{"start":{"line":203,"column":12},"end":{"line":203,"column":24}},"25":{"start":{"line":205,"column":12},"end":{"line":205,"column":81}},"26":{"start":{"line":221,"column":8},"end":{"line":221,"column":55}},"27":{"start":{"line":224,"column":8},"end":{"line":224,"column":56}},"28":{"start":{"line":234,"column":8},"end":{"line":234,"column":70}},"29":{"start":{"line":240,"column":8},"end":{"line":240,"column":62}},"30":{"start":{"line":246,"column":8},"end":{"line":246,"column":64}},"31":{"start":{"line":250,"column":8},"end":{"line":250,"column":58}},"32":{"start":{"line":254,"column":8},"end":{"line":254,"column":61}},"33":{"start":{"line":262,"column":8},"end":{"line":262,"column":88}},"34":{"start":{"line":270,"column":8},"end":{"line":270,"column":89}},"35":{"start":{"line":274,"column":8},"end":{"line":274,"column":66}},"36":{"start":{"line":275,"column":8},"end":{"line":275,"column":79}},"37":{"start":{"line":285,"column":8},"end":{"line":285,"column":69}},"38":{"start":{"line":301,"column":8},"end":{"line":301,"column":53}},"39":{"start":{"line":310,"column":9},"end":{"line":310,"column":64}},"40":{"start":{"line":322,"column":8},"end":{"line":322,"column":51}}},"branchMap":{"1":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":21},"end":{"line":56,"column":21}},{"start":{"line":56,"column":21},"end":{"line":56,"column":21}}]},"2":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":23},"end":{"line":72,"column":23}},{"start":{"line":72,"column":23},"end":{"line":72,"column":23}}]},"3":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":125},"end":{"line":90,"column":125}},{"start":{"line":90,"column":125},"end":{"line":90,"column":125}}]},"4":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":217},"end":{"line":101,"column":217}},{"start":{"line":101,"column":217},"end":{"line":101,"column":217}}]},"5":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":95},"end":{"line":122,"column":95}},{"start":{"line":122,"column":95},"end":{"line":122,"column":95}}]},"6":{"line":184,"type":"if","locations":[{"start":{"line":184,"column":8},"end":{"line":184,"column":8}},{"start":{"line":184,"column":8},"end":{"line":184,"column":8}}]},"7":{"line":202,"type":"if","locations":[{"start":{"line":202,"column":8},"end":{"line":202,"column":8}},{"start":{"line":202,"column":8},"end":{"line":202,"column":8}}]},"8":{"line":214,"type":"if","locations":[{"start":{"line":214,"column":70},"end":{"line":214,"column":70}},{"start":{"line":214,"column":70},"end":{"line":214,"column":70}}]},"9":{"line":215,"type":"if","locations":[{"start":{"line":215,"column":75},"end":{"line":215,"column":75}},{"start":{"line":215,"column":75},"end":{"line":215,"column":75}}]},"10":{"line":217,"type":"if","locations":[{"start":{"line":217,"column":77},"end":{"line":217,"column":77}},{"start":{"line":217,"column":77},"end":{"line":217,"column":77}}]},"11":{"line":219,"type":"if","locations":[{"start":{"line":219,"column":88},"end":{"line":219,"column":88}},{"start":{"line":219,"column":88},"end":{"line":219,"column":88}}]}}},
+"contracts/modules/3_CMTATBaseRuleEngine.sol":{"l":{"47":4748,"64":4748,"83":4748,"86":4748,"89":4748,"91":4748,"94":4748,"102":4748,"103":4748,"105":4748,"112":4748,"119":4748,"129":700,"130":662,"140":1579,"141":1579,"142":570,"144":1009,"157":251,"158":251,"159":76,"161":175,"178":7434,"179":7282},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol","s":{"1":4748,"2":4748,"3":4748,"4":4748,"5":4748,"6":4748,"7":4748,"8":4748,"9":4748,"10":4748,"11":4748,"12":4748,"13":700,"14":662,"15":1579,"16":1579,"17":570,"18":1009,"19":251,"20":251,"21":76,"22":175,"23":7434,"24":7282},"b":{"1":[4748,4],"2":[4748,0],"3":[4748,0],"4":[4748,0],"5":[4748,0],"6":[4748,0],"7":[700,19],"8":[570,1009],"9":[76,175],"10":[573,39],"11":[238,19],"12":[551,57],"13":[361,3]},"f":{"1":4748,"2":4748,"3":4748,"4":4748,"5":4748,"6":4748,"7":700,"8":1579,"9":251,"10":573,"11":238,"12":551,"13":361,"14":7434},"fnMap":{"1":{"name":"initialize","line":46,"loc":{"start":{"line":41,"column":4},"end":{"line":53,"column":4}}},"2":{"name":"_initialize","line":63,"loc":{"start":{"line":58,"column":4},"end":{"line":70,"column":4}}},"3":{"name":"__CMTAT_init","line":80,"loc":{"start":{"line":75,"column":4},"end":{"line":95,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":106,"column":4}}},"5":{"name":"__CMTAT_internal_init_unchained","line":111,"loc":{"start":{"line":111,"column":4},"end":{"line":113,"column":4}}},"6":{"name":"__CMTAT_modules_init_unchained","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":120,"column":4}}},"7":{"name":"approve","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":131,"column":4}}},"8":{"name":"canTransfer","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":146,"column":4}}},"9":{"name":"canTransferFrom","line":151,"loc":{"start":{"line":151,"column":3},"end":{"line":163,"column":4}}},"10":{"name":"_authorizePause","line":169,"loc":{"start":{"line":169,"column":4},"end":{"line":169,"column":92}}},"11":{"name":"_authorizeDeactivate","line":170,"loc":{"start":{"line":170,"column":4},"end":{"line":170,"column":104}}},"12":{"name":"_authorizeFreeze","line":172,"loc":{"start":{"line":172,"column":4},"end":{"line":172,"column":101}}},"13":{"name":"_authorizeRuleEngineManagement","line":174,"loc":{"start":{"line":174,"column":4},"end":{"line":174,"column":129}}},"14":{"name":"_checkTransferred","line":177,"loc":{"start":{"line":177,"column":4},"end":{"line":180,"column":4}}}},"statementMap":{"1":{"start":{"line":47,"column":8},"end":{"line":47,"column":2158}},"2":{"start":{"line":64,"column":8},"end":{"line":64,"column":2665}},"3":{"start":{"line":83,"column":8},"end":{"line":83,"column":33}},"4":{"start":{"line":86,"column":8},"end":{"line":86,"column":32}},"5":{"start":{"line":89,"column":8},"end":{"line":89,"column":60}},"6":{"start":{"line":91,"column":7},"end":{"line":91,"column":47}},"7":{"start":{"line":94,"column":8},"end":{"line":94,"column":91}},"8":{"start":{"line":102,"column":8},"end":{"line":102,"column":39}},"9":{"start":{"line":103,"column":8},"end":{"line":103,"column":34}},"10":{"start":{"line":105,"column":8},"end":{"line":105,"column":77}},"11":{"start":{"line":112,"column":8},"end":{"line":112,"column":65}},"12":{"start":{"line":119,"column":8},"end":{"line":119,"column":96}},"13":{"start":{"line":129,"column":8},"end":{"line":129,"column":69}},"14":{"start":{"line":130,"column":8},"end":{"line":130,"column":55}},"15":{"start":{"line":140,"column":8},"end":{"line":140,"column":90}},"16":{"start":{"line":141,"column":8},"end":{"line":141,"column":5761}},"17":{"start":{"line":142,"column":12},"end":{"line":142,"column":24}},"18":{"start":{"line":144,"column":12},"end":{"line":144,"column":74}},"19":{"start":{"line":157,"column":8},"end":{"line":157,"column":89}},"20":{"start":{"line":158,"column":8},"end":{"line":158,"column":6269}},"21":{"start":{"line":159,"column":12},"end":{"line":159,"column":24}},"22":{"start":{"line":161,"column":12},"end":{"line":161,"column":87}},"23":{"start":{"line":178,"column":8},"end":{"line":178,"column":66}},"24":{"start":{"line":179,"column":8},"end":{"line":179,"column":72}}},"branchMap":{"1":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":21},"end":{"line":46,"column":21}},{"start":{"line":46,"column":21},"end":{"line":46,"column":21}}]},"2":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":23},"end":{"line":63,"column":23}},{"start":{"line":63,"column":23},"end":{"line":63,"column":23}}]},"3":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":23},"end":{"line":80,"column":23}},{"start":{"line":80,"column":23},"end":{"line":80,"column":23}}]},"4":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":125},"end":{"line":100,"column":125}},{"start":{"line":100,"column":125},"end":{"line":100,"column":125}}]},"5":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":104},"end":{"line":111,"column":104}},{"start":{"line":111,"column":104},"end":{"line":111,"column":104}}]},"6":{"line":118,"type":"if","locations":[{"start":{"line":118,"column":216},"end":{"line":118,"column":216}},{"start":{"line":118,"column":216},"end":{"line":118,"column":216}}]},"7":{"line":128,"type":"if","locations":[{"start":{"line":128,"column":95},"end":{"line":128,"column":95}},{"start":{"line":128,"column":95},"end":{"line":128,"column":95}}]},"8":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":8}},{"start":{"line":141,"column":8},"end":{"line":141,"column":8}}]},"9":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":8},"end":{"line":158,"column":8}},{"start":{"line":158,"column":8},"end":{"line":158,"column":8}}]},"10":{"line":169,"type":"if","locations":[{"start":{"line":169,"column":70},"end":{"line":169,"column":70}},{"start":{"line":169,"column":70},"end":{"line":169,"column":70}}]},"11":{"line":170,"type":"if","locations":[{"start":{"line":170,"column":75},"end":{"line":170,"column":75}},{"start":{"line":170,"column":75},"end":{"line":170,"column":75}}]},"12":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":77},"end":{"line":172,"column":77}},{"start":{"line":172,"column":77},"end":{"line":172,"column":77}}]},"13":{"line":174,"type":"if","locations":[{"start":{"line":174,"column":100},"end":{"line":174,"column":100}},{"start":{"line":174,"column":100},"end":{"line":174,"column":100}}]}}},
+"contracts/modules/4_CMTATBaseDebt.sol":{"l":{"19":92,"25":82,"31":44,"37":4,"43":12,"49":12,"55":1250},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseDebt.sol","s":{"1":92,"2":82,"3":44,"4":4,"5":12,"6":12,"7":1250},"b":{"1":[12,12],"2":[96,3]},"f":{"1":92,"2":82,"3":44,"4":4,"5":12,"6":12,"7":1250,"8":12,"9":96},"fnMap":{"1":{"name":"approve","line":16,"loc":{"start":{"line":16,"column":3},"end":{"line":20,"column":3}}},"2":{"name":"transfer","line":22,"loc":{"start":{"line":22,"column":3},"end":{"line":26,"column":3}}},"3":{"name":"transferFrom","line":28,"loc":{"start":{"line":28,"column":3},"end":{"line":32,"column":3}}},"4":{"name":"decimals","line":34,"loc":{"start":{"line":34,"column":3},"end":{"line":38,"column":3}}},"5":{"name":"name","line":40,"loc":{"start":{"line":40,"column":3},"end":{"line":44,"column":3}}},"6":{"name":"symbol","line":46,"loc":{"start":{"line":46,"column":3},"end":{"line":50,"column":3}}},"7":{"name":"_update","line":52,"loc":{"start":{"line":52,"column":3},"end":{"line":56,"column":3}}},"8":{"name":"_authorizeDebtManagement","line":58,"loc":{"start":{"line":58,"column":3},"end":{"line":58,"column":97}}},"9":{"name":"_authorizeSnapshots","line":60,"loc":{"start":{"line":60,"column":3},"end":{"line":60,"column":110}}}},"statementMap":{"1":{"start":{"line":19,"column":6},"end":{"line":19,"column":56}},"2":{"start":{"line":25,"column":6},"end":{"line":25,"column":48}},"3":{"start":{"line":31,"column":6},"end":{"line":31,"column":58}},"4":{"start":{"line":37,"column":6},"end":{"line":37,"column":39}},"5":{"start":{"line":43,"column":6},"end":{"line":43,"column":35}},"6":{"start":{"line":49,"column":6},"end":{"line":49,"column":37}},"7":{"start":{"line":55,"column":6},"end":{"line":55,"column":48}}},"branchMap":{"1":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":77},"end":{"line":58,"column":77}},{"start":{"line":58,"column":77},"end":{"line":58,"column":77}}]},"2":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":82},"end":{"line":60,"column":82}},{"start":{"line":60,"column":82},"end":{"line":60,"column":82}}]}}},
+"contracts/modules/4_CMTATBaseERC1404.sol":{"l":{"34":159,"35":66,"37":93,"50":1255,"62":207,"73":377,"74":377,"75":198,"76":198,"77":22,"79":176,"80":176,"81":132,"84":223},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC1404.sol","s":{"1":159,"2":66,"3":93,"4":1255,"5":207,"6":377,"7":377,"8":198,"9":198,"10":22,"11":176,"12":176,"13":132,"14":223},"b":{"1":[66,93],"2":[198,179],"3":[22,176],"4":[132,44]},"f":{"1":159,"2":1255,"3":207,"4":377},"fnMap":{"1":{"name":"messageForTransferRestriction","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"canTransfer","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"canTransferFrom","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"_detectTransferRestriction","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":85,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1333}},"2":{"start":{"line":35,"column":12},"end":{"line":35,"column":74}},"3":{"start":{"line":37,"column":12},"end":{"line":37,"column":89}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":63}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":76}},"6":{"start":{"line":73,"column":8},"end":{"line":73,"column":80}},"7":{"start":{"line":74,"column":8},"end":{"line":74,"column":2816}},"8":{"start":{"line":75,"column":12},"end":{"line":75,"column":62}},"9":{"start":{"line":76,"column":12},"end":{"line":76,"column":2924}},"10":{"start":{"line":77,"column":16},"end":{"line":77,"column":114}},"11":{"start":{"line":79,"column":12},"end":{"line":79,"column":63}},"12":{"start":{"line":80,"column":12},"end":{"line":80,"column":3167}},"13":{"start":{"line":81,"column":16},"end":{"line":81,"column":114}},"14":{"start":{"line":84,"column":8},"end":{"line":84,"column":82}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":34,"column":8}},{"start":{"line":34,"column":8},"end":{"line":34,"column":8}}]},"2":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":8},"end":{"line":74,"column":8}},{"start":{"line":74,"column":8},"end":{"line":74,"column":8}}]},"3":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":12},"end":{"line":76,"column":12}},{"start":{"line":76,"column":12},"end":{"line":76,"column":12}}]},"4":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":12},"end":{"line":80,"column":12}},{"start":{"line":80,"column":12},"end":{"line":80,"column":12}}]}}},
+"contracts/modules/5_CMTATBaseERC20CrossChain.sol":{"l":{"24":627,"27":295,"42":199,"57":15,"65":59,"72":47,"76":66,"88":4518,"96":869,"104":207,"125":218},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol","s":{"1":627,"2":295,"3":199,"4":15,"5":59,"6":47,"7":66,"8":4518,"9":869,"10":207,"11":218},"b":{"1":[24,24],"2":[36,12],"3":[218,48],"4":[84,12],"5":[60,24],"6":[72,24],"7":[48,24]},"f":{"1":627,"2":295,"3":199,"4":15,"5":59,"6":47,"7":66,"8":4518,"9":869,"10":207,"11":36,"12":218,"13":60,"14":48},"fnMap":{"1":{"name":"approve","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":25,"column":4}}},"2":{"name":"transfer","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":28,"column":4}}},"3":{"name":"transferFrom","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":43,"column":4}}},"4":{"name":"decimals","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":58,"column":4}}},"5":{"name":"name","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":66,"column":4}}},"6":{"name":"symbol","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":73,"column":4}}},"7":{"name":"supportsInterface","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":77,"column":4}}},"8":{"name":"_mintOverride","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":89,"column":4}}},"9":{"name":"_burnOverride","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":97,"column":4}}},"10":{"name":"_minterTransferOverride","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":105,"column":4}}},"11":{"name":"_authorizeCCIPSetAdmin","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":113,"column":106}}},"12":{"name":"_checkTokenBridge","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":126,"column":4}}},"13":{"name":"_authorizeBurnFrom","line":133,"loc":{"start":{"line":133,"column":4},"end":{"line":133,"column":124}}},"14":{"name":"_authorizeSelfBurn","line":140,"loc":{"start":{"line":140,"column":4},"end":{"line":140,"column":124}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":58}},"2":{"start":{"line":27,"column":9},"end":{"line":27,"column":51}},"3":{"start":{"line":42,"column":8},"end":{"line":42,"column":60}},"4":{"start":{"line":57,"column":8},"end":{"line":57,"column":41}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":37}},"6":{"start":{"line":72,"column":8},"end":{"line":72,"column":39}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":127}},"8":{"start":{"line":88,"column":8},"end":{"line":88,"column":52}},"9":{"start":{"line":96,"column":8},"end":{"line":96,"column":52}},"10":{"start":{"line":104,"column":8},"end":{"line":104,"column":63}},"11":{"start":{"line":125,"column":8},"end":{"line":125,"column":68}}},"branchMap":{"1":{"line":76,"type":"cond-expr","locations":[{"start":{"line":76,"column":16},"end":{"line":76,"column":68}},{"start":{"line":76,"column":72},"end":{"line":76,"column":126}}]},"2":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":76},"end":{"line":113,"column":76}},{"start":{"line":113,"column":76},"end":{"line":113,"column":76}}]},"3":{"line":124,"type":"if","locations":[{"start":{"line":124,"column":96},"end":{"line":124,"column":96}},{"start":{"line":124,"column":96},"end":{"line":124,"column":96}}]},"4":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":83},"end":{"line":133,"column":83}},{"start":{"line":133,"column":83},"end":{"line":133,"column":83}}]},"5":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":110},"end":{"line":133,"column":110}},{"start":{"line":133,"column":110},"end":{"line":133,"column":110}}]},"6":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":83},"end":{"line":140,"column":83}},{"start":{"line":140,"column":83},"end":{"line":140,"column":83}}]},"7":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":110},"end":{"line":140,"column":110}},{"start":{"line":140,"column":110},"end":{"line":140,"column":110}}]}}},
+"contracts/modules/6_CMTATBaseDebtEngine.sol":{"l":{"25":923,"31":60,"37":33,"43":69,"49":3,"55":9,"61":9},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseDebtEngine.sol","s":{"1":923,"2":60,"3":33,"4":69,"5":3,"6":9,"7":9},"b":{"1":[15,3],"2":[49,2]},"f":{"1":923,"2":60,"3":33,"4":69,"5":3,"6":9,"7":9,"8":15,"9":49},"fnMap":{"1":{"name":"_update","line":22,"loc":{"start":{"line":22,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"transfer","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":32,"column":4}}},"3":{"name":"transferFrom","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":38,"column":4}}},"4":{"name":"approve","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":44,"column":4}}},"5":{"name":"decimals","line":46,"loc":{"start":{"line":46,"column":4},"end":{"line":50,"column":4}}},"6":{"name":"name","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":56,"column":4}}},"7":{"name":"symbol","line":58,"loc":{"start":{"line":58,"column":4},"end":{"line":62,"column":4}}},"8":{"name":"_authorizeDebtEngineManagement","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":68,"column":118}}},"9":{"name":"_authorizeSnapshots","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":70,"column":111}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":50}},"2":{"start":{"line":31,"column":8},"end":{"line":31,"column":59}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":69}},"4":{"start":{"line":43,"column":8},"end":{"line":43,"column":63}},"5":{"start":{"line":49,"column":8},"end":{"line":49,"column":50}},"6":{"start":{"line":55,"column":8},"end":{"line":55,"column":46}},"7":{"start":{"line":61,"column":8},"end":{"line":61,"column":48}}},"branchMap":{"1":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":90},"end":{"line":68,"column":90}},{"start":{"line":68,"column":90},"end":{"line":68,"column":90}}]},"2":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":83},"end":{"line":70,"column":83}},{"start":{"line":70,"column":83},"end":{"line":70,"column":83}}]}}},
+"contracts/modules/6_CMTATBaseERC2612.sol":{"l":{"27":460,"28":460,"29":460,"30":460,"49":10,"50":4,"61":92,"71":31,"87":26,"101":2,"114":18,"127":8},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol","s":{"1":460,"2":460,"3":460,"4":460,"5":10,"6":4,"7":92,"8":31,"9":26,"10":2,"11":18,"12":8},"b":{"1":[460,0]},"f":{"1":460,"2":10,"3":92,"4":31,"5":26,"6":2,"7":18,"8":8},"fnMap":{"1":{"name":"__CMTAT_openzeppelin_init_unchained","line":26,"loc":{"start":{"line":24,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"permit","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"approve","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":62,"column":4}}},"4":{"name":"transfer","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"transferFrom","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":88,"column":4}}},"6":{"name":"decimals","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":102,"column":4}}},"7":{"name":"name","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":115,"column":4}}},"8":{"name":"symbol","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":128,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":80}},"2":{"start":{"line":28,"column":8},"end":{"line":28,"column":58}},"3":{"start":{"line":29,"column":8},"end":{"line":29,"column":58}},"4":{"start":{"line":30,"column":8},"end":{"line":30,"column":35}},"5":{"start":{"line":49,"column":8},"end":{"line":49,"column":62}},"6":{"start":{"line":50,"column":8},"end":{"line":50,"column":78}},"7":{"start":{"line":61,"column":8},"end":{"line":61,"column":63}},"8":{"start":{"line":71,"column":8},"end":{"line":71,"column":59}},"9":{"start":{"line":87,"column":8},"end":{"line":87,"column":79}},"10":{"start":{"line":101,"column":8},"end":{"line":101,"column":50}},"11":{"start":{"line":114,"column":8},"end":{"line":114,"column":46}},"12":{"start":{"line":127,"column":8},"end":{"line":127,"column":48}}},"branchMap":{"1":{"line":26,"type":"if","locations":[{"start":{"line":26,"column":32},"end":{"line":26,"column":32}},{"start":{"line":26,"column":32},"end":{"line":26,"column":32}}]}}},
+"contracts/modules/6_CMTATBaseERC2771.sol":{"l":{"26":18475,"35":18481,"47":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2771.sol","s":{"1":18475,"2":18481,"3":6},"b":{},"f":{"1":18475,"2":18481,"3":6},"fnMap":{"1":{"name":"_msgSender","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"_contextSuffixLength","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":36,"column":4}}},"3":{"name":"_msgData","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":48,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":53}},"2":{"start":{"line":35,"column":9},"end":{"line":35,"column":64}},"3":{"start":{"line":47,"column":8},"end":{"line":47,"column":51}}},"branchMap":{}},
+"contracts/modules/7_CMTATBaseERC2771Snapshot.sol":{"l":{"24":778,"30":58,"36":26,"42":92,"48":2,"54":6,"60":6,"70":3814,"76":2,"82":3816},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC2771Snapshot.sol","s":{"1":778,"2":58,"3":26,"4":92,"5":2,"6":6,"7":6,"8":3814,"9":2,"10":3816},"b":{"1":[189,4]},"f":{"1":778,"2":58,"3":26,"4":92,"5":2,"6":6,"7":6,"8":3814,"9":2,"10":3816,"11":189},"fnMap":{"1":{"name":"_update","line":21,"loc":{"start":{"line":21,"column":4},"end":{"line":25,"column":4}}},"2":{"name":"transfer","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":31,"column":4}}},"3":{"name":"transferFrom","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":37,"column":4}}},"4":{"name":"approve","line":39,"loc":{"start":{"line":39,"column":4},"end":{"line":43,"column":4}}},"5":{"name":"decimals","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":49,"column":4}}},"6":{"name":"name","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":55,"column":4}}},"7":{"name":"symbol","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":61,"column":4}}},"8":{"name":"_msgSender","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":71,"column":4}}},"9":{"name":"_msgData","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":77,"column":4}}},"10":{"name":"_contextSuffixLength","line":79,"loc":{"start":{"line":79,"column":4},"end":{"line":83,"column":4}}},"11":{"name":"_authorizeSnapshots","line":89,"loc":{"start":{"line":89,"column":4},"end":{"line":89,"column":111}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":50}},"2":{"start":{"line":30,"column":8},"end":{"line":30,"column":59}},"3":{"start":{"line":36,"column":8},"end":{"line":36,"column":69}},"4":{"start":{"line":42,"column":8},"end":{"line":42,"column":63}},"5":{"start":{"line":48,"column":8},"end":{"line":48,"column":50}},"6":{"start":{"line":54,"column":8},"end":{"line":54,"column":46}},"7":{"start":{"line":60,"column":8},"end":{"line":60,"column":48}},"8":{"start":{"line":70,"column":8},"end":{"line":70,"column":44}},"9":{"start":{"line":76,"column":8},"end":{"line":76,"column":42}},"10":{"start":{"line":82,"column":8},"end":{"line":82,"column":54}}},"branchMap":{"1":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":83},"end":{"line":89,"column":83}},{"start":{"line":89,"column":83},"end":{"line":89,"column":83}}]}}},
+"contracts/modules/7_CMTATBaseERC7551Enforcement.sol":{"l":{"22":390,"26":78,"37":11591,"45":4,"53":11595,"64":114,"72":90,"80":282,"88":20,"96":18,"104":6,"112":336},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC7551Enforcement.sol","s":{"1":390,"2":78,"3":11591,"4":4,"5":11595,"6":114,"7":90,"8":282,"9":20,"10":18,"11":6,"12":336},"b":{},"f":{"1":390,"2":78,"3":11591,"4":4,"5":11595,"6":114,"7":90,"8":282,"9":20,"10":18,"11":6,"12":336},"fnMap":{"1":{"name":"_authorizeERC20Enforcer","line":21,"loc":{"start":{"line":21,"column":4},"end":{"line":23,"column":4}}},"2":{"name":"_authorizeForcedTransfer","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":27,"column":4}}},"3":{"name":"_msgSender","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":38,"column":4}}},"4":{"name":"_msgData","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":46,"column":4}}},"5":{"name":"_contextSuffixLength","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":54,"column":4}}},"6":{"name":"transfer","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":65,"column":4}}},"7":{"name":"transferFrom","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":73,"column":4}}},"8":{"name":"approve","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":81,"column":4}}},"9":{"name":"name","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":89,"column":4}}},"10":{"name":"symbol","line":91,"loc":{"start":{"line":91,"column":4},"end":{"line":97,"column":4}}},"11":{"name":"decimals","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":105,"column":4}}},"12":{"name":"getFrozenTokens","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":113,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":55}},"2":{"start":{"line":26,"column":8},"end":{"line":26,"column":56}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":44}},"4":{"start":{"line":45,"column":8},"end":{"line":45,"column":42}},"5":{"start":{"line":53,"column":8},"end":{"line":53,"column":54}},"6":{"start":{"line":64,"column":8},"end":{"line":64,"column":59}},"7":{"start":{"line":72,"column":8},"end":{"line":72,"column":69}},"8":{"start":{"line":80,"column":8},"end":{"line":80,"column":63}},"9":{"start":{"line":88,"column":8},"end":{"line":88,"column":46}},"10":{"start":{"line":96,"column":8},"end":{"line":96,"column":48}},"11":{"start":{"line":104,"column":8},"end":{"line":104,"column":50}},"12":{"start":{"line":112,"column":8},"end":{"line":112,"column":69}}},"branchMap":{}},
+"contracts/modules/8_CMTATBaseERC1363.sol":{"l":{"26":499,"27":499,"39":93,"46":39,"62":28,"70":18,"84":2,"92":6,"99":6,"119":3508,"128":3510,"140":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol","s":{"1":499,"2":499,"3":93,"4":39,"5":28,"6":18,"7":2,"8":6,"9":6,"10":3508,"11":3510,"12":2},"b":{"1":[499,0],"2":[6,8]},"f":{"1":499,"2":93,"3":39,"4":28,"5":18,"6":2,"7":6,"8":6,"9":3508,"10":3510,"11":2},"fnMap":{"1":{"name":"__CMTAT_openzeppelin_init_unchained","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"approve","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":40,"column":4}}},"3":{"name":"transfer","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":47,"column":4}}},"4":{"name":"transferFrom","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":63,"column":4}}},"5":{"name":"supportsInterface","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":71,"column":4}}},"6":{"name":"decimals","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":85,"column":4}}},"7":{"name":"name","line":91,"loc":{"start":{"line":91,"column":4},"end":{"line":93,"column":4}}},"8":{"name":"symbol","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":100,"column":4}}},"9":{"name":"_msgSender","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":120,"column":4}}},"10":{"name":"_contextSuffixLength","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":129,"column":4}}},"11":{"name":"_msgData","line":134,"loc":{"start":{"line":134,"column":4},"end":{"line":141,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":80}},"2":{"start":{"line":27,"column":8},"end":{"line":27,"column":33}},"3":{"start":{"line":39,"column":8},"end":{"line":39,"column":66}},"4":{"start":{"line":46,"column":8},"end":{"line":46,"column":62}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":82}},"6":{"start":{"line":70,"column":8},"end":{"line":70,"column":123}},"7":{"start":{"line":84,"column":8},"end":{"line":84,"column":53}},"8":{"start":{"line":92,"column":8},"end":{"line":92,"column":49}},"9":{"start":{"line":99,"column":8},"end":{"line":99,"column":51}},"10":{"start":{"line":119,"column":8},"end":{"line":119,"column":55}},"11":{"start":{"line":128,"column":9},"end":{"line":128,"column":66}},"12":{"start":{"line":140,"column":8},"end":{"line":140,"column":53}}},"branchMap":{"1":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":134},"end":{"line":25,"column":134}},{"start":{"line":25,"column":134},"end":{"line":25,"column":134}}]},"2":{"line":70,"type":"cond-expr","locations":[{"start":{"line":70,"column":15},"end":{"line":70,"column":63}},{"start":{"line":70,"column":68},"end":{"line":70,"column":122}}]}}},
+"contracts/modules/8_CMTATBaseERC7551.sol":{"l":{"20":20},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC7551.sol","s":{"1":20},"b":{},"f":{"1":20},"fnMap":{"1":{"name":"_authorizeExtraInfoManagement","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":21,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":61}}},"branchMap":{}},
+"contracts/modules/internal/AllowlistModuleInternal.sol":{"l":{"30":594,"31":594,"40":296,"41":296,"45":2396,"49":532,"50":528,"51":528,"52":2100,"60":142,"61":142,"69":1438,"70":1438,"77":1424,"78":1424,"85":4422},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol","s":{"1":594,"2":296,"3":296,"4":532,"5":528,"6":528,"7":2100,"8":142,"9":1438,"10":1438,"11":1424,"12":1424},"b":{"1":[594,0]},"f":{"1":594,"2":296,"3":2396,"4":532,"5":142,"6":1438,"7":1424,"8":4422},"fnMap":{"1":{"name":"__Allowlist_init_unchained","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":33,"column":4}}},"2":{"name":"_addToAllowlist","line":39,"loc":{"start":{"line":39,"column":4},"end":{"line":42,"column":4}}},"3":{"name":"_addToAllowlist","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":4}}},"4":{"name":"_addToAllowlist","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":54,"column":4}}},"5":{"name":"_enableAllowlist","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":62,"column":4}}},"6":{"name":"_isAllowlisted","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":71,"column":4}}},"7":{"name":"_isAllowlistEnabled","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"8":{"name":"_getAllowlistModuleInternalStorage","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":88,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":9},"end":{"line":30,"column":88}},"2":{"start":{"line":40,"column":8},"end":{"line":40,"column":87}},"3":{"start":{"line":41,"column":8},"end":{"line":41,"column":48}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":61}},"5":{"start":{"line":50,"column":8},"end":{"line":50,"column":87}},"6":{"start":{"line":51,"column":8},"end":{"line":51,"column":2408}},"7":{"start":{"line":52,"column":12},"end":{"line":52,"column":59}},"8":{"start":{"line":60,"column":8},"end":{"line":60,"column":87}},"9":{"start":{"line":69,"column":8},"end":{"line":69,"column":87}},"10":{"start":{"line":70,"column":8},"end":{"line":70,"column":36}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":87}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":33}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":51},"end":{"line":29,"column":51}},{"start":{"line":29,"column":51},"end":{"line":29,"column":51}}]}}},
+"contracts/modules/internal/common/EnforcementModuleLibrary.sol":{"l":{"16":657,"19":630},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/common/EnforcementModuleLibrary.sol","s":{"1":657,"2":630},"b":{"1":[630,27],"2":[603,27]},"f":{"1":657},"fnMap":{"1":{"name":"_checkInput","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":20,"column":4}}}},"statementMap":{"1":{"start":{"line":16,"column":8},"end":{"line":16,"column":70}},"2":{"start":{"line":19,"column":8},"end":{"line":19,"column":98}}},"branchMap":{"1":{"line":16,"type":"if","locations":[{"start":{"line":16,"column":8},"end":{"line":16,"column":8}},{"start":{"line":16,"column":8},"end":{"line":16,"column":8}}]},"2":{"line":19,"type":"if","locations":[{"start":{"line":19,"column":8},"end":{"line":19,"column":8}},{"start":{"line":19,"column":8},"end":{"line":19,"column":8}}]}}},
+"contracts/modules/internal/EnforcementModuleInternal.sol":{"l":{"34":571,"35":571,"39":721,"40":75,"42":646,"46":125,"47":75,"48":75,"49":150,"58":16612,"59":16612,"64":17258},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInternal.sol","s":{"1":571,"2":571,"3":721,"4":125,"5":75,"6":75,"7":150,"8":16612,"9":16612},"b":{"1":[75,646]},"f":{"1":571,"2":721,"3":125,"4":16612,"5":17258},"fnMap":{"1":{"name":"_addAddressToTheList","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":36,"column":4}}},"2":{"name":"_addAddressToTheList","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":43,"column":4}}},"3":{"name":"_addAddressesToTheList","line":45,"loc":{"start":{"line":45,"column":2},"end":{"line":51,"column":4}}},"4":{"name":"_addressIsListed","line":57,"loc":{"start":{"line":57,"column":4},"end":{"line":60,"column":4}}},"5":{"name":"_getEnforcementModuleInternalStorage","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":67,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":91}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":53}},"3":{"start":{"line":39,"column":8},"end":{"line":39,"column":1738}},"4":{"start":{"line":46,"column":8},"end":{"line":46,"column":61}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":91}},"6":{"start":{"line":48,"column":8},"end":{"line":48,"column":2170}},"7":{"start":{"line":49,"column":12},"end":{"line":49,"column":64}},"8":{"start":{"line":58,"column":8},"end":{"line":58,"column":91}},"9":{"start":{"line":59,"column":8},"end":{"line":59,"column":31}}},"branchMap":{"1":{"line":39,"type":"if","locations":[{"start":{"line":39,"column":8},"end":{"line":39,"column":8}},{"start":{"line":39,"column":8},"end":{"line":39,"column":8}}]}}},
+"contracts/modules/internal/ERC20BurnModuleInternal.sol":{"l":{"30":330,"33":306,"34":258,"35":638,"47":1017},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol","s":{"1":330,"2":306,"3":258,"4":638,"5":1017},"b":{"1":[306,24],"2":[258,48]},"f":{"1":330,"2":1017},"fnMap":{"1":{"name":"_batchBurn","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":37,"column":4}}},"2":{"name":"_burnOverride","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":48,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":70}},"2":{"start":{"line":33,"column":8},"end":{"line":33,"column":97}},"3":{"start":{"line":34,"column":8},"end":{"line":34,"column":1431}},"4":{"start":{"line":35,"column":13},"end":{"line":35,"column":49}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":45}}},"branchMap":{"1":{"line":30,"type":"if","locations":[{"start":{"line":30,"column":8},"end":{"line":30,"column":8}},{"start":{"line":30,"column":8},"end":{"line":30,"column":8}}]},"2":{"line":33,"type":"if","locations":[{"start":{"line":33,"column":8},"end":{"line":33,"column":8}},{"start":{"line":33,"column":8},"end":{"line":33,"column":8}}]}}},
+"contracts/modules/internal/ERC20EnforcementModuleInternal.sol":{"l":{"34":378,"35":378,"37":378,"38":84,"39":84,"40":84,"43":273,"44":273,"45":273,"47":21,"49":357,"53":622,"54":29,"56":593,"58":593,"59":593,"61":593,"63":572,"64":572,"68":226,"69":29,"71":197,"72":197,"74":176,"75":176,"76":176,"83":220,"84":220,"85":21,"87":199,"88":199,"90":199,"92":199,"93":178,"95":199,"96":63,"97":63,"98":63,"99":63,"104":220,"105":199,"106":42,"110":157,"111":157,"112":42,"113":21,"114":21,"117":21,"118":21,"123":157,"125":199,"129":845,"133":323,"138":8426,"139":8426,"140":8426,"141":8426,"148":10527,"149":10527,"150":1533,"152":1533,"153":105,"154":42,"156":63,"158":1428,"159":1428,"160":819,"165":9603,"169":12921,"170":12921,"174":432,"175":432,"176":432,"178":432,"179":32,"181":400,"186":14720},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol","s":{"1":378,"2":378,"3":378,"4":84,"5":84,"6":294,"7":273,"8":273,"9":357,"10":622,"11":593,"12":593,"13":593,"14":593,"15":572,"16":226,"17":197,"18":197,"19":176,"20":176,"21":220,"22":220,"23":199,"24":199,"25":199,"26":199,"27":199,"28":63,"29":63,"30":220,"31":199,"32":42,"33":157,"34":157,"35":42,"36":21,"37":21,"38":157,"39":199,"40":845,"41":323,"42":8426,"43":8426,"44":8426,"45":10527,"46":10527,"47":1533,"48":1533,"49":105,"50":42,"51":63,"52":1428,"53":819,"54":9603,"55":12921,"56":12921,"57":432,"58":432,"59":432,"60":432,"61":32,"62":400},"b":{"1":[84,294],"2":[273,21],"3":[29,593],"4":[572,21],"5":[29,197],"6":[176,21],"7":[21,199],"8":[178,21],"9":[63,136],"10":[42,157],"11":[42,115],"12":[21,21],"13":[8258,168],"14":[1533,8994],"15":[105,1428],"16":[42,63],"17":[819,609],"18":[32,400]},"f":{"1":378,"2":622,"3":226,"4":220,"5":220,"6":845,"7":323,"8":8426,"9":10527,"10":12921,"11":432,"12":14720},"fnMap":{"1":{"name":"_setFrozenTokens","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":50,"column":4}}},"2":{"name":"_freezePartialTokens","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":65,"column":4}}},"3":{"name":"_unfreezePartialTokens","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":77,"column":4}}},"4":{"name":"_unfreezeTokens","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":101,"column":4}}},"5":{"name":"_forcedTransfer","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":126,"column":4}}},"6":{"name":"_freezeTokensEmitEvents","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":130,"column":4}}},"7":{"name":"_unfreezeTokensEmitEvents","line":132,"loc":{"start":{"line":132,"column":4},"end":{"line":134,"column":4}}},"8":{"name":"_checkActiveBalanceAndRevert","line":137,"loc":{"start":{"line":137,"column":4},"end":{"line":142,"column":4}}},"9":{"name":"_checkActiveBalance","line":147,"loc":{"start":{"line":147,"column":4},"end":{"line":166,"column":4}}},"10":{"name":"_getFrozenTokens","line":168,"loc":{"start":{"line":168,"column":4},"end":{"line":171,"column":5}}},"11":{"name":"_getActiveBalanceOf","line":173,"loc":{"start":{"line":173,"column":4},"end":{"line":182,"column":5}}},"12":{"name":"_getEnforcementModuleStorage","line":185,"loc":{"start":{"line":185,"column":4},"end":{"line":189,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":80}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":60}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":1822}},"4":{"start":{"line":38,"column":13},"end":{"line":38,"column":59}},"5":{"start":{"line":40,"column":13},"end":{"line":40,"column":65}},"6":{"start":{"line":41,"column":15},"end":{"line":41,"column":2048}},"7":{"start":{"line":43,"column":12},"end":{"line":43,"column":58}},"8":{"start":{"line":45,"column":12},"end":{"line":45,"column":62}},"9":{"start":{"line":49,"column":8},"end":{"line":49,"column":19}},"10":{"start":{"line":53,"column":7},"end":{"line":53,"column":2570}},"11":{"start":{"line":56,"column":7},"end":{"line":56,"column":79}},"12":{"start":{"line":58,"column":8},"end":{"line":58,"column":61}},"13":{"start":{"line":59,"column":8},"end":{"line":59,"column":68}},"14":{"start":{"line":61,"column":8},"end":{"line":61,"column":105}},"15":{"start":{"line":64,"column":8},"end":{"line":64,"column":65}},"16":{"start":{"line":68,"column":8},"end":{"line":68,"column":3309}},"17":{"start":{"line":71,"column":8},"end":{"line":71,"column":80}},"18":{"start":{"line":72,"column":8},"end":{"line":72,"column":107}},"19":{"start":{"line":74,"column":8},"end":{"line":74,"column":69}},"20":{"start":{"line":76,"column":8},"end":{"line":76,"column":68}},"21":{"start":{"line":83,"column":8},"end":{"line":83,"column":61}},"22":{"start":{"line":84,"column":8},"end":{"line":84,"column":4071}},"23":{"start":{"line":87,"column":8},"end":{"line":87,"column":80}},"24":{"start":{"line":88,"column":8},"end":{"line":88,"column":60}},"25":{"start":{"line":90,"column":8},"end":{"line":90,"column":29}},"26":{"start":{"line":92,"column":8},"end":{"line":92,"column":4490}},"27":{"start":{"line":95,"column":8},"end":{"line":95,"column":4600}},"28":{"start":{"line":96,"column":12},"end":{"line":96,"column":60}},"29":{"start":{"line":99,"column":12},"end":{"line":99,"column":83}},"30":{"start":{"line":104,"column":8},"end":{"line":104,"column":35}},"31":{"start":{"line":105,"column":8},"end":{"line":105,"column":5058}},"32":{"start":{"line":106,"column":12},"end":{"line":106,"column":46}},"33":{"start":{"line":110,"column":12},"end":{"line":110,"column":58}},"34":{"start":{"line":111,"column":12},"end":{"line":111,"column":5346}},"35":{"start":{"line":112,"column":16},"end":{"line":112,"column":5434}},"36":{"start":{"line":114,"column":24},"end":{"line":114,"column":68}},"37":{"start":{"line":118,"column":25},"end":{"line":118,"column":92}},"38":{"start":{"line":123,"column":12},"end":{"line":123,"column":54}},"39":{"start":{"line":125,"column":8},"end":{"line":125,"column":44}},"40":{"start":{"line":129,"column":8},"end":{"line":129,"column":83}},"41":{"start":{"line":133,"column":8},"end":{"line":133,"column":84}},"42":{"start":{"line":138,"column":8},"end":{"line":138,"column":20}},"43":{"start":{"line":139,"column":8},"end":{"line":139,"column":29}},"44":{"start":{"line":141,"column":8},"end":{"line":141,"column":89}},"45":{"start":{"line":148,"column":8},"end":{"line":148,"column":58}},"46":{"start":{"line":149,"column":8},"end":{"line":149,"column":6991}},"47":{"start":{"line":150,"column":12},"end":{"line":150,"column":62}},"48":{"start":{"line":152,"column":12},"end":{"line":152,"column":7171}},"49":{"start":{"line":153,"column":16},"end":{"line":153,"column":7227}},"50":{"start":{"line":154,"column":20},"end":{"line":154,"column":36}},"51":{"start":{"line":156,"column":16},"end":{"line":156,"column":33}},"52":{"start":{"line":159,"column":12},"end":{"line":159,"column":7415}},"53":{"start":{"line":160,"column":19},"end":{"line":160,"column":48}},"54":{"start":{"line":165,"column":8},"end":{"line":165,"column":36}},"55":{"start":{"line":169,"column":8},"end":{"line":169,"column":80}},"56":{"start":{"line":170,"column":8},"end":{"line":170,"column":39}},"57":{"start":{"line":174,"column":8},"end":{"line":174,"column":80}},"58":{"start":{"line":175,"column":8},"end":{"line":175,"column":61}},"59":{"start":{"line":176,"column":8},"end":{"line":176,"column":55}},"60":{"start":{"line":178,"column":8},"end":{"line":178,"column":8335}},"61":{"start":{"line":179,"column":12},"end":{"line":179,"column":20}},"62":{"start":{"line":181,"column":8},"end":{"line":181,"column":37}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":8}},{"start":{"line":37,"column":8},"end":{"line":37,"column":8}}]},"2":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":15},"end":{"line":41,"column":15}},{"start":{"line":41,"column":15},"end":{"line":41,"column":15}}]},"3":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":7},"end":{"line":53,"column":7}},{"start":{"line":53,"column":7},"end":{"line":53,"column":7}}]},"4":{"line":61,"type":"if","locations":[{"start":{"line":61,"column":8},"end":{"line":61,"column":8}},{"start":{"line":61,"column":8},"end":{"line":61,"column":8}}]},"5":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":8},"end":{"line":68,"column":8}},{"start":{"line":68,"column":8},"end":{"line":68,"column":8}}]},"6":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":8}},{"start":{"line":72,"column":8},"end":{"line":72,"column":8}}]},"7":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":8},"end":{"line":84,"column":8}},{"start":{"line":84,"column":8},"end":{"line":84,"column":8}}]},"8":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":8},"end":{"line":92,"column":8}},{"start":{"line":92,"column":8},"end":{"line":92,"column":8}}]},"9":{"line":95,"type":"if","locations":[{"start":{"line":95,"column":8},"end":{"line":95,"column":8}},{"start":{"line":95,"column":8},"end":{"line":95,"column":8}}]},"10":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":8},"end":{"line":105,"column":8}},{"start":{"line":105,"column":8},"end":{"line":105,"column":8}}]},"11":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":12},"end":{"line":111,"column":12}},{"start":{"line":111,"column":12},"end":{"line":111,"column":12}}]},"12":{"line":112,"type":"if","locations":[{"start":{"line":112,"column":16},"end":{"line":112,"column":16}},{"start":{"line":112,"column":16},"end":{"line":112,"column":16}}]},"13":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":8}},{"start":{"line":141,"column":8},"end":{"line":141,"column":8}}]},"14":{"line":149,"type":"if","locations":[{"start":{"line":149,"column":8},"end":{"line":149,"column":8}},{"start":{"line":149,"column":8},"end":{"line":149,"column":8}}]},"15":{"line":152,"type":"if","locations":[{"start":{"line":152,"column":12},"end":{"line":152,"column":12}},{"start":{"line":152,"column":12},"end":{"line":152,"column":12}}]},"16":{"line":153,"type":"if","locations":[{"start":{"line":153,"column":16},"end":{"line":153,"column":16}},{"start":{"line":153,"column":16},"end":{"line":153,"column":16}}]},"17":{"line":159,"type":"if","locations":[{"start":{"line":159,"column":12},"end":{"line":159,"column":12}},{"start":{"line":159,"column":12},"end":{"line":159,"column":12}}]},"18":{"line":178,"type":"if","locations":[{"start":{"line":178,"column":8},"end":{"line":178,"column":8}},{"start":{"line":178,"column":8},"end":{"line":178,"column":8}}]}}},
+"contracts/modules/internal/ERC20MintModuleInternal.sol":{"l":{"34":730,"37":706,"38":658,"39":1836,"47":238,"48":214,"51":214,"52":166,"53":310,"57":43,"64":6409,"70":211},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol","s":{"1":730,"2":706,"3":658,"4":1836,"5":238,"6":214,"7":214,"8":166,"9":310,"10":43,"11":6409,"12":211},"b":{"1":[706,24],"2":[658,48],"3":[214,24],"4":[166,48]},"f":{"1":730,"2":238,"3":6409,"4":211},"fnMap":{"1":{"name":"_batchMint","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"_batchTransfer","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":58,"column":4}}},"3":{"name":"_mintOverride","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"_minterTransferOverride","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":71,"column":5}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":69}},"2":{"start":{"line":37,"column":8},"end":{"line":37,"column":97}},"3":{"start":{"line":38,"column":8},"end":{"line":38,"column":1716}},"4":{"start":{"line":39,"column":12},"end":{"line":39,"column":48}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":59}},"6":{"start":{"line":48,"column":8},"end":{"line":48,"column":37}},"7":{"start":{"line":51,"column":8},"end":{"line":51,"column":87}},"8":{"start":{"line":52,"column":8},"end":{"line":52,"column":2292}},"9":{"start":{"line":53,"column":12},"end":{"line":53,"column":61}},"10":{"start":{"line":57,"column":8},"end":{"line":57,"column":19}},"11":{"start":{"line":64,"column":8},"end":{"line":64,"column":45}},"12":{"start":{"line":70,"column":12},"end":{"line":70,"column":54}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":8},"end":{"line":34,"column":8}},{"start":{"line":34,"column":8},"end":{"line":34,"column":8}}]},"2":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":8},"end":{"line":37,"column":8}},{"start":{"line":37,"column":8},"end":{"line":37,"column":8}}]},"3":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":8},"end":{"line":47,"column":8}},{"start":{"line":47,"column":8},"end":{"line":47,"column":8}}]},"4":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":8},"end":{"line":51,"column":8}},{"start":{"line":51,"column":8},"end":{"line":51,"column":8}}]}}},
+"contracts/modules/internal/ValidationModuleRuleEngineInternal.sol":{"l":{"38":4748,"39":83,"53":8704,"54":8704,"68":441,"69":441,"70":441,"75":9145},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol","s":{"1":4748,"2":83,"3":8704,"4":8704,"5":441,"6":441},"b":{"1":[4748,0],"2":[83,4665]},"f":{"1":4748,"2":8704,"3":441,"4":9145},"fnMap":{"1":{"name":"__ValidationRuleEngine_init_unchained","line":37,"loc":{"start":{"line":35,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"ruleEngine","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":55,"column":4}}},"3":{"name":"_setRuleEngine","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":71,"column":4}}},"4":{"name":"_getValidationModuleRuleEngineStorage","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":78,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":1469}},"2":{"start":{"line":39,"column":12},"end":{"line":39,"column":38}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":93}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":28}},"5":{"start":{"line":68,"column":8},"end":{"line":68,"column":93}},"6":{"start":{"line":70,"column":8},"end":{"line":70,"column":36}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":15},"end":{"line":37,"column":15}},{"start":{"line":37,"column":15},"end":{"line":37,"column":15}}]},"2":{"line":38,"type":"if","locations":[{"start":{"line":38,"column":8},"end":{"line":38,"column":8}},{"start":{"line":38,"column":8},"end":{"line":38,"column":8}}]}}},
+"contracts/modules/wrapper/controllers/ValidationModule.sol":{"l":{"27":352,"32":46,"48":1437,"49":34,"52":14,"55":1389,"65":8325,"66":6229,"69":1175,"72":921,"84":42,"88":12,"90":30,"100":6606,"101":6557,"102":60,"113":1247,"114":1175,"115":84,"129":1353,"132":240,"134":1113,"143":744,"144":24,"146":24,"148":50,"157":1353,"159":384,"161":969,"175":911,"176":744,"186":1906,"195":28},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol","s":{"1":352,"2":46,"3":1437,"4":34,"5":1403,"6":14,"7":1389,"8":8325,"9":6229,"10":2096,"11":1175,"12":921,"13":42,"14":12,"15":30,"16":6606,"17":6557,"18":1247,"19":1175,"20":1353,"21":240,"22":1113,"23":744,"24":720,"25":696,"26":1353,"27":384,"28":969,"29":911,"30":744,"31":1906,"32":28},"b":{"1":[34,1403],"2":[14,1389],"3":[6229,2096],"4":[1175,921],"5":[12,30],"6":[0,12],"7":[60,6497],"8":[84,1091],"9":[240,1113],"10":[24,168],"11":[168,48],"12":[24,720],"13":[24,696],"14":[50,646],"15":[384,969],"16":[240,144]},"f":{"1":352,"2":46,"3":1437,"4":8325,"5":42,"6":6606,"7":1247,"8":1353,"9":744,"10":1353,"11":911,"12":1906,"13":28},"fnMap":{"1":{"name":"canSend","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"canReceive","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":33,"column":4}}},"3":{"name":"_canTransferGenericByModule","line":42,"loc":{"start":{"line":42,"column":4},"end":{"line":57,"column":4}}},"4":{"name":"_canTransferGenericByModuleAndRevert","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":74,"column":4}}},"5":{"name":"_canMintBurnByModule","line":81,"loc":{"start":{"line":81,"column":4},"end":{"line":91,"column":4}}},"6":{"name":"_canMintByModuleAndRevert","line":97,"loc":{"start":{"line":97,"column":4},"end":{"line":104,"column":4}}},"7":{"name":"_canBurnByModuleAndRevert","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":117,"column":4}}},"8":{"name":"_canTransferisFrozen","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":136,"column":4}}},"9":{"name":"_canTransferisFrozenAndRevert","line":138,"loc":{"start":{"line":138,"column":4},"end":{"line":150,"column":4}}},"10":{"name":"_canTransferStandardByModule","line":152,"loc":{"start":{"line":152,"column":2},"end":{"line":163,"column":4}}},"11":{"name":"_canTransferStandardByModuleAndRevert","line":165,"loc":{"start":{"line":165,"column":4},"end":{"line":177,"column":4}}},"12":{"name":"_canSend","line":185,"loc":{"start":{"line":185,"column":4},"end":{"line":187,"column":4}}},"13":{"name":"_canReceive","line":194,"loc":{"start":{"line":194,"column":4},"end":{"line":196,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":32}},"2":{"start":{"line":32,"column":8},"end":{"line":32,"column":35}},"3":{"start":{"line":48,"column":8},"end":{"line":48,"column":1732}},"4":{"start":{"line":49,"column":12},"end":{"line":49,"column":43}},"5":{"start":{"line":51,"column":13},"end":{"line":51,"column":1832}},"6":{"start":{"line":52,"column":12},"end":{"line":52,"column":45}},"7":{"start":{"line":55,"column":12},"end":{"line":55,"column":66}},"8":{"start":{"line":65,"column":8},"end":{"line":65,"column":2203}},"9":{"start":{"line":66,"column":13},"end":{"line":66,"column":41}},"10":{"start":{"line":68,"column":13},"end":{"line":68,"column":2302}},"11":{"start":{"line":69,"column":12},"end":{"line":69,"column":42}},"12":{"start":{"line":72,"column":13},"end":{"line":72,"column":68}},"13":{"start":{"line":84,"column":8},"end":{"line":84,"column":2831}},"14":{"start":{"line":88,"column":12},"end":{"line":88,"column":24}},"15":{"start":{"line":90,"column":8},"end":{"line":90,"column":19}},"16":{"start":{"line":100,"column":8},"end":{"line":100,"column":31}},"17":{"start":{"line":101,"column":8},"end":{"line":101,"column":3428}},"18":{"start":{"line":113,"column":8},"end":{"line":113,"column":31}},"19":{"start":{"line":114,"column":8},"end":{"line":114,"column":3793}},"20":{"start":{"line":129,"column":8},"end":{"line":129,"column":4251}},"21":{"start":{"line":132,"column":12},"end":{"line":132,"column":23}},"22":{"start":{"line":134,"column":13},"end":{"line":134,"column":25}},"23":{"start":{"line":143,"column":8},"end":{"line":143,"column":4616}},"24":{"start":{"line":145,"column":15},"end":{"line":145,"column":4720}},"25":{"start":{"line":147,"column":15},"end":{"line":147,"column":4819}},"26":{"start":{"line":157,"column":8},"end":{"line":157,"column":5078}},"27":{"start":{"line":159,"column":12},"end":{"line":159,"column":24}},"28":{"start":{"line":161,"column":13},"end":{"line":161,"column":24}},"29":{"start":{"line":175,"column":8},"end":{"line":175,"column":26}},"30":{"start":{"line":176,"column":8},"end":{"line":176,"column":55}},"31":{"start":{"line":186,"column":8},"end":{"line":186,"column":51}},"32":{"start":{"line":195,"column":8},"end":{"line":195,"column":51}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":8},"end":{"line":48,"column":8}},{"start":{"line":48,"column":8},"end":{"line":48,"column":8}}]},"2":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":13},"end":{"line":51,"column":13}},{"start":{"line":51,"column":13},"end":{"line":51,"column":13}}]},"3":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":8},"end":{"line":65,"column":8}},{"start":{"line":65,"column":8},"end":{"line":65,"column":8}}]},"4":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":13},"end":{"line":68,"column":13}},{"start":{"line":68,"column":13},"end":{"line":68,"column":13}}]},"5":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":8},"end":{"line":84,"column":8}},{"start":{"line":84,"column":8},"end":{"line":84,"column":8}}]},"6":{"line":84,"type":"cond-expr","locations":[{"start":{"line":84,"column":11},"end":{"line":84,"column":35}},{"start":{"line":84,"column":40},"end":{"line":84,"column":73}}]},"7":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":8},"end":{"line":101,"column":8}},{"start":{"line":101,"column":8},"end":{"line":101,"column":8}}]},"8":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":8},"end":{"line":114,"column":8}},{"start":{"line":114,"column":8},"end":{"line":114,"column":8}}]},"9":{"line":129,"type":"if","locations":[{"start":{"line":129,"column":8},"end":{"line":129,"column":8}},{"start":{"line":129,"column":8},"end":{"line":129,"column":8}}]},"10":{"line":129,"type":"cond-expr","locations":[{"start":{"line":129,"column":12},"end":{"line":129,"column":46}},{"start":{"line":130,"column":11},"end":{"line":130,"column":42}}]},"11":{"line":129,"type":"cond-expr","locations":[{"start":{"line":129,"column":12},"end":{"line":130,"column":42}},{"start":{"line":131,"column":11},"end":{"line":131,"column":40}}]},"12":{"line":143,"type":"if","locations":[{"start":{"line":143,"column":8},"end":{"line":143,"column":8}},{"start":{"line":143,"column":8},"end":{"line":143,"column":8}}]},"13":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":15},"end":{"line":145,"column":15}},{"start":{"line":145,"column":15},"end":{"line":145,"column":15}}]},"14":{"line":147,"type":"if","locations":[{"start":{"line":147,"column":15},"end":{"line":147,"column":15}},{"start":{"line":147,"column":15},"end":{"line":147,"column":15}}]},"15":{"line":157,"type":"if","locations":[{"start":{"line":157,"column":8},"end":{"line":157,"column":8}},{"start":{"line":157,"column":8},"end":{"line":157,"column":8}}]},"16":{"line":157,"type":"cond-expr","locations":[{"start":{"line":157,"column":12},"end":{"line":157,"column":50}},{"start":{"line":158,"column":11},"end":{"line":158,"column":30}}]}}},
+"contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol":{"l":{"27":12,"28":6,"30":6,"42":191,"43":166,"44":166,"45":36,"48":155,"59":191,"60":36,"62":155,"67":207,"68":26,"70":181,"76":34,"77":18,"79":16,"88":740,"89":4,"91":736,"99":128,"100":4,"102":124,"111":108,"112":98,"120":108,"121":79,"122":2,"124":2,"126":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol","s":{"1":12,"2":6,"3":6,"4":191,"5":166,"6":166,"7":36,"8":155,"9":191,"10":36,"11":155,"12":207,"13":26,"14":181,"15":34,"16":18,"17":16,"18":740,"19":736,"20":128,"21":124,"22":108,"23":98,"24":108,"25":79,"26":77,"27":75},"b":{"1":[6,6],"2":[166,25],"3":[36,130],"4":[2,18],"5":[18,16],"6":[36,155],"7":[26,181],"8":[18,16],"9":[4,736],"10":[4,124],"11":[79,29],"12":[2,77],"13":[2,75],"14":[6,69]},"f":{"1":12,"2":191,"3":191,"4":207,"5":34,"6":740,"7":128,"8":108,"9":108},"fnMap":{"1":{"name":"_canMintBurnByModule","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"_canTransferStandardByModuleAllowlist","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"_canTransferStandardByModule","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"_canSend","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"_canReceive","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"_canMintByModuleAndRevert","line":85,"loc":{"start":{"line":85,"column":4},"end":{"line":93,"column":4}}},"7":{"name":"_canBurnByModuleAndRevert","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":104,"column":4}}},"8":{"name":"_canTransferStandardByModuleAndRevert","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":113,"column":4}}},"9":{"name":"_canTransferStandardByModuleAllowlistAndRevert","line":115,"loc":{"start":{"line":115,"column":4},"end":{"line":129,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":932}},"2":{"start":{"line":28,"column":12},"end":{"line":28,"column":24}},"3":{"start":{"line":30,"column":12},"end":{"line":30,"column":65}},"4":{"start":{"line":42,"column":8},"end":{"line":42,"column":1352}},"5":{"start":{"line":43,"column":12},"end":{"line":43,"column":80}},"6":{"start":{"line":44,"column":12},"end":{"line":44,"column":1477}},"7":{"start":{"line":45,"column":16},"end":{"line":45,"column":27}},"8":{"start":{"line":48,"column":7},"end":{"line":48,"column":19}},"9":{"start":{"line":59,"column":8},"end":{"line":59,"column":1876}},"10":{"start":{"line":60,"column":11},"end":{"line":60,"column":23}},"11":{"start":{"line":62,"column":8},"end":{"line":62,"column":79}},"12":{"start":{"line":67,"column":8},"end":{"line":67,"column":2219}},"13":{"start":{"line":68,"column":12},"end":{"line":68,"column":24}},"14":{"start":{"line":70,"column":12},"end":{"line":70,"column":53}},"15":{"start":{"line":76,"column":8},"end":{"line":76,"column":2549}},"16":{"start":{"line":77,"column":12},"end":{"line":77,"column":24}},"17":{"start":{"line":79,"column":12},"end":{"line":79,"column":56}},"18":{"start":{"line":88,"column":8},"end":{"line":88,"column":2946}},"19":{"start":{"line":91,"column":12},"end":{"line":91,"column":57}},"20":{"start":{"line":99,"column":8},"end":{"line":99,"column":3297}},"21":{"start":{"line":102,"column":12},"end":{"line":102,"column":59}},"22":{"start":{"line":111,"column":8},"end":{"line":111,"column":72}},"23":{"start":{"line":112,"column":8},"end":{"line":112,"column":80}},"24":{"start":{"line":120,"column":8},"end":{"line":120,"column":3993}},"25":{"start":{"line":121,"column":12},"end":{"line":121,"column":4036}},"26":{"start":{"line":123,"column":19},"end":{"line":123,"column":4161}},"27":{"start":{"line":125,"column":19},"end":{"line":125,"column":4256}}},"branchMap":{"1":{"line":27,"type":"if","locations":[{"start":{"line":27,"column":8},"end":{"line":27,"column":8}},{"start":{"line":27,"column":8},"end":{"line":27,"column":8}}]},"2":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":8},"end":{"line":42,"column":8}},{"start":{"line":42,"column":8},"end":{"line":42,"column":8}}]},"3":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":12},"end":{"line":44,"column":12}},{"start":{"line":44,"column":12},"end":{"line":44,"column":12}}]},"4":{"line":44,"type":"cond-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":27}},{"start":{"line":44,"column":32},"end":{"line":44,"column":51}}]},"5":{"line":44,"type":"cond-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":51}},{"start":{"line":44,"column":56},"end":{"line":44,"column":73}}]},"6":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":8},"end":{"line":59,"column":8}},{"start":{"line":59,"column":8},"end":{"line":59,"column":8}}]},"7":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":8},"end":{"line":67,"column":8}},{"start":{"line":67,"column":8},"end":{"line":67,"column":8}}]},"8":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":8},"end":{"line":76,"column":8}},{"start":{"line":76,"column":8},"end":{"line":76,"column":8}}]},"9":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":8},"end":{"line":88,"column":8}},{"start":{"line":88,"column":8},"end":{"line":88,"column":8}}]},"10":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":8},"end":{"line":99,"column":8}},{"start":{"line":99,"column":8},"end":{"line":99,"column":8}}]},"11":{"line":120,"type":"if","locations":[{"start":{"line":120,"column":8},"end":{"line":120,"column":8}},{"start":{"line":120,"column":8},"end":{"line":120,"column":8}}]},"12":{"line":121,"type":"if","locations":[{"start":{"line":121,"column":12},"end":{"line":121,"column":12}},{"start":{"line":121,"column":12},"end":{"line":121,"column":12}}]},"13":{"line":123,"type":"if","locations":[{"start":{"line":123,"column":19},"end":{"line":123,"column":19}},{"start":{"line":123,"column":19},"end":{"line":123,"column":19}}]},"14":{"line":125,"type":"if","locations":[{"start":{"line":125,"column":19},"end":{"line":125,"column":19}},{"start":{"line":125,"column":19},"end":{"line":125,"column":19}}]}}},
+"contracts/modules/wrapper/core/EnforcementModule.sol":{"l":{"27":771,"28":696,"42":271,"60":300,"71":125,"79":16612,"87":721,"88":646},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol","s":{"1":771,"2":271,"3":300,"4":125,"5":16612,"6":721,"7":646},"b":{"1":[271,0],"2":[300,50],"3":[125,25]},"f":{"1":771,"2":271,"3":300,"4":125,"5":16612,"6":721},"fnMap":{"1":{"name":"onlyEnforcer","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":29,"column":4}}},"2":{"name":"setAddressFrozen","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":4}}},"3":{"name":"setAddressFrozen","line":59,"loc":{"start":{"line":57,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"batchSetAddressFrozen","line":70,"loc":{"start":{"line":68,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"isFrozen","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"_addAddressToTheList","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":89,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":25}},"2":{"start":{"line":42,"column":9},"end":{"line":42,"column":49}},"3":{"start":{"line":60,"column":9},"end":{"line":60,"column":51}},"4":{"start":{"line":71,"column":9},"end":{"line":71,"column":53}},"5":{"start":{"line":79,"column":7},"end":{"line":79,"column":39}},"6":{"start":{"line":87,"column":8},"end":{"line":87,"column":79}},"7":{"start":{"line":88,"column":8},"end":{"line":88,"column":63}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":105},"end":{"line":41,"column":105}},{"start":{"line":41,"column":105},"end":{"line":41,"column":105}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":21},"end":{"line":59,"column":21}},{"start":{"line":59,"column":21},"end":{"line":59,"column":21}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":51},"end":{"line":70,"column":51}},{"start":{"line":70,"column":51},"end":{"line":70,"column":51}}]}}},
+"contracts/modules/wrapper/core/ERC20BaseModule.sol":{"l":{"39":98,"40":50,"55":5624,"56":5624,"57":5624,"58":5624,"78":128,"80":80,"83":80,"86":80,"96":24,"97":24,"104":86,"105":86,"113":74,"114":74,"125":26,"126":26,"127":26,"134":24,"135":24,"136":24,"143":48,"144":48,"145":24,"147":48,"158":5858},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol","s":{"1":98,"2":5624,"3":128,"4":80,"5":80,"6":80,"7":24,"8":24,"9":86,"10":86,"11":74,"12":74,"13":26,"14":26,"15":24,"16":24,"17":48},"b":{"1":[5624,0],"2":[80,0],"3":[26,24],"4":[24,24]},"f":{"1":98,"2":5624,"3":128,"4":24,"5":86,"6":74,"7":26,"8":24,"9":48,"10":5858},"fnMap":{"1":{"name":"onlyERC20AttributeManager","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"__ERC20BaseModule_init_unchained","line":54,"loc":{"start":{"line":50,"column":4},"end":{"line":59,"column":4}}},"3":{"name":"transferFrom","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":87,"column":4}}},"4":{"name":"decimals","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":98,"column":4}}},"5":{"name":"name","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":106,"column":4}}},"6":{"name":"symbol","line":112,"loc":{"start":{"line":112,"column":4},"end":{"line":115,"column":4}}},"7":{"name":"setName","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":128,"column":4}}},"8":{"name":"setSymbol","line":133,"loc":{"start":{"line":133,"column":4},"end":{"line":137,"column":4}}},"9":{"name":"batchBalanceOf","line":142,"loc":{"start":{"line":142,"column":4},"end":{"line":148,"column":4}}},"10":{"name":"_getERC20BaseModuleStorage","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":161,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":43}},"2":{"start":{"line":55,"column":8},"end":{"line":55,"column":71}},"3":{"start":{"line":78,"column":8},"end":{"line":78,"column":68}},"4":{"start":{"line":80,"column":8},"end":{"line":80,"column":3039}},"5":{"start":{"line":83,"column":12},"end":{"line":83,"column":49}},"6":{"start":{"line":86,"column":8},"end":{"line":86,"column":21}},"7":{"start":{"line":96,"column":8},"end":{"line":96,"column":71}},"8":{"start":{"line":97,"column":8},"end":{"line":97,"column":26}},"9":{"start":{"line":104,"column":8},"end":{"line":104,"column":71}},"10":{"start":{"line":105,"column":8},"end":{"line":105,"column":22}},"11":{"start":{"line":113,"column":8},"end":{"line":113,"column":71}},"12":{"start":{"line":114,"column":8},"end":{"line":114,"column":24}},"13":{"start":{"line":125,"column":8},"end":{"line":125,"column":71}},"14":{"start":{"line":127,"column":8},"end":{"line":127,"column":31}},"15":{"start":{"line":134,"column":8},"end":{"line":134,"column":71}},"16":{"start":{"line":136,"column":8},"end":{"line":136,"column":37}},"17":{"start":{"line":144,"column":8},"end":{"line":144,"column":5304}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":23},"end":{"line":54,"column":23}},{"start":{"line":54,"column":23},"end":{"line":54,"column":23}}]},"2":{"line":80,"type":"if","locations":[{"start":{"line":80,"column":8},"end":{"line":80,"column":8}},{"start":{"line":80,"column":8},"end":{"line":80,"column":8}}]},"3":{"line":124,"type":"if","locations":[{"start":{"line":124,"column":87},"end":{"line":124,"column":87}},{"start":{"line":124,"column":87},"end":{"line":124,"column":87}}]},"4":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":91},"end":{"line":133,"column":91}},{"start":{"line":133,"column":91},"end":{"line":133,"column":91}}]}}},
+"contracts/modules/wrapper/core/ERC20BurnModule.sol":{"l":{"26":835,"27":739,"45":271,"57":138,"73":254,"74":91,"87":76,"88":74,"100":409,"101":292},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol","s":{"1":835,"2":271,"3":138,"4":254,"5":91,"6":76,"7":74,"8":409,"9":292},"b":{"1":[271,72],"2":[138,0],"3":[254,24],"4":[76,0]},"f":{"1":835,"2":271,"3":138,"4":254,"5":76,"6":409},"fnMap":{"1":{"name":"onlyBurner","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"burn","line":44,"loc":{"start":{"line":40,"column":4},"end":{"line":46,"column":4}}},"3":{"name":"burn","line":56,"loc":{"start":{"line":53,"column":4},"end":{"line":58,"column":4}}},"4":{"name":"batchBurn","line":72,"loc":{"start":{"line":68,"column":4},"end":{"line":75,"column":4}}},"5":{"name":"batchBurn","line":86,"loc":{"start":{"line":83,"column":4},"end":{"line":89,"column":4}}},"6":{"name":"_burn","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":102,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":23}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":34}},"3":{"start":{"line":57,"column":7},"end":{"line":57,"column":30}},"4":{"start":{"line":73,"column":8},"end":{"line":73,"column":35}},"5":{"start":{"line":74,"column":8},"end":{"line":74,"column":60}},"6":{"start":{"line":87,"column":8},"end":{"line":87,"column":35}},"7":{"start":{"line":88,"column":8},"end":{"line":88,"column":58}},"8":{"start":{"line":100,"column":8},"end":{"line":100,"column":36}},"9":{"start":{"line":101,"column":8},"end":{"line":101,"column":53}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":44},"end":{"line":44,"column":44}},{"start":{"line":44,"column":44},"end":{"line":44,"column":44}}]},"2":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":44},"end":{"line":56,"column":44}},{"start":{"line":56,"column":44},"end":{"line":56,"column":44}}]},"3":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":47},"end":{"line":72,"column":47}},{"start":{"line":72,"column":47},"end":{"line":72,"column":47}}]},"4":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":45},"end":{"line":86,"column":45}},{"start":{"line":86,"column":45},"end":{"line":86,"column":45}}]}}},
+"contracts/modules/wrapper/core/ERC20MintModule.sol":{"l":{"28":5722,"29":5650,"44":148,"60":4534,"76":730,"77":583,"89":238,"96":4682,"97":4586},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol","s":{"1":5722,"2":148,"3":4534,"4":730,"5":583,"6":238,"7":4682,"8":4586},"b":{"1":[148,24],"2":[4534,24],"3":[730,24],"4":[238,0]},"f":{"1":5722,"2":148,"3":4534,"4":730,"5":238,"6":4682},"fnMap":{"1":{"name":"onlyMinter","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"mint","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":4}}},"3":{"name":"mint","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"batchMint","line":75,"loc":{"start":{"line":72,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"batchTransfer","line":88,"loc":{"start":{"line":85,"column":3},"end":{"line":90,"column":4}}},"6":{"name":"_mint","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":98,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":23}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":34}},"3":{"start":{"line":60,"column":7},"end":{"line":60,"column":31}},"4":{"start":{"line":76,"column":7},"end":{"line":76,"column":34}},"5":{"start":{"line":77,"column":8},"end":{"line":77,"column":54}},"6":{"start":{"line":89,"column":8},"end":{"line":89,"column":42}},"7":{"start":{"line":96,"column":8},"end":{"line":96,"column":36}},"8":{"start":{"line":97,"column":8},"end":{"line":97,"column":53}}},"branchMap":{"1":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":109},"end":{"line":43,"column":109}},{"start":{"line":43,"column":109},"end":{"line":43,"column":109}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":88},"end":{"line":59,"column":88}},{"start":{"line":59,"column":88},"end":{"line":59,"column":88}}]},"3":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":44},"end":{"line":75,"column":44}},{"start":{"line":75,"column":44},"end":{"line":75,"column":44}}]},"4":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":53},"end":{"line":88,"column":53}},{"start":{"line":88,"column":53},"end":{"line":88,"column":53}}]}}},
+"contracts/modules/wrapper/core/PauseModule.sol":{"l":{"41":763,"42":712,"46":318,"47":293,"60":637,"69":75,"70":75,"71":50,"86":293,"87":268,"88":268,"89":25,"91":243,"92":243,"100":5339,"107":8168,"108":8168,"119":7853,"120":121,"126":8511},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol","s":{"1":763,"2":318,"3":637,"4":75,"5":75,"6":50,"7":293,"8":268,"9":268,"10":243,"11":5339,"12":8168,"13":8168,"14":7853},"b":{"1":[637,26],"2":[75,25],"3":[50,25],"4":[293,25],"5":[25,243],"6":[121,7732]},"f":{"1":763,"2":318,"3":637,"4":75,"5":293,"6":5339,"7":8168,"8":7853,"9":8511},"fnMap":{"1":{"name":"onlyPauseManager","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":43,"column":4}}},"2":{"name":"onlyDeactivateContractManager","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":48,"column":4}}},"3":{"name":"pause","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"unpause","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":72,"column":4}}},"5":{"name":"deactivateContract","line":83,"loc":{"start":{"line":81,"column":4},"end":{"line":93,"column":4}}},"6":{"name":"paused","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":101,"column":3}}},"7":{"name":"deactivated","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":109,"column":4}}},"8":{"name":"_requireNotDeactivated","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":122,"column":4}}},"9":{"name":"_getPauseModuleStorage","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":129,"column":4}}}},"statementMap":{"1":{"start":{"line":41,"column":8},"end":{"line":41,"column":24}},"2":{"start":{"line":46,"column":8},"end":{"line":46,"column":29}},"3":{"start":{"line":60,"column":8},"end":{"line":60,"column":35}},"4":{"start":{"line":69,"column":8},"end":{"line":69,"column":63}},"5":{"start":{"line":70,"column":8},"end":{"line":70,"column":76}},"6":{"start":{"line":71,"column":8},"end":{"line":71,"column":37}},"7":{"start":{"line":86,"column":8},"end":{"line":86,"column":43}},"8":{"start":{"line":87,"column":8},"end":{"line":87,"column":63}},"9":{"start":{"line":88,"column":8},"end":{"line":88,"column":3423}},"10":{"start":{"line":92,"column":7},"end":{"line":92,"column":37}},"11":{"start":{"line":100,"column":8},"end":{"line":100,"column":43}},"12":{"start":{"line":107,"column":8},"end":{"line":107,"column":63}},"13":{"start":{"line":108,"column":8},"end":{"line":108,"column":31}},"14":{"start":{"line":119,"column":8},"end":{"line":119,"column":4507}}},"branchMap":{"1":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":75},"end":{"line":59,"column":75}},{"start":{"line":59,"column":75},"end":{"line":59,"column":75}}]},"2":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":77},"end":{"line":68,"column":77}},{"start":{"line":68,"column":77},"end":{"line":68,"column":77}}]},"3":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":8},"end":{"line":70,"column":8}},{"start":{"line":70,"column":8},"end":{"line":70,"column":8}}]},"4":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":8},"end":{"line":83,"column":8}},{"start":{"line":83,"column":8},"end":{"line":83,"column":8}}]},"5":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":8},"end":{"line":88,"column":8}},{"start":{"line":88,"column":8},"end":{"line":88,"column":8}}]},"6":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":8},"end":{"line":119,"column":8}},{"start":{"line":119,"column":8},"end":{"line":119,"column":8}}]}}},
+"contracts/modules/wrapper/core/ValidationModuleCore.sol":{"l":{"25":1229,"34":208,"50":1437},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol","s":{"1":1229,"2":208,"3":1437},"b":{},"f":{"1":1229,"2":208,"3":1437},"fnMap":{"1":{"name":"canTransfer","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"canTransferFrom","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":35,"column":4}}},"3":{"name":"_canTransferByModule","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":51,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":64}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":61}},"3":{"start":{"line":50,"column":8},"end":{"line":50,"column":78}}},"branchMap":{}},
+"contracts/modules/wrapper/core/VersionModule.sol":{"l":{"28":25},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/VersionModule.sol","s":{"1":25},"b":{},"f":{"1":25},"fnMap":{"1":{"name":"version","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":29,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":7},"end":{"line":28,"column":21}}},"branchMap":{}},
+"contracts/modules/wrapper/extensions/DocumentERC1643Module.sol":{"l":{"24":299,"25":253,"29":138,"33":46,"37":207,"38":207,"39":207,"40":207,"41":207,"43":207,"44":184,"45":184,"48":207,"52":46,"53":46,"54":46,"56":46,"57":46,"58":46,"60":46,"61":23,"62":23,"63":23,"66":46,"67":46,"68":46,"70":46,"76":437},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol","s":{"1":299,"2":138,"3":46,"4":207,"5":207,"6":207,"7":184,"8":207,"9":46,"10":46,"11":46,"12":46,"13":46,"14":46,"15":46,"16":23,"17":46,"18":46},"b":{"1":[207,23],"2":[184,23],"3":[46,23],"4":[46,0],"5":[23,23]},"f":{"1":299,"2":138,"3":46,"4":207,"5":46,"6":437},"fnMap":{"1":{"name":"onlyDocumentManager","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"getDocument","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":30,"column":4}}},"3":{"name":"getAllDocuments","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":34,"column":4}}},"4":{"name":"setDocument","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":49,"column":4}}},"5":{"name":"removeDocument","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":71,"column":4}}},"6":{"name":"_getDocumentERC1643ModuleStorage","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":79,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":37}},"2":{"start":{"line":29,"column":8},"end":{"line":29,"column":66}},"3":{"start":{"line":33,"column":8},"end":{"line":33,"column":64}},"4":{"start":{"line":37,"column":8},"end":{"line":37,"column":83}},"5":{"start":{"line":38,"column":8},"end":{"line":38,"column":54}},"6":{"start":{"line":43,"column":8},"end":{"line":43,"column":1758}},"7":{"start":{"line":44,"column":12},"end":{"line":44,"column":38}},"8":{"start":{"line":48,"column":8},"end":{"line":48,"column":53}},"9":{"start":{"line":52,"column":8},"end":{"line":52,"column":83}},"10":{"start":{"line":53,"column":8},"end":{"line":53,"column":42}},"11":{"start":{"line":54,"column":8},"end":{"line":54,"column":58}},"12":{"start":{"line":56,"column":8},"end":{"line":56,"column":53}},"13":{"start":{"line":57,"column":8},"end":{"line":57,"column":31}},"14":{"start":{"line":58,"column":8},"end":{"line":58,"column":55}},"15":{"start":{"line":60,"column":8},"end":{"line":60,"column":2398}},"16":{"start":{"line":61,"column":12},"end":{"line":61,"column":59}},"17":{"start":{"line":66,"column":8},"end":{"line":66,"column":29}},"18":{"start":{"line":70,"column":8},"end":{"line":70,"column":71}}},"branchMap":{"1":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":106},"end":{"line":36,"column":106}},{"start":{"line":36,"column":106},"end":{"line":36,"column":106}}]},"2":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":8}},{"start":{"line":43,"column":8},"end":{"line":43,"column":8}}]},"3":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":66},"end":{"line":51,"column":66}},{"start":{"line":51,"column":66},"end":{"line":51,"column":66}}]},"4":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":8},"end":{"line":54,"column":8}},{"start":{"line":54,"column":8},"end":{"line":54,"column":8}}]},"5":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":8},"end":{"line":60,"column":8}},{"start":{"line":60,"column":8},"end":{"line":60,"column":8}}]}}},
+"contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol":{"l":{"26":1289,"27":1226,"32":262,"33":220,"44":2246,"55":146,"56":125,"66":574,"76":194,"87":378,"95":845,"96":845,"100":323,"101":323},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol","s":{"1":1289,"2":262,"3":2246,"4":146,"5":125,"6":574,"7":194,"8":378,"9":845,"10":845,"11":323,"12":323},"b":{"1":[146,42],"2":[574,21],"3":[194,21],"4":[378,21]},"f":{"1":1289,"2":262,"3":2246,"4":146,"5":574,"6":194,"7":378,"8":845,"9":323},"fnMap":{"1":{"name":"onlyERC20Enforcer","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"onlyForcedTransferManager","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":34,"column":4}}},"3":{"name":"getFrozenTokens","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":45,"column":4}}},"4":{"name":"forcedTransfer","line":54,"loc":{"start":{"line":53,"column":4},"end":{"line":57,"column":4}}},"5":{"name":"freezePartialTokens","line":65,"loc":{"start":{"line":64,"column":4},"end":{"line":67,"column":4}}},"6":{"name":"unfreezePartialTokens","line":75,"loc":{"start":{"line":74,"column":4},"end":{"line":77,"column":4}}},"7":{"name":"setFrozenTokens","line":85,"loc":{"start":{"line":84,"column":4},"end":{"line":88,"column":4}}},"8":{"name":"_freezeTokensEmitEvents","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":97,"column":4}}},"9":{"name":"_unfreezeTokensEmitEvents","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":102,"column":4}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":32}},"2":{"start":{"line":32,"column":8},"end":{"line":32,"column":33}},"3":{"start":{"line":44,"column":8},"end":{"line":44,"column":40}},"4":{"start":{"line":55,"column":8},"end":{"line":55,"column":39}},"5":{"start":{"line":56,"column":8},"end":{"line":56,"column":19}},"6":{"start":{"line":66,"column":8},"end":{"line":66,"column":43}},"7":{"start":{"line":76,"column":8},"end":{"line":76,"column":45}},"8":{"start":{"line":87,"column":8},"end":{"line":87,"column":47}},"9":{"start":{"line":95,"column":8},"end":{"line":95,"column":71}},"10":{"start":{"line":96,"column":8},"end":{"line":96,"column":71}},"11":{"start":{"line":100,"column":8},"end":{"line":100,"column":73}},"12":{"start":{"line":101,"column":8},"end":{"line":101,"column":73}}},"branchMap":{"1":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":57},"end":{"line":54,"column":57}},{"start":{"line":54,"column":57},"end":{"line":54,"column":57}}]},"2":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":54},"end":{"line":65,"column":54}},{"start":{"line":65,"column":54},"end":{"line":65,"column":54}}]},"3":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":54},"end":{"line":75,"column":54}},{"start":{"line":75,"column":54},"end":{"line":75,"column":54}}]},"4":{"line":85,"type":"if","locations":[{"start":{"line":85,"column":65},"end":{"line":85,"column":65}},{"start":{"line":85,"column":65},"end":{"line":85,"column":65}}]}}},
+"contracts/modules/wrapper/extensions/ExtraInformationModule.sol":{"l":{"32":164,"33":82,"45":5402,"47":5402,"49":5402,"51":5402,"68":26,"69":26,"79":26,"92":26,"93":26,"101":130,"102":130,"109":58,"110":58,"117":104,"118":104,"125":28,"126":28,"132":5428,"133":5428,"138":5430,"140":5430,"141":5430,"142":5430,"144":5430,"148":5428,"149":5428,"157":5774},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ExtraInformationModule.sol","s":{"1":164,"2":5402,"3":5402,"4":5402,"5":5402,"6":26,"7":26,"8":26,"9":26,"10":26,"11":130,"12":130,"13":58,"14":58,"15":104,"16":104,"17":28,"18":28,"19":5428,"20":5430,"21":5428},"b":{"1":[5402,0],"2":[26,26],"3":[26,26],"4":[26,26]},"f":{"1":164,"2":5402,"3":26,"4":26,"5":26,"6":130,"7":58,"8":104,"9":28,"10":5428,"11":5430,"12":5428,"13":5774},"fnMap":{"1":{"name":"onlyExtraInfoManager","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":34,"column":4}}},"2":{"name":"__ExtraInformationModule_init_unchained","line":44,"loc":{"start":{"line":40,"column":4},"end":{"line":52,"column":4}}},"3":{"name":"setTokenId","line":67,"loc":{"start":{"line":65,"column":4},"end":{"line":70,"column":4}}},"4":{"name":"setTerms","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":80,"column":4}}},"5":{"name":"setInformation","line":91,"loc":{"start":{"line":89,"column":4},"end":{"line":94,"column":4}}},"6":{"name":"tokenId","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":103,"column":4}}},"7":{"name":"terms","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":111,"column":4}}},"8":{"name":"information","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":119,"column":4}}},"9":{"name":"_setTerms","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":127,"column":4}}},"10":{"name":"_setTokenId","line":129,"loc":{"start":{"line":129,"column":4},"end":{"line":134,"column":4}}},"11":{"name":"_setTerms","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":145,"column":4}}},"12":{"name":"_setInformation","line":147,"loc":{"start":{"line":147,"column":4},"end":{"line":150,"column":4}}},"13":{"name":"_getExtraInformationModuleStorage","line":156,"loc":{"start":{"line":156,"column":4},"end":{"line":160,"column":4}}}},"statementMap":{"1":{"start":{"line":32,"column":8},"end":{"line":32,"column":38}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":85}},"3":{"start":{"line":47,"column":8},"end":{"line":47,"column":31}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":27}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":39}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":85}},"7":{"start":{"line":69,"column":8},"end":{"line":69,"column":31}},"8":{"start":{"line":79,"column":2},"end":{"line":79,"column":18}},"9":{"start":{"line":92,"column":8},"end":{"line":92,"column":85}},"10":{"start":{"line":93,"column":8},"end":{"line":93,"column":39}},"11":{"start":{"line":101,"column":8},"end":{"line":101,"column":85}},"12":{"start":{"line":102,"column":8},"end":{"line":102,"column":25}},"13":{"start":{"line":109,"column":8},"end":{"line":109,"column":85}},"14":{"start":{"line":110,"column":8},"end":{"line":110,"column":23}},"15":{"start":{"line":117,"column":8},"end":{"line":117,"column":85}},"16":{"start":{"line":118,"column":8},"end":{"line":118,"column":29}},"17":{"start":{"line":125,"column":2},"end":{"line":125,"column":79}},"18":{"start":{"line":126,"column":8},"end":{"line":126,"column":27}},"19":{"start":{"line":133,"column":8},"end":{"line":133,"column":40}},"20":{"start":{"line":144,"column":8},"end":{"line":144,"column":28}},"21":{"start":{"line":149,"column":8},"end":{"line":149,"column":38}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":23},"end":{"line":44,"column":23}},{"start":{"line":44,"column":23},"end":{"line":44,"column":23}}]},"2":{"line":67,"type":"if","locations":[{"start":{"line":67,"column":42},"end":{"line":67,"column":42}},{"start":{"line":67,"column":42},"end":{"line":67,"column":42}}]},"3":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":102},"end":{"line":78,"column":102}},{"start":{"line":78,"column":102},"end":{"line":78,"column":102}}]},"4":{"line":91,"type":"if","locations":[{"start":{"line":91,"column":21},"end":{"line":91,"column":21}},{"start":{"line":91,"column":21},"end":{"line":91,"column":21}}]}}},
+"contracts/modules/wrapper/extensions/SnapshotEngineModule.sol":{"l":{"30":343,"31":334,"45":27,"46":18,"47":18,"65":334,"66":334,"67":325,"77":3300,"78":3300,"87":343,"88":343,"95":3652},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol","s":{"1":343,"2":27,"3":18,"4":18,"5":334,"6":334,"7":325,"8":3300,"9":3300,"10":343},"b":{"1":[27,0],"2":[18,9],"3":[334,9],"4":[325,9]},"f":{"1":343,"2":27,"3":334,"4":3300,"5":343,"6":3652},"fnMap":{"1":{"name":"onlySnapshooter","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"__SnapshotEngineModule_init_unchained","line":44,"loc":{"start":{"line":43,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"setSnapshotEngine","line":64,"loc":{"start":{"line":62,"column":4},"end":{"line":68,"column":4}}},"4":{"name":"snapshotEngine","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"5":{"name":"_setSnapshotEngine","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":89,"column":4}}},"6":{"name":"_getSnapshotEngineModuleStorage","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":98,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":28}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":1821}},"3":{"start":{"line":46,"column":12},"end":{"line":46,"column":85}},"4":{"start":{"line":47,"column":12},"end":{"line":47,"column":49}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"6":{"start":{"line":66,"column":8},"end":{"line":66,"column":104}},"7":{"start":{"line":67,"column":8},"end":{"line":67,"column":45}},"8":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}},"10":{"start":{"line":88,"column":8},"end":{"line":88,"column":44}}},"branchMap":{"1":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":21},"end":{"line":44,"column":21}},{"start":{"line":44,"column":21},"end":{"line":44,"column":21}}]},"2":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]},"3":{"line":64,"type":"if","locations":[{"start":{"line":64,"column":53},"end":{"line":64,"column":53}},{"start":{"line":64,"column":53},"end":{"line":64,"column":53}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]}}},
+"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol":{"l":{"27":808,"28":804,"29":28,"31":776,"32":28},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol","s":{"1":808,"2":804,"3":776},"b":{"1":[28,776],"2":[28,748]},"f":{"1":808},"fnMap":{"1":{"name":"_canAuthorizeAllowanceByModuleAndRevert","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":34,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":26}},"2":{"start":{"line":28,"column":8},"end":{"line":28,"column":917}},"3":{"start":{"line":31,"column":8},"end":{"line":31,"column":1004}}},"branchMap":{"1":{"line":28,"type":"if","locations":[{"start":{"line":28,"column":8},"end":{"line":28,"column":8}},{"start":{"line":28,"column":8},"end":{"line":28,"column":8}}]},"2":{"line":31,"type":"if","locations":[{"start":{"line":31,"column":8},"end":{"line":31,"column":8}},{"start":{"line":31,"column":8},"end":{"line":31,"column":8}}]}}},
+"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol":{"l":{"55":93,"56":93,"57":6,"62":22,"67":11,"72":11,"77":11,"82":11,"84":18,"86":3,"103":199,"104":199,"105":199,"106":132,"108":42,"110":25,"120":189,"121":189,"122":11,"124":178,"125":178,"126":132,"128":24,"130":22,"147":223,"148":33,"150":55,"152":11,"154":11,"157":113},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol","s":{"1":93,"2":93,"3":6,"4":87,"5":22,"6":65,"7":11,"8":54,"9":11,"10":43,"11":11,"12":32,"13":11,"14":21,"15":18,"16":3,"17":199,"18":199,"19":199,"20":132,"21":67,"22":42,"23":25,"24":189,"25":189,"26":11,"27":178,"28":178,"29":132,"30":46,"31":24,"32":22,"33":223,"34":33,"35":190,"36":55,"37":135,"38":11,"39":124,"40":11,"41":113},"b":{"1":[6,87],"2":[22,65],"3":[11,54],"4":[11,43],"5":[11,32],"6":[11,21],"7":[18,3],"8":[132,67],"9":[42,25],"10":[11,178],"11":[132,46],"12":[24,22],"13":[33,190],"14":[55,135],"15":[11,124],"16":[11,113]},"f":{"1":93,"2":199,"3":189,"4":223},"fnMap":{"1":{"name":"messageForTransferRestriction","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":88,"column":4}}},"2":{"name":"detectTransferRestriction","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":112,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":114,"loc":{"start":{"line":114,"column":4},"end":{"line":133,"column":4}}},"4":{"name":"_detectTransferRestriction","line":142,"loc":{"start":{"line":142,"column":4},"end":{"line":159,"column":4}}}},"statementMap":{"1":{"start":{"line":55,"column":10},"end":{"line":55,"column":84}},"2":{"start":{"line":56,"column":8},"end":{"line":56,"column":2157}},"3":{"start":{"line":57,"column":12},"end":{"line":57,"column":35}},"4":{"start":{"line":58,"column":15},"end":{"line":58,"column":2288}},"5":{"start":{"line":62,"column":12},"end":{"line":62,"column":48}},"6":{"start":{"line":63,"column":15},"end":{"line":63,"column":2479}},"7":{"start":{"line":67,"column":12},"end":{"line":67,"column":53}},"8":{"start":{"line":68,"column":15},"end":{"line":68,"column":2680}},"9":{"start":{"line":72,"column":12},"end":{"line":72,"column":53}},"10":{"start":{"line":73,"column":15},"end":{"line":73,"column":2881}},"11":{"start":{"line":77,"column":12},"end":{"line":77,"column":51}},"12":{"start":{"line":78,"column":16},"end":{"line":78,"column":3079}},"13":{"start":{"line":82,"column":12},"end":{"line":82,"column":56}},"14":{"start":{"line":83,"column":15},"end":{"line":83,"column":3286}},"15":{"start":{"line":84,"column":12},"end":{"line":84,"column":77}},"16":{"start":{"line":86,"column":12},"end":{"line":86,"column":36}},"17":{"start":{"line":103,"column":9},"end":{"line":103,"column":83}},"18":{"start":{"line":104,"column":9},"end":{"line":104,"column":71}},"19":{"start":{"line":105,"column":9},"end":{"line":105,"column":4192}},"20":{"start":{"line":106,"column":12},"end":{"line":106,"column":29}},"21":{"start":{"line":107,"column":16},"end":{"line":107,"column":4312}},"22":{"start":{"line":108,"column":12},"end":{"line":108,"column":73}},"23":{"start":{"line":110,"column":12},"end":{"line":110,"column":71}},"24":{"start":{"line":120,"column":8},"end":{"line":120,"column":82}},"25":{"start":{"line":121,"column":8},"end":{"line":121,"column":4834}},"26":{"start":{"line":122,"column":12},"end":{"line":122,"column":92}},"27":{"start":{"line":124,"column":12},"end":{"line":124,"column":74}},"28":{"start":{"line":125,"column":12},"end":{"line":125,"column":5062}},"29":{"start":{"line":126,"column":16},"end":{"line":126,"column":33}},"30":{"start":{"line":127,"column":19},"end":{"line":127,"column":5190}},"31":{"start":{"line":128,"column":16},"end":{"line":128,"column":90}},"32":{"start":{"line":130,"column":16},"end":{"line":130,"column":75}},"33":{"start":{"line":147,"column":8},"end":{"line":147,"column":5893}},"34":{"start":{"line":148,"column":12},"end":{"line":148,"column":89}},"35":{"start":{"line":149,"column":15},"end":{"line":149,"column":6019}},"36":{"start":{"line":150,"column":12},"end":{"line":150,"column":84}},"37":{"start":{"line":151,"column":15},"end":{"line":151,"column":6136}},"38":{"start":{"line":152,"column":12},"end":{"line":152,"column":89}},"39":{"start":{"line":153,"column":15},"end":{"line":153,"column":6264}},"40":{"start":{"line":154,"column":12},"end":{"line":154,"column":87}},"41":{"start":{"line":157,"column":12},"end":{"line":157,"column":71}}},"branchMap":{"1":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":8},"end":{"line":56,"column":8}},{"start":{"line":56,"column":8},"end":{"line":56,"column":8}}]},"2":{"line":58,"type":"if","locations":[{"start":{"line":58,"column":15},"end":{"line":58,"column":15}},{"start":{"line":58,"column":15},"end":{"line":58,"column":15}}]},"3":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":15},"end":{"line":63,"column":15}},{"start":{"line":63,"column":15},"end":{"line":63,"column":15}}]},"4":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":15},"end":{"line":68,"column":15}},{"start":{"line":68,"column":15},"end":{"line":68,"column":15}}]},"5":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":15},"end":{"line":73,"column":15}},{"start":{"line":73,"column":15},"end":{"line":73,"column":15}}]},"6":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":16},"end":{"line":78,"column":16}},{"start":{"line":78,"column":16},"end":{"line":78,"column":16}}]},"7":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":15},"end":{"line":83,"column":15}},{"start":{"line":83,"column":15},"end":{"line":83,"column":15}}]},"8":{"line":105,"type":"if","locations":[{"start":{"line":105,"column":9},"end":{"line":105,"column":9}},{"start":{"line":105,"column":9},"end":{"line":105,"column":9}}]},"9":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":16},"end":{"line":107,"column":16}},{"start":{"line":107,"column":16},"end":{"line":107,"column":16}}]},"10":{"line":121,"type":"if","locations":[{"start":{"line":121,"column":8},"end":{"line":121,"column":8}},{"start":{"line":121,"column":8},"end":{"line":121,"column":8}}]},"11":{"line":125,"type":"if","locations":[{"start":{"line":125,"column":12},"end":{"line":125,"column":12}},{"start":{"line":125,"column":12},"end":{"line":125,"column":12}}]},"12":{"line":127,"type":"if","locations":[{"start":{"line":127,"column":19},"end":{"line":127,"column":19}},{"start":{"line":127,"column":19},"end":{"line":127,"column":19}}]},"13":{"line":147,"type":"if","locations":[{"start":{"line":147,"column":8},"end":{"line":147,"column":8}},{"start":{"line":147,"column":8},"end":{"line":147,"column":8}}]},"14":{"line":149,"type":"if","locations":[{"start":{"line":149,"column":15},"end":{"line":149,"column":15}},{"start":{"line":149,"column":15},"end":{"line":149,"column":15}}]},"15":{"line":151,"type":"if","locations":[{"start":{"line":151,"column":15},"end":{"line":151,"column":15}},{"start":{"line":151,"column":15},"end":{"line":151,"column":15}}]},"16":{"line":153,"type":"if","locations":[{"start":{"line":153,"column":15},"end":{"line":153,"column":15}},{"start":{"line":153,"column":15},"end":{"line":153,"column":15}}]}}},
+"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol":{"l":{"28":364,"29":361,"50":361,"51":358,"63":1009,"76":175,"88":1009,"89":240,"91":769,"101":175,"102":76,"104":99,"114":99,"115":99,"116":30,"118":69,"126":769,"127":769,"128":60,"130":709,"139":7282,"140":6851,"141":6851,"142":715,"143":703,"145":12},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol","s":{"1":364,"2":361,"3":358,"4":1009,"5":175,"6":1009,"7":240,"8":769,"9":175,"10":76,"11":99,"12":99,"13":99,"14":30,"15":69,"16":769,"17":769,"18":60,"19":709,"20":7282,"21":6851,"22":6851,"23":715,"24":703,"25":12},"b":{"1":[361,3],"2":[358,3],"3":[240,769],"4":[76,99],"5":[30,69],"6":[60,709],"7":[715,6136],"8":[703,12]},"f":{"1":364,"2":361,"3":1009,"4":175,"5":1009,"6":175,"7":99,"8":769,"9":7282},"fnMap":{"1":{"name":"onlyRuleEngineManager","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"setRuleEngine","line":49,"loc":{"start":{"line":47,"column":4},"end":{"line":52,"column":4}}},"3":{"name":"canTransfer","line":58,"loc":{"start":{"line":58,"column":4},"end":{"line":64,"column":4}}},"4":{"name":"canTransferFrom","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":77,"column":4}}},"5":{"name":"_canTransfer","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":93,"column":4}}},"6":{"name":"_canTransferFrom","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":106,"column":4}}},"7":{"name":"_canTransferFromWithRuleEngine","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":120,"column":4}}},"8":{"name":"_canTransferWithRuleEngine","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":132,"column":4}}},"9":{"name":"_transferred","line":138,"loc":{"start":{"line":138,"column":4},"end":{"line":148,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":39}},"2":{"start":{"line":50,"column":9},"end":{"line":50,"column":98}},"3":{"start":{"line":51,"column":8},"end":{"line":51,"column":34}},"4":{"start":{"line":63,"column":7},"end":{"line":63,"column":43}},"5":{"start":{"line":76,"column":8},"end":{"line":76,"column":57}},"6":{"start":{"line":88,"column":7},"end":{"line":88,"column":3016}},"7":{"start":{"line":89,"column":12},"end":{"line":89,"column":24}},"8":{"start":{"line":91,"column":12},"end":{"line":91,"column":62}},"9":{"start":{"line":101,"column":8},"end":{"line":101,"column":3371}},"10":{"start":{"line":102,"column":12},"end":{"line":102,"column":24}},"11":{"start":{"line":104,"column":12},"end":{"line":104,"column":75}},"12":{"start":{"line":114,"column":8},"end":{"line":114,"column":46}},"13":{"start":{"line":115,"column":8},"end":{"line":115,"column":3814}},"14":{"start":{"line":116,"column":12},"end":{"line":116,"column":72}},"15":{"start":{"line":118,"column":12},"end":{"line":118,"column":23}},"16":{"start":{"line":126,"column":8},"end":{"line":126,"column":46}},"17":{"start":{"line":127,"column":8},"end":{"line":127,"column":4193}},"18":{"start":{"line":128,"column":12},"end":{"line":128,"column":59}},"19":{"start":{"line":130,"column":12},"end":{"line":130,"column":23}},"20":{"start":{"line":139,"column":8},"end":{"line":139,"column":62}},"21":{"start":{"line":140,"column":8},"end":{"line":140,"column":46}},"22":{"start":{"line":141,"column":8},"end":{"line":141,"column":4745}},"23":{"start":{"line":142,"column":12},"end":{"line":142,"column":4802}},"24":{"start":{"line":143,"column":16},"end":{"line":143,"column":64}},"25":{"start":{"line":145,"column":16},"end":{"line":145,"column":55}}},"branchMap":{"1":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":21},"end":{"line":49,"column":21}},{"start":{"line":49,"column":21},"end":{"line":49,"column":21}}]},"2":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":9},"end":{"line":50,"column":9}},{"start":{"line":50,"column":9},"end":{"line":50,"column":9}}]},"3":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":7},"end":{"line":88,"column":7}},{"start":{"line":88,"column":7},"end":{"line":88,"column":7}}]},"4":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":8},"end":{"line":101,"column":8}},{"start":{"line":101,"column":8},"end":{"line":101,"column":8}}]},"5":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":8},"end":{"line":115,"column":8}},{"start":{"line":115,"column":8},"end":{"line":115,"column":8}}]},"6":{"line":127,"type":"if","locations":[{"start":{"line":127,"column":8},"end":{"line":127,"column":8}},{"start":{"line":127,"column":8},"end":{"line":127,"column":8}}]},"7":{"line":141,"type":"if","locations":[{"start":{"line":141,"column":8},"end":{"line":141,"column":8}},{"start":{"line":141,"column":8},"end":{"line":141,"column":8}}]},"8":{"line":142,"type":"if","locations":[{"start":{"line":142,"column":12},"end":{"line":142,"column":12}},{"start":{"line":142,"column":12},"end":{"line":142,"column":12}}]}}},
+"contracts/modules/wrapper/options/AllowlistModule.sol":{"l":{"25":978,"26":970,"37":4,"47":292,"57":532,"67":142,"68":142,"77":4,"84":1438,"91":2396,"92":2396},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/AllowlistModule.sol","s":{"1":978,"2":4,"3":292,"4":532,"5":142,"6":142,"7":4,"8":1438,"9":2396,"10":2396},"b":{"1":[4,2],"2":[292,4],"3":[532,2],"4":[142,0]},"f":{"1":978,"2":4,"3":292,"4":532,"5":142,"6":4,"7":1438,"8":2396},"fnMap":{"1":{"name":"onlyAllowlistManager","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"setAddressAllowlist","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":38,"column":4}}},"3":{"name":"setAddressAllowlist","line":46,"loc":{"start":{"line":44,"column":4},"end":{"line":48,"column":4}}},"4":{"name":"batchSetAddressAllowlist","line":56,"loc":{"start":{"line":54,"column":4},"end":{"line":58,"column":4}}},"5":{"name":"enableAllowlist","line":66,"loc":{"start":{"line":64,"column":4},"end":{"line":69,"column":4}}},"6":{"name":"isAllowlistEnabled","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":78,"column":4}}},"7":{"name":"isAllowlisted","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":85,"column":4}}},"8":{"name":"_addToAllowlist","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":93,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":38}},"2":{"start":{"line":37,"column":9},"end":{"line":37,"column":44}},"3":{"start":{"line":47,"column":9},"end":{"line":47,"column":46}},"4":{"start":{"line":57,"column":9},"end":{"line":57,"column":45}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":31}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":56}},"7":{"start":{"line":77,"column":8},"end":{"line":77,"column":36}},"8":{"start":{"line":84,"column":7},"end":{"line":84,"column":37}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":72}},"10":{"start":{"line":92,"column":8},"end":{"line":92,"column":73}}},"branchMap":{"1":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":78},"end":{"line":36,"column":78}},{"start":{"line":36,"column":78},"end":{"line":36,"column":78}}]},"2":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":21},"end":{"line":46,"column":21}},{"start":{"line":46,"column":21},"end":{"line":46,"column":21}}]},"3":{"line":56,"type":"if","locations":[{"start":{"line":56,"column":21},"end":{"line":56,"column":21}},{"start":{"line":56,"column":21},"end":{"line":56,"column":21}}]},"4":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":21},"end":{"line":66,"column":21}},{"start":{"line":66,"column":21},"end":{"line":66,"column":21}}]}}},
+"contracts/modules/wrapper/options/CCIPModule.sol":{"l":{"31":48,"32":36,"42":36,"43":36,"44":36,"46":24,"48":24,"55":24,"56":24,"67":60},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/CCIPModule.sol","s":{"1":48,"2":36,"3":36,"4":36,"5":24,"6":24,"7":24},"b":{"1":[36,12],"2":[24,12]},"f":{"1":48,"2":36,"3":24,"4":60},"fnMap":{"1":{"name":"onlyCCIPSetAdmin","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":33,"column":4}}},"2":{"name":"setCCIPAdmin","line":41,"loc":{"start":{"line":41,"column":2},"end":{"line":49,"column":2}}},"3":{"name":"getCCIPAdmin","line":54,"loc":{"start":{"line":54,"column":2},"end":{"line":57,"column":2}}},"4":{"name":"_getCCIPModuleStorage","line":66,"loc":{"start":{"line":66,"column":2},"end":{"line":70,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":31}},"2":{"start":{"line":42,"column":4},"end":{"line":42,"column":57}},"3":{"start":{"line":43,"column":4},"end":{"line":43,"column":40}},"4":{"start":{"line":44,"column":4},"end":{"line":44,"column":66}},"5":{"start":{"line":48,"column":4},"end":{"line":48,"column":53}},"6":{"start":{"line":55,"column":4},"end":{"line":55,"column":57}},"7":{"start":{"line":56,"column":4},"end":{"line":56,"column":24}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":57},"end":{"line":41,"column":57}},{"start":{"line":41,"column":57},"end":{"line":41,"column":57}}]},"2":{"line":44,"type":"if","locations":[{"start":{"line":44,"column":4},"end":{"line":44,"column":4}},{"start":{"line":44,"column":4},"end":{"line":44,"column":4}}]}}},
"contracts/modules/wrapper/options/DebtEngineModule.sol":{"l":{"28":18,"29":15,"48":15,"49":15,"50":12,"61":6,"62":6,"63":3,"74":6,"75":6,"76":3,"85":12,"86":12,"95":12,"96":12,"106":39},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtEngineModule.sol","s":{"1":18,"2":15,"3":15,"4":12,"5":6,"6":6,"7":6,"8":6,"9":12,"10":12,"11":12},"b":{"1":[15,3],"2":[12,3],"3":[3,3],"4":[3,3]},"f":{"1":18,"2":15,"3":6,"4":6,"5":12,"6":12,"7":39},"fnMap":{"1":{"name":"onlyDebtEngineManager","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"setDebtEngine","line":47,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"3":{"name":"creditEvents","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"debt","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"debtEngine","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":87,"column":4}}},"6":{"name":"_setDebtEngine","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":97,"column":4}}},"7":{"name":"_getDebtEngineModuleStorage","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":109,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":39}},"2":{"start":{"line":48,"column":8},"end":{"line":48,"column":67}},"3":{"start":{"line":49,"column":8},"end":{"line":49,"column":98}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":37}},"5":{"start":{"line":61,"column":8},"end":{"line":61,"column":67}},"6":{"start":{"line":62,"column":8},"end":{"line":62,"column":2681}},"7":{"start":{"line":74,"column":8},"end":{"line":74,"column":67}},"8":{"start":{"line":75,"column":8},"end":{"line":75,"column":3262}},"9":{"start":{"line":85,"column":8},"end":{"line":85,"column":67}},"10":{"start":{"line":86,"column":8},"end":{"line":86,"column":28}},"11":{"start":{"line":96,"column":8},"end":{"line":96,"column":36}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":49},"end":{"line":47,"column":49}},{"start":{"line":47,"column":49},"end":{"line":47,"column":49}}]},"2":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":8},"end":{"line":49,"column":8}},{"start":{"line":49,"column":8},"end":{"line":49,"column":8}}]},"3":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":8},"end":{"line":62,"column":8}},{"start":{"line":62,"column":8},"end":{"line":62,"column":8}}]},"4":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":8},"end":{"line":75,"column":8}},{"start":{"line":75,"column":8},"end":{"line":75,"column":8}}]}}},
"contracts/modules/wrapper/options/DebtModule.sol":{"l":{"30":24,"31":12,"47":4,"48":4,"49":4,"60":4,"61":4,"62":4,"73":4,"74":4,"75":4,"83":4,"84":4,"91":8,"92":8,"102":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtModule.sol","s":{"1":24,"2":4,"3":4,"4":4,"5":4,"6":4,"7":4,"8":4,"9":8},"b":{"1":[4,4],"2":[4,4],"3":[4,4]},"f":{"1":24,"2":4,"3":4,"4":4,"5":4,"6":8,"7":24},"fnMap":{"1":{"name":"onlyDebtManager","line":29,"loc":{"start":{"line":29,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"setCreditEvents","line":46,"loc":{"start":{"line":44,"column":4},"end":{"line":50,"column":4}}},"3":{"name":"setDebt","line":59,"loc":{"start":{"line":57,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"setDebtInstrument","line":72,"loc":{"start":{"line":70,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"creditEvents","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":85,"column":4}}},"6":{"name":"debt","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":93,"column":4}}},"7":{"name":"_getDebtModuleStorage","line":101,"loc":{"start":{"line":101,"column":4},"end":{"line":105,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":33}},"2":{"start":{"line":47,"column":8},"end":{"line":47,"column":61}},"3":{"start":{"line":49,"column":8},"end":{"line":49,"column":35}},"4":{"start":{"line":60,"column":8},"end":{"line":60,"column":61}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":27}},"6":{"start":{"line":73,"column":8},"end":{"line":73,"column":61}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":37}},"8":{"start":{"line":83,"column":8},"end":{"line":83,"column":61}},"9":{"start":{"line":91,"column":8},"end":{"line":91,"column":61}}},"branchMap":{"1":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":13},"end":{"line":46,"column":13}},{"start":{"line":46,"column":13},"end":{"line":46,"column":13}}]},"2":{"line":59,"type":"if","locations":[{"start":{"line":59,"column":43},"end":{"line":59,"column":43}},{"start":{"line":59,"column":43},"end":{"line":59,"column":43}}]},"3":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":43},"end":{"line":72,"column":43}},{"start":{"line":72,"column":43},"end":{"line":72,"column":43}}]}}},
-"contracts/modules/wrapper/options/ERC20CrossChainModule.sol":{"l":{"33":172,"34":112,"39":60,"40":30,"45":80,"46":40,"61":52,"62":42,"74":60,"75":40,"86":30,"87":30,"99":40,"101":40,"106":68,"114":30,"117":20,"118":20,"125":60,"128":30},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol","s":{"1":172,"2":60,"3":80,"4":52,"5":42,"6":60,"7":40,"8":30,"9":30,"10":40,"11":40,"12":68,"13":30,"14":20,"15":20,"16":60,"17":30},"b":{"1":[52,30],"2":[60,30],"3":[30,30],"4":[40,40],"5":[10,10]},"f":{"1":172,"2":60,"3":80,"4":52,"5":60,"6":30,"7":40,"8":68,"9":30,"10":60},"fnMap":{"1":{"name":"onlyTokenBridge","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":35,"column":4}}},"2":{"name":"onlyBurnerFrom","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"3":{"name":"onlySelfBurn","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":47,"column":4}}},"4":{"name":"crosschainMint","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":63,"column":4}}},"5":{"name":"crosschainBurn","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":76,"column":4}}},"6":{"name":"burnFrom","line":84,"loc":{"start":{"line":83,"column":4},"end":{"line":88,"column":4}}},"7":{"name":"burn","line":97,"loc":{"start":{"line":95,"column":4},"end":{"line":102,"column":4}}},"8":{"name":"supportsInterface","line":105,"loc":{"start":{"line":105,"column":4},"end":{"line":107,"column":4}}},"9":{"name":"_burnFrom","line":112,"loc":{"start":{"line":112,"column":4},"end":{"line":119,"column":4}}},"10":{"name":"_burn","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":129,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":36}},"2":{"start":{"line":39,"column":8},"end":{"line":39,"column":27}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":27}},"4":{"start":{"line":61,"column":8},"end":{"line":61,"column":31}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":51}},"6":{"start":{"line":74,"column":8},"end":{"line":74,"column":33}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":54}},"8":{"start":{"line":86,"column":8},"end":{"line":86,"column":38}},"9":{"start":{"line":87,"column":8},"end":{"line":87,"column":40}},"10":{"start":{"line":99,"column":8},"end":{"line":99,"column":37}},"11":{"start":{"line":101,"column":8},"end":{"line":101,"column":35}},"12":{"start":{"line":106,"column":8},"end":{"line":106,"column":110}},"13":{"start":{"line":114,"column":8},"end":{"line":114,"column":64}},"14":{"start":{"line":117,"column":8},"end":{"line":117,"column":58}},"15":{"start":{"line":118,"column":8},"end":{"line":118,"column":36}},"16":{"start":{"line":125,"column":8},"end":{"line":125,"column":36}},"17":{"start":{"line":128,"column":8},"end":{"line":128,"column":53}}},"branchMap":{"1":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":89},"end":{"line":60,"column":89}},{"start":{"line":60,"column":89},"end":{"line":60,"column":89}}]},"2":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":91},"end":{"line":73,"column":91}},{"start":{"line":73,"column":91},"end":{"line":73,"column":91}}]},"3":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":48},"end":{"line":84,"column":48}},{"start":{"line":84,"column":48},"end":{"line":84,"column":48}}]},"4":{"line":97,"type":"if","locations":[{"start":{"line":97,"column":46},"end":{"line":97,"column":46}},{"start":{"line":97,"column":46},"end":{"line":97,"column":46}}]},"5":{"line":106,"type":"cond-expr","locations":[{"start":{"line":106,"column":15},"end":{"line":106,"column":56}},{"start":{"line":106,"column":61},"end":{"line":106,"column":109}}]}}},
-"contracts/modules/wrapper/options/ERC2771Module.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC2771Module.sol","s":{},"b":{},"f":{"1":2541},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":22,"column":4}}}},"statementMap":{},"branchMap":{}},
+"contracts/modules/wrapper/options/DocumentEngineModule.sol":{"l":{"29":34,"30":29,"43":37,"44":6,"45":6,"57":15,"58":15,"65":9,"66":9,"67":6,"69":3,"77":5,"78":5,"79":2,"84":9,"85":9,"89":2,"90":2,"101":18,"102":18,"103":15,"113":21,"114":21,"122":64},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DocumentEngineModule.sol","s":{"1":34,"2":37,"3":6,"4":6,"5":15,"6":15,"7":9,"8":9,"9":6,"10":3,"11":5,"12":5,"13":9,"14":9,"15":2,"16":2,"17":18,"18":18,"19":15,"20":21},"b":{"1":[37,0],"2":[6,31],"3":[6,3],"4":[2,3],"5":[9,1],"6":[2,1],"7":[18,3],"8":[15,3]},"f":{"1":34,"2":37,"3":15,"4":9,"5":5,"6":9,"7":2,"8":18,"9":21,"10":64},"fnMap":{"1":{"name":"onlyDocumentManager","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"__DocumentEngineModule_init_unchained","line":42,"loc":{"start":{"line":41,"column":4},"end":{"line":47,"column":4}}},"3":{"name":"documentEngine","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":59,"column":4}}},"4":{"name":"getDocument","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":71,"column":4}}},"5":{"name":"getAllDocuments","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":81,"column":4}}},"6":{"name":"setDocument","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":86,"column":4}}},"7":{"name":"removeDocument","line":88,"loc":{"start":{"line":88,"column":4},"end":{"line":91,"column":4}}},"8":{"name":"setDocumentEngine","line":100,"loc":{"start":{"line":98,"column":4},"end":{"line":104,"column":4}}},"9":{"name":"_setDocumentEngine","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":115,"column":4}}},"10":{"name":"_getDocumentEngineModuleStorage","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":125,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":37}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":1712}},"3":{"start":{"line":44,"column":12},"end":{"line":44,"column":85}},"4":{"start":{"line":45,"column":12},"end":{"line":45,"column":49}},"5":{"start":{"line":57,"column":8},"end":{"line":57,"column":81}},"6":{"start":{"line":58,"column":8},"end":{"line":58,"column":32}},"7":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"8":{"start":{"line":66,"column":8},"end":{"line":66,"column":2654}},"9":{"start":{"line":67,"column":12},"end":{"line":67,"column":54}},"10":{"start":{"line":69,"column":12},"end":{"line":69,"column":39}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":3076}},"13":{"start":{"line":84,"column":8},"end":{"line":84,"column":81}},"14":{"start":{"line":85,"column":8},"end":{"line":85,"column":61}},"15":{"start":{"line":89,"column":8},"end":{"line":89,"column":81}},"16":{"start":{"line":90,"column":8},"end":{"line":90,"column":45}},"17":{"start":{"line":101,"column":8},"end":{"line":101,"column":81}},"18":{"start":{"line":102,"column":8},"end":{"line":102,"column":110}},"19":{"start":{"line":103,"column":8},"end":{"line":103,"column":45}},"20":{"start":{"line":114,"column":8},"end":{"line":114,"column":44}}},"branchMap":{"1":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":21},"end":{"line":42,"column":21}},{"start":{"line":42,"column":21},"end":{"line":42,"column":21}}]},"2":{"line":43,"type":"if","locations":[{"start":{"line":43,"column":8},"end":{"line":43,"column":8}},{"start":{"line":43,"column":8},"end":{"line":43,"column":8}}]},"3":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":8},"end":{"line":66,"column":8}},{"start":{"line":66,"column":8},"end":{"line":66,"column":8}}]},"4":{"line":78,"type":"if","locations":[{"start":{"line":78,"column":8},"end":{"line":78,"column":8}},{"start":{"line":78,"column":8},"end":{"line":78,"column":8}}]},"5":{"line":83,"type":"if","locations":[{"start":{"line":83,"column":116},"end":{"line":83,"column":116}},{"start":{"line":83,"column":116},"end":{"line":83,"column":116}}]},"6":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":76},"end":{"line":88,"column":76}},{"start":{"line":88,"column":76},"end":{"line":88,"column":76}}]},"7":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":53},"end":{"line":100,"column":53}},{"start":{"line":100,"column":53},"end":{"line":100,"column":53}}]},"8":{"line":102,"type":"if","locations":[{"start":{"line":102,"column":8},"end":{"line":102,"column":8}},{"start":{"line":102,"column":8},"end":{"line":102,"column":8}}]}}},
+"contracts/modules/wrapper/options/ERC20CrossChainModule.sol":{"l":{"33":266,"34":194,"39":96,"40":60,"45":96,"46":48,"61":86,"62":62,"74":108,"75":60,"86":60,"87":60,"98":48,"99":48,"104":84,"112":60,"115":48,"116":48,"120":96,"121":48},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol","s":{"1":266,"2":96,"3":96,"4":86,"5":62,"6":108,"7":60,"8":60,"9":60,"10":48,"11":48,"12":84,"13":60,"14":48,"15":48,"16":96,"17":48},"b":{"1":[86,36],"2":[108,36],"3":[60,36],"4":[48,48],"5":[12,12]},"f":{"1":266,"2":96,"3":96,"4":86,"5":108,"6":60,"7":48,"8":84,"9":60,"10":96},"fnMap":{"1":{"name":"onlyTokenBridge","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":35,"column":4}}},"2":{"name":"onlyBurnerFrom","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"3":{"name":"onlySelfBurn","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":47,"column":4}}},"4":{"name":"crosschainMint","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":63,"column":4}}},"5":{"name":"crosschainBurn","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":76,"column":4}}},"6":{"name":"burnFrom","line":84,"loc":{"start":{"line":83,"column":4},"end":{"line":88,"column":4}}},"7":{"name":"burn","line":97,"loc":{"start":{"line":95,"column":4},"end":{"line":100,"column":4}}},"8":{"name":"supportsInterface","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":105,"column":4}}},"9":{"name":"_burnFrom","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":117,"column":4}}},"10":{"name":"_burnFromOperator","line":119,"loc":{"start":{"line":119,"column":4},"end":{"line":122,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":36}},"2":{"start":{"line":39,"column":8},"end":{"line":39,"column":27}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":27}},"4":{"start":{"line":61,"column":8},"end":{"line":61,"column":31}},"5":{"start":{"line":62,"column":8},"end":{"line":62,"column":51}},"6":{"start":{"line":74,"column":8},"end":{"line":74,"column":33}},"7":{"start":{"line":75,"column":8},"end":{"line":75,"column":54}},"8":{"start":{"line":86,"column":8},"end":{"line":86,"column":38}},"9":{"start":{"line":87,"column":8},"end":{"line":87,"column":40}},"10":{"start":{"line":98,"column":8},"end":{"line":98,"column":37}},"11":{"start":{"line":99,"column":8},"end":{"line":99,"column":47}},"12":{"start":{"line":104,"column":8},"end":{"line":104,"column":110}},"13":{"start":{"line":112,"column":8},"end":{"line":112,"column":64}},"14":{"start":{"line":115,"column":8},"end":{"line":115,"column":58}},"15":{"start":{"line":116,"column":8},"end":{"line":116,"column":48}},"16":{"start":{"line":120,"column":8},"end":{"line":120,"column":36}},"17":{"start":{"line":121,"column":8},"end":{"line":121,"column":53}}},"branchMap":{"1":{"line":60,"type":"if","locations":[{"start":{"line":60,"column":89},"end":{"line":60,"column":89}},{"start":{"line":60,"column":89},"end":{"line":60,"column":89}}]},"2":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":91},"end":{"line":73,"column":91}},{"start":{"line":73,"column":91},"end":{"line":73,"column":91}}]},"3":{"line":84,"type":"if","locations":[{"start":{"line":84,"column":48},"end":{"line":84,"column":48}},{"start":{"line":84,"column":48},"end":{"line":84,"column":48}}]},"4":{"line":97,"type":"if","locations":[{"start":{"line":97,"column":46},"end":{"line":97,"column":46}},{"start":{"line":97,"column":46},"end":{"line":97,"column":46}}]},"5":{"line":104,"type":"cond-expr","locations":[{"start":{"line":104,"column":15},"end":{"line":104,"column":56}},{"start":{"line":104,"column":61},"end":{"line":104,"column":109}}]}}},
+"contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol":{"l":{"30":452,"39":432,"49":74,"50":74,"51":74,"52":74,"53":24,"55":74,"56":74,"66":48,"67":40,"77":32,"78":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol","s":{"1":452,"2":432,"3":74,"4":74,"5":74,"6":74,"7":24,"8":74,"9":74,"10":48,"11":40,"12":32,"13":24},"b":{"1":[74,0],"2":[24,50],"3":[48,0],"4":[32,0]},"f":{"1":452,"2":432,"3":74,"4":48,"5":32},"fnMap":{"1":{"name":"getFrozenTokens","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"getActiveBalanceOf","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":40,"column":4}}},"3":{"name":"forcedTransfer","line":48,"loc":{"start":{"line":47,"column":4},"end":{"line":57,"column":4}}},"4":{"name":"freezePartialTokens","line":65,"loc":{"start":{"line":64,"column":4},"end":{"line":68,"column":4}}},"5":{"name":"unfreezePartialTokens","line":76,"loc":{"start":{"line":75,"column":4},"end":{"line":79,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":62}},"2":{"start":{"line":39,"column":8},"end":{"line":39,"column":43}},"3":{"start":{"line":49,"column":8},"end":{"line":49,"column":59}},"4":{"start":{"line":50,"column":8},"end":{"line":50,"column":39}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":58}},"6":{"start":{"line":52,"column":8},"end":{"line":52,"column":1980}},"7":{"start":{"line":53,"column":12},"end":{"line":53,"column":124}},"8":{"start":{"line":55,"column":8},"end":{"line":55,"column":94}},"9":{"start":{"line":56,"column":8},"end":{"line":56,"column":19}},"10":{"start":{"line":66,"column":8},"end":{"line":66,"column":43}},"11":{"start":{"line":67,"column":8},"end":{"line":67,"column":88}},"12":{"start":{"line":77,"column":8},"end":{"line":77,"column":45}},"13":{"start":{"line":78,"column":8},"end":{"line":78,"column":90}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":54},"end":{"line":48,"column":54}},{"start":{"line":48,"column":54},"end":{"line":48,"column":54}}]},"2":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":8},"end":{"line":52,"column":8}},{"start":{"line":52,"column":8},"end":{"line":52,"column":8}}]},"3":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":54},"end":{"line":65,"column":54}},{"start":{"line":65,"column":54},"end":{"line":65,"column":54}}]},"4":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":54},"end":{"line":76,"column":54}},{"start":{"line":76,"column":54},"end":{"line":76,"column":54}}]}}},
+"contracts/modules/wrapper/options/ERC2771Module.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC2771Module.sol","s":{},"b":{},"f":{"1":3323},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":18,"column":4},"end":{"line":22,"column":4}}}},"statementMap":{},"branchMap":{}},
"contracts/modules/wrapper/options/ERC7551Module.sol":{"l":{"43":2,"44":2,"53":2,"54":2,"55":2,"60":4,"61":4,"68":2,"77":2,"78":2,"83":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC7551Module.sol","s":{"1":2,"2":2,"3":2,"4":2,"5":2,"6":4,"7":4,"8":2,"9":2},"b":{"1":[2,2],"2":[2,2]},"f":{"1":2,"2":2,"3":4,"4":2,"5":2,"6":6},"fnMap":{"1":{"name":"setMetaData","line":42,"loc":{"start":{"line":40,"column":4},"end":{"line":45,"column":4}}},"2":{"name":"setTerms","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":56,"column":4}}},"3":{"name":"metaData","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":62,"column":4}}},"4":{"name":"termsHash","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":69,"column":4}}},"5":{"name":"_setMetaData","line":74,"loc":{"start":{"line":74,"column":3},"end":{"line":79,"column":4}}},"6":{"name":"_getERC7551ModuleStorage","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":86,"column":4}}}},"statementMap":{"1":{"start":{"line":43,"column":8},"end":{"line":43,"column":67}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":34}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":94}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":24}},"5":{"start":{"line":55,"column":8},"end":{"line":55,"column":31}},"6":{"start":{"line":60,"column":8},"end":{"line":60,"column":67}},"7":{"start":{"line":61,"column":8},"end":{"line":61,"column":26}},"8":{"start":{"line":68,"column":8},"end":{"line":68,"column":39}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":32}}},"branchMap":{"1":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":48},"end":{"line":42,"column":48}},{"start":{"line":42,"column":48},"end":{"line":42,"column":48}}]},"2":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":101},"end":{"line":52,"column":101}},{"start":{"line":52,"column":101},"end":{"line":52,"column":101}}]}}},
-"contracts/modules/wrapper/security/AccessControlModule.sol":{"l":{"25":3945,"26":2,"31":3943,"45":13682,"46":8159,"48":5523},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol","s":{"1":3945,"2":3943,"3":13682,"4":8159,"5":5523},"b":{"1":[3945,0],"2":[2,3943],"3":[8159,5523]},"f":{"1":3945,"2":13682},"fnMap":{"1":{"name":"__AccessControlModule_init_unchained","line":24,"loc":{"start":{"line":23,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"hasRole","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":1015}},"2":{"start":{"line":31,"column":8},"end":{"line":31,"column":44}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":1867}},"4":{"start":{"line":46,"column":12},"end":{"line":46,"column":23}},"5":{"start":{"line":48,"column":12},"end":{"line":48,"column":66}}},"branchMap":{"1":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":13},"end":{"line":24,"column":13}},{"start":{"line":24,"column":13},"end":{"line":24,"column":13}}]},"2":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":8},"end":{"line":25,"column":8}},{"start":{"line":25,"column":8},"end":{"line":25,"column":8}}]},"3":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]}}}}
+"contracts/modules/wrapper/security/AccessControlModule.sol":{"l":{"25":5688,"26":2,"31":5686,"45":20013,"46":12061,"48":7952},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol","s":{"1":5688,"2":5686,"3":20013,"4":12061,"5":7952},"b":{"1":[5688,0],"2":[2,5686],"3":[12061,7952]},"f":{"1":5688,"2":20013},"fnMap":{"1":{"name":"__AccessControlModule_init_unchained","line":24,"loc":{"start":{"line":23,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"hasRole","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":1015}},"2":{"start":{"line":31,"column":8},"end":{"line":31,"column":44}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":1867}},"4":{"start":{"line":46,"column":12},"end":{"line":46,"column":23}},"5":{"start":{"line":48,"column":12},"end":{"line":48,"column":66}}},"branchMap":{"1":{"line":24,"type":"if","locations":[{"start":{"line":24,"column":13},"end":{"line":24,"column":13}},{"start":{"line":24,"column":13},"end":{"line":24,"column":13}}]},"2":{"line":25,"type":"if","locations":[{"start":{"line":25,"column":8},"end":{"line":25,"column":8}},{"start":{"line":25,"column":8},"end":{"line":25,"column":8}}]},"3":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]}}}}
diff --git a/doc/test/coverage/deployment/CMTATStandalone.sol.html b/doc/test/coverage/deployment/CMTATStandardStandalone.sol.html
similarity index 91%
rename from doc/test/coverage/deployment/CMTATStandalone.sol.html
rename to doc/test/coverage/deployment/CMTATStandardStandalone.sol.html
index c1244778..b8576a0c 100644
--- a/doc/test/coverage/deployment/CMTATStandalone.sol.html
+++ b/doc/test/coverage/deployment/CMTATStandardStandalone.sol.html
@@ -1,7 +1,7 @@
- Code coverage report for deployment/CMTATStandalone.sol
+ Code coverage report for deployment/CMTATStandardStandalone.sol
@@ -16,7 +16,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseERC2771} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
/**
-* @title CMTAT version for a standalone deployment (without proxy)
+* @title CMTAT standard version for a standalone deployment (without proxy) — no snapshot engine
*/
-contract CMTATStandalone is CMTATBaseERC2771 {
+contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement {
/**
* @notice Contract version for standalone deployment
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -163,7 +163,7 @@
diff --git a/doc/test/coverage/deployment/CMTATUpgradeable.sol.html b/doc/test/coverage/deployment/CMTATStandardUpgradeable.sol.html
similarity index 88%
rename from doc/test/coverage/deployment/CMTATUpgradeable.sol.html
rename to doc/test/coverage/deployment/CMTATStandardUpgradeable.sol.html
index 0021c410..eb0eff88 100644
--- a/doc/test/coverage/deployment/CMTATUpgradeable.sol.html
+++ b/doc/test/coverage/deployment/CMTATStandardUpgradeable.sol.html
@@ -1,7 +1,7 @@
- Code coverage report for deployment/CMTATUpgradeable.sol
+ Code coverage report for deployment/CMTATStandardUpgradeable.sol
@@ -16,7 +16,7 @@
//SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;
-import {CMTATBaseERC2771} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
/**
-* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
+* @title CMTAT standard version for a proxy deployment (Transparent or Beacon proxy) — no snapshot engine
*/
-contract CMTATUpgradeable is CMTATBaseERC2771 {
+contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement {
/**
* @notice Contract version for the deployment with a proxy
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -121,7 +121,7 @@
pragma solidity ^0.8.20;
import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
-import {CMTATBaseERC7551} from "../../modules/6_CMTATBaseERC7551.sol";
+import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol";
/**
* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
@@ -118,7 +118,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseDebt} from "../../modules/3_CMTATBaseDebt.sol";
+import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT version for a standalone deployment (without proxy)
@@ -148,7 +148,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseDebtEngine} from "../../modules/5_CMTATBaseDebtEngine.sol";
+import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT version for a standalone deployment (without proxy)
@@ -148,7 +148,7 @@
//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol";
+
+/**
+* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy) with Permit and Multicall
+*/
+contract CMTATUpgradeablePermit is CMTATBaseERC2612 {
+ /**
+ * @notice Contract version for the deployment with a proxy
+ */
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor() {
+ // Disable the possibility to initialize the implementation
+ _disableInitializers();
+ }
+}
+
/* ============ Events ============ */
/**
* @notice Emitted when a `spender` spends a `value` amount of tokens on behalf of an `account`.
- * @dev
+ * @dev
* - This event is similar in semantics to the ERC-20 `Approval` event.
* Approval(address indexed _owner, address indexed _spender, uint256 _value)
* - It represents a reduction in the spender’s allowance granted by the account.
* - Can also be used for function which uses the allowance, e.g.`burnFrom
+ * - This event is NOT emitted when the allowance is infinite (type(uint256).max),
+ * because in that case OpenZeppelin does not reduce the allowance.
+ * Integrators must not rely solely on this event to track allowance changes
+ * when infinite approvals are in use.
* @param account The owner of the tokens whose allowance is being spent.
* @param spender The address authorized to spend the tokens.
* @param value The amount of tokens that were spent.
@@ -121,7 +133,7 @@
* Batch version of {burn}.
* - For each burn, emits a `Transfer` event to the zero address.
* - Emits a `burnBatch` event
- * - The `data` parameter applies uniformly to all burn operations in this batch.
+ * - The `data` parameter is batch-level metadata for the `BatchBurn` event.
+ * - It is not forwarded to each individual burn item.
* - Requirements:
* - `accounts.length` must equal `values.length`.
* @param accounts The list of addresses whose tokens will be burned.
@@ -427,13 +432,14 @@
* @dev This function is restricted to authorized roles.
*/
function burn(uint256 value) external;
-}
pragma solidity ^0.8.20;
-import {IERC1643CMTAT, IERC1643} from "./draft-IERC1643CMTAT.sol";
+import {IERC1643CMTAT} from "./draft-IERC1643CMTAT.sol";
+import {IERC1643} from "./draft-IERC1643.sol";
/**
* The issuer must be able to “deactivate” the smart contract, to prevent execution of transactions on
@@ -467,7 +476,12 @@
* @notice Emitted when the contract is permanently deactivated.
* @param account The address that performed the deactivation.
*/
- event Deactivated(address account);
+ event Deactivated(address indexed account);
+
+ /**
+ * @notice Error raised when deactivation is attempted after deactivation is already final.
+ */
+ error AlreadyDeactivated();
/*
* @notice Permanently deactivates the contract.
@@ -632,15 +646,13 @@
* @dev For event definitions, see {IERC7551ERC20Enforcement}.
*/
interface IERC3643ERC20Enforcement is IERC7943FungibleEnforcement {
+ /**
+ * @dev Emitted when a certain amount of tokens is frozen on a wallet.
+ * This event is emitted by `freezePartialTokens` and `batchFreezePartialTokens`.
+ * @param account The wallet address impacted by the freezing status.
+ * @param value The amount of tokens that is frozen.
+ */
+ event TokensFrozen(address indexed account, uint256 value);
+
+ /**
+ * @dev Emitted when a certain amount of tokens is unfrozen on a wallet.
+ * This event is emitted by `unfreezePartialTokens` and `batchUnfreezePartialTokens`.
+ * @param account The wallet address impacted by the freezing status.
+ * @param value The amount of tokens that is unfrozen.
+ */
+ event TokensUnfrozen(address indexed account, uint256 value);
/* ============ State Functions ============ */
/**
* @notice Freezes a specific amount of tokens for a given account.
@@ -900,14 +943,13 @@
*/
function transferred(address from, address to, uint256 value) external;
}
-
* @param name The unique name used to identify the document.
* @return document The associated document's metadata (URI, hash, timestamp).
*/
- function getDocument(string memory name) external view returns (Document memory document);
+ function getDocument(bytes32 name) external view returns (Document memory document);
/**
* @notice Returns the list of all document names registered in the contract.
* @return documentNames_ An array of strings representing all document identifiers.
*/
- function getAllDocuments() external view returns (string[] memory documentNames_);
-}
}
interface IERC7551ERC20EnforcementEvent {
/**
- * @notice Emitted when a forced transfer or burn occurs.
- * @param enforcer The address that initiated the enforcement.
- * @param account The address affected by the enforcement.
- * @param amount The number of tokens involved.
- * @param data Additional data related to the enforcement.
+ * @notice Emitted when a forced transfer is executed.
+ * @param operator The address that initiated the forced transfer.
+ * @param from The address from which tokens are debited.
+ * @param to The address to which tokens are credited.
+ * @param value The amount of tokens transferred.
+ * @param data Optional metadata associated with the action.
*/
- event Enforcement (address indexed enforcer, address indexed account, uint256 amount, bytes data);
+ event ForcedTransfer(address indexed operator, address indexed from, address indexed to, uint256 value, bytes data);
}
interface IERC7551ERC20EnforcementTokenFrozenEvent {
@@ -640,13 +645,14 @@
* @param metaData_ The new metadata value.
*/
function setMetaData(string calldata metaData_) external;
-}
}
/**
-* @notice Transfer Error Interface for ERC-20, ERC-721 and ERC-1155 based implementations.
-*
+* @notice Send/Receive Error Interface for ERC-20 based implementations.
+*
*/
-interface IERC7943TransactError{
+interface IERC7943FungibleSendReceiveError {
+ /**
+ * @notice Error reverted when an account is not allowed to send tokens.
+ * @param account The address of the account which is not allowed to send.
+ */
+ error ERC7943CannotSend(address account);
+
/**
- * @notice Error reverted when an account is not allowed to transact.
- * @param account The address of the account which is not allowed for transfers.
- */
- error ERC7943CannotTransact(address account);
+ * @notice Error reverted when an account is not allowed to receive tokens.
+ * @param account The address of the account which is not allowed to receive.
+ */
+ error ERC7943CannotReceive(address account);
}
/**
* @notice Transfer Error Interface for ERC-20 based implementations.
-*
+*
*/
interface IERC7943FungibleTransferError {
- /**
- * @notice Error reverted when a transfer is not allowed according to internal rules.
+ /**
+ * @notice Error reverted when a transfer is not allowed according to internal rules.
* @param from The address from which tokens are being sent.
* @param to The address to which tokens are being sent.
* @param amount The amount sent.
@@ -399,12 +429,18 @@
error ERC7943CannotTransfer(address from, address to, uint256 amount);
}
-interface IERC7943TransactCheck{
- /// @notice Checks if a specific account is allowed to transact according to token rules.
+interface IERC7943FungibleSendReceiveCheck {
+ /// @notice Checks if a specific account is allowed to send tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to send, false otherwise.
+ function canSend(address account) external view returns (bool allowed);
+
+ /// @notice Checks if a specific account is allowed to receive tokens according to token rules.
/// @dev This is often used for allowlist/KYC/KYB/AML checks.
/// @param account The address to check.
- /// @return allowed True if the account is allowed, false otherwise.
- function canTransact(address account) external view returns (bool allowed);
+ /// @return allowed True if the account is allowed to receive, false otherwise.
+ function canReceive(address account) external view returns (bool allowed);
}
@@ -415,7 +451,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseERC2771} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
/**
-* @title CMTAT version for a standalone deployment (without proxy)
+* @title CMTAT standard version for a standalone deployment (without proxy) — no snapshot engine
*/
-contract CMTATStandalone is CMTATBaseERC2771 {
+contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement {
/**
* @notice Contract version for standalone deployment
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -163,7 +163,7 @@
diff --git a/doc/test/coverage/lcov-report/deployment/CMTATUpgradeable.sol.html b/doc/test/coverage/lcov-report/deployment/CMTATStandardUpgradeable.sol.html
similarity index 88%
rename from doc/test/coverage/lcov-report/deployment/CMTATUpgradeable.sol.html
rename to doc/test/coverage/lcov-report/deployment/CMTATStandardUpgradeable.sol.html
index 0021c410..eb0eff88 100644
--- a/doc/test/coverage/lcov-report/deployment/CMTATUpgradeable.sol.html
+++ b/doc/test/coverage/lcov-report/deployment/CMTATStandardUpgradeable.sol.html
@@ -1,7 +1,7 @@
- Code coverage report for deployment/CMTATUpgradeable.sol
+ Code coverage report for deployment/CMTATStandardUpgradeable.sol
@@ -16,7 +16,7 @@
//SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;
-import {CMTATBaseERC2771} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
/**
-* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
+* @title CMTAT standard version for a proxy deployment (Transparent or Beacon proxy) — no snapshot engine
*/
-contract CMTATUpgradeable is CMTATBaseERC2771 {
+contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement {
/**
* @notice Contract version for the deployment with a proxy
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -121,7 +121,7 @@
pragma solidity ^0.8.20;
import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
-import {CMTATBaseERC7551} from "../../modules/6_CMTATBaseERC7551.sol";
+import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol";
/**
* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
@@ -118,7 +118,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseDebt} from "../../modules/3_CMTATBaseDebt.sol";
+import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT version for a standalone deployment (without proxy)
@@ -148,7 +148,7 @@
pragma solidity ^0.8.20;
-import {CMTATBaseDebtEngine} from "../../modules/5_CMTATBaseDebtEngine.sol";
+import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol";
import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT version for a standalone deployment (without proxy)
@@ -148,7 +148,7 @@
//SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol";
+
+/**
+* @title CMTAT version for a proxy deployment (Transparent or Beacon proxy) with Permit and Multicall
+*/
+contract CMTATUpgradeablePermit is CMTATBaseERC2612 {
+ /**
+ * @notice Contract version for the deployment with a proxy
+ */
+ /// @custom:oz-upgrades-unsafe-allow constructor
+ constructor() {
+ // Disable the possibility to initialize the implementation
+ _disableInitializers();
+ }
+}
+
/* ============ Events ============ */
/**
* @notice Emitted when a `spender` spends a `value` amount of tokens on behalf of an `account`.
- * @dev
+ * @dev
* - This event is similar in semantics to the ERC-20 `Approval` event.
* Approval(address indexed _owner, address indexed _spender, uint256 _value)
* - It represents a reduction in the spender’s allowance granted by the account.
* - Can also be used for function which uses the allowance, e.g.`burnFrom
+ * - This event is NOT emitted when the allowance is infinite (type(uint256).max),
+ * because in that case OpenZeppelin does not reduce the allowance.
+ * Integrators must not rely solely on this event to track allowance changes
+ * when infinite approvals are in use.
* @param account The owner of the tokens whose allowance is being spent.
* @param spender The address authorized to spend the tokens.
* @param value The amount of tokens that were spent.
@@ -121,7 +133,7 @@
* Batch version of {burn}.
* - For each burn, emits a `Transfer` event to the zero address.
* - Emits a `burnBatch` event
- * - The `data` parameter applies uniformly to all burn operations in this batch.
+ * - The `data` parameter is batch-level metadata for the `BatchBurn` event.
+ * - It is not forwarded to each individual burn item.
* - Requirements:
* - `accounts.length` must equal `values.length`.
* @param accounts The list of addresses whose tokens will be burned.
@@ -427,13 +432,14 @@
* @dev This function is restricted to authorized roles.
*/
function burn(uint256 value) external;
-}
pragma solidity ^0.8.20;
-import {IERC1643CMTAT, IERC1643} from "./draft-IERC1643CMTAT.sol";
+import {IERC1643CMTAT} from "./draft-IERC1643CMTAT.sol";
+import {IERC1643} from "./draft-IERC1643.sol";
/**
* The issuer must be able to “deactivate” the smart contract, to prevent execution of transactions on
@@ -467,7 +476,12 @@
* @notice Emitted when the contract is permanently deactivated.
* @param account The address that performed the deactivation.
*/
- event Deactivated(address account);
+ event Deactivated(address indexed account);
+
+ /**
+ * @notice Error raised when deactivation is attempted after deactivation is already final.
+ */
+ error AlreadyDeactivated();
/*
* @notice Permanently deactivates the contract.
@@ -632,15 +646,13 @@
* @dev For event definitions, see {IERC7551ERC20Enforcement}.
*/
interface IERC3643ERC20Enforcement is IERC7943FungibleEnforcement {
+ /**
+ * @dev Emitted when a certain amount of tokens is frozen on a wallet.
+ * This event is emitted by `freezePartialTokens` and `batchFreezePartialTokens`.
+ * @param account The wallet address impacted by the freezing status.
+ * @param value The amount of tokens that is frozen.
+ */
+ event TokensFrozen(address indexed account, uint256 value);
+
+ /**
+ * @dev Emitted when a certain amount of tokens is unfrozen on a wallet.
+ * This event is emitted by `unfreezePartialTokens` and `batchUnfreezePartialTokens`.
+ * @param account The wallet address impacted by the freezing status.
+ * @param value The amount of tokens that is unfrozen.
+ */
+ event TokensUnfrozen(address indexed account, uint256 value);
/* ============ State Functions ============ */
/**
* @notice Freezes a specific amount of tokens for a given account.
@@ -900,14 +943,13 @@
*/
function transferred(address from, address to, uint256 value) external;
}
-
* @param name The unique name used to identify the document.
* @return document The associated document's metadata (URI, hash, timestamp).
*/
- function getDocument(string memory name) external view returns (Document memory document);
+ function getDocument(bytes32 name) external view returns (Document memory document);
/**
* @notice Returns the list of all document names registered in the contract.
* @return documentNames_ An array of strings representing all document identifiers.
*/
- function getAllDocuments() external view returns (string[] memory documentNames_);
-}
}
interface IERC7551ERC20EnforcementEvent {
/**
- * @notice Emitted when a forced transfer or burn occurs.
- * @param enforcer The address that initiated the enforcement.
- * @param account The address affected by the enforcement.
- * @param amount The number of tokens involved.
- * @param data Additional data related to the enforcement.
+ * @notice Emitted when a forced transfer is executed.
+ * @param operator The address that initiated the forced transfer.
+ * @param from The address from which tokens are debited.
+ * @param to The address to which tokens are credited.
+ * @param value The amount of tokens transferred.
+ * @param data Optional metadata associated with the action.
*/
- event Enforcement (address indexed enforcer, address indexed account, uint256 amount, bytes data);
+ event ForcedTransfer(address indexed operator, address indexed from, address indexed to, uint256 value, bytes data);
}
interface IERC7551ERC20EnforcementTokenFrozenEvent {
@@ -640,13 +645,14 @@
* @param metaData_ The new metadata value.
*/
function setMetaData(string calldata metaData_) external;
-}
}
/**
-* @notice Transfer Error Interface for ERC-20, ERC-721 and ERC-1155 based implementations.
-*
+* @notice Send/Receive Error Interface for ERC-20 based implementations.
+*
*/
-interface IERC7943TransactError{
+interface IERC7943FungibleSendReceiveError {
+ /**
+ * @notice Error reverted when an account is not allowed to send tokens.
+ * @param account The address of the account which is not allowed to send.
+ */
+ error ERC7943CannotSend(address account);
+
/**
- * @notice Error reverted when an account is not allowed to transact.
- * @param account The address of the account which is not allowed for transfers.
- */
- error ERC7943CannotTransact(address account);
+ * @notice Error reverted when an account is not allowed to receive tokens.
+ * @param account The address of the account which is not allowed to receive.
+ */
+ error ERC7943CannotReceive(address account);
}
/**
* @notice Transfer Error Interface for ERC-20 based implementations.
-*
+*
*/
interface IERC7943FungibleTransferError {
- /**
- * @notice Error reverted when a transfer is not allowed according to internal rules.
+ /**
+ * @notice Error reverted when a transfer is not allowed according to internal rules.
* @param from The address from which tokens are being sent.
* @param to The address to which tokens are being sent.
* @param amount The amount sent.
@@ -399,12 +429,18 @@
error ERC7943CannotTransfer(address from, address to, uint256 amount);
}
-interface IERC7943TransactCheck{
- /// @notice Checks if a specific account is allowed to transact according to token rules.
+interface IERC7943FungibleSendReceiveCheck {
+ /// @notice Checks if a specific account is allowed to send tokens according to token rules.
+ /// @dev This is often used for allowlist/KYC/KYB/AML checks.
+ /// @param account The address to check.
+ /// @return allowed True if the account is allowed to send, false otherwise.
+ function canSend(address account) external view returns (bool allowed);
+
+ /// @notice Checks if a specific account is allowed to receive tokens according to token rules.
/// @dev This is often used for allowlist/KYC/KYB/AML checks.
/// @param account The address to check.
- /// @return allowed True if the account is allowed, false otherwise.
- function canTransact(address account) external view returns (bool allowed);
+ /// @return allowed True if the account is allowed to receive, false otherwise.
+ function canReceive(address account) external view returns (bool allowed);
}
@@ -415,7 +451,7 @@
ERC20Upgradeable._transfer(from, to, value);
return true;
}
- /*
+ /**
* @inheritdoc ERC20BaseModule
*/
function transferFrom(
@@ -531,35 +458,6 @@
function _checkTransferred(address /*spender*/, address from, address /* to */, uint256 value) internal virtual {
ERC20EnforcementModuleInternal._checkActiveBalanceAndRevert(from, value);
}
- /**
- * @dev we don't check the transfer validity here
- *
- *
- */
- function _update(
- address from,
- address to,
- uint256 amount
- ) internal virtual override(ERC20Upgradeable) {
- // We check here the address of the snapshotEngine here because we don't want to read balance/totalSupply if there is no Snapshot Engine
- ISnapshotEngine snapshotEngineLocal = snapshotEngine();
-
- if(address(snapshotEngineLocal) != address(0)){
- uint256 fromBalanceBefore = balanceOf(from);
- uint256 toBalanceBefore = balanceOf(to);
- uint256 totalSupplyBefore = totalSupply();
-
- // We perform the update here (CEI pattern)
- ERC20Upgradeable._update(from, to, amount);
-
- // Required to use the balance before the update
- snapshotEngineLocal.operateOnTransfer(from, to, fromBalanceBefore, toBalanceBefore, totalSupplyBefore);
- } else {
- // Update without snapshot call
- ERC20Upgradeable._update(from, to, amount);
- }
- }
-
/* ==== Mint and Burn Operations ==== */
/**
@@ -568,7 +466,7 @@
* Check if the mint is valid
*/
function _mintOverride(address account, uint256 value) internal virtual override(ERC20MintModuleInternal) {
- _checkTransferred(address(0), address(0), account, value);
+ _checkTransferred(_msgSender(), address(0), account, value);
ERC20MintModuleInternal._mintOverride(account, value);
}
@@ -578,7 +476,7 @@
* Check if the burn is valid
*/
function _burnOverride(address account, uint256 value) internal virtual override(ERC20BurnModuleInternal) {
- _checkTransferred(address(0), account, address(0), value);
+ _checkTransferred(_msgSender(), account, address(0), value);
ERC20BurnModuleInternal._burnOverride(account, value);
}
@@ -588,7 +486,7 @@
* Check if a minter transfer is valid
*/
function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(ERC20MintModuleInternal) {
- _checkTransferred(address(0), from, to, value);
+ _checkTransferred(_msgSender(), from, to, value);
ERC20MintModuleInternal._minterTransferOverride(from, to, value);
}
}
@@ -598,7 +496,7 @@
* @dev
* We can not use type(IERC5679).interfaceId, we use instead of 0xd0017968
* because IERC5679 inherits from two interfaces (IERC5679Burn and Mint)
- * Core version does not implement in its integrality ERC-7943 (0x29388973)
+ * Core version does not implement in its integrality ERC-7943 (0x3edbb4c4)
+ * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) {
- return interfaceId == 0xd0017968 || AccessControlUpgradeable.supportsInterface(interfaceId);
+ return interfaceId == 0xd0017968 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId);
}
/* ============ State Functions ============ */
@@ -764,6 +786,14 @@
// Extensions
import {ExtraInformationModule} from "./wrapper/extensions/ExtraInformationModule.sol";
import {ERC20EnforcementModule} from "./wrapper/extensions/ERC20EnforcementModule.sol";
-import {DocumentEngineModule, IERC1643} from "./wrapper/extensions/DocumentEngineModule.sol";
-import {SnapshotEngineModule} from "./wrapper/extensions/SnapshotEngineModule.sol";
+import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol";
// options
-import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol";
+import {ERC20BaseModule} from "./wrapper/core/ERC20BaseModule.sol";
/* ==== Interface and other library === */
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
+import {CMTATBaseDocument} from "./1_CMTATBaseDocument.sol";
abstract contract CMTATBaseAccessControl is
AccessControlModule,
- CMTATBaseCommon
+ CMTATBaseCommon,
+ CMTATBaseDocument
{
+
/*//////////////////////////////////////////////////////////////
INITIALIZER FUNCTION
//////////////////////////////////////////////////////////////*/
@@ -301,10 +299,11 @@
* @dev
* We can not use type(IERC5679).interfaceId instead of 0xd0017968
* because IERC5679 inherits from two interfaces (IERC5679Burn and Mint)
- * 0x29388973 is the interfaceId of ERC-7943
+ * 0x3edbb4c4 is the interfaceId of ERC-7943
+ * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) {
- return interfaceId == 0xd0017968 || interfaceId == 0x29388973 || AccessControlUpgradeable.supportsInterface(interfaceId);
+ return interfaceId == 0xd0017968 || interfaceId == 0x3edbb4c4 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId);
}
@@ -335,7 +334,7 @@
* @custom:access-control
* - the caller must have the `DOCUMENT_ROLE`.
*/
- function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) onlyRole(DOCUMENT_ROLE){}
+ function _authorizeDocumentManagement() internal virtual override(DocumentERC1643Module) onlyRole(DOCUMENT_ROLE){}
/**
* @custom:access-control
@@ -355,11 +354,6 @@
*/
function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) onlyRole(DEFAULT_ADMIN_ROLE){}
- /**
- * @custom:access-control
- * - the caller must have the `SNAPSHOOTER_ROLE`.
- */
- function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE){}
}
@@ -367,7 +361,7 @@
diff --git a/doc/test/coverage/modules/2_CMTATBaseAllowlist.sol.html b/doc/test/coverage/lcov-report/modules/3_CMTATBaseAllowlist.sol.html
similarity index 71%
rename from doc/test/coverage/modules/2_CMTATBaseAllowlist.sol.html
rename to doc/test/coverage/lcov-report/modules/3_CMTATBaseAllowlist.sol.html
index d26094db..440d207a 100644
--- a/doc/test/coverage/modules/2_CMTATBaseAllowlist.sol.html
+++ b/doc/test/coverage/lcov-report/modules/3_CMTATBaseAllowlist.sol.html
@@ -1,7 +1,7 @@
- Code coverage report for modules/2_CMTATBaseAllowlist.sol
+ Code coverage report for modules/3_CMTATBaseAllowlist.sol
@@ -16,13 +16,13 @@
//////////////////////////////////////////////////////////////*/
/**
* @dev revert if the contract is in pause state
+ * @notice Changing a non-zero allowance to another non-zero value carries the standard
+ * ERC-20 allowance race condition: a spender who observes the pending transaction can
+ * front-run it and spend the old allowance before the new value takes effect.
+ * To avoid this, callers should set the allowance to zero before assigning a new value
+ * if strict control over the total amount a spender can consume is required.
*/
function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) {
+ _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender);
return ERC20Upgradeable.approve(spender, value);
}
+
+ function transfer(address to, uint256 value)
+ public
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (bool)
+ {
+ return CMTATBaseCommon.transfer(to, value);
+ }
+
+ function transferFrom(address from, address to, uint256 value)
+ public
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (bool)
+ {
+ return CMTATBaseCommon.transferFrom(from, to, value);
+ }
+
+ function decimals()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (uint8)
+ {
+ return CMTATBaseCommon.decimals();
+ }
+
+ function name()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (string memory)
+ {
+ return CMTATBaseCommon.name();
+ }
+
+ function symbol()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (string memory)
+ {
+ return CMTATBaseCommon.symbol();
+ }
/**
* @inheritdoc ValidationModuleCore
@@ -687,6 +910,12 @@
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
/* ==== Wrapper === */
// Core
-import {CMTATBaseAccessControl} from "./1_CMTATBaseAccessControl.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
import {PauseModule} from "./wrapper/core/PauseModule.sol";
import {EnforcementModule} from "./wrapper/core/EnforcementModule.sol";
// Extensions
-import {ERC20EnforcementModule, ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
+import {ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
// Controllers
import {ValidationModuleRuleEngine} from "./wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
@@ -531,6 +533,7 @@
* @dev revert if the contract is in pause state
*/
function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) {
+ _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender);
return ERC20Upgradeable.approve(spender, value);
}
/**
@@ -589,7 +592,7 @@
// SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;
/* ==== OpenZeppelin === */
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
/* ==== Module === */
-import {CMTATBaseERC1404, CMTATBaseRuleEngine, ERC20Upgradeable} from "./3_CMTATBaseERC1404.sol";
-import {CMTATBaseAccessControl} from "./1_CMTATBaseAccessControl.sol";
+import {CMTATBaseERC1404, CMTATBaseRuleEngine, ERC20Upgradeable} from "./4_CMTATBaseERC1404.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
-import {ERC20BurnModule, ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol";
-import {ERC20MintModule, ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol";
+import {ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol";
+import {ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol";
import {ERC20CrossChainModule} from "./wrapper/options/ERC20CrossChainModule.sol";
import {CCIPModule} from "./wrapper/options/CCIPModule.sol";
@@ -427,7 +413,7 @@
* @dev Check if the mint is valid
*/
function _mintOverride(address account, uint256 value) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
- CMTATBaseRuleEngine._checkTransferred(address(0), address(0), account, value);
+ // _checkTransferred is called by _mintOverride
CMTATBaseCommon._mintOverride(account, value);
}
@@ -435,7 +421,7 @@
* @dev Check if the burn is valid
*/
function _burnOverride(address account, uint256 value) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) {
- CMTATBaseRuleEngine._checkTransferred(address(0), account, address(0), value);
+ // _checkTransferred is called by _burnOverride
CMTATBaseCommon._burnOverride(account, value);
}
@@ -443,7 +429,7 @@
* @dev Check if a minter transfer is valid
*/
function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
- CMTATBaseRuleEngine._checkTransferred(address(0), from, to, value);
+ // _checkTransferred is called by _minterTransferOverride
CMTATBaseCommon._minterTransferOverride(from, to, value);
}
@@ -475,28 +461,21 @@
*/
function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{}
- /**
+ /**
* @custom:access-control
- * - the caller must have the `BURNER_FROM_ROLE`.
+ * - the caller must have the `BURNER_SELF_ROLE`.
* - We don't allow token holder to burn their own tokens if they don't have this role.
*/
function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{}
- /* ==== ERC-20 OpenZeppelin ==== */
- function _update(
- address from,
- address to,
- uint256 amount
- ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) {
- return CMTATBaseCommon._update(from, to, amount);
- }
-}
import {ERC1363Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC1363Upgradeable.sol";
import {ERC20Upgradeable, IERC20} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
/* ==== Module === */
-import {CMTATBaseRuleEngine} from "./2_CMTATBaseRuleEngine.sol";
-import {CMTATBaseERC2771, CMTATBaseERC20CrossChain} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseRuleEngine} from "./3_CMTATBaseRuleEngine.sol";
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseERC7551Enforcement} from "./7_CMTATBaseERC7551Enforcement.sol";
/* ==== Interface and other library === */
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT Base for ERC-1363
*/
-abstract contract CMTATBaseERC1363 is ERC1363Upgradeable,CMTATBaseERC2771{
+abstract contract CMTATBaseERC1363 is ERC1363Upgradeable, CMTATBaseERC7551Enforcement {
/*//////////////////////////////////////////////////////////////
INITIALIZER FUNCTION
//////////////////////////////////////////////////////////////*/
@@ -383,19 +364,19 @@
/**
* @dev revert if the contract is in pause state
*/
- function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain, IERC20) returns (bool) {
- return CMTATBaseERC20CrossChain.approve(spender, value);
+ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) {
+ return CMTATBaseERC7551Enforcement.approve(spender, value);
}
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
- function transfer(address to, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain, IERC20) returns (bool) {
- return CMTATBaseERC20CrossChain.transfer(to, value);
+ function transfer(address to, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) {
+ return CMTATBaseERC7551Enforcement.transfer(to, value);
}
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
function transferFrom(
address sender,
@@ -404,10 +385,10 @@
}
/**
- * @dev check if the contract is deactivated or the address is frozen
- * check relevant for mint and burn operations
- * Use forcedTransfer (or forcedBurn) to burn tokens from a frozen address
- */
- function _canMintBurnByModuleAndRevert(
- address target
+ * @dev Reverts if mint is not allowed for `to`.
+ * Checks deactivation and frozen status of the recipient.
+ */
+ function _canMintByModuleAndRevert(
+ address to
+ ) internal view virtual {
+ _requireNotDeactivated();
+ if(EnforcementModule.isFrozen(to)){
+ revert ERC7943CannotReceive(to);
+ }
+ }
+
+ /**
+ * @dev Reverts if burn is not allowed for `from`.
+ * Checks deactivation and frozen status of the token holder.
+ */
+ function _canBurnByModuleAndRevert(
+ address from
) internal view virtual {
- // can not mint or burn if the contract is deactivated
_requireNotDeactivated();
- // cannot burn if target is frozen (used forcedTransfer instead if available)
- // cannot mint if target is frozen
- if(EnforcementModule.isFrozen(target)){
- revert ERC7943CannotTransact(target);
+ if(EnforcementModule.isFrozen(from)){
+ revert ERC7943CannotSend(from);
}
}
@@ -537,17 +579,13 @@
/**
* We don't check the deactivate status because
* the contract will be in the pause state if deactivated
- * This remove a supplementary check and reduce runtime gas sot
+ * This removes a supplementary check and reduces runtime gas cost
*/
_requireNotPaused();
_canTransferisFrozenAndRevert(spender, from, to);
}
- /**
- * @notice Checks if a specific account is allowed to transact according to token rules.
- * @dev This is often used for allowlist/KYC/KYB/AML checks.
- * @param account The address to check.
- * @return allowed True if the account is allowed, false otherwise.
+ /**
+ * @dev Returns true if `account` is allowed to send tokens.
+ * Base check: account must not be frozen.
+ * Override in subclasses to add allowlist or other checks.
*/
- function _canTransact(address account) internal view virtual returns (bool allowed) {
- if(EnforcementModule.isFrozen(account)) {
- return false;
- } else {
- return true;
- }
+ function _canSend(address account) internal view virtual returns (bool allowed) {
+ return !EnforcementModule.isFrozen(account);
+ }
+
+ /**
+ * @dev Returns true if `account` is allowed to receive tokens.
+ * Base check: account must not be frozen.
+ * Override in subclasses to add allowlist or other checks.
+ */
+ function _canReceive(address account) internal view virtual returns (bool allowed) {
+ return !EnforcementModule.isFrozen(account);
}
}
bool result = ERC20Upgradeable.transferFrom(from, to, value);
// The result will be normally always true because OpenZeppelin will revert in case of an error
Eif (result) {
+ // emit Spend does not necessarily imply an allowance reduction
+ // This is the case if the allowance is set to uint256.max
emit Spend(from, _msgSender(), value);
}
@@ -529,7 +535,7 @@
/**
*
* @inheritdoc IBurnBatchERC20
+ * @dev `data` is batch-level metadata emitted in {BatchBurn} only.
+ * It is not forwarded to each internal burn item.
* @custom:access-control
* - the caller must have the `BURNER_ROLE`.
*/
@@ -361,7 +367,7 @@
import {IERC7802} from "../../../interfaces/technical/IERC7802.sol";
import {IBurnFromERC20} from "../../../interfaces/technical/IMintBurnToken.sol";
import {IERC20Allowance} from "../../../interfaces/technical/IERC20Allowance.sol";
-import {ERC20BurnModule, ERC20BurnModuleInternal} from "../core/ERC20BurnModule.sol";
-import {ERC20MintModule, ERC20MintModuleInternal} from "../core/ERC20MintModule.sol";
+import {ERC20BurnModule} from "../core/ERC20BurnModule.sol";
+import {ERC20MintModule} from "../core/ERC20MintModule.sol";
/**
* @title ERC20CrossChainModule (ERC-7802)
* @dev
@@ -422,10 +410,8 @@
function burn(
uint256 value
) public virtual override(IBurnFromERC20) onlySelfBurn{
- // Don't emit Spend event because allowance is not used here
address sender = _msgSender();
- // burn from itself
- _burn(sender, sender, value);
+ _burnFromOperator(sender, sender, value);
}
/* ============ View functions ============ */
@@ -442,16 +428,11 @@
// Specific event for the spend operation, same as transferFrom (ERC20BaseModule)
// Importing the event through inheritance will result in the following error: "Linearization of inheritance graph impossible"
emit IERC20Allowance.Spend(account, sender, value);
- _burn(sender, account, value);
+ _burnFromOperator(sender, account, value);
}
- function _burn(
- address sender, address account, uint256 value
- ) internal virtual{
- // burn
+ function _burnFromOperator(address sender, address account, uint256 value) internal virtual {
_burnOverride(account, value);
- // Specific event to burnFrom and self-burn (burn)
- // Don't emit CrossChainBurn because this function burn is not part of the IERC7802 interface
emit BurnFrom(sender, account, sender, value);
}
@@ -466,13 +447,14 @@
function _authorizeBurnFrom() internal virtual;
function _authorizeSelfBurn() internal virtual;
-}
ERC20Upgradeable._transfer(from, to, value);
return true;
}
- /*
+ /**
* @inheritdoc ERC20BaseModule
*/
function transferFrom(
@@ -531,35 +458,6 @@
function _checkTransferred(address /*spender*/, address from, address /* to */, uint256 value) internal virtual {
ERC20EnforcementModuleInternal._checkActiveBalanceAndRevert(from, value);
}
- /**
- * @dev we don't check the transfer validity here
- *
- *
- */
- function _update(
- address from,
- address to,
- uint256 amount
- ) internal virtual override(ERC20Upgradeable) {
- // We check here the address of the snapshotEngine here because we don't want to read balance/totalSupply if there is no Snapshot Engine
- ISnapshotEngine snapshotEngineLocal = snapshotEngine();
-
- if(address(snapshotEngineLocal) != address(0)){
- uint256 fromBalanceBefore = balanceOf(from);
- uint256 toBalanceBefore = balanceOf(to);
- uint256 totalSupplyBefore = totalSupply();
-
- // We perform the update here (CEI pattern)
- ERC20Upgradeable._update(from, to, amount);
-
- // Required to use the balance before the update
- snapshotEngineLocal.operateOnTransfer(from, to, fromBalanceBefore, toBalanceBefore, totalSupplyBefore);
- } else {
- // Update without snapshot call
- ERC20Upgradeable._update(from, to, amount);
- }
- }
-
/* ==== Mint and Burn Operations ==== */
/**
@@ -568,7 +466,7 @@
* Check if the mint is valid
*/
function _mintOverride(address account, uint256 value) internal virtual override(ERC20MintModuleInternal) {
- _checkTransferred(address(0), address(0), account, value);
+ _checkTransferred(_msgSender(), address(0), account, value);
ERC20MintModuleInternal._mintOverride(account, value);
}
@@ -578,7 +476,7 @@
* Check if the burn is valid
*/
function _burnOverride(address account, uint256 value) internal virtual override(ERC20BurnModuleInternal) {
- _checkTransferred(address(0), account, address(0), value);
+ _checkTransferred(_msgSender(), account, address(0), value);
ERC20BurnModuleInternal._burnOverride(account, value);
}
@@ -588,7 +486,7 @@
* Check if a minter transfer is valid
*/
function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(ERC20MintModuleInternal) {
- _checkTransferred(address(0), from, to, value);
+ _checkTransferred(_msgSender(), from, to, value);
ERC20MintModuleInternal._minterTransferOverride(from, to, value);
}
}
@@ -598,7 +496,7 @@
* @dev
* We can not use type(IERC5679).interfaceId, we use instead of 0xd0017968
* because IERC5679 inherits from two interfaces (IERC5679Burn and Mint)
- * Core version does not implement in its integrality ERC-7943 (0x29388973)
+ * Core version does not implement in its integrality ERC-7943 (0x3edbb4c4)
+ * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) {
- return interfaceId == 0xd0017968 || AccessControlUpgradeable.supportsInterface(interfaceId);
+ return interfaceId == 0xd0017968 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId);
}
/* ============ State Functions ============ */
@@ -764,6 +786,14 @@
// Extensions
import {ExtraInformationModule} from "./wrapper/extensions/ExtraInformationModule.sol";
import {ERC20EnforcementModule} from "./wrapper/extensions/ERC20EnforcementModule.sol";
-import {DocumentEngineModule, IERC1643} from "./wrapper/extensions/DocumentEngineModule.sol";
-import {SnapshotEngineModule} from "./wrapper/extensions/SnapshotEngineModule.sol";
+import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol";
// options
-import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol";
+import {ERC20BaseModule} from "./wrapper/core/ERC20BaseModule.sol";
/* ==== Interface and other library === */
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
+import {CMTATBaseDocument} from "./1_CMTATBaseDocument.sol";
abstract contract CMTATBaseAccessControl is
AccessControlModule,
- CMTATBaseCommon
+ CMTATBaseCommon,
+ CMTATBaseDocument
{
+
/*//////////////////////////////////////////////////////////////
INITIALIZER FUNCTION
//////////////////////////////////////////////////////////////*/
@@ -301,10 +299,11 @@
* @dev
* We can not use type(IERC5679).interfaceId instead of 0xd0017968
* because IERC5679 inherits from two interfaces (IERC5679Burn and Mint)
- * 0x29388973 is the interfaceId of ERC-7943
+ * 0x3edbb4c4 is the interfaceId of ERC-7943
+ * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) {
- return interfaceId == 0xd0017968 || interfaceId == 0x29388973 || AccessControlUpgradeable.supportsInterface(interfaceId);
+ return interfaceId == 0xd0017968 || interfaceId == 0x3edbb4c4 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId);
}
@@ -335,7 +334,7 @@
* @custom:access-control
* - the caller must have the `DOCUMENT_ROLE`.
*/
- function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) onlyRole(DOCUMENT_ROLE){}
+ function _authorizeDocumentManagement() internal virtual override(DocumentERC1643Module) onlyRole(DOCUMENT_ROLE){}
/**
* @custom:access-control
@@ -355,11 +354,6 @@
*/
function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) onlyRole(DEFAULT_ADMIN_ROLE){}
- /**
- * @custom:access-control
- * - the caller must have the `SNAPSHOOTER_ROLE`.
- */
- function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE){}
}
@@ -367,7 +361,7 @@
diff --git a/doc/test/coverage/lcov-report/modules/2_CMTATBaseAllowlist.sol.html b/doc/test/coverage/modules/3_CMTATBaseAllowlist.sol.html
similarity index 71%
rename from doc/test/coverage/lcov-report/modules/2_CMTATBaseAllowlist.sol.html
rename to doc/test/coverage/modules/3_CMTATBaseAllowlist.sol.html
index d26094db..440d207a 100644
--- a/doc/test/coverage/lcov-report/modules/2_CMTATBaseAllowlist.sol.html
+++ b/doc/test/coverage/modules/3_CMTATBaseAllowlist.sol.html
@@ -1,7 +1,7 @@
- Code coverage report for modules/2_CMTATBaseAllowlist.sol
+ Code coverage report for modules/3_CMTATBaseAllowlist.sol
@@ -16,13 +16,13 @@
//////////////////////////////////////////////////////////////*/
/**
* @dev revert if the contract is in pause state
+ * @notice Changing a non-zero allowance to another non-zero value carries the standard
+ * ERC-20 allowance race condition: a spender who observes the pending transaction can
+ * front-run it and spend the old allowance before the new value takes effect.
+ * To avoid this, callers should set the allowance to zero before assigning a new value
+ * if strict control over the total amount a spender can consume is required.
*/
function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) {
+ _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender);
return ERC20Upgradeable.approve(spender, value);
}
+
+ function transfer(address to, uint256 value)
+ public
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (bool)
+ {
+ return CMTATBaseCommon.transfer(to, value);
+ }
+
+ function transferFrom(address from, address to, uint256 value)
+ public
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (bool)
+ {
+ return CMTATBaseCommon.transferFrom(from, to, value);
+ }
+
+ function decimals()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (uint8)
+ {
+ return CMTATBaseCommon.decimals();
+ }
+
+ function name()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (string memory)
+ {
+ return CMTATBaseCommon.name();
+ }
+
+ function symbol()
+ public
+ view
+ virtual
+ override(ERC20Upgradeable, CMTATBaseCommon)
+ returns (string memory)
+ {
+ return CMTATBaseCommon.symbol();
+ }
/**
* @inheritdoc ValidationModuleCore
@@ -687,6 +910,12 @@
import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
/* ==== Wrapper === */
// Core
-import {CMTATBaseAccessControl} from "./1_CMTATBaseAccessControl.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
import {PauseModule} from "./wrapper/core/PauseModule.sol";
import {EnforcementModule} from "./wrapper/core/EnforcementModule.sol";
// Extensions
-import {ERC20EnforcementModule, ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
+import {ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol";
// Controllers
import {ValidationModuleRuleEngine} from "./wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
@@ -531,6 +533,7 @@
* @dev revert if the contract is in pause state
*/
function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) {
+ _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender);
return ERC20Upgradeable.approve(spender, value);
}
/**
@@ -589,7 +592,7 @@
// SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;
/* ==== OpenZeppelin === */
import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
/* ==== Module === */
-import {CMTATBaseERC1404, CMTATBaseRuleEngine, ERC20Upgradeable} from "./3_CMTATBaseERC1404.sol";
-import {CMTATBaseAccessControl} from "./1_CMTATBaseAccessControl.sol";
+import {CMTATBaseERC1404, CMTATBaseRuleEngine, ERC20Upgradeable} from "./4_CMTATBaseERC1404.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
-import {ERC20BurnModule, ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol";
-import {ERC20MintModule, ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol";
+import {ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol";
+import {ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol";
import {ERC20CrossChainModule} from "./wrapper/options/ERC20CrossChainModule.sol";
import {CCIPModule} from "./wrapper/options/CCIPModule.sol";
@@ -427,7 +413,7 @@
* @dev Check if the mint is valid
*/
function _mintOverride(address account, uint256 value) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
- CMTATBaseRuleEngine._checkTransferred(address(0), address(0), account, value);
+ // _checkTransferred is called by _mintOverride
CMTATBaseCommon._mintOverride(account, value);
}
@@ -435,7 +421,7 @@
* @dev Check if the burn is valid
*/
function _burnOverride(address account, uint256 value) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) {
- CMTATBaseRuleEngine._checkTransferred(address(0), account, address(0), value);
+ // _checkTransferred is called by _burnOverride
CMTATBaseCommon._burnOverride(account, value);
}
@@ -443,7 +429,7 @@
* @dev Check if a minter transfer is valid
*/
function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
- CMTATBaseRuleEngine._checkTransferred(address(0), from, to, value);
+ // _checkTransferred is called by _minterTransferOverride
CMTATBaseCommon._minterTransferOverride(from, to, value);
}
@@ -475,28 +461,21 @@
*/
function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{}
- /**
+ /**
* @custom:access-control
- * - the caller must have the `BURNER_FROM_ROLE`.
+ * - the caller must have the `BURNER_SELF_ROLE`.
* - We don't allow token holder to burn their own tokens if they don't have this role.
*/
function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{}
- /* ==== ERC-20 OpenZeppelin ==== */
- function _update(
- address from,
- address to,
- uint256 amount
- ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) {
- return CMTATBaseCommon._update(from, to, amount);
- }
-}
import {ERC1363Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC1363Upgradeable.sol";
import {ERC20Upgradeable, IERC20} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
/* ==== Module === */
-import {CMTATBaseRuleEngine} from "./2_CMTATBaseRuleEngine.sol";
-import {CMTATBaseERC2771, CMTATBaseERC20CrossChain} from "../modules/5_CMTATBaseERC2771.sol";
+import {CMTATBaseRuleEngine} from "./3_CMTATBaseRuleEngine.sol";
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseERC7551Enforcement} from "./7_CMTATBaseERC7551Enforcement.sol";
/* ==== Interface and other library === */
import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
/**
* @title CMTAT Base for ERC-1363
*/
-abstract contract CMTATBaseERC1363 is ERC1363Upgradeable,CMTATBaseERC2771{
+abstract contract CMTATBaseERC1363 is ERC1363Upgradeable, CMTATBaseERC7551Enforcement {
/*//////////////////////////////////////////////////////////////
INITIALIZER FUNCTION
//////////////////////////////////////////////////////////////*/
@@ -383,19 +364,19 @@
/**
* @dev revert if the contract is in pause state
*/
- function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain, IERC20) returns (bool) {
- return CMTATBaseERC20CrossChain.approve(spender, value);
+ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) {
+ return CMTATBaseERC7551Enforcement.approve(spender, value);
}
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
- function transfer(address to, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC20CrossChain, IERC20) returns (bool) {
- return CMTATBaseERC20CrossChain.transfer(to, value);
+ function transfer(address to, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) {
+ return CMTATBaseERC7551Enforcement.transfer(to, value);
}
/**
- * @inheritdoc CMTATBaseERC20CrossChain
+ * @inheritdoc CMTATBaseERC7551Enforcement
*/
function transferFrom(
address sender,
@@ -404,10 +385,10 @@
}
/**
- * @dev check if the contract is deactivated or the address is frozen
- * check relevant for mint and burn operations
- * Use forcedTransfer (or forcedBurn) to burn tokens from a frozen address
- */
- function _canMintBurnByModuleAndRevert(
- address target
+ * @dev Reverts if mint is not allowed for `to`.
+ * Checks deactivation and frozen status of the recipient.
+ */
+ function _canMintByModuleAndRevert(
+ address to
+ ) internal view virtual {
+ _requireNotDeactivated();
+ if(EnforcementModule.isFrozen(to)){
+ revert ERC7943CannotReceive(to);
+ }
+ }
+
+ /**
+ * @dev Reverts if burn is not allowed for `from`.
+ * Checks deactivation and frozen status of the token holder.
+ */
+ function _canBurnByModuleAndRevert(
+ address from
) internal view virtual {
- // can not mint or burn if the contract is deactivated
_requireNotDeactivated();
- // cannot burn if target is frozen (used forcedTransfer instead if available)
- // cannot mint if target is frozen
- if(EnforcementModule.isFrozen(target)){
- revert ERC7943CannotTransact(target);
+ if(EnforcementModule.isFrozen(from)){
+ revert ERC7943CannotSend(from);
}
}
@@ -537,17 +579,13 @@
/**
* We don't check the deactivate status because
* the contract will be in the pause state if deactivated
- * This remove a supplementary check and reduce runtime gas sot
+ * This removes a supplementary check and reduces runtime gas cost
*/
_requireNotPaused();
_canTransferisFrozenAndRevert(spender, from, to);
}
- /**
- * @notice Checks if a specific account is allowed to transact according to token rules.
- * @dev This is often used for allowlist/KYC/KYB/AML checks.
- * @param account The address to check.
- * @return allowed True if the account is allowed, false otherwise.
+ /**
+ * @dev Returns true if `account` is allowed to send tokens.
+ * Base check: account must not be frozen.
+ * Override in subclasses to add allowlist or other checks.
*/
- function _canTransact(address account) internal view virtual returns (bool allowed) {
- if(EnforcementModule.isFrozen(account)) {
- return false;
- } else {
- return true;
- }
+ function _canSend(address account) internal view virtual returns (bool allowed) {
+ return !EnforcementModule.isFrozen(account);
+ }
+
+ /**
+ * @dev Returns true if `account` is allowed to receive tokens.
+ * Base check: account must not be frozen.
+ * Override in subclasses to add allowlist or other checks.
+ */
+ function _canReceive(address account) internal view virtual returns (bool allowed) {
+ return !EnforcementModule.isFrozen(account);
}
}
bool result = ERC20Upgradeable.transferFrom(from, to, value);
// The result will be normally always true because OpenZeppelin will revert in case of an error
Eif (result) {
+ // emit Spend does not necessarily imply an allowance reduction
+ // This is the case if the allowance is set to uint256.max
emit Spend(from, _msgSender(), value);
}
@@ -529,7 +535,7 @@
/**
*
* @inheritdoc IBurnBatchERC20
+ * @dev `data` is batch-level metadata emitted in {BatchBurn} only.
+ * It is not forwarded to each internal burn item.
* @custom:access-control
* - the caller must have the `BURNER_ROLE`.
*/
@@ -361,7 +367,7 @@
import {IERC7802} from "../../../interfaces/technical/IERC7802.sol";
import {IBurnFromERC20} from "../../../interfaces/technical/IMintBurnToken.sol";
import {IERC20Allowance} from "../../../interfaces/technical/IERC20Allowance.sol";
-import {ERC20BurnModule, ERC20BurnModuleInternal} from "../core/ERC20BurnModule.sol";
-import {ERC20MintModule, ERC20MintModuleInternal} from "../core/ERC20MintModule.sol";
+import {ERC20BurnModule} from "../core/ERC20BurnModule.sol";
+import {ERC20MintModule} from "../core/ERC20MintModule.sol";
/**
* @title ERC20CrossChainModule (ERC-7802)
* @dev
@@ -422,10 +410,8 @@
function burn(
uint256 value
) public virtual override(IBurnFromERC20) onlySelfBurn{
- // Don't emit Spend event because allowance is not used here
address sender = _msgSender();
- // burn from itself
- _burn(sender, sender, value);
+ _burnFromOperator(sender, sender, value);
}
/* ============ View functions ============ */
@@ -442,16 +428,11 @@
// Specific event for the spend operation, same as transferFrom (ERC20BaseModule)
// Importing the event through inheritance will result in the following error: "Linearization of inheritance graph impossible"
emit IERC20Allowance.Spend(account, sender, value);
- _burn(sender, account, value);
+ _burnFromOperator(sender, account, value);
}
- function _burn(
- address sender, address account, uint256 value
- ) internal virtual{
- // burn
+ function _burnFromOperator(address sender, address account, uint256 value) internal virtual {
_burnOverride(account, value);
- // Specific event to burnFrom and self-burn (burn)
- // Don't emit CrossChainBurn because this function burn is not part of the IERC7802 interface
emit BurnFrom(sender, account, sender, value);
}
@@ -466,13 +447,14 @@
function _authorizeBurnFrom() internal virtual;
function _authorizeSelfBurn() internal virtual;
-}