diff --git a/.claude/tree/contracts_tree.txt b/.claude/tree/contracts_tree.txt index 93c8da0a..4974d292 100644 --- a/.claude/tree/contracts_tree.txt +++ b/.claude/tree/contracts_tree.txt @@ -3,8 +3,8 @@ contracts │   ├── allowlist │   │   ├── CMTATStandaloneAllowlist.sol │   │   └── CMTATUpgradeableAllowlist.sol -│   ├── CMTATStandalone.sol -│   ├── CMTATUpgradeable.sol +│   ├── CMTATStandardStandalone.sol +│   ├── CMTATStandardUpgradeable.sol │   ├── CMTATUpgradeableUUPS.sol │   ├── debt │   │   ├── CMTATStandaloneDebt.sol @@ -21,15 +21,15 @@ contracts │   ├── holderList │   │   ├── CMTATStandaloneHolderList.sol │   │   └── CMTATUpgradeableHolderList.sol +│   ├── light +│   │   ├── CMTATStandaloneLight.sol +│   │   └── CMTATUpgradeableLight.sol │   ├── permit │   │   ├── CMTATStandalonePermit.sol │   │   └── CMTATUpgradeablePermit.sol -│   ├── snapshot -│   │   ├── CMTATStandaloneSnapshot.sol -│   │   └── CMTATUpgradeableSnapshot.sol -│   └── light -│   ├── CMTATStandaloneLight.sol -│   └── CMTATUpgradeableLight.sol +│   └── snapshot +│   ├── CMTATStandaloneSnapshot.sol +│   └── CMTATUpgradeableSnapshot.sol ├── interfaces │   ├── engine │   │   ├── IDebtEngine.sol @@ -41,6 +41,7 @@ contracts │   │   ├── IDebtEngineModule.sol │   │   ├── IDebtModule.sol │   │   ├── IDocumentEngineModule.sol +│   │   ├── IHolderListModule.sol │   │   └── ISnapshotEngineModule.sol │   ├── technical │   │   ├── ICMTATConstructor.sol @@ -55,15 +56,18 @@ contracts │   ├── draft-IERC1643.sol │   ├── draft-IERC7551.sol │   ├── draft-IERC7943.sol +│   ├── draft-IERC8343.sol │   ├── ICMTAT.sol │   └── IERC3643Partial.sol ├── library │   ├── ERC1404ExtendInterfaceId.sol │   └── RuleEngineInterfaceId.sol ├── mocks +│   ├── CMTATMsgDataMock.sol │   ├── DebtEngineMock.sol │   ├── DocumentEngineMock.sol │   ├── engine +│   │   ├── CMTATDocumentEngineModuleMock.sol │   │   └── CMTATEngineInitializerMock.sol │   ├── ERC1363ReceiverMock.sol │   ├── ERC165Helper @@ -82,76 +86,83 @@ contracts │   │   ├── CodeList.sol │   │   ├── interfaces │   │   │   ├── IRuleEngineMock.sol -│   │   │   └── IRule.sol +│   │   │   ├── IRule.sol +│   │   │   └── IRuleTransferHook.sol │   │   ├── RuleEngineMock.sol +│   │   ├── RuleEngineReentrantMock.sol +│   │   ├── RuleEngineSpenderRecorderMock.sol │   │   ├── RuleMockMint.sol -│   │   └── RuleMock.sol +│   │   ├── RuleMock.sol +│   │   ├── RuleSpenderAuthorized.sol +│   │   └── RuleTokenHolderTracker.sol │   ├── SnapshotEngineMock.sol │   └── test │   └── proxy │   ├── CMTAT_PROXY_TEST.sol │   └── CMTAT_PROXY_TEST_UUPS.sol -├── modules -│   ├── 0_CMTATBaseCommon.sol -│   ├── 0_CMTATBaseCore.sol -│   ├── 0_CMTATBaseGeneric.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_CMTATBaseERC2771Snapshot.sol -│   ├── 6_CMTATBaseERC7551Enforcement.sol -│   ├── 7_CMTATBaseERC1363.sol -│   ├── 7_CMTATBaseERC7551.sol -│   ├── 8_CMTATBaseHolderList.sol -│   ├── internal -│   │   ├── AllowlistModuleInternal.sol -│   │   ├── common -│   │   │   └── EnforcementModuleLibrary.sol -│   │   ├── EnforcementModuleInternal.sol -│   │   ├── ERC20BurnModuleInternal.sol -│   │   ├── ERC20EnforcementModuleInternal.sol -│   │   ├── ERC20MintModuleInternal.sol -│   │   └── ValidationModuleRuleEngineInternal.sol -│   └── wrapper -│   ├── controllers -│   │   ├── ValidationModuleAllowlist.sol -│   │   └── ValidationModule.sol -│   ├── core -│   │   ├── EnforcementModule.sol -│   │   ├── ERC20BaseModule.sol -│   │   ├── ERC20BurnModule.sol -│   │   ├── ERC20MintModule.sol -│   │   ├── PauseModule.sol -│   │   ├── TokenAttributeModule.sol -│   │   ├── ValidationModuleCore.sol -│   │   └── VersionModule.sol -│   ├── extensions -│   │   ├── DocumentEngineModule.sol -│   │   ├── ERC20EnforcementModule.sol -│   │   ├── ExtraInformationModule.sol -│   │   ├── SnapshotEngineModule.sol -│   │   └── ValidationModule -│   │   ├── ValidationModuleAllowance.sol -│   │   ├── ValidationModuleERC1404.sol -│   │   └── ValidationModuleRuleEngine.sol -│   ├── options -│   │   ├── AllowlistModule.sol -│   │   ├── CCIPModule.sol -│   │   ├── DebtEngineModule.sol -│   │   ├── DebtModule.sol -│   │   ├── ERC20CrossChainModule.sol -│   │   ├── ERC20EnforcementERC7551Module.sol -│   │   ├── ERC2771Module.sol -│   │   ├── ERC7551Module.sol -│   │   └── HolderListModule.sol -│   └── security -│   └── AccessControlModule.sol -33 directories, 110 files +└── modules + ├── 0_CMTATBaseCommon.sol + ├── 0_CMTATBaseCore.sol + ├── 0_CMTATBaseGeneric.sol + ├── 0_CMTATBaseSnapshot.sol + ├── 1_CMTATBaseDocument.sol + ├── 2_CMTATBaseAccessControl.sol + ├── 3_CMTATBaseAllowlist.sol + ├── 3_CMTATBaseRuleEngine.sol + ├── 4_CMTATBaseDebt.sol + ├── 4_CMTATBaseERC1404.sol + ├── 5_CMTATBaseERC20CrossChain.sol + ├── 6_CMTATBaseDebtEngine.sol + ├── 6_CMTATBaseERC2612.sol + ├── 6_CMTATBaseERC2771.sol + ├── 7_CMTATBaseERC2771Snapshot.sol + ├── 7_CMTATBaseERC7551Enforcement.sol + ├── 8_CMTATBaseERC1363.sol + ├── 8_CMTATBaseERC7551.sol + ├── 8_CMTATBaseHolderList.sol + ├── internal + │   ├── AllowlistModuleInternal.sol + │   ├── common + │   │   └── EnforcementModuleLibrary.sol + │   ├── EnforcementModuleInternal.sol + │   ├── ERC20BurnModuleInternal.sol + │   ├── ERC20EnforcementModuleInternal.sol + │   ├── ERC20MintModuleInternal.sol + │   └── ValidationModuleRuleEngineInternal.sol + └── wrapper + ├── controllers + │   ├── ValidationModuleAllowlist.sol + │   └── ValidationModule.sol + ├── core + │   ├── EnforcementModule.sol + │   ├── ERC20BaseModule.sol + │   ├── ERC20BurnModule.sol + │   ├── ERC20MintModule.sol + │   ├── PauseModule.sol + │   ├── TokenAttributeModule.sol + │   ├── ValidationModuleCore.sol + │   └── VersionModule.sol + ├── extensions + │   ├── DocumentERC1643Module.sol + │   ├── ERC20EnforcementModule.sol + │   ├── ExtraInformationModule.sol + │   ├── SnapshotEngineModule.sol + │   └── ValidationModule + │   ├── ValidationModuleAllowance.sol + │   ├── ValidationModuleERC1404.sol + │   └── ValidationModuleRuleEngine.sol + ├── options + │   ├── AllowlistModule.sol + │   ├── CCIPModule.sol + │   ├── DebtEngineModule.sol + │   ├── DebtModule.sol + │   ├── DocumentEngineModule.sol + │   ├── ERC20CrossChainModule.sol + │   ├── ERC20EnforcementERC7551Module.sol + │   ├── ERC2771Module.sol + │   ├── ERC7551Module.sol + │   └── HolderListModule.sol + └── security + └── AccessControlModule.sol + +35 directories, 129 files diff --git a/.claude/tree/test_tree.txt b/.claude/tree/test_tree.txt index 96d3134e..ef6805ca 100644 --- a/.claude/tree/test_tree.txt +++ b/.claude/tree/test_tree.txt @@ -16,13 +16,15 @@ test │   ├── ERC20BaseModuleCommon.js │   ├── ERC20BurnModuleCommon.js │   ├── ERC20CrossChainModuleCommon.js +│   ├── ERC20EnforcementERC7551ModuleCommon.js │   ├── ERC20EnforcementModuleCommon.js │   ├── ERC20MintModuleCommon.js │   ├── ERC7551ModuleCommon.js │   ├── ExtraInfoModuleCommon.js │   ├── HolderListModuleCommon.js -│   ├── MulticallModuleCommon.js │   ├── MetaTxModuleCommon.js +│   ├── MetaTxMsgDataCommon.js +│   ├── MulticallModuleCommon.js │   ├── PauseModuleCommon.js │   ├── PermitModuleCommon.js │   ├── SnapshotModuleCommon @@ -42,6 +44,7 @@ test │   ├── ValidationModule │   │   ├── proxy │   │   │   └── ValidationModuleProxyCommon.js +│   │   ├── RuleEngineReentrancyCommon.js │   │   ├── ValidationModuleCommonCore.js │   │   ├── ValidationModuleCommon.js │   │   └── ValidationModuleSetRuleEngineCommon.js @@ -57,7 +60,7 @@ test │   │   ├── deploymentUpgradeableDebtSnapshot.test.js │   │   └── deploymentUpgradeableDebt.test.js │   ├── debtEngine -│   │   ├── deploymentStandaloneDebtEngineSnapshot.test .js +│   │   ├── deploymentStandaloneDebtEngineSnapshot.test.js │   │   ├── deploymentStandaloneDebtEngine.test.js │   │   └── deploymentUpgradeableDebtEngine.test.js │   ├── deployment.test.js @@ -71,12 +74,15 @@ test │   ├── erc7551 │   │   ├── deploymentERC7551Standalone.test.js │   │   └── deploymentERC7551Upgradeable.test.js +│   ├── light +│   │   ├── deploymentStandaloneLight.test.js +│   │   └── deploymentUpgradeableLight.test.js │   ├── permit │   │   ├── deploymentPermitStandalone.test.js │   │   └── deploymentPermitUpgradeable.test.js -│   └── light -│   ├── deploymentStandaloneLight.test.js -│   └── deploymentUpgradeableLight.test.js +│   └── snapshot +│   ├── deploymentStandaloneSnapshot.test.js +│   └── deploymentUpgradeableSnapshot.test.js ├── deploymentUtils.js ├── proxy │   ├── general @@ -104,6 +110,7 @@ test │   ├── SnapshotModule │   │   └── SnapshotModule.test.js │   ├── ValidationModule +│   │   ├── ValidationModuleReentrancy.test.js │   │   └── ValidationModule.test.js │   └── VersionModule.test.js ├── standard @@ -112,6 +119,8 @@ test │   │   └── AuthorizationModule.test.js │   ├── CCIPModule.test.js │   ├── CMTATIntegration.test.js +│   ├── DocumentEngineModule +│   │   └── DocumentEngineModule.test.js │   ├── DocumentModule │   │   └── DocumentModule.test.js │   ├── EnforcementModule.test.js @@ -126,14 +135,20 @@ test │   ├── MetaTxModuleERC1363.test.js │   ├── MetaTxModule.test.js │   ├── MetaTxModuleUUPS.test.js +│   ├── MetaTxMsgDataAllowlist.test.js +│   ├── MetaTxMsgDataERC1363.test.js +│   ├── MetaTxMsgDataSnapshot.test.js +│   ├── MetaTxMsgData.test.js │   ├── PauseModule.test.js +│   ├── RuleEngineMockStatefulRule.test.js │   ├── SnapshotModule │   │   └── SnapshotModule.test.js │   ├── ValidationModule │   │   ├── ValidationModuleConstructor.test.js +│   │   ├── ValidationModuleReentrancy.test.js │   │   ├── ValidationModuleSetRuleEngine.test.js │   │   └── ValidationModule.test.js │   └── VersionModule.test.js └── utils.js -30 directories, 101 files +33 directories, 118 files diff --git a/AGENTS.md b/AGENTS.md index af97791e..25493f09 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -81,6 +81,18 @@ npm run coverage # Generate coverage report npm run hardhat:compile # Compile contracts ``` +## Test Catalogue + +The test suite is catalogued per feature module and per deployment version in **[doc/test/Test.md](doc/test/Test.md)** +— a hand-maintained map whose purpose is to make **missing tests easy to find**. + +**Whenever you add, change or remove a test, update `doc/test/Test.md` in the same change:** +- test added → adjust the module's `it` count / scenario, and add a matrix row or column if it covers a new feature or variant; +- test removed → remove it, and note any resulting coverage gap; +- new deployment variant or shared test module → add the corresponding matrix column / row and module-reference entry. + +An out-of-date catalogue is worse than none — keep it in sync. + ## 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: @@ -99,6 +111,31 @@ DeactivateReportGas=true npx hardhat test - `hardhat.config.js` - Build configuration (EVM & Solidity version) - `package.json` - Dependencies and scripts +## Documentation Lookup + +Before stating that something is **not documented**, search **all** of the documentation surfaces below. They +overlap and none of them is authoritative on its own — a rationale is often recorded in one place and the +per-function facts in another. + +| Surface | What lives there | +| --- | --- | +| `doc/README.md` | The largest document. Standards mapping (ERC-3643, ERC-7943, ERC-7551, ERC-7802), architecture, module list, access control, engines, and the **Enforcement / Transfer restriction** chapter — including behavioural rationales such as why pause does not block issuer mint/burn. | +| `doc/USAGE.md` | Build, test, deploy and tooling instructions. | +| `doc/modules/**` | Per-module reference pages (`core/`, `extensions/`, `options/`, `controllers/`), one per module, with per-function requirements, events and errors. | +| `doc/technical/**` | Cross-cutting topics: `access-control.md`, `cross-chain-bridge-integration.md`, `deployment.md`, `upgradeable.md`, `stablecoin.md`, ERC-specific notes. | +| `doc/SUMMARY.md` | Short index of modules, deployment variants and roles. | +| `doc/security/**` | Audit reports and maintainer feedback. | +| `contracts/**` NatSpec + inline comments | Design rationales are frequently recorded only in code comments (e.g. the `onlyTokenBridge` `msg.sender` justification). | + +Practical rule: grep the whole `doc/` tree **and** `contracts/`, not a subset. + +```bash +grep -rn -i "" doc/ contracts/ --include=*.md --include=*.sol | grep -v doc/hardhat-compilation +``` + +Exclude `doc/hardhat-compilation/` (flattened build artifacts, including vendored OpenZeppelin comments) — matches +there are **not** CMTAT statements and must not be quoted as project documentation. + ## Note After each implemented feature or fix, provide a one-line GitHub commit message for all changes since the last commit. diff --git a/CHANGELOG.md b/CHANGELOG.md index fec79349..a93e9699 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,12 +43,72 @@ Custom changelog tag: `Dependencies`, `Documentation`, `Testing` - Update changelog +## 3.3.0 - rc3 +> **Note:** This version has not been audited. + +Main theme: remediation of the **Nethermind AuditAgent v3.3.0-rc2** automated review. Maintainer triage outcome: **12 fixed in code · 8 accepted as design (5 documented) · 4 rejected**; no open item. Full per-finding dispositions in [audit_agent_report_v3.3.0-rc2-feedback.md](./doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md). + +### Smart contract + +#### Fixed + +- **NM-15/17 — missing `address(0)` guard in `_setFrozenTokens`** (`ERC20EnforcementModuleInternal`): an `ERC20ENFORCER_ROLE` holder could freeze tokens on the zero address and brick every mint path. A zero-address guard now rejects it. +- **NM-3/8 — allowance revocation blocked while paused / frozen**: setting an allowance to `0` is now always permitted. `_canAuthorizeAllowanceByModuleAndRevert` returns early when `value == 0`, so an owner can revoke a spender even while the contract is paused or a party is frozen/delisted. +- **NM-22 — `setTerms(bytes32,string)` overload erased the terms document name**: the overload now preserves the existing document `name` instead of silently clearing it (`ERC7551Module` / `ExtraInformationModule`). +- **NM-24 — `forcedTransfer` allowance accounting**: `forcedTransfer` now emits `Spend(from, to, min(currentAllowance, value))` and the `IERC20Allowance.Spend` NatSpec was corrected. +- **NM-5 — Light minter transfer**: `_minterTransferOverride` now threads `_msgSender()` as the spender argument, aligning the Light variant with the other deployments. + +#### Security + +- **NM-7/9/11/16/18 — reentrancy on the RuleEngine `transferred` callback**: the `transferred` callback (invoked before balance effects) is now protected by a transient-storage reentrancy guard (OpenZeppelin `ReentrancyGuardTransient`, EIP-1153) on the deployment variants with bytecode headroom. `_callRuleEngineTransferred` is `virtual` and only guards when a RuleEngine is set; size-constrained variants can override, and the limitation is documented. Added a malicious reentrant RuleEngine mock (`RuleEngineReentrantMock`) to cover the attack. + +#### Changed + +- Raised the Solidity source pragma floor to `^0.8.24` across all contracts, required by the EIP-1153 transient storage used by the new reentrancy guard. + +### Testing + +#### Added + +- Malicious-engine reentrancy tests (`test/common/ValidationModule/RuleEngineReentrancyCommon.js`) plus per-variant wiring. +- Regression tests for the fixes above: zero-value permit/allowance revocation while paused or with a frozen owner/spender, `setTerms` name preservation, `forcedTransfer` `Spend` event, the Light minter-transfer spender. +- Coverage tests that a non-allowlisted minter can still mint, a frozen minter can still mint, and that freeze does not block `mint`/`batchMint` (standard + light). +- **ERC-1643 document tests** (`test/common/DocumentModule/DocumentModuleCommon.js`): event emission on `setDocument` / `removeDocument`, the zero-name case and the missing-document case, run against both the native `DocumentERC1643Module` and the external `DocumentEngineModule` variants. +- **RuleEngine spender-dispatch tests** (`test/common/ValidationModule/RuleEngineSpenderDispatchCommon.js`, wired for the standalone and proxy variants): assert through CMTAT that `transferFrom` routes to the spender-aware 4-argument `transferred(spender, from, to, value)` and forwards the real spender, while a direct `transfer` routes to the legacy 3-argument overload. Uses a new recording mock, `RuleEngineSpenderRecorderMock`, and kills the `spender != address(0)` dispatch mutant. +- **`doc/test/Test.md`** — a hand-maintained test catalogue (module × deployment-version matrix, per-module scenario reference) to make missing tests easy to find; its maintenance is now required by `CLAUDE.md` / `AGENTS.md`. + +#### Fixed + +- **`npm run coverage` no longer fails with `Transaction ran out of gas`** on the largest deployment variants (ERC1363, ERC7551, DebtEngine, HolderList). The Hardhat network defaults to the `osaka` hardfork, which enforces the EIP-7825 per-transaction gas cap of 2\*\*24 (16,777,216 gas); solidity-coverage's instrumented bytecode exceeds it at deployment, and each failed `beforeEach` skipped its whole suite. `hardhat.config.js` now runs the coverage task on `prague` (overridable with `HARDHAT_HARDFORK`) while `npm run test` stays on `osaka`. Deployed contracts are unaffected — they use about a third of the cap (~5.7M gas). Full coverage run: 6108 passing, 0 failing. +- **Flaky timestamp assertions** in the snapshot scheduling and rescheduling suites (`test/common/SnapshotModuleCommon/`): `CMTAT_SnapshotModule_SnapshotScheduledInThePast` was checked against `(await time.latest()) + 1` read while the reverting call was in flight, which resolved to a different block depending on run speed. The executing block's timestamp is now pinned with `time.setNextBlockTimestamp`. + +### Documentation -## 3.3.0 - rc2 +- Documented the accepted-as-design findings: NM-4 (raw `msg.sender` bridge gate and the `CROSS_CHAIN_ROLE` forwarder constraint), NM-6 (permissionless zero-value `transferred` callbacks in the `IRuleEngine` NatSpec), NM-20 (the ERC20Burn pause note — `burnFrom` / `burn(value)` carry the pause check as cross-chain/third-party operations), NM-21 (`setName` does not update the EIP-712 domain; signers must read `eip712Domain()`), and an allowance-spend-event technical note (NM-24). +- Expanded `doc/README.md`: ERC-2771 per-deployment support table; split of the ERC-1404 version-support row into base (`detectTransferRestriction`) and reworked-only Extension (`detectTransferRestrictionFrom`); native `DocumentERC1643Module` vs external `DocumentEngineModule`; inheritance schemas for ERC-1363, Light, Debt, DebtEngine, Permit and Allowlist; a per-tool security-tools overview; and a `CMTAT-Confidential` entry under official implementations. +- Renamed `guideline-new-blockchain.md` → `cmtat-specification-analyse.md` (rescoped to a CMTAT-specification-vs-implementation comparison); porting now points to the external [CMTAT-equivalency-assessment](https://github.com/CMTA/CMTAT-equivalency-assessment) repository. Removed the ERC-1450 links from the Technical Guides. +- Corrected `holder-list.md` (the gas cost of a transfer between existing holders, and off-chain balance-at-a-block via `eth_call`). +- **ERC-1404 predictor scope** — `detectTransferRestriction` and `detectTransferRestrictionFrom` describe the holder transfer path (`transfer` / `transferFrom`) only. The `address(0)` encoding of the ERC-1404 rework draft (mint as `from == address(0)`, burn as `to == address(0)`) is **not** supported, because CMTAT's pause rule differs *between entry points of the same operation* — `MINTER_ROLE` mint and `BURNER_ROLE` burn proceed while paused, while `crosschainMint`, `crosschainBurn`, `burnFrom` and `burn(uint256)` do not — and the ERC-1404 signature carries no entry-point discriminator. CMTAT therefore designates no ERC-1404 predictor for supply-changing operations and designates `canTransfer` / `canTransferFrom` instead. Documented in `ValidationModuleERC1404` NatSpec, `doc/README.md`, `doc/technical/ruleengine-integration.md` and `doc/modules/core/Pause/pause.md`. +- **RuleEngine authoring obligations** (`doc/technical/ruleengine-integration.md`): an engine must return a non-empty `messageForTransferRestriction` string for every code it can return — never one denoting the absence of a restriction for a non-zero code — and must implement `IRuleEngineERC1404` when the token exposes ERC-1404. The token forwards both the code and the message verbatim by design (trusted, `DEFAULT_ADMIN_ROLE`-set engine; bytecode headroom), which is now recorded as an explicit design choice. +- Documented that `forcedTransfer` / `forcedBurn` intentionally remain available **after deactivation** (ERC-8343 named privileged operations, e.g. to sweep a frozen or migrated position), and corrected the absolute "no operation after deactivation" wording in `doc/README.md` / `doc/technical/stablecoin.md` and in the `0_CMTATBaseCore` / `ERC20EnforcementModuleInternal` NatSpec. +- Corrected misleading access-control NatSpec: the cross-chain `burn(uint256)` is gated by `onlySelfBurn` (`BURNER_SELF_ROLE`), not the burner role, and `EnforcementModule`'s `onlyEnforcer` gates the address freeze. +- `doc/README.md`: refreshed the DocumentEngine version table (CMTAT v3.3.0 → DocumentEngine v0.4.0; v3.0.0–v3.2.0 marked as not developed) and added Permit (ERC-2612), Multicall (ERC-6357) and Holder List to the optional-features list. +- Regenerated the **Surya** schema for rc3 — call graphs, inheritance graphs and reports for all 129 contracts, picking up `ReentrancyGuardTransient` in the deployment-variant inheritance and the two new RuleEngine mocks — and re-synced the per-module report copies under `doc/modules/**` with the canonical set (74 files, two ghosts from the deployment-filenames rename dropped, 13 missing reports added). +- Documented the coverage hardfork in `doc/USAGE.md` (with `doc/README.md` pointing to it): why the coverage run uses `prague` while the test run uses `osaka`, and the measured deployment gas of the largest variants against the EIP-7825 cap, showing that the cap constrains the instrumented build only and not the deployed contracts. +- Refreshed the **Slither** and **Aderyn** reports and maintainer feedback against the rc3 source: Slither 158 results (0 High; `calls-loop` rises 28 → 76 purely because the RuleEngine hook was factored into the `virtual` `_callRuleEngineTransferred`, not from any new external call), Aderyn unchanged at 2 High / 10 Low with identical instance counts (3736 → 3826 nSLOC). **Nothing to fix** in either; see [AUDIT.md](./doc/security/AUDIT.md). + +### Dependencies + +- Update the pinned Solidity compiler from 0.8.34 to [0.8.36](https://docs.soliditylang.org/en/v0.8.36/) in `hardhat.config.js` and `foundry.toml`. +- Bump the `npm` devDependency to `^12.0.1`. + +## 3.3.0 - rc2 - 2026-07-23 > **Note:** This version has not been audited. +Commit: `35d8940b40943828c5ea407dc6b22d559d92e4ae` + ### Smart contract #### Added @@ -416,10 +476,22 @@ Commit: `49544f4de1993008acfc9e848d0bf03bd31d8579` - Update Solidity version to [0.8.34](https://www.soliditylang.org/blog/2026/02/18/solidity-0.8.34-release-announcement) in Hardhat config file. -## 3.1.0 - 20251209 +## 3.1.0 - 2025-12-09 + +Commit: `9c96c8eed903cb092e37b089316515ecefbd10fe` > This version is not audited +**Issue** + +Known issue for this release + +- [Frozen tokens may exceed balance and break active-balance assumptions](https://github.com/CMTA/CMTAT/issues/375) (medium) + +- [Operator/Spender Identity Lost in RuleEngine Hooks (burn/mint/cross-chain)](https://github.com/CMTA/CMTAT/issues/376) (low) +- [Operator/Spender Identity Lost in RuleEngine Hooks (burn/mint/cross-chain)](https://github.com/CMTA/CMTAT/issues/376)(Informational) +- [setAddressFrozen(address(0)) should be rejected](https://github.com/CMTA/CMTAT/issues/372) + **Fixed** - [Misleading NatSpec Comments](https://github.com/CMTA/CMTAT/issues/330) @@ -464,13 +536,26 @@ Commit: `49544f4de1993008acfc9e848d0bf03bd31d8579` - Add summary tab for CMTAT framework functionalities to help build CMTAT version for other blockchains - Add audit reports made by [Nethermind Audit Agents](https://auditagent.nethermind.io) - ## 3.0.0 - 2025-08-28 -- Major release audited by [Halborn](https://www.halborn.com) -- Improved comments and documentation +Commit: `69eecc9735ce8ada84fd35801888b05747658939` + +Major release audited by [Halborn](https://www.halborn.com) + +**Issue** -See changelogs of the rc versions for details. +Known issues for this release: + +- [Misleading NatSpec Comments](https://github.com/CMTA/CMTAT/issues/330) +- [Incorrect error parameters in _unfreezeTokens](https://github.com/CMTA/CMTAT/issues/329) +- [CMTATUpgradeableUUPS contract may be not initializable](https://github.com/CMTA/CMTAT/issues/327) +- [CMTATBaseAllowlist - Redundant State Checks](https://github.com/CMTA/CMTAT/issues/332) +- [Snpashot update - CEI pattern](https://github.com/CMTA/CMTAT/issues/326) +- [Operator/Spender Identity Lost in RuleEngine Hooks (burn/mint/cross-chain)](https://github.com/CMTA/CMTAT/issues/376) (low) + +Difference with v.3.0.0 rc version: +- Improved comments and documentation +- See changelogs of the rc versions for details. Main changes with the last audited release (v2.3.0): diff --git a/CLAUDE.md b/CLAUDE.md index af97791e..25493f09 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -81,6 +81,18 @@ npm run coverage # Generate coverage report npm run hardhat:compile # Compile contracts ``` +## Test Catalogue + +The test suite is catalogued per feature module and per deployment version in **[doc/test/Test.md](doc/test/Test.md)** +— a hand-maintained map whose purpose is to make **missing tests easy to find**. + +**Whenever you add, change or remove a test, update `doc/test/Test.md` in the same change:** +- test added → adjust the module's `it` count / scenario, and add a matrix row or column if it covers a new feature or variant; +- test removed → remove it, and note any resulting coverage gap; +- new deployment variant or shared test module → add the corresponding matrix column / row and module-reference entry. + +An out-of-date catalogue is worse than none — keep it in sync. + ## 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: @@ -99,6 +111,31 @@ DeactivateReportGas=true npx hardhat test - `hardhat.config.js` - Build configuration (EVM & Solidity version) - `package.json` - Dependencies and scripts +## Documentation Lookup + +Before stating that something is **not documented**, search **all** of the documentation surfaces below. They +overlap and none of them is authoritative on its own — a rationale is often recorded in one place and the +per-function facts in another. + +| Surface | What lives there | +| --- | --- | +| `doc/README.md` | The largest document. Standards mapping (ERC-3643, ERC-7943, ERC-7551, ERC-7802), architecture, module list, access control, engines, and the **Enforcement / Transfer restriction** chapter — including behavioural rationales such as why pause does not block issuer mint/burn. | +| `doc/USAGE.md` | Build, test, deploy and tooling instructions. | +| `doc/modules/**` | Per-module reference pages (`core/`, `extensions/`, `options/`, `controllers/`), one per module, with per-function requirements, events and errors. | +| `doc/technical/**` | Cross-cutting topics: `access-control.md`, `cross-chain-bridge-integration.md`, `deployment.md`, `upgradeable.md`, `stablecoin.md`, ERC-specific notes. | +| `doc/SUMMARY.md` | Short index of modules, deployment variants and roles. | +| `doc/security/**` | Audit reports and maintainer feedback. | +| `contracts/**` NatSpec + inline comments | Design rationales are frequently recorded only in code comments (e.g. the `onlyTokenBridge` `msg.sender` justification). | + +Practical rule: grep the whole `doc/` tree **and** `contracts/`, not a subset. + +```bash +grep -rn -i "" doc/ contracts/ --include=*.md --include=*.sol | grep -v doc/hardhat-compilation +``` + +Exclude `doc/hardhat-compilation/` (flattened build artifacts, including vendored OpenZeppelin comments) — matches +there are **not** CMTAT statements and must not be quoted as project documentation. + ## Note After each implemented feature or fix, provide a one-line GitHub commit message for all changes since the last commit. diff --git a/README.md b/README.md index 3d251ad6..30a2937a 100644 --- a/README.md +++ b/README.md @@ -191,7 +191,15 @@ CMTAT has been audited by [ABDK](https://abdk.consulting) (v1.0, v2.3.0) and [Ha 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). -Per-tool reports, maintainer feedback, and dispositions are collected in **[doc/security/AUDIT.md](./doc/security/AUDIT.md)**. The v3.3.0 static-analysis run (Slither 0.11.5 — 110 results; Aderyn 0.6.5 — 2 High, 10 Low) surfaced **no exploitable finding requiring a code fix**: every result is a false positive, a documented design choice, an environment note, or a style/optimization item. +Per-tool reports, maintainer feedback, and dispositions are collected in **[doc/security/AUDIT.md](./doc/security/AUDIT.md)**. + +**Last version** + +NethermindAudit Agent tool + +Report: [audit_agent_report_v3.3.0-rc2.pdf](./doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2.pdf) · Maintainer triage: [audit_agent_report_v3.3.0-rc2-feedback.md](./doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md) + +> Note: This scan was performed by an AI-powered automated tool, not a formal human-led audit. See [SECURITY.md](./SECURITY.md) for the responsible disclosure policy. @@ -236,6 +244,8 @@ npm run test npm run coverage ``` +The test suite is catalogued per feature module and per deployment version in **[doc/test/Test.md](./doc/test/Test.md)** — a map of what is tested where, kept up to date to make missing coverage easy to find. + ## Documentation Full specification, architecture details, module descriptions, and ERC compatibility tables are in **[doc/README.md](./doc/README.md)**. A short module/variant overview is in [doc/SUMMARY.md](./doc/SUMMARY.md). @@ -257,5 +267,5 @@ Focused, subsystem-level guides live in [`doc/technical/`](./doc/technical/): - **Architecture & operations** — [Deployment variants](./doc/technical/deployment.md) · [Lifecycle: pause & deactivation](./doc/technical/lifecycle.md) · [Access control (roles)](./doc/technical/access-control.md) - **Standards** — [ERC-3643 implementation](./doc/technical/erc-3643-implementation.md) · [ERC-7551 (eWpG)](./doc/technical/erc7551.md) · [ERC-7943 (uRWA) integration](./doc/technical/erc-7943-uRWA-integration.md) · [Documents (ERC-1643)](./doc/technical/document.md) · [RuleEngine (ERC-1404)](./doc/technical/ruleengine-integration.md) -- **Features** — [Holder list](./doc/technical/holder-list.md) · [Snapshots](./doc/technical/snapshot.md) · [Debt & credit events](./doc/technical/debt.md) · [Permit & Multicall](./doc/technical/permit-multicall.md) · [Cross-chain bridge integration](./doc/technical/cross-chain-bridge-integration.md) -- **Use cases & porting** — [Stablecoins](./doc/technical/stablecoin.md) · [ERC-1450 integration](./doc/technical/erc-1450-integration.md) · [ERC-1450 improvements](./doc/technical/erc-1450-improvement.md) · [Guideline: porting to a new blockchain](./doc/technical/guideline-new-blockchain.md) +- **Features** — [Holder list](./doc/technical/holder-list.md) · [Snapshots](./doc/technical/snapshot.md) · [Debt & credit events](./doc/technical/debt.md) · [Permit & Multicall](./doc/technical/permit-multicall.md) · [Cross-chain bridge integration](./doc/technical/cross-chain-bridge-integration.md) · [Spend allowance event](./doc/technical/allowance-spend-event.md) +- **Use cases & porting** — [Stablecoins](./doc/technical/stablecoin.md) · [CMTAT specification vs implementation](./doc/technical/cmtat-specification-analyse.md) · [Porting to another blockchain](https://github.com/CMTA/CMTAT-equivalency-assessment) diff --git a/contracts/deployment/CMTATStandardStandalone.sol b/contracts/deployment/CMTATStandardStandalone.sol index 1aff14bb..4030f927 100644 --- a/contracts/deployment/CMTATStandardStandalone.sol +++ b/contracts/deployment/CMTATStandardStandalone.sol @@ -1,8 +1,11 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol"; +import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol"; +import {ValidationModuleRuleEngine} from "../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol"; +import {IRuleEngine} from "../interfaces/engine/IRuleEngine.sol"; import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol"; import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol"; @@ -10,7 +13,7 @@ import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol"; /** * @title CMTAT standard version for a standalone deployment (without proxy) — no snapshot engine */ -contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement { +contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement, ReentrancyGuardTransient { /** * @notice Contract version for standalone deployment * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -35,4 +38,28 @@ contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement { engines_ ); } + + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } } diff --git a/contracts/deployment/CMTATStandardUpgradeable.sol b/contracts/deployment/CMTATStandardUpgradeable.sol index 7c4a4a5f..13f2b520 100644 --- a/contracts/deployment/CMTATStandardUpgradeable.sol +++ b/contracts/deployment/CMTATStandardUpgradeable.sol @@ -1,15 +1,18 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol"; +import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol"; +import {ValidationModuleRuleEngine} from "../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol"; +import {IRuleEngine} from "../interfaces/engine/IRuleEngine.sol"; import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol"; /** * @title CMTAT standard version for a proxy deployment (Transparent or Beacon proxy) — no snapshot engine */ -contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement { +contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement, ReentrancyGuardTransient { /** * @notice Contract version for the deployment with a proxy * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -21,4 +24,28 @@ contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement { // Disable the possibility to initialize the implementation _disableInitializers(); } + + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } } diff --git a/contracts/deployment/CMTATUpgradeableUUPS.sol b/contracts/deployment/CMTATUpgradeableUUPS.sol index 72a6eae8..3ba09ecc 100644 --- a/contracts/deployment/CMTATUpgradeableUUPS.sol +++ b/contracts/deployment/CMTATUpgradeableUUPS.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.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 dded7613..f67bdc0f 100644 --- a/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol +++ b/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseERC1363} from "../../modules/8_CMTATBaseERC1363.sol"; import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol"; diff --git a/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol b/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol index 3d76e8a0..5cae6f7d 100644 --- a/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol +++ b/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; 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 dc44b8d2..92db90f4 100644 --- a/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol +++ b/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol @@ -1,15 +1,18 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol"; +import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol"; +import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol"; +import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.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) */ -contract CMTATStandaloneERC7551 is CMTATBaseERC7551 { +contract CMTATStandaloneERC7551 is CMTATBaseERC7551, ReentrancyGuardTransient { /** * @notice Contract version for standalone deployment * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -39,4 +42,28 @@ contract CMTATStandaloneERC7551 is CMTATBaseERC7551 { + + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } } diff --git a/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol b/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol index 4e3250a1..ec5e49bf 100644 --- a/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol +++ b/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol @@ -1,14 +1,17 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol"; import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol"; +import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol"; +import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol"; +import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol"; /** * @title CMTAT version for a proxy deployment (Transparent or Beacon proxy) */ -contract CMTATUpgradeableERC7551 is CMTATBaseERC7551 { +contract CMTATUpgradeableERC7551 is CMTATBaseERC7551, ReentrancyGuardTransient { /** * @notice Contract version for the deployment with a proxy * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -20,4 +23,28 @@ contract CMTATUpgradeableERC7551 is CMTATBaseERC7551 { // Disable the possibility to initialize the implementation _disableInitializers(); } + + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } } diff --git a/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol b/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol index fc05184c..54585258 100644 --- a/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol +++ b/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseAllowlist} from "../../modules/3_CMTATBaseAllowlist.sol"; import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol"; diff --git a/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol b/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol index 082af72c..24b8acbb 100644 --- a/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol +++ b/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; 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 af677d4b..274a8405 100644 --- a/contracts/deployment/debt/CMTATStandaloneDebt.sol +++ b/contracts/deployment/debt/CMTATStandaloneDebt.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol"; import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol"; diff --git a/contracts/deployment/debt/CMTATUpgradeableDebt.sol b/contracts/deployment/debt/CMTATUpgradeableDebt.sol index bdf6786a..bd27b4fb 100644 --- a/contracts/deployment/debt/CMTATUpgradeableDebt.sol +++ b/contracts/deployment/debt/CMTATUpgradeableDebt.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol"; /** diff --git a/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol b/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol index 00489ec8..e113c095 100644 --- a/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol +++ b/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol"; import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol"; diff --git a/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol b/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol index 89e22b73..e7de40e5 100644 --- a/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol +++ b/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol"; /** diff --git a/contracts/deployment/holderList/CMTATStandaloneHolderList.sol b/contracts/deployment/holderList/CMTATStandaloneHolderList.sol index c73e8baa..2833815b 100644 --- a/contracts/deployment/holderList/CMTATStandaloneHolderList.sol +++ b/contracts/deployment/holderList/CMTATStandaloneHolderList.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseHolderList} from "../../modules/8_CMTATBaseHolderList.sol"; import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol"; diff --git a/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol b/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol index a7178e15..724b988d 100644 --- a/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol +++ b/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseHolderList} from "../../modules/8_CMTATBaseHolderList.sol"; import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol"; diff --git a/contracts/deployment/light/CMTATStandaloneLight.sol b/contracts/deployment/light/CMTATStandaloneLight.sol index 5cad80e6..3c6f589a 100644 --- a/contracts/deployment/light/CMTATStandaloneLight.sol +++ b/contracts/deployment/light/CMTATStandaloneLight.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseCore} from "../../modules/0_CMTATBaseCore.sol"; import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol"; diff --git a/contracts/deployment/light/CMTATUpgradeableLight.sol b/contracts/deployment/light/CMTATUpgradeableLight.sol index 00a6aab9..96ac0341 100644 --- a/contracts/deployment/light/CMTATUpgradeableLight.sol +++ b/contracts/deployment/light/CMTATUpgradeableLight.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseCore} from "../../modules/0_CMTATBaseCore.sol"; diff --git a/contracts/deployment/permit/CMTATStandalonePermit.sol b/contracts/deployment/permit/CMTATStandalonePermit.sol index 5a013fad..83b09c96 100644 --- a/contracts/deployment/permit/CMTATStandalonePermit.sol +++ b/contracts/deployment/permit/CMTATStandalonePermit.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol"; import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol"; diff --git a/contracts/deployment/permit/CMTATUpgradeablePermit.sol b/contracts/deployment/permit/CMTATUpgradeablePermit.sol index 9eac96e9..3cb06896 100644 --- a/contracts/deployment/permit/CMTATUpgradeablePermit.sol +++ b/contracts/deployment/permit/CMTATUpgradeablePermit.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol"; diff --git a/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol b/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol index 3fc248c0..363a4675 100644 --- a/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol +++ b/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol @@ -1,8 +1,11 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseERC2771Snapshot} from "../../modules/7_CMTATBaseERC2771Snapshot.sol"; +import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol"; +import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol"; +import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol"; import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol"; import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol"; @@ -10,7 +13,7 @@ import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.so /** * @title CMTAT with snapshot engine — standalone deployment (without proxy) */ -contract CMTATStandaloneSnapshot is CMTATBaseERC2771Snapshot { +contract CMTATStandaloneSnapshot is CMTATBaseERC2771Snapshot, ReentrancyGuardTransient { /** * @notice Contract version for standalone deployment with snapshot engine * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -35,4 +38,28 @@ contract CMTATStandaloneSnapshot is CMTATBaseERC2771Snapshot { engines_ ); } + + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } } diff --git a/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol b/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol index b7bd0b7c..073bb078 100644 --- a/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol +++ b/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol @@ -1,15 +1,18 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseERC2771Snapshot} from "../../modules/7_CMTATBaseERC2771Snapshot.sol"; +import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol"; +import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol"; +import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol"; import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol"; /** * @title CMTAT with snapshot engine — proxy deployment (Transparent or Beacon proxy) */ -contract CMTATUpgradeableSnapshot is CMTATBaseERC2771Snapshot { +contract CMTATUpgradeableSnapshot is CMTATBaseERC2771Snapshot, ReentrancyGuardTransient { /** * @notice Contract version for the deployment with a proxy, with snapshot engine * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -21,4 +24,28 @@ contract CMTATUpgradeableSnapshot is CMTATBaseERC2771Snapshot { // Disable the possibility to initialize the implementation _disableInitializers(); } + + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } } diff --git a/contracts/interfaces/engine/IDebtEngine.sol b/contracts/interfaces/engine/IDebtEngine.sol index 43e1107e..fdb01cdd 100644 --- a/contracts/interfaces/engine/IDebtEngine.sol +++ b/contracts/interfaces/engine/IDebtEngine.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol"; /* diff --git a/contracts/interfaces/engine/IDocumentEngine.sol b/contracts/interfaces/engine/IDocumentEngine.sol index dc5f1904..f5eeecd6 100644 --- a/contracts/interfaces/engine/IDocumentEngine.sol +++ b/contracts/interfaces/engine/IDocumentEngine.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IERC1643} from "../tokenization/draft-IERC1643.sol"; /* diff --git a/contracts/interfaces/engine/IRuleEngine.sol b/contracts/interfaces/engine/IRuleEngine.sol index 21075e9c..18aa689f 100644 --- a/contracts/interfaces/engine/IRuleEngine.sol +++ b/contracts/interfaces/engine/IRuleEngine.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IERC1404Extend} from "../tokenization/draft-IERC1404.sol"; import {IERC3643IComplianceContract} from "../tokenization/IERC3643Partial.sol"; @@ -14,15 +14,30 @@ interface IRuleEngine is IERC7551Compliance, IERC3643IComplianceContract, IERC16 /** * @notice * Function called whenever tokens are transferred from one wallet to another - * @dev + * @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 + * + * WARNING - zero-value calls are permissionless. ERC-20 requires transfers of `0` to be + * treated as normal transfers, and OpenZeppelin's `_spendAllowance` consumes no allowance + * when `value == 0`. Any address can therefore call `transferFrom(victim, anyone, 0)` on the + * token and reach this callback for an arbitrary `from`, with itself as `spender`, without + * ever having been approved. The token deliberately does not suppress the notification, + * because doing so would make its compliance notifications inconsistent with its own + * ERC-20 transfer semantics. + * + * Implementations MUST therefore treat `value == 0` as carrying no economic meaning: any + * stateful rule (cooldown, holding period, quota, tax bucket, counter, holder tracking, ...) + * MUST be a no-op for a zero value, otherwise an attacker can desynchronize policy state + * from balances, or keep a holder permanently restricted, at no cost. The same applies to + * the 3-argument ERC-3643 overload, which a zero-value `transfer(to, 0)` reaches the same way. + * * @param spender spender address (sender) * @param from token holder address * @param to receiver address - * @param value value of tokens involved in the transfer + * @param value value of tokens involved in the transfer; MAY be `0` — see the warning above */ function transferred(address spender, address from, address to, uint256 value) external; } diff --git a/contracts/interfaces/engine/ISnapshotEngine.sol b/contracts/interfaces/engine/ISnapshotEngine.sol index 05e8540d..62a6a8ab 100644 --- a/contracts/interfaces/engine/ISnapshotEngine.sol +++ b/contracts/interfaces/engine/ISnapshotEngine.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* * @dev minimum interface to define a SnapshotEngine diff --git a/contracts/interfaces/modules/IAllowlistModule.sol b/contracts/interfaces/modules/IAllowlistModule.sol index ea14a029..35b436a2 100644 --- a/contracts/interfaces/modules/IAllowlistModule.sol +++ b/contracts/interfaces/modules/IAllowlistModule.sol @@ -1,7 +1,7 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* * @title Allowlist Module Interface diff --git a/contracts/interfaces/modules/IDebtEngineModule.sol b/contracts/interfaces/modules/IDebtEngineModule.sol index d6bda020..db27cffe 100644 --- a/contracts/interfaces/modules/IDebtEngineModule.sol +++ b/contracts/interfaces/modules/IDebtEngineModule.sol @@ -1,7 +1,7 @@ //SPDX-License-Identifier: MPL-2.0 import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol"; import {IDebtEngine} from "../engine/IDebtEngine.sol"; -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @notice interface to represent DebtEngineModule (debt information and credit events.) */ diff --git a/contracts/interfaces/modules/IDebtModule.sol b/contracts/interfaces/modules/IDebtModule.sol index b189de9f..6fa43185 100644 --- a/contracts/interfaces/modules/IDebtModule.sol +++ b/contracts/interfaces/modules/IDebtModule.sol @@ -1,7 +1,7 @@ //SPDX-License-Identifier: MPL-2.0 import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol"; -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @notice interface to represent DebtModule (debt information and credit events.) */ diff --git a/contracts/interfaces/modules/IDocumentEngineModule.sol b/contracts/interfaces/modules/IDocumentEngineModule.sol index e736a6c3..e3981201 100644 --- a/contracts/interfaces/modules/IDocumentEngineModule.sol +++ b/contracts/interfaces/modules/IDocumentEngineModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IERC1643} from "../tokenization/draft-IERC1643.sol"; diff --git a/contracts/interfaces/modules/IHolderListModule.sol b/contracts/interfaces/modules/IHolderListModule.sol index 525fd3e0..cd990db7 100644 --- a/contracts/interfaces/modules/IHolderListModule.sol +++ b/contracts/interfaces/modules/IHolderListModule.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* * @title Holder List Module Interface diff --git a/contracts/interfaces/modules/ISnapshotEngineModule.sol b/contracts/interfaces/modules/ISnapshotEngineModule.sol index 5273cbe9..1f13a78e 100644 --- a/contracts/interfaces/modules/ISnapshotEngineModule.sol +++ b/contracts/interfaces/modules/ISnapshotEngineModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Engine === */ import {ISnapshotEngine} from "../engine/ISnapshotEngine.sol"; diff --git a/contracts/interfaces/technical/ICMTATConstructor.sol b/contracts/interfaces/technical/ICMTATConstructor.sol index d748af03..b2b76154 100644 --- a/contracts/interfaces/technical/ICMTATConstructor.sol +++ b/contracts/interfaces/technical/ICMTATConstructor.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IRuleEngine} from "../engine/IRuleEngine.sol"; import {IERC1643CMTAT} from "../tokenization/draft-IERC1643CMTAT.sol"; diff --git a/contracts/interfaces/technical/IERC20Allowance.sol b/contracts/interfaces/technical/IERC20Allowance.sol index 2ea5845e..4b0ecc8d 100644 --- a/contracts/interfaces/technical/IERC20Allowance.sol +++ b/contracts/interfaces/technical/IERC20Allowance.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @title IERC20Allowance @@ -9,19 +9,28 @@ pragma solidity ^0.8.20; interface IERC20Allowance { /* ============ Events ============ */ /** - * @notice Emitted when a `spender` spends a `value` amount of tokens on behalf of an `account`. + * @notice Emitted when a `spender` uses a `value` amount of an `account`'s allowance. * @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. + * - Similar in intent to the ERC-20 `Approval` event, but signals *consumption* of an + * allowance rather than its granting. + * - Emitted by the allowance-consuming entry points: `transferFrom` (ERC20BaseModule), + * `burnFrom` (ERC20CrossChainModule), and `forcedTransfer` (ERC20EnforcementModule) when the + * latter reduces a finite owner→recipient allowance. + * - WARNING - this event does NOT, by itself, imply that the on-chain allowance decreased. + * It is emitted on *every* successful allowance-consuming `transferFrom` / `burnFrom`, + * including when the allowance is infinite (`type(uint256).max`), in which case OpenZeppelin + * leaves the allowance unchanged. `value` is the amount used, not the size of any reduction. + * - For `forcedTransfer`, `Spend` is emitted only when the allowance is finite and non-zero + * (the case where it is actually reduced), and `value` is the amount taken from it (capped by + * the allowance). `forcedTransfer` does not emit `Approval` for that reduction. + * - To reconstruct the current allowance, read `allowance(owner, spender)` — never accumulate + * `Spend` (or `Approval`) events. + * - Event ordering differs between the emit sites: `transferFrom` emits `Transfer` then + * `Spend`; `burnFrom` emits `Spend` then `Transfer` then `BurnFrom`. See + * [doc/technical/allowance-spend-event.md](../../../doc/technical/allowance-spend-event.md). * @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. + * @param value The amount of allowance used (not necessarily the amount by which it decreased). */ event Spend(address indexed account, address indexed spender, uint256 value); } diff --git a/contracts/interfaces/technical/IERC5679.sol b/contracts/interfaces/technical/IERC5679.sol index e40bd5c2..ad8052d3 100644 --- a/contracts/interfaces/technical/IERC5679.sol +++ b/contracts/interfaces/technical/IERC5679.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol"; diff --git a/contracts/interfaces/technical/IERC7802.sol b/contracts/interfaces/technical/IERC7802.sol index eaff6a9a..8d7d376e 100644 --- a/contracts/interfaces/technical/IERC7802.sol +++ b/contracts/interfaces/technical/IERC7802.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // From https://github.com/ethereum-optimism/optimism/blob/op-node/v1.13.2/packages/contracts-bedrock/interfaces/L2/IERC7802.sol -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; diff --git a/contracts/interfaces/technical/IGetCCIPAdmin.sol b/contracts/interfaces/technical/IGetCCIPAdmin.sol index e7fc916d..f0530c0f 100644 --- a/contracts/interfaces/technical/IGetCCIPAdmin.sol +++ b/contracts/interfaces/technical/IGetCCIPAdmin.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; interface IGetCCIPAdmin { event CCIPAdminTransferred(address indexed previousAdmin, address indexed newAdmin); diff --git a/contracts/interfaces/technical/IMintBurnToken.sol b/contracts/interfaces/technical/IMintBurnToken.sol index 5f37f004..6bfb5de6 100644 --- a/contracts/interfaces/technical/IMintBurnToken.sol +++ b/contracts/interfaces/technical/IMintBurnToken.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** diff --git a/contracts/interfaces/tokenization/ICMTAT.sol b/contracts/interfaces/tokenization/ICMTAT.sol index c0a27c8f..2cb9e111 100644 --- a/contracts/interfaces/tokenization/ICMTAT.sol +++ b/contracts/interfaces/tokenization/ICMTAT.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IERC1643CMTAT} from "./draft-IERC1643CMTAT.sol"; import {IERC1643} from "./draft-IERC1643.sol"; diff --git a/contracts/interfaces/tokenization/IERC3643Partial.sol b/contracts/interfaces/tokenization/IERC3643Partial.sol index 01d65833..bacae33d 100644 --- a/contracts/interfaces/tokenization/IERC3643Partial.sol +++ b/contracts/interfaces/tokenization/IERC3643Partial.sol @@ -7,7 +7,7 @@ * (e.g., `amount` → `value`). */ -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IERC7943FungibleEnforcement} from "./draft-IERC7943.sol"; diff --git a/contracts/interfaces/tokenization/draft-IERC1404.sol b/contracts/interfaces/tokenization/draft-IERC1404.sol index b53a1deb..2c301a09 100644 --- a/contracts/interfaces/tokenization/draft-IERC1404.sol +++ b/contracts/interfaces/tokenization/draft-IERC1404.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* * @dev Contrary to the ERC-1404, diff --git a/contracts/interfaces/tokenization/draft-IERC1643.sol b/contracts/interfaces/tokenization/draft-IERC1643.sol index f95493c2..b09bffeb 100644 --- a/contracts/interfaces/tokenization/draft-IERC1643.sol +++ b/contracts/interfaces/tokenization/draft-IERC1643.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @title IERC1643 Document Management diff --git a/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol b/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol index 86c4f529..a71c1bae 100644 --- a/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol +++ b/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; interface IERC1643CMTAT { struct DocumentInfo { string name; diff --git a/contracts/interfaces/tokenization/draft-IERC7551.sol b/contracts/interfaces/tokenization/draft-IERC7551.sol index d32676b3..d6bebf23 100644 --- a/contracts/interfaces/tokenization/draft-IERC7551.sol +++ b/contracts/interfaces/tokenization/draft-IERC7551.sol @@ -2,7 +2,7 @@ import {IERC3643ComplianceRead} from "./IERC3643Partial.sol"; import {IERC5679Mint, IERC5679Burn} from "../technical/IERC5679.sol"; -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** diff --git a/contracts/interfaces/tokenization/draft-IERC7943.sol b/contracts/interfaces/tokenization/draft-IERC7943.sol index 74355cbe..ecc47ec5 100644 --- a/contracts/interfaces/tokenization/draft-IERC7943.sol +++ b/contracts/interfaces/tokenization/draft-IERC7943.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @notice Enforcement Interface for ERC-20 based implementations common with ERC-3643 interface. diff --git a/contracts/interfaces/tokenization/draft-IERC8343.sol b/contracts/interfaces/tokenization/draft-IERC8343.sol index 2fa24d93..14c5e7f1 100644 --- a/contracts/interfaces/tokenization/draft-IERC8343.sol +++ b/contracts/interfaces/tokenization/draft-IERC8343.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @title IERC8343 - Contract Deactivation diff --git a/contracts/library/ERC1404ExtendInterfaceId.sol b/contracts/library/ERC1404ExtendInterfaceId.sol index 6f620836..62528770 100644 --- a/contracts/library/ERC1404ExtendInterfaceId.sol +++ b/contracts/library/ERC1404ExtendInterfaceId.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; library ERC1404ExtendInterfaceId { /** diff --git a/contracts/library/RuleEngineInterfaceId.sol b/contracts/library/RuleEngineInterfaceId.sol index 76b0b5b8..1371ed82 100644 --- a/contracts/library/RuleEngineInterfaceId.sol +++ b/contracts/library/RuleEngineInterfaceId.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; library RuleEngineInterfaceId { bytes4 public constant RULE_ENGINE_INTERFACE_ID = 0x20c49ce7; diff --git a/contracts/mocks/CMTATMsgDataMock.sol b/contracts/mocks/CMTATMsgDataMock.sol index b5335cdf..c7972c59 100644 --- a/contracts/mocks/CMTATMsgDataMock.sol +++ b/contracts/mocks/CMTATMsgDataMock.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATStandardStandalone} from "../deployment/CMTATStandardStandalone.sol"; import {CMTATStandaloneAllowlist} from "../deployment/allowlist/CMTATStandaloneAllowlist.sol"; diff --git a/contracts/mocks/DebtEngineMock.sol b/contracts/mocks/DebtEngineMock.sol index 289a6e11..8afd3a13 100644 --- a/contracts/mocks/DebtEngineMock.sol +++ b/contracts/mocks/DebtEngineMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IDebtEngine} from "../interfaces/engine/IDebtEngine.sol"; interface IDebtEngineMock is IDebtEngine { function setDebt(DebtInformation calldata debt_) external; diff --git a/contracts/mocks/DocumentEngineMock.sol b/contracts/mocks/DocumentEngineMock.sol index de03ddb6..7d82a236 100644 --- a/contracts/mocks/DocumentEngineMock.sol +++ b/contracts/mocks/DocumentEngineMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {DocumentERC1643Module} from "../modules/wrapper/extensions/DocumentERC1643Module.sol"; diff --git a/contracts/mocks/ERC1363ReceiverMock.sol b/contracts/mocks/ERC1363ReceiverMock.sol index d51035f1..a049eab9 100644 --- a/contracts/mocks/ERC1363ReceiverMock.sol +++ b/contracts/mocks/ERC1363ReceiverMock.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import "@openzeppelin/contracts/interfaces/IERC1363Receiver.sol"; diff --git a/contracts/mocks/ERC165Helper/ExampleAccessControlERC165.sol b/contracts/mocks/ERC165Helper/ExampleAccessControlERC165.sol index feb7b8d3..97d3cee0 100644 --- a/contracts/mocks/ERC165Helper/ExampleAccessControlERC165.sol +++ b/contracts/mocks/ERC165Helper/ExampleAccessControlERC165.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /// @notice ERC-165 interface for AccessControlUpgradeable interface IAccessControlUpgradeable165 { diff --git a/contracts/mocks/ERC165Helper/ExampleERC1404ExtendERC165.sol b/contracts/mocks/ERC165Helper/ExampleERC1404ExtendERC165.sol index 9a40a215..f3aaca56 100644 --- a/contracts/mocks/ERC165Helper/ExampleERC1404ExtendERC165.sol +++ b/contracts/mocks/ERC165Helper/ExampleERC1404ExtendERC165.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; interface IERC1404ExtendERC165 { function detectTransferRestrictionFrom( diff --git a/contracts/mocks/ERC165Helper/ExampleRuleEngineERC165.sol b/contracts/mocks/ERC165Helper/ExampleRuleEngineERC165.sol index c2c1c814..18607078 100644 --- a/contracts/mocks/ERC165Helper/ExampleRuleEngineERC165.sol +++ b/contracts/mocks/ERC165Helper/ExampleRuleEngineERC165.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; interface IRuleEngineERC165 { function transferred(address from, address to, uint256 value) external; diff --git a/contracts/mocks/ERC721MockUpgradeable.sol b/contracts/mocks/ERC721MockUpgradeable.sol index 999f34d4..c6b5a44b 100644 --- a/contracts/mocks/ERC721MockUpgradeable.sol +++ b/contracts/mocks/ERC721MockUpgradeable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; diff --git a/contracts/mocks/MinimalForwarderMock.sol b/contracts/mocks/MinimalForwarderMock.sol index 66dde3cd..2a755df6 100644 --- a/contracts/mocks/MinimalForwarderMock.sol +++ b/contracts/mocks/MinimalForwarderMock.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {ERC2771ForwarderUpgradeable} from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ForwarderUpgradeable.sol"; diff --git a/contracts/mocks/RuleEngine/CodeList.sol b/contracts/mocks/RuleEngine/CodeList.sol index 427068f2..2ef6dba0 100644 --- a/contracts/mocks/RuleEngine/CodeList.sol +++ b/contracts/mocks/RuleEngine/CodeList.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; abstract contract CodeList { // Used by RuleMock.sol diff --git a/contracts/mocks/RuleEngine/RuleEngineMock.sol b/contracts/mocks/RuleEngine/RuleEngineMock.sol index 5bccc084..2c0e627b 100644 --- a/contracts/mocks/RuleEngine/RuleEngineMock.sol +++ b/contracts/mocks/RuleEngine/RuleEngineMock.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IRule} from "./interfaces/IRule.sol"; import {IRuleEngineMock} from "./interfaces/IRuleEngineMock.sol"; diff --git a/contracts/mocks/RuleEngine/RuleEngineReentrantMock.sol b/contracts/mocks/RuleEngine/RuleEngineReentrantMock.sol new file mode 100644 index 00000000..35399741 --- /dev/null +++ b/contracts/mocks/RuleEngine/RuleEngineReentrantMock.sol @@ -0,0 +1,104 @@ +//SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.24; + +import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {ERC165, IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {RuleEngineInterfaceId} from "../../library/RuleEngineInterfaceId.sol"; + +/** +* @title A malicious RuleEngine that reenters the token during `transferred`. +* @dev +* TESTING ONLY - never deploy this. +* +* The token calls `transferred(...)` from `_checkTransferred`, i.e. after the active-balance +* (frozen) check but before `ERC20Upgradeable._transfer` moves any balance. A rule engine that +* calls back into the token during that window is re-evaluated against the *same* pre-transfer +* balance, so without a reentrancy guard both the outer and the inner transfer can independently +* pass `_checkActiveBalanceAndRevert` and together move more than the unfrozen amount. +* +* This mock reproduces exactly that: on the first `transferred` callback it performs one nested +* `transferFrom`, then disarms itself so the nested call terminates the recursion. +* +* It intentionally implements no rules: every `canTransfer*` returns true, so the only behaviour +* under test is the reentrancy, not any compliance logic. +*/ +contract RuleEngineReentrantMock is ERC165, IRuleEngine { + IERC20 public token; + address public victim; + address public attacker; + uint256 public nestedValue; + bool public armed; + /// @notice True once a nested `transferFrom` has been attempted. + bool public reentered; + /// @notice True if the nested `transferFrom` returned without reverting. + bool public reentrySucceeded; + /// @notice When true, the nested call is made without try/catch so its revert bubbles up. + bool public bubbleRevert; + + function setBubbleRevert(bool bubble_) external { + bubbleRevert = bubble_; + } + + function arm( + IERC20 token_, + address victim_, + address attacker_, + uint256 nestedValue_ + ) external { + token = token_; + victim = victim_; + attacker = attacker_; + nestedValue = nestedValue_; + armed = true; + reentered = false; + reentrySucceeded = false; + } + + /* ============ IRuleEngine - state ============ */ + + function transferred(address /*spender*/, address from, address to, uint256 value) public override { + _attack(from, to, value); + } + + function transferred(address from, address to, uint256 value) public override { + _attack(from, to, value); + } + + /* ============ IRuleEngine - views ============ */ + + function canTransfer(address, address, uint256) public pure override returns (bool) { + return true; + } + + function canTransferFrom(address, address, address, uint256) public pure override returns (bool) { + return true; + } + + function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { + return interfaceId == RuleEngineInterfaceId.RULE_ENGINE_INTERFACE_ID || super.supportsInterface(interfaceId); + } + + /* ============ Internal ============ */ + + function _attack(address /*from*/, address /*to*/, uint256 /*value*/) internal { + if (!armed) { + return; + } + // Disarm first so the nested call does not recurse forever + armed = false; + reentered = true; + // Reenter the token while the outer transfer has not yet moved any balance + if (bubbleRevert) { + token.transferFrom(victim, attacker, nestedValue); + reentrySucceeded = true; + return; + } + try token.transferFrom(victim, attacker, nestedValue) returns (bool) { + reentrySucceeded = true; + } catch { + reentrySucceeded = false; + } + } +} diff --git a/contracts/mocks/RuleEngine/RuleEngineSpenderRecorderMock.sol b/contracts/mocks/RuleEngine/RuleEngineSpenderRecorderMock.sol new file mode 100644 index 00000000..daa3cd80 --- /dev/null +++ b/contracts/mocks/RuleEngine/RuleEngineSpenderRecorderMock.sol @@ -0,0 +1,59 @@ +//SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.24; + +import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol"; +import {ERC165, IERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol"; +import {RuleEngineInterfaceId} from "../../library/RuleEngineInterfaceId.sol"; + +/** +* @title A permissive RuleEngine that records which `transferred` overload the token invoked. +* @dev +* TESTING ONLY - never deploy this. +* +* CMTAT routes the RuleEngine `transferred` callback through +* {ValidationModuleRuleEngine-_callRuleEngineTransferred}, which selects the spender-aware +* 4-argument overload when a spender is present (a `transferFrom`) and the legacy 3-argument +* overload otherwise (a direct `transfer`, `mint` or `burn`). This mock records the arguments +* seen on the last callback so a test can assert the correct overload was taken - i.e. that the +* `spender != address(0)` dispatch was not inverted. +* +* Every `canTransfer*` returns true, so the only behaviour under test is the overload selection, +* not any compliance logic. +*/ +contract RuleEngineSpenderRecorderMock is ERC165, IRuleEngine { + /// @notice Spender seen on the last callback (address(0) on the 3-arg legacy path). + address public lastSpender; + /// @notice True if the last callback used the spender-aware 4-argument overload. + bool public lastWasSpenderOverload; + /// @notice Number of callbacks received across both overloads. + uint256 public callCount; + + /* ============ IRuleEngine - state ============ */ + + function transferred(address spender, address /*from*/, address /*to*/, uint256 /*value*/) public override { + lastSpender = spender; + lastWasSpenderOverload = true; + callCount += 1; + } + + function transferred(address /*from*/, address /*to*/, uint256 /*value*/) public override { + lastSpender = address(0); + lastWasSpenderOverload = false; + callCount += 1; + } + + /* ============ IRuleEngine - views ============ */ + + function canTransfer(address, address, uint256) public pure override returns (bool) { + return true; + } + + function canTransferFrom(address, address, address, uint256) public pure override returns (bool) { + return true; + } + + function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { + return interfaceId == RuleEngineInterfaceId.RULE_ENGINE_INTERFACE_ID || super.supportsInterface(interfaceId); + } +} diff --git a/contracts/mocks/RuleEngine/RuleMock.sol b/contracts/mocks/RuleEngine/RuleMock.sol index 6af3d61a..d5ebcc30 100644 --- a/contracts/mocks/RuleEngine/RuleMock.sol +++ b/contracts/mocks/RuleEngine/RuleMock.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IRule} from "./interfaces/IRule.sol"; import {CodeList} from "./CodeList.sol"; diff --git a/contracts/mocks/RuleEngine/RuleMockMint.sol b/contracts/mocks/RuleEngine/RuleMockMint.sol index 9d5b5d1a..fd824f71 100644 --- a/contracts/mocks/RuleEngine/RuleMockMint.sol +++ b/contracts/mocks/RuleEngine/RuleMockMint.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IRule} from "./interfaces/IRule.sol"; import {CodeList} from "./CodeList.sol"; diff --git a/contracts/mocks/RuleEngine/RuleSpenderAuthorized.sol b/contracts/mocks/RuleEngine/RuleSpenderAuthorized.sol index 4020764c..9dc7757a 100644 --- a/contracts/mocks/RuleEngine/RuleSpenderAuthorized.sol +++ b/contracts/mocks/RuleEngine/RuleSpenderAuthorized.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IRule} from "./interfaces/IRule.sol"; import {CodeList} from "./CodeList.sol"; diff --git a/contracts/mocks/RuleEngine/RuleTokenHolderTracker.sol b/contracts/mocks/RuleEngine/RuleTokenHolderTracker.sol index 3a66be9c..482dfb42 100644 --- a/contracts/mocks/RuleEngine/RuleTokenHolderTracker.sol +++ b/contracts/mocks/RuleEngine/RuleTokenHolderTracker.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IRule} from "./interfaces/IRule.sol"; import {IRuleTransferHook} from "./interfaces/IRuleTransferHook.sol"; diff --git a/contracts/mocks/RuleEngine/interfaces/IRule.sol b/contracts/mocks/RuleEngine/interfaces/IRule.sol index 7117508a..e4c225b1 100644 --- a/contracts/mocks/RuleEngine/interfaces/IRule.sol +++ b/contracts/mocks/RuleEngine/interfaces/IRule.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IERC1404Extend} from "../../../interfaces/tokenization/draft-IERC1404.sol"; import {IERC3643ComplianceRead} from "../../../interfaces/tokenization/IERC3643Partial.sol"; diff --git a/contracts/mocks/RuleEngine/interfaces/IRuleEngineMock.sol b/contracts/mocks/RuleEngine/interfaces/IRuleEngineMock.sol index 2b7dc785..01de652f 100644 --- a/contracts/mocks/RuleEngine/interfaces/IRuleEngineMock.sol +++ b/contracts/mocks/RuleEngine/interfaces/IRuleEngineMock.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IRule} from "./IRule.sol"; import {IRuleEngineERC1404} from "../../../interfaces/engine/IRuleEngine.sol"; diff --git a/contracts/mocks/RuleEngine/interfaces/IRuleTransferHook.sol b/contracts/mocks/RuleEngine/interfaces/IRuleTransferHook.sol index b794d0e5..4a1e3597 100644 --- a/contracts/mocks/RuleEngine/interfaces/IRuleTransferHook.sol +++ b/contracts/mocks/RuleEngine/interfaces/IRuleTransferHook.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @dev Optional hook interface for rules that need to update their own state diff --git a/contracts/mocks/SnapshotEngineMock.sol b/contracts/mocks/SnapshotEngineMock.sol index b53200cc..42d56949 100644 --- a/contracts/mocks/SnapshotEngineMock.sol +++ b/contracts/mocks/SnapshotEngineMock.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import {SnapshotModuleBase} from "./library/snapshot/SnapshotModuleBase.sol"; diff --git a/contracts/mocks/engine/CMTATDocumentEngineModuleMock.sol b/contracts/mocks/engine/CMTATDocumentEngineModuleMock.sol index a317a170..0eac3b42 100644 --- a/contracts/mocks/engine/CMTATDocumentEngineModuleMock.sol +++ b/contracts/mocks/engine/CMTATDocumentEngineModuleMock.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseCore} from "../../modules/0_CMTATBaseCore.sol"; import {DocumentEngineModule} from "../../modules/wrapper/options/DocumentEngineModule.sol"; diff --git a/contracts/mocks/engine/CMTATEngineInitializerMock.sol b/contracts/mocks/engine/CMTATEngineInitializerMock.sol index a8c234b5..b12a8018 100644 --- a/contracts/mocks/engine/CMTATEngineInitializerMock.sol +++ b/contracts/mocks/engine/CMTATEngineInitializerMock.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATUpgradeableSnapshot} from "../../deployment/snapshot/CMTATUpgradeableSnapshot.sol"; import {ISnapshotEngine} from "../../interfaces/engine/ISnapshotEngine.sol"; diff --git a/contracts/mocks/library/snapshot/ICMTATSnapshot.sol b/contracts/mocks/library/snapshot/ICMTATSnapshot.sol index 999441b7..30d62371 100644 --- a/contracts/mocks/library/snapshot/ICMTATSnapshot.sol +++ b/contracts/mocks/library/snapshot/ICMTATSnapshot.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @notice minimum interface to represent a CMTAT with snapshot diff --git a/contracts/mocks/library/snapshot/SnapshotErrors.sol b/contracts/mocks/library/snapshot/SnapshotErrors.sol index 75c69f96..ef725646 100644 --- a/contracts/mocks/library/snapshot/SnapshotErrors.sol +++ b/contracts/mocks/library/snapshot/SnapshotErrors.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* * @dev Snapshot custom errors diff --git a/contracts/mocks/library/snapshot/SnapshotModuleBase.sol b/contracts/mocks/library/snapshot/SnapshotModuleBase.sol index 198e92b1..548907f4 100644 --- a/contracts/mocks/library/snapshot/SnapshotModuleBase.sol +++ b/contracts/mocks/library/snapshot/SnapshotModuleBase.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import {Arrays} from '@openzeppelin/contracts/utils/Arrays.sol'; diff --git a/contracts/mocks/test/proxy/CMTAT_PROXY_TEST.sol b/contracts/mocks/test/proxy/CMTAT_PROXY_TEST.sol index 359f6c24..e188a8c8 100644 --- a/contracts/mocks/test/proxy/CMTAT_PROXY_TEST.sol +++ b/contracts/mocks/test/proxy/CMTAT_PROXY_TEST.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATStandardUpgradeable} from "../../../deployment/CMTATStandardUpgradeable.sol"; diff --git a/contracts/mocks/test/proxy/CMTAT_PROXY_TEST_UUPS.sol b/contracts/mocks/test/proxy/CMTAT_PROXY_TEST_UUPS.sol index f3bcbf71..75733794 100644 --- a/contracts/mocks/test/proxy/CMTAT_PROXY_TEST_UUPS.sol +++ b/contracts/mocks/test/proxy/CMTAT_PROXY_TEST_UUPS.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATUpgradeableUUPS} from "../../../deployment/CMTATUpgradeableUUPS.sol"; /** diff --git a/contracts/modules/0_CMTATBaseCommon.sol b/contracts/modules/0_CMTATBaseCommon.sol index 28ab4cd2..9edbc1c8 100644 --- a/contracts/modules/0_CMTATBaseCommon.sol +++ b/contracts/modules/0_CMTATBaseCommon.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Wrapper === */ diff --git a/contracts/modules/0_CMTATBaseCore.sol b/contracts/modules/0_CMTATBaseCore.sol index 0b9e01f7..f53b3243 100644 --- a/contracts/modules/0_CMTATBaseCore.sol +++ b/contracts/modules/0_CMTATBaseCore.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; @@ -190,7 +190,7 @@ abstract contract CMTATBaseCore is * @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); } /* @@ -230,6 +230,10 @@ abstract contract CMTATBaseCore is /** * @inheritdoc IForcedBurnERC20 + * @dev Burns directly via `ERC20Upgradeable._burn`, so it bypasses the pause/deactivation + * validation used by the standard burn path. This is intentional — the Light variant's + * enforcement burn remains available **after deactivation** (per ERC-8343), so the enforcer + * can still cancel a frozen or migrated position on a terminated token. * @custom:access-control * - The caller must have the `DEFAULT_ADMIN_ROLE`. */ @@ -264,7 +268,11 @@ abstract contract CMTATBaseCore is * @dev Check if a minter transfer is valid */ function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(ERC20MintModuleInternal) { - ValidationModule._canTransferGenericByModuleAndRevert(address(0), from, to); + // Pass the operator (_msgSender()) as spender, consistent with CMTATBaseCommon and the + // transferFrom path, instead of hardcoding address(0). A minter transfer moves the + // minter's own tokens, so `from == _msgSender()`; threading the spender keeps the + // spender-aware validation surface uniform across the Light and full bases (NM-5). + ValidationModule._canTransferGenericByModuleAndRevert(_msgSender(), from, to); ERC20MintModuleInternal._minterTransferOverride(from, to, value); } diff --git a/contracts/modules/0_CMTATBaseGeneric.sol b/contracts/modules/0_CMTATBaseGeneric.sol index 8a517bb5..97fe63d1 100644 --- a/contracts/modules/0_CMTATBaseGeneric.sol +++ b/contracts/modules/0_CMTATBaseGeneric.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; diff --git a/contracts/modules/0_CMTATBaseSnapshot.sol b/contracts/modules/0_CMTATBaseSnapshot.sol index 343bb87d..fb8cd0db 100644 --- a/contracts/modules/0_CMTATBaseSnapshot.sol +++ b/contracts/modules/0_CMTATBaseSnapshot.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; diff --git a/contracts/modules/1_CMTATBaseDocument.sol b/contracts/modules/1_CMTATBaseDocument.sol index f428819e..fda704b9 100644 --- a/contracts/modules/1_CMTATBaseDocument.sol +++ b/contracts/modules/1_CMTATBaseDocument.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol"; diff --git a/contracts/modules/2_CMTATBaseAccessControl.sol b/contracts/modules/2_CMTATBaseAccessControl.sol index cdfc343b..a8c493c8 100644 --- a/contracts/modules/2_CMTATBaseAccessControl.sol +++ b/contracts/modules/2_CMTATBaseAccessControl.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol"; diff --git a/contracts/modules/3_CMTATBaseAllowlist.sol b/contracts/modules/3_CMTATBaseAllowlist.sol index 7baf3326..64404b6d 100644 --- a/contracts/modules/3_CMTATBaseAllowlist.sol +++ b/contracts/modules/3_CMTATBaseAllowlist.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; @@ -112,7 +112,9 @@ abstract contract CMTATBaseAllowlist is Functions requiring several modules //////////////////////////////////////////////////////////////*/ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. * @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. @@ -120,8 +122,10 @@ abstract contract CMTATBaseAllowlist is * if strict control over the total amount a spender can consume is required. * @inheritdoc ERC20Upgradeable */ - function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) returns (bool) { + // The pause check lives in _canAuthorizeAllowanceByModuleAndRevert, which lets a + // revocation (value == 0) through. A `whenNotPaused` modifier here would block it. + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); } diff --git a/contracts/modules/3_CMTATBaseRuleEngine.sol b/contracts/modules/3_CMTATBaseRuleEngine.sol index 07292616..0b6a07bc 100644 --- a/contracts/modules/3_CMTATBaseRuleEngine.sol +++ b/contracts/modules/3_CMTATBaseRuleEngine.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol"; /* ==== OpenZeppelin === */ @@ -123,11 +123,15 @@ abstract contract CMTATBaseRuleEngine is PUBLIC/EXTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. * @inheritdoc ERC20Upgradeable */ - function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) returns (bool) { + // The pause check lives in _canAuthorizeAllowanceByModuleAndRevert, which lets a + // revocation (value == 0) through. A `whenNotPaused` modifier here would block it. + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); } /** diff --git a/contracts/modules/4_CMTATBaseDebt.sol b/contracts/modules/4_CMTATBaseDebt.sol index 50c23149..17e75adb 100644 --- a/contracts/modules/4_CMTATBaseDebt.sol +++ b/contracts/modules/4_CMTATBaseDebt.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; /* ==== Module === */ diff --git a/contracts/modules/4_CMTATBaseERC1404.sol b/contracts/modules/4_CMTATBaseERC1404.sol index 4b83ecea..b48380bf 100644 --- a/contracts/modules/4_CMTATBaseERC1404.sol +++ b/contracts/modules/4_CMTATBaseERC1404.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {CMTATBaseRuleEngine} from "./3_CMTATBaseRuleEngine.sol"; import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol"; diff --git a/contracts/modules/5_CMTATBaseERC20CrossChain.sol b/contracts/modules/5_CMTATBaseERC20CrossChain.sol index e463b2d7..5ee22e56 100644 --- a/contracts/modules/5_CMTATBaseERC20CrossChain.sol +++ b/contracts/modules/5_CMTATBaseERC20CrossChain.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; /* ==== Module === */ @@ -17,7 +17,9 @@ import {CCIPModule} from "./wrapper/options/CCIPModule.sol"; abstract contract CMTATBaseERC20CrossChain is ERC20CrossChainModule, CCIPModule, CMTATBaseERC1404 { /* ============ State Functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. * @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseRuleEngine) returns (bool) { diff --git a/contracts/modules/6_CMTATBaseDebtEngine.sol b/contracts/modules/6_CMTATBaseDebtEngine.sol index 417cfef4..d16dbbd9 100644 --- a/contracts/modules/6_CMTATBaseDebtEngine.sol +++ b/contracts/modules/6_CMTATBaseDebtEngine.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; diff --git a/contracts/modules/6_CMTATBaseERC2612.sol b/contracts/modules/6_CMTATBaseERC2612.sol index 16e36fc3..b2e8329e 100644 --- a/contracts/modules/6_CMTATBaseERC2612.sol +++ b/contracts/modules/6_CMTATBaseERC2612.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol"; @@ -35,7 +35,14 @@ abstract contract CMTATBaseERC2612 is CMTATBaseERC20CrossChain, ERC20PermitUpgra //////////////////////////////////////////////////////////////*/ /** * @inheritdoc ERC20PermitUpgradeable - * @dev Reverts if the contract is paused or if owner/spender is frozen. + * @dev Reverts if the contract is paused or if owner/spender is frozen, unless `value` + * is zero: a zero-value permit is a gasless revocation and stays available so an owner + * can always sever ties with a spender, even while restricted. + * + * The EIP-712 domain name is fixed at initialization and is **not** updated by + * {TokenAttributeModule-setName}. Signers must build the domain from the ERC-5267 + * {eip712Domain} function (or `DOMAIN_SEPARATOR()`), not from {name}, which may have + * been changed since deployment. */ function permit( address owner, @@ -46,13 +53,15 @@ abstract contract CMTATBaseERC2612 is CMTATBaseERC20CrossChain, ERC20PermitUpgra bytes32 r, bytes32 s ) public virtual override(ERC20PermitUpgradeable) { - _canAuthorizeAllowanceByModuleAndRevert(owner, spender); + _canAuthorizeAllowanceByModuleAndRevert(owner, spender, value); ERC20PermitUpgradeable.permit(owner, spender, value, deadline, v, r, s); } /* ============ State functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. * @inheritdoc ERC20Upgradeable */ function approve( diff --git a/contracts/modules/6_CMTATBaseERC2771.sol b/contracts/modules/6_CMTATBaseERC2771.sol index 8d09a842..0be37632 100644 --- a/contracts/modules/6_CMTATBaseERC2771.sol +++ b/contracts/modules/6_CMTATBaseERC2771.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; /* ==== Module === */ diff --git a/contracts/modules/7_CMTATBaseERC2771Snapshot.sol b/contracts/modules/7_CMTATBaseERC2771Snapshot.sol index 1d0499ac..2e84eac8 100644 --- a/contracts/modules/7_CMTATBaseERC2771Snapshot.sol +++ b/contracts/modules/7_CMTATBaseERC2771Snapshot.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; diff --git a/contracts/modules/7_CMTATBaseERC7551Enforcement.sol b/contracts/modules/7_CMTATBaseERC7551Enforcement.sol index fc81586b..dc63c40e 100644 --- a/contracts/modules/7_CMTATBaseERC7551Enforcement.sol +++ b/contracts/modules/7_CMTATBaseERC7551Enforcement.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; diff --git a/contracts/modules/8_CMTATBaseERC1363.sol b/contracts/modules/8_CMTATBaseERC1363.sol index 94dfc23e..5456d9ce 100644 --- a/contracts/modules/8_CMTATBaseERC1363.sol +++ b/contracts/modules/8_CMTATBaseERC1363.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import {ERC1363Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC1363Upgradeable.sol"; @@ -33,7 +33,9 @@ abstract contract CMTATBaseERC1363 is ERC1363Upgradeable, CMTATBaseERC7551Enforc /* ============ State functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. * @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) { diff --git a/contracts/modules/8_CMTATBaseERC7551.sol b/contracts/modules/8_CMTATBaseERC7551.sol index 8d0d90b4..f107a80a 100644 --- a/contracts/modules/8_CMTATBaseERC7551.sol +++ b/contracts/modules/8_CMTATBaseERC7551.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ /* ==== Module === */ diff --git a/contracts/modules/8_CMTATBaseHolderList.sol b/contracts/modules/8_CMTATBaseHolderList.sol index e4648469..edd93384 100644 --- a/contracts/modules/8_CMTATBaseHolderList.sol +++ b/contracts/modules/8_CMTATBaseHolderList.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; diff --git a/contracts/modules/internal/AllowlistModuleInternal.sol b/contracts/modules/internal/AllowlistModuleInternal.sol index b45d4a2c..8cd928af 100644 --- a/contracts/modules/internal/AllowlistModuleInternal.sol +++ b/contracts/modules/internal/AllowlistModuleInternal.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; diff --git a/contracts/modules/internal/ERC20BurnModuleInternal.sol b/contracts/modules/internal/ERC20BurnModuleInternal.sol index 699086af..e5a69983 100644 --- a/contracts/modules/internal/ERC20BurnModuleInternal.sol +++ b/contracts/modules/internal/ERC20BurnModuleInternal.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; diff --git a/contracts/modules/internal/ERC20EnforcementModuleInternal.sol b/contracts/modules/internal/ERC20EnforcementModuleInternal.sol index 4a2a113d..af3a46bf 100644 --- a/contracts/modules/internal/ERC20EnforcementModuleInternal.sol +++ b/contracts/modules/internal/ERC20EnforcementModuleInternal.sol @@ -1,9 +1,11 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +/* ==== Technical === */ +import {IERC20Allowance} from "../../interfaces/technical/IERC20Allowance.sol"; /* ==== Tokenization === */ import {IERC7943FungibleEnforcementEventAndError} from "../../interfaces/tokenization/draft-IERC7943.sol"; @@ -32,6 +34,13 @@ abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable, IERC7943Fu INTERNAL/PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////*/ function _setFrozenTokens(address account, uint256 value) internal virtual returns(bool) { + // The zero address holds no balance, so a non-zero frozen amount on it would make + // _checkActiveBalance(address(0), value) fail for every value > 0 and revert the common + // mint path (mint, batchMint, crosschainMint, the mint leg of burnAndMint). + // Same guard as _freezePartialTokens / _unfreezePartialTokens. + if (account == address(0)) { + revert CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed(); + } ERC20EnforcementModuleStorage storage $ = _getEnforcementModuleStorage(); uint256 frozenTokensLocal = $._frozenTokens[account]; // Unfreeze path @@ -101,6 +110,13 @@ abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable, IERC7943Fu } } + /** + * @dev + * Moves tokens through the ERC-20 `_update` primitive directly, without the pause/deactivation + * validation applied to holder transfers and standard issuance. This is intentional: forced + * transfer/burn is the enforcer's regulatory tool and, per ERC-8343, a named privileged operation + * that remains available **after deactivation** (e.g. to sweep a frozen or migrated position). + */ function _forcedTransfer(address from, address to, uint256 value) internal virtual { // A self forced transfer moves no token, but _unfreezeTokens would still release the frozen ones require(from != to, CMTAT_ERC20EnforcementModule_SelfTransferNotAllowed()); @@ -112,16 +128,14 @@ abstract contract ERC20EnforcementModuleInternal is ERC20Upgradeable, IERC7943Fu // See https://ethereum-magicians.org/t/erc-3643-the-t-rex-token-standard/6844/11 uint256 currentAllowance = allowance(from, to); if (currentAllowance > 0 && currentAllowance < type(uint256).max) { - if (currentAllowance < value) { - unchecked { - ERC20Upgradeable._approve(from, to, 0, false); - } - } else{ - unchecked { - ERC20Upgradeable._approve(from, to, currentAllowance - value, false); - } + // Amount actually taken from the from->to allowance (capped by the allowance) + uint256 spentAllowance = currentAllowance < value ? currentAllowance : value; + unchecked { + ERC20Upgradeable._approve(from, to, currentAllowance - spentAllowance, false); } - + // Emit Spend so the allowance consumption is observable, consistent with + // transferFrom / burnFrom. `_approve(..., false)` above still suppresses Approval. + emit IERC20Allowance.Spend(from, to, spentAllowance); } ERC20Upgradeable._transfer(from, to, value); } diff --git a/contracts/modules/internal/ERC20MintModuleInternal.sol b/contracts/modules/internal/ERC20MintModuleInternal.sol index e472b8d0..d4e754f5 100644 --- a/contracts/modules/internal/ERC20MintModuleInternal.sol +++ b/contracts/modules/internal/ERC20MintModuleInternal.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; diff --git a/contracts/modules/internal/EnforcementModuleInternal.sol b/contracts/modules/internal/EnforcementModuleInternal.sol index bb7f3bfc..b697245e 100644 --- a/contracts/modules/internal/EnforcementModuleInternal.sol +++ b/contracts/modules/internal/EnforcementModuleInternal.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; diff --git a/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol b/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol index 693d6589..aa5cf0c9 100644 --- a/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol +++ b/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol"; diff --git a/contracts/modules/internal/common/EnforcementModuleLibrary.sol b/contracts/modules/internal/common/EnforcementModuleLibrary.sol index 3be1f272..5a3fecca 100644 --- a/contracts/modules/internal/common/EnforcementModuleLibrary.sol +++ b/contracts/modules/internal/common/EnforcementModuleLibrary.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /** * @dev Enforcement module library diff --git a/contracts/modules/wrapper/controllers/ValidationModule.sol b/contracts/modules/wrapper/controllers/ValidationModule.sol index 7587c7a2..13cb9213 100644 --- a/contracts/modules/wrapper/controllers/ValidationModule.sol +++ b/contracts/modules/wrapper/controllers/ValidationModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {PauseModule} from "../core/PauseModule.sol"; diff --git a/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol b/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol index bc777c26..e99e1e2e 100644 --- a/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol +++ b/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {ValidationModule} from "./ValidationModule.sol"; diff --git a/contracts/modules/wrapper/core/ERC20BaseModule.sol b/contracts/modules/wrapper/core/ERC20BaseModule.sol index 1f3fa3d3..a72660a7 100644 --- a/contracts/modules/wrapper/core/ERC20BaseModule.sol +++ b/contracts/modules/wrapper/core/ERC20BaseModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; diff --git a/contracts/modules/wrapper/core/ERC20BurnModule.sol b/contracts/modules/wrapper/core/ERC20BurnModule.sol index 1f84fecd..73c73338 100644 --- a/contracts/modules/wrapper/core/ERC20BurnModule.sol +++ b/contracts/modules/wrapper/core/ERC20BurnModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {ERC20BurnModuleInternal} from "../../internal/ERC20BurnModuleInternal.sol"; diff --git a/contracts/modules/wrapper/core/ERC20MintModule.sol b/contracts/modules/wrapper/core/ERC20MintModule.sol index 38eb0c17..244335be 100644 --- a/contracts/modules/wrapper/core/ERC20MintModule.sol +++ b/contracts/modules/wrapper/core/ERC20MintModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {ERC20MintModuleInternal} from "../../internal/ERC20MintModuleInternal.sol"; diff --git a/contracts/modules/wrapper/core/EnforcementModule.sol b/contracts/modules/wrapper/core/EnforcementModule.sol index b12a06b1..30d6b908 100644 --- a/contracts/modules/wrapper/core/EnforcementModule.sol +++ b/contracts/modules/wrapper/core/EnforcementModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {EnforcementModuleInternal} from "../../internal/EnforcementModuleInternal.sol"; @@ -22,7 +22,7 @@ abstract contract EnforcementModule is /* ============ Modifier ============ */ - /// @dev Modifier to restrict access to the burner functions + /// @dev Modifier to restrict access to the address-freeze functions (via `_authorizeFreeze`, ENFORCER_ROLE) modifier onlyEnforcer() { _authorizeFreeze(); _; diff --git a/contracts/modules/wrapper/core/PauseModule.sol b/contracts/modules/wrapper/core/PauseModule.sol index 806f5191..570d5f13 100644 --- a/contracts/modules/wrapper/core/PauseModule.sol +++ b/contracts/modules/wrapper/core/PauseModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; diff --git a/contracts/modules/wrapper/core/TokenAttributeModule.sol b/contracts/modules/wrapper/core/TokenAttributeModule.sol index 9d2b91e4..e9e36e1d 100644 --- a/contracts/modules/wrapper/core/TokenAttributeModule.sol +++ b/contracts/modules/wrapper/core/TokenAttributeModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; @@ -78,6 +78,15 @@ abstract contract TokenAttributeModule is Initializable, IERC3643ERC20Base { /* ======== State functions ======= */ /** * @inheritdoc IERC3643ERC20Base + * @dev + * WARNING - on deployment variants that also support ERC-2612 (`permit`), renaming the token does **not** + * change the EIP-712 domain separator. The domain name is captured at initialization by OpenZeppelin's + * `EIP712Upgradeable` and, per its own documentation, "cannot be changed except through a smart contract + * upgrade"; `DOMAIN_SEPARATOR()` therefore keeps using the original name after {setName}. + * + * Existing and future permits remain valid: signers must simply build the EIP-712 domain from the ERC-5267 + * {eip712Domain} function (or from `DOMAIN_SEPARATOR()`), which reports the name actually in use — never + * from {name}. A signature produced with the post-rename {name} is rejected with `ERC2612InvalidSigner`. */ function setName(string calldata name_) public virtual override(IERC3643ERC20Base) onlyTokenAttributeManager { TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage(); diff --git a/contracts/modules/wrapper/core/ValidationModuleCore.sol b/contracts/modules/wrapper/core/ValidationModuleCore.sol index 8351307c..a43ed55f 100644 --- a/contracts/modules/wrapper/core/ValidationModuleCore.sol +++ b/contracts/modules/wrapper/core/ValidationModuleCore.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {ValidationModule} from "../controllers/ValidationModule.sol"; diff --git a/contracts/modules/wrapper/core/VersionModule.sol b/contracts/modules/wrapper/core/VersionModule.sol index fd90800a..b8a1488b 100644 --- a/contracts/modules/wrapper/core/VersionModule.sol +++ b/contracts/modules/wrapper/core/VersionModule.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Tokenization === */ import {IERC3643Version} from "../../../interfaces/tokenization/IERC3643Partial.sol"; diff --git a/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol b/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol index 7defdcb6..3145b7d4 100644 --- a/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol +++ b/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import {IERC1643} from "../../../interfaces/tokenization/draft-IERC1643.sol"; diff --git a/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol b/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol index 4f2db67c..af57886f 100644 --- a/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol +++ b/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {ERC20EnforcementModuleInternal} from "../../internal/ERC20EnforcementModuleInternal.sol"; diff --git a/contracts/modules/wrapper/extensions/ExtraInformationModule.sol b/contracts/modules/wrapper/extensions/ExtraInformationModule.sol index 0249ce44..fcf6e133 100644 --- a/contracts/modules/wrapper/extensions/ExtraInformationModule.sol +++ b/contracts/modules/wrapper/extensions/ExtraInformationModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Openzeppelin === */ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; @@ -126,6 +126,22 @@ abstract contract ExtraInformationModule is Initializable, ICMTATBase { _setTerms($, terms_); } + /** + * @dev Update the terms document (uri + hash) while leaving the document name untouched. + * + * Used by the ERC-7551 `setTerms(bytes32,string)` overload, whose signature carries no name: + * forwarding an empty one through {_setTerms} would silently erase a name previously set via + * {setTerms(IERC1643CMTAT.DocumentInfo)}. + */ + function _setTermsDocument(bytes32 documentHash_, string memory uri_) internal virtual { + ExtraInformationModuleStorage storage $ = _getExtraInformationModuleStorage(); + $._terms.doc.documentHash = documentHash_; + $._terms.doc.uri = uri_; + $._terms.doc.lastModified = block.timestamp; + // Event + emit Terms($._terms); + } + function _setTokenId( ExtraInformationModuleStorage storage $, string memory tokenId_ ) internal virtual { diff --git a/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol b/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol index 9f23ebf2..42fc88fd 100644 --- a/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol +++ b/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; diff --git a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol index 04017b4f..0d4820ee 100644 --- a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol +++ b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== ValidationModule === */ import {ValidationModuleCore} from "../../core/ValidationModuleCore.sol"; @@ -15,15 +15,33 @@ abstract contract ValidationModuleAllowance is ValidationModuleCore { /** * @dev Reverts when allowance authorization cannot be performed. * - * Requirements: + * Requirements (for `value > 0`): * - contract must not be paused. * - `owner` must be allowed to send (`canSend` returns true). * - `spender` must be allowed to send (`canSend` returns true). + * + * Setting an allowance to zero is a **revocation**, never a new grant: it can only + * reduce what a spender may move. It is therefore always authorized, including while + * the contract is paused or when `owner`/`spender` is frozen or off the allowlist. + * Blocking it would leave a holder unable to sever ties with a compromised or + * sanctioned spender for the whole duration of the restriction, and would make the + * zero-first allowance mitigation documented on `approve` unusable exactly when it + * matters. No value can move while the restriction holds, since `transferFrom` is + * gated by the same checks. + * + * @param owner The account granting (or revoking) the allowance. + * @param spender The account being granted (or revoked). + * @param value The new allowance value; `0` means revocation. */ function _canAuthorizeAllowanceByModuleAndRevert( address owner, - address spender + address spender, + uint256 value ) internal view virtual { + // A revocation is always allowed + if (value == 0) { + return; + } _requireNotPaused(); if (!_canSend(owner)) { revert ERC7943CannotSend(owner); diff --git a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol index e0c160a6..88fd8040 100644 --- a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol +++ b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Tokenization === */ @@ -13,6 +13,31 @@ import {IRuleEngineERC1404} from "../../../../interfaces/engine/IRuleEngine.sol" * * Useful for to restrict and validate transfers * Required a RuleEngine implementing the interface IRuleEngineERC1404 + * + * @custom:scope {detectTransferRestriction} and {detectTransferRestrictionFrom} describe the + * **holder transfer path only** — `transfer` and `transferFrom`. They do **not** govern the + * mint and burn entry points, and the `address(0)` encoding of the ERC-1404 rework draft + * (`from == address(0)` for a mint, `to == address(0)` for a burn) is **not** supported here: + * a query built that way is answered as if it were a holder transfer, so it can report a + * restriction the mint/burn path does not enforce (typically {PauseModule-paused}). + * + * The reason is structural, not an oversight. CMTAT exposes several entry points per + * supply-changing operation and the **pause rule differs between them**: + * - mint: `mint` / `batchMint` (`MINTER_ROLE`) are allowed while paused, `crosschainMint` + * (token bridge) is not; + * - burn: `burn(address,uint256[,bytes])` / `batchBurn` (`BURNER_ROLE`) are allowed while paused, + * `burnFrom` (`BURNER_FROM_ROLE`), `burn(uint256)` (`BURNER_SELF_ROLE`) and `crosschainBurn` + * are not. + * + * `(from, to, value)` — and `(spender, from, to, value)` — carry no entry-point discriminator, and + * the operator address does not identify one either (the same address may hold several burn roles), + * so no single return value can describe every mint or every burn. Rather than designate a predictor + * that would be right for one entry point and wrong for another, this module designates **none**. + * + * To predict a mint or a burn, use the module's own predicates instead — {canTransfer} / + * {canTransferFrom}, which branch on the `address(0)` encoding through + * {ValidationModule-_canTransferGenericByModule}, the same helper the enforcement path uses — and + * the role/pause requirements documented per entry point. */ abstract contract ValidationModuleERC1404 is ValidationModuleRuleEngine, IERC1404Extend @@ -94,6 +119,9 @@ abstract contract ValidationModuleERC1404 is * @param value uint256 the amount of tokens to be transferred * @return code of the rejection reason * @dev see {ERC-1404} + * @dev Scope: `transfer` / `transferFrom` only. Passing `address(0)` as `from` or `to` to query + * a mint or a burn is **not** supported — see the scope note on this contract; use + * {canTransfer} / {canTransferFrom} for those operations. */ function detectTransferRestriction( address from, @@ -111,6 +139,21 @@ abstract contract ValidationModuleERC1404 is } } + /** + * @notice check if `spender` can transfer `value` token from `from` to `to` + * @param spender address The address initiating the delegated transfer + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 the amount of tokens to be transferred + * @return code of the rejection reason + * @dev see {ERC-1404} (rework draft, spender-aware extension) + * @dev Scope: `transferFrom` only. The `spender` argument is the delegated-transfer initiator, + * **not** a mint/burn operator: passing an operator with `from`/`to` set to `address(0)` to + * predict a mint or a burn is not supported — see the scope note on this contract. + * The `spender == from` case is deliberately evaluated through this path (no short-circuit to + * {detectTransferRestriction}), because a frozen initiator blocks `transferFrom` even when it + * owns the tokens. + */ function detectTransferRestrictionFrom( address spender, address from, diff --git a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol index 5ffb891a..2cf9dd25 100644 --- a/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol +++ b/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Engine === */ @@ -23,6 +23,7 @@ abstract contract ValidationModuleRuleEngine is */ error CMTAT_ValidationModule_SameValue(); + /* ============ Modifier ============ */ modifier onlyRuleEngineManager() { _authorizeRuleEngineManagement(); @@ -135,15 +136,60 @@ abstract contract ValidationModuleRuleEngine is function _authorizeRuleEngineManagement() internal virtual; /* ============ State functions ============ */ + /** + * @dev + * @custom:security The RuleEngine callback is the only point at which a transfer hands control + * to an external contract, and it happens *before* the ERC-20 balances move: the active-balance + * (frozen) check in {CMTATBaseCommon-_checkTransferred} has already run against the pre-transfer + * state and is not re-evaluated afterwards. A RuleEngine that reenters the token during + * `transferred(...)` — because it is malicious, compromised, or because one of its rules calls + * untrusted code — is therefore validated twice against the same snapshot, and the outer and + * inner transfers can together move more than the holder's unfrozen balance, breaking the + * `frozenTokens <= balanceOf` invariant. + * + * The external call is isolated in {_callRuleEngineTransferred}, which is `virtual` so that a + * deployment variant can wrap it in a reentrancy guard by inheriting OpenZeppelin's + * `ReentrancyGuardTransient` and overriding {_callRuleEngineTransferred} with `nonReentrant` + * (see e.g. `contracts/deployment/CMTATStandardStandalone.sol`). + * + * WARNING - the guard is **not** enabled on every variant. It costs ~195 bytes of deployed + * bytecode, and several variants are within a few hundred bytes of the EIP-170 24 KiB limit, so + * enabling it there would make them undeployable. Variants without the guard rely on the standard + * CMTAT trust assumption: the RuleEngine is set by `DEFAULT_ADMIN_ROLE`, is fully trusted, and + * MUST NOT hand control to untrusted code during `transferred(...)`. See the module documentation + * for the per-variant table. + * + * The guard is entered only when a RuleEngine is set, so a deployment with no engine pays + * nothing, and it is released when the callback returns, so sequential hooks (batch operations, + * `burnAndMint`) are unaffected. + */ function _transferred(address spender, address from, address to, uint256 value) internal virtual{ _canTransferGenericByModuleAndRevert(spender, from, to); IRuleEngine ruleEngine_ = ruleEngine(); if (address(ruleEngine_) != address(0)){ - if(spender != address(0)){ - ruleEngine_.transferred(spender, from, to, value); - } else { - ruleEngine_.transferred(from, to, value); - } + _callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } + } + + /** + * @dev Performs the RuleEngine `transferred` call. + * + * Declared `virtual` so a deployment variant can wrap it in a reentrancy guard by overriding it + * with `nonReentrant` (inheriting OpenZeppelin's `ReentrancyGuardTransient`). The base + * implementation is **unguarded**: see the security note on {_transferred} for which variants + * enable the guard and why it is not enabled everywhere. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual { + if(spender != address(0)){ + ruleEngine_.transferred(spender, from, to, value); + } else { + ruleEngine_.transferred(from, to, value); } } } diff --git a/contracts/modules/wrapper/options/AllowlistModule.sol b/contracts/modules/wrapper/options/AllowlistModule.sol index 4a9ab3a1..31325f48 100644 --- a/contracts/modules/wrapper/options/AllowlistModule.sol +++ b/contracts/modules/wrapper/options/AllowlistModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {IAllowlistModule} from "../../../interfaces/modules/IAllowlistModule.sol"; diff --git a/contracts/modules/wrapper/options/CCIPModule.sol b/contracts/modules/wrapper/options/CCIPModule.sol index a158bf83..0b0ab3e4 100644 --- a/contracts/modules/wrapper/options/CCIPModule.sol +++ b/contracts/modules/wrapper/options/CCIPModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; import {IGetCCIPAdmin} from "../../../interfaces/technical/IGetCCIPAdmin.sol"; /** diff --git a/contracts/modules/wrapper/options/DebtEngineModule.sol b/contracts/modules/wrapper/options/DebtEngineModule.sol index b9591e99..8164e9d5 100644 --- a/contracts/modules/wrapper/options/DebtEngineModule.sol +++ b/contracts/modules/wrapper/options/DebtEngineModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Engine === */ import {IDebtEngine, ICMTATDebt, ICMTATCreditEvents} from "../../../interfaces/engine/IDebtEngine.sol"; diff --git a/contracts/modules/wrapper/options/DebtModule.sol b/contracts/modules/wrapper/options/DebtModule.sol index 0d10b099..92979d76 100644 --- a/contracts/modules/wrapper/options/DebtModule.sol +++ b/contracts/modules/wrapper/options/DebtModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Engine === */ import {ICMTATDebt, ICMTATCreditEvents} from "../../../interfaces/engine/IDebtEngine.sol"; diff --git a/contracts/modules/wrapper/options/DocumentEngineModule.sol b/contracts/modules/wrapper/options/DocumentEngineModule.sol index e0679b96..f1376f57 100644 --- a/contracts/modules/wrapper/options/DocumentEngineModule.sol +++ b/contracts/modules/wrapper/options/DocumentEngineModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin=== */ import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; diff --git a/contracts/modules/wrapper/options/ERC20CrossChainModule.sol b/contracts/modules/wrapper/options/ERC20CrossChainModule.sol index 9f8a8924..37518ff3 100644 --- a/contracts/modules/wrapper/options/ERC20CrossChainModule.sol +++ b/contracts/modules/wrapper/options/ERC20CrossChainModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC165Upgradeable, IERC165} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol"; /* ==== Module === */ @@ -30,6 +30,12 @@ abstract contract ERC20CrossChainModule is ERC20MintModule, ERC20BurnModule, ERC modifier onlyTokenBridge() { // Token bridge should never be impersonated using a relayer/forwarder. Using msg.sender is preferable to // _msgSender() for security reasons. + // + // DEPLOYMENT CONSTRAINT - this is the only role gate in CMTAT that authorizes the raw msg.sender, so a + // bridge MUST call crosschainMint/crosschainBurn directly; a call relayed through the ERC-2771 forwarder + // reverts, because the forwarder is the raw caller. CROSS_CHAIN_ROLE MUST NOT be granted to that + // forwarder to work around it: every relayed call would then pass this gate, letting any user mint an + // arbitrary amount to any address. See doc/technical/cross-chain-bridge-integration.md _checkTokenBridge(msg.sender); _; } @@ -90,7 +96,7 @@ abstract contract ERC20CrossChainModule is ERC20MintModule, ERC20BurnModule, ERC /** * @inheritdoc IBurnFromERC20 * @custom:access-control - * - Protected by the modifier onlyBurnerFrom + * - Protected by the modifier onlySelfBurn (BURNER_SELF_ROLE). */ function burn( uint256 value diff --git a/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol b/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol index 51512324..1b9febe7 100644 --- a/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol +++ b/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {ERC20EnforcementModule} from "../extensions/ERC20EnforcementModule.sol"; diff --git a/contracts/modules/wrapper/options/ERC2771Module.sol b/contracts/modules/wrapper/options/ERC2771Module.sol index fea0662d..90b6ed5c 100644 --- a/contracts/modules/wrapper/options/ERC2771Module.sol +++ b/contracts/modules/wrapper/options/ERC2771Module.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC2771ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol"; diff --git a/contracts/modules/wrapper/options/ERC7551Module.sol b/contracts/modules/wrapper/options/ERC7551Module.sol index b3502517..3daeed8a 100644 --- a/contracts/modules/wrapper/options/ERC7551Module.sol +++ b/contracts/modules/wrapper/options/ERC7551Module.sol @@ -1,11 +1,10 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== Module === */ import {ExtraInformationModule} from "../extensions/ExtraInformationModule.sol"; /* ==== Tokenization === */ -import {IERC1643CMTAT} from "../../../interfaces/tokenization/draft-IERC1643CMTAT.sol"; import {IERC7551Document} from "../../../interfaces/tokenization/draft-IERC7551.sol"; /** @@ -50,8 +49,10 @@ abstract contract ERC7551Module is ExtraInformationModule, IERC7551Document { * - the caller must have the `EXTRA_INFORMATION_ROLE`. */ function setTerms(bytes32 hash_, string calldata uri_) public virtual override(IERC7551Document) onlyExtraInfoManager { - IERC1643CMTAT.DocumentInfo memory terms_ = IERC1643CMTAT.DocumentInfo("", uri_, hash_); - _setTerms(terms_); + // The ERC-7551 signature carries no document name, so only the document (uri + hash) is + // updated. Forwarding an empty name through _setTerms would silently erase a name set + // through the {ICMTATBase-setTerms} overload. + _setTermsDocument(hash_, uri_); emit Terms(hash_, uri_); } diff --git a/contracts/modules/wrapper/options/HolderListModule.sol b/contracts/modules/wrapper/options/HolderListModule.sol index 53bf1e25..e1d5ffca 100644 --- a/contracts/modules/wrapper/options/HolderListModule.sol +++ b/contracts/modules/wrapper/options/HolderListModule.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; @@ -17,8 +17,10 @@ import {IHolderListModule} from "../../../interfaces/modules/IHolderListModule.s * transferFrom, mint, burn, forced transfer and cross-chain mint/burn. * * Gas: the first transfer to a new address writes two slots (EnumerableSet stores the value - * and its index), and the transfer emptying an account clears them. Transfers between - * existing holders that leave both balances non-zero cost nothing extra. + * and its index), and the transfer emptying an account clears them. A transfer between + * existing holders that leaves both balances non-zero performs no storage write to the set + * (no add/remove, no event), but still reads balanceOf(from) and balanceOf(to) and does one + * EnumerableSet membership-check SLOAD in add(to) — roughly two warm + one cold SLOAD, no SSTORE. */ abstract contract HolderListModule is ERC20Upgradeable, IHolderListModule { using EnumerableSet for EnumerableSet.AddressSet; diff --git a/contracts/modules/wrapper/security/AccessControlModule.sol b/contracts/modules/wrapper/security/AccessControlModule.sol index e4eb7c8e..c3578432 100644 --- a/contracts/modules/wrapper/security/AccessControlModule.sol +++ b/contracts/modules/wrapper/security/AccessControlModule.sol @@ -1,6 +1,6 @@ //SPDX-License-Identifier: MPL-2.0 -pragma solidity ^0.8.20; +pragma solidity ^0.8.24; /* ==== OpenZeppelin === */ import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; diff --git a/doc/ERCSpecification/erc-1643-analysis.md b/doc/ERCSpecification/erc-1643-analysis.md new file mode 100644 index 00000000..06aa596f --- /dev/null +++ b/doc/ERCSpecification/erc-1643-analysis.md @@ -0,0 +1,128 @@ +# ERC-1643 Conformance Analysis — CMTAT + +**Scope of review:** does CMTAT correctly implement ERC-1643 (Document Management)? +**Checked against both specs in this repo:** +- Rework: [`rework/erc-1643.md`](./rework/erc-1643.md) — *"Document Management for Security Tokens"* (ethereum/ERCs PR #1754, draft). +- Original: [`original/draft-erc-1643-document.md`](./original/draft-erc-1643-document.md) — the 2018 ERC-1400 draft (GitHub issue only, never merged). + +**CMTAT sources reviewed:** +- Interface: `contracts/interfaces/tokenization/draft-IERC1643.sol` +- Native (in-contract) module: `contracts/modules/wrapper/extensions/DocumentERC1643Module.sol` (via `CMTATBaseDocument`, level 1) +- ERC-165 registration + role gate: `contracts/modules/2_CMTATBaseAccessControl.sol` +- External-engine alternative: `contracts/modules/wrapper/options/DocumentEngineModule.sol` (forwards to any `IERC1643` engine) + +**Reviewed on:** CMTAT v3.3.0-rc2/rc3 (`dev`). + +--- + +## Verdict + +**CMTAT correctly and fully implements ERC-1643** — every `MUST` in the rework spec and every requirement of the original draft is satisfied by the on-chain behaviour, and the `SHOULD`s (ERC-165 detection, `bytes32(0)` rejection with the named error, `lastModified != 0` absence sentinel) are met too. Both the rework and the original are ABI-compatible with CMTAT's interface. + +The only shortfalls are **non-normative**: three of the spec's *recommended test cases* are not asserted in the suite (the code implements them correctly), one advisory security-consideration (pagination) is not addressed, and one NatSpec `@return` line is mislabeled. None affect conformance. + +--- + +## Rework spec — clause-by-clause (`rework/erc-1643.md`) + +### Interface shape (§Specification / §Interface) + +| Spec member | CMTAT | OK | +|---|---|---| +| `event DocumentUpdated(bytes32 indexed name, string uri, bytes32 documentHash)` | identical selector (`draft-IERC1643.sol:47`) | ✅ | +| `event DocumentRemoved(bytes32 indexed name, string uri, bytes32 documentHash)` | identical (`:49`) | ✅ | +| `error ERC1643InvalidName()` | defined (`:14`) | ✅ | +| `error ERC1643MissingDocument()` | defined (`:12`) | ✅ | +| `setDocument(bytes32,string,bytes32)` | present (`:43`) | ✅ | +| `removeDocument(bytes32)` | present (`:45`) | ✅ | +| `getDocument(bytes32) → (string,bytes32,uint256)` | present (`:36`) | ✅ | +| `getAllDocuments() → bytes32[]` | present (`:41`) | ✅ | + +The document entry stores exactly the spec's three fields — URI (`string`), content hash (`bytes32`), last-modified (`uint256`) — via the `Document` struct (`:17`). CMTAT exposes them as the flat `(uri, documentHash, lastModified)` tuple the ABI requires, so representing them internally as a struct is invisible to callers. ✅ + +### `getDocument` (§Function Requirements) + +| Requirement | CMTAT (`DocumentERC1643Module.sol:28`) | OK | +|---|---|---| +| MUST return the latest values | reads `$._documents[name]` | ✅ | +| MUST return empty values when absent (`""`, `bytes32(0)`, `0`) | mapping default is exactly that | ✅ | +| MUST NOT revert solely because absent | plain storage read, no guard | ✅ | +| SHOULD keep stored `lastModified != 0` as the absence sentinel | `setDocument` writes `block.timestamp` (always > 0 on-chain); absent = 0 | ✅ | + +### `setDocument` (§Function Requirements) + +| Requirement | CMTAT (`:37`) | OK | +|---|---|---| +| MUST create when absent / overwrite when present | writes struct unconditionally; pushes the name only when `_documentKey[name] == 0` | ✅ | +| MUST update the last-modified timestamp | `document.lastModified = block.timestamp` | ✅ | +| MUST emit `DocumentUpdated` after state changes | emitted last | ✅ | +| MUST revert if it cannot persist | writes to storage; a failed write reverts | ✅ | +| SHOULD revert on `name == bytes32(0)` with `ERC1643InvalidName()` | `require(name != bytes32(0), ERC1643InvalidName())` | ✅ | +| `uri` / `documentHash` MAY be empty | not rejected | ✅ | + +### `removeDocument` (§Function Requirements) + +| Requirement | CMTAT (`:53`) | OK | +|---|---|---| +| MUST remove the named entry | `delete $._documents[name]` + key cleanup | ✅ | +| MUST emit `DocumentRemoved` with the removed metadata | reads `document` into memory **before** delete, emits `(name, uri, documentHash)` | ✅ | +| MUST revert if removal cannot complete | `require(key != 0, ERC1643MissingDocument())` | ✅ | +| SHOULD use `ERC1643MissingDocument()` when absent | exactly that | ✅ | + +### `getAllDocuments` (§Function Requirements) + +| Requirement | CMTAT (`:33`) | OK | +|---|---|---| +| MUST include every set-and-not-removed name | returns `_documentNames` | ✅ | +| MUST NOT include removed names | swap-and-pop removal keeps the array exact | ✅ | +| Order unspecified; removal MAY reorder | swap-and-pop moves the last element into the freed slot — matches the "consumers MUST NOT rely on ordering" note | ✅ | + +The removal uses 1-based `_documentKey` indexing (`0` = absent) plus swap-and-pop for O(1) deletes — precisely the "index tracking to support O(1) removals" pattern the spec's Reference Implementation describes (§Reference Implementation). ✅ + +### Interface Detection — ERC-165 (§Interface Detection, SHOULD) + +`type(IERC1643).interfaceId` (`0xecfecec8`) is returned by `supportsInterface` in `2_CMTATBaseAccessControl.sol:57`, which every document-bearing deployment inherits (the native module sits at level 1, the registration at level 2). ✅ The external-engine mock advertises it too (`CMTATDocumentEngineModuleMock.sol:38`). + +### Authorization (§Security Considerations) + +`setDocument` / `removeDocument` are gated by `onlyDocumentManager` → `_authorizeDocumentManagement()` → `onlyRole(DOCUMENT_ROLE)` (`2_CMTATBaseAccessControl.sol:88`; Light path `0_CMTATBaseGeneric.sol:86`). Reads are unrestricted. This matches the spec's "protect `setDocument`/`removeDocument` with appropriate authorization". ✅ + +--- + +## Original draft (`original/draft-erc-1643-document.md`) + +The original is a strict subset of the rework: same four functions, same two events, no custom errors, no ERC-165. CMTAT is a superset and remains **ABI-compatible**: + +- `getDocument`/`setDocument`/`removeDocument`/`getAllDocuments` selectors are identical (the original's `_name`/`_uri`/`_documentHash` parameter names don't affect the ABI signature). ✅ +- The original's events `DocumentUpdated(bytes32 indexed,string,bytes32)` / `DocumentRemoved(...)` have the same topic-0 as CMTAT's. ✅ +- Original: *"`setDocument`/`removeDocument` MUST throw if not stored/removed."* CMTAT reverts (with named custom errors instead of the original's implicit throw) — the rework explicitly permits custom error names/signatures, and the original only requires *a* revert. ✅ +- CMTAT adds `name == bytes32(0)` rejection, which the original does not mention. This is a stricter (safe) addition, not a violation. ✅ + +The interface header even documents the sole intentional deviation: *"Contrary to the original specification, use a struct Document to represent a Document"* (`draft-IERC1643.sol:8`) — an internal representation choice, ABI-transparent. + +--- + +## Non-normative gaps (no conformance impact) + +1. **Test coverage vs the spec's recommended Test Cases.** ~~The suite was missing event-emission, `name==0`, and missing-doc assertions.~~ **Fixed** — `test/common/DocumentModule/DocumentModuleCommon.js` (now 13 tests) adds `testSetDocumentEmitsDocumentUpdated`, `testRemoveDocumentEmitsDocumentRemoved`, `testCannotSetDocumentWithZeroName` (`ERC1643InvalidName`) and `testCannotRemoveMissingDocument` (`ERC1643MissingDocument`). They run on both the native `DocumentERC1643Module` and the external `DocumentEngineModule` (which re-emits the events on the token and forwards the typed errors from the engine). `doc/test/Test.md` updated. + +2. **Pagination (advisory).** `getAllDocuments` returns the whole array in one call. The rework §Security Considerations says implementations expecting large sets *should consider* a paginated accessor (as CMTAT already does for `HolderListModule` via `holdersInRange`). This is a `SHOULD-consider`, not a `MUST`; documents are typically few, so CMTAT deliberately leaves it unpaginated. **Documented** — the [module doc](../modules/extensions/documentEngine/document.md#getalldocuments--bytes32) now carries an explicit "unbounded read / keep the set small" note pointing at the ERC-1643 security consideration and contrasting with `HolderListModule`. + +3. **NatSpec nit.** `draft-IERC1643.sol:39` documents `getAllDocuments`' return as *"An array of strings representing all document identifiers"* — it returns `bytes32[]`, not strings. Trivial wording fix. + +--- + +## Summary + +| Area | Result | +|---|---| +| Rework spec — all `MUST` | ✅ met | +| Rework spec — `SHOULD` (ERC-165, `bytes32(0)` error, `lastModified` sentinel) | ✅ met | +| Original draft | ✅ met (ABI-compatible superset) | +| ERC-165 detection | ✅ registered (`0xecfecec8`) | +| Authorization | ✅ `DOCUMENT_ROLE` | +| Recommended test cases | ✅ added (events, `name==0`, missing-doc) — 13 tests, both variants | +| Pagination | ✅ advisory; documented "keep the set small" (unpaginated by design) | +| NatSpec | ⚠️ one `@return` mislabels `bytes32[]` as "strings" (open) | + +**Conclusion: CMTAT is conformant with ERC-1643 (both the rework draft and the original).** The remaining follow-up is the one-line NatSpec `@return` wording fix; the test-coverage and pagination-note gaps are now closed. diff --git a/doc/ERCSpecification/rework/erc-1404-analysis-rework.md b/doc/ERCSpecification/rework/erc-1404-analysis-rework.md deleted file mode 100644 index cb914482..00000000 --- a/doc/ERCSpecification/rework/erc-1404-analysis-rework.md +++ /dev/null @@ -1,431 +0,0 @@ -# ERC-1404 (rework) — Conformance Analysis of the CMTAT Implementation - -**Scope:** compares the CMTAT ERC-1404 implementation against -[`doc/ERCSpecification/rework/erc-1404.md`](./erc-1404.md) (the reworked draft that -adds the optional spender-aware extension). - -**Files reviewed** - -| Layer | File | -|-------|------| -| Interface | `contracts/interfaces/tokenization/draft-IERC1404.sol` (`IERC1404`, `IERC1404Extend`) | -| Extension id | `contracts/library/ERC1404ExtendInterfaceId.sol` | -| Reporting logic | `contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol` | -| Composition / 165 / active balance | `contracts/modules/4_CMTATBaseERC1404.sol` | -| Enforcement path | `contracts/modules/wrapper/controllers/ValidationModule.sol`, `0_CMTATBaseCommon.sol`, `3_CMTATBaseRuleEngine.sol`, `internal/ERC20EnforcementModuleInternal.sol` | -| Reference rule engine | `contracts/mocks/RuleEngine/RuleEngineMock.sol`, `RuleSpenderAuthorized.sol` | - ---- - -## 1. Verdict - -The implementation is **substantially conformant**. Both mandatory methods and the -optional spender-aware extension are present, both ERC-165 identifiers are computed -correctly and advertised, and the enforcement path is consistent with the reporting -path in the reject/allow sense the standard requires. - -One **normative (MUST) deviation** was found: the `spender == from` degenerate case of -`detectTransferRestrictionFrom` does **not** return the same code as -`detectTransferRestriction`, violating the extension's second MUST clause and the -corresponding row of the Test Cases table. Details in §4. - ---- - -## 2. Mandatory interface — CONFORMANT - -### `detectTransferRestriction(address,address,uint256)` -Implemented at `ValidationModuleERC1404.sol:98`. Returns `0` (`TRANSFER_OK`) when -unrestricted, otherwise a `uint8` code. It layers CMTAT-native checks -(`deactivated`, `paused`, `isFrozen(from)`, `isFrozen(to)`, insufficient active -balance) over an optional rule-engine delegation, exactly the "issuer-defined policy" -the spec describes. - -### `messageForTransferRestriction(uint8)` -Implemented at `ValidationModuleERC1404.sol:52` (+ override in -`4_CMTATBaseERC1404.sol:31` for the active-balance code). Deterministic, pure -string lookup; delegates unknown codes to the rule engine and falls back to -`"UnknownCode"`. Code `0` → `"NoRestriction"`. Conformant (the spec's example string -`"No restriction"` is non-normative). - -### Enforcement consistency — CONFORMANT (via the "re-evaluate" path) -The spec permits two strategies (§Specification): call `detectTransferRestriction` -inside the transfer, **or** re-evaluate the equivalent conditions and revert with typed -errors, "provided the observable outcome remains consistent." CMTAT uses the second -strategy — `transfer`/`transferFrom` route through `_checkTransferred` → -`_canTransferGenericByModuleAndRevert` (`ValidationModule.sol:59`) and the rule -engine's `transferred`, reverting with ERC-7943 typed errors rather than a code. - -The two codepaths re-evaluate the **same predicates** in the same order: - -| Condition | Reporting (`_detectTransferRestriction`) | Enforcement | -|-----------|------------------------------------------|-------------| -| insufficient active balance | `4_CMTATBaseERC1404.sol:98` (`_checkActiveBalance`) | `_checkActiveBalanceAndRevert` (`ERC20EnforcementModuleInternal.sol:140`) | -| paused | `ValidationModuleERC1404.sol:149` | `_requireNotPaused` (`ValidationModule.sol:175`) | -| `isFrozen(from)` / `isFrozen(to)` | `:151` / `:153` | `_canTransferisFrozenAndRevert` (`ValidationModule.sol:138`) | -| rule engine | `ruleEngine.detectTransferRestriction` (`:108`) | `ruleEngine.transferred` (`ValidationModuleRuleEngine.sol:143`) | - -Both **reject iff** at least one predicate fails, satisfying the base method's MUST. -This is a good design — it reuses `_checkActiveBalance` for both paths -(`4_CMTATBaseERC1404.sol:88` documents this intent), so the two cannot drift on the -frozen-balance dimension. - -> **Note (not a bug):** `detectTransferRestriction` returns -> `TRANSFER_REJECTED_DEACTIVATED` for a deactivated contract -> (`ValidationModuleERC1404.sol:147`), but the standard-transfer enforcement path -> checks only `paused`, not `deactivated` (`ValidationModule.sol:171` comment). This -> stays consistent **only because** of the invariant `deactivated ⇒ paused`, enforced -> by `deactivateContract()` requiring the paused state (`PauseModule.sol:86`) and -> `unpause()` reverting while deactivated (`PauseModule.sol:70`). The consistency -> therefore relies on that invariant rather than on the two paths checking the same -> flag. See suggestion §6.2. - ---- - -## 3. Optional spender-aware extension — MOSTLY CONFORMANT - -### ERC-165 identifiers — CONFORMANT (verified) -Selectors and identifiers were recomputed from scratch: - -| Selector | Value | -|----------|-------| -| `detectTransferRestriction(address,address,uint256)` | `0xd4ce1415` | -| `messageForTransferRestriction(uint8)` | `0x7f4ab1dd` | -| `detectTransferRestrictionFrom(address,address,address,uint256)` | `0xd32c7bb5` | -| **Mandatory id** = XOR of first two | **`0xab84a5c8`** ✓ | -| **Extension id** = XOR of all three | **`0x78a8de7d`** ✓ | - -- `supportsInterface` (`4_CMTATBaseERC1404.sol:75`) returns `true` for **both** - `0xab84a5c8` and `0x78a8de7d`, exactly as the spec requires (a base-only integrator - still detects the mandatory id). -- The mandatory id is taken from `type(IERC1404).interfaceId`, which is correct here - **only because** the repo's `IERC1404` (`draft-IERC1404.sol:9`) deliberately does - *not* inherit `IERC20` — so the type-level id covers exactly the two mandatory - selectors and equals `0xab84a5c8`. -- The extension id is taken from the **hand-computed constant** - `ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID` (`:15`), **not** from - `type(IERC1404Extend).interfaceId`. This is precisely the point the spec calls out in - §Extension ("a language-level construct that derives an interface identifier only - from a type's *directly declared* methods … MUST NOT be used"): `IERC1404Extend` - inherits `IERC1404`, so `type(...).interfaceId` would yield only the single selector - `0xd32c7bb5`. The implementation avoids the trap correctly, and the code comment at - `4_CMTATBaseERC1404.sol:70-72` explains why. **Well done.** - -### Delegated-transfer enforcement consistency — CONFORMANT -`transferFrom` enforcement additionally checks `isFrozen(spender)` -(`ValidationModule.sol:143`) and the rule engine's 4-arg `transferred`. -`detectTransferRestrictionFrom` (`ValidationModuleERC1404.sol:114`) mirrors this: -`isFrozen(spender)` → base predicates → `ruleEngine.detectTransferRestrictionFrom`. -Reject-iff-nonzero holds for the 4-argument form. - ---- - -## 4. FINDING — `spender == from` code equality (MUST violation) — Severity: Low - -**Spec requirement** (§Extension, second bullet, and the Test Cases row -"`spender == from` → Equal to `detectTransferRestriction(from, to, value)`"): - -> MUST, when `spender == from`, return the same code as -> `detectTransferRestriction(from, to, value)`, since a direct transfer is the -> degenerate delegated transfer whose initiator is the holder. - -The current `detectTransferRestrictionFrom` does **not** satisfy this. It checks -`isFrozen(spender)` first and, on any spender-specific policy, returns a -spender-specific code — even when `spender == from`. Two concrete divergences: - -**(a) Frozen holder, self-initiated `transferFrom`.** With `spender == from` and `from` -frozen: -- `detectTransferRestrictionFrom(from, from, to, v)` → `isFrozen(spender)` true → - returns `TRANSFER_REJECTED_SPENDER_FROZEN` = **5** (`ValidationModuleERC1404.sol:121-122`). -- `detectTransferRestriction(from, to, v)` → `isFrozen(from)` true → returns - `TRANSFER_REJECTED_FROM_FROZEN` = **3** (`ValidationModuleERC1404.sol:151-152`). -- `5 ≠ 3` → **MUST violated.** - -**(b) Rule-engine spender policy.** When `spender == from`, the method still delegates -to `ruleEngine.detectTransferRestrictionFrom(spender, …)` (`:128`) rather than -`ruleEngine.detectTransferRestriction(…)`. With the shipped `RuleSpenderAuthorized` -mock, a holder who is not the authorized spender gets code **21** -(`RuleSpenderAuthorized.sol:46`) from the `From` variant but **0** from the base -variant — again unequal. - -**Impact.** Enforcement itself stays correct: in both cases the self-transfer is still -*rejected* (frozen) or the divergence is confined to the mock's non-production policy, -so the reject/allow consistency MUST is **not** broken. What breaks is the **code-equality -MUST** for the degenerate case — an integrator that trusts the spec's guarantee "for -`spender == from`, the two predictors agree" will mis-map the reason code (e.g. show -"spender frozen" where the base method says "holder frozen"). Hence **Low severity**: -a conformance/reporting defect, not an enforcement bug. - -**Reachability through `transferFrom` (why the enforcement impact is narrow).** OpenZeppelin's -ERC-20 has **no** `spender == from` special case. `ERC20Upgradeable.transferFrom` -(`ERC20Upgradeable.sol:165`) unconditionally calls `_spendAllowance(from, msg.sender, value)` -before `_transfer`, and `_spendAllowance` (`:319`) consumes `allowance(from, spender)`: - -```solidity -function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { - address spender = _msgSender(); - _spendAllowance(from, spender, value); // no `if (spender == from)` bypass - _transfer(from, to, value); - return true; -} -``` - -So when the holder is the caller (`spender == from`), OZ still spends the holder's -*self-allowance* `allowance(from, from)`, which is `0` by default. A holder calling -`transferFrom(self, to, value)` therefore **reverts with `ERC20InsufficientAllowance(from, 0, value)`** -unless they have explicitly done `approve(self, …)` (and if that self-allowance is -`type(uint256).max`, `:321` skips the decrement). CMTAT runs its restriction checks *before* -this allowance logic (`0_CMTATBaseCommon.sol:92` → `ERC20BaseModule.transferFrom` → OZ), so the -`spender == from` branch of `detectTransferRestrictionFrom` is reached through a real -`transferFrom` only in the narrow case where the holder has self-approved. - -This narrows the *enforcement* exposure but does **not** downgrade the finding: the spec's -`spender == from` MUST is stated over the **view function's return value**, unconditionally. -`detectTransferRestrictionFrom` is public and can be called with `spender == from` regardless -of any allowance, and integrators are told to trust that it agrees with -`detectTransferRestriction` in that case — reachability through `transferFrom` does not gate -the conformance obligation. - -**Fix (one line, guarantees the MUST regardless of the rule engine):** short-circuit the -degenerate case at the top of `detectTransferRestrictionFrom`: - -```solidity -function detectTransferRestrictionFrom( - address spender, address from, address to, uint256 value -) public view virtual override(IERC1404Extend) returns (uint8 code) { - if (spender == from) { - // degenerate delegated transfer == direct transfer (ERC-1404 extension MUST) - return detectTransferRestriction(from, to, value); - } - IRuleEngineERC1404 ruleEngine_ = IRuleEngineERC1404(address(ruleEngine())); - if (isFrozen(spender)) { - return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN); - } - ... -} -``` - -This matches the enforcement path **for the frozen dimension**: when `spender == from`, -the `isFrozen(spender)` and `isFrozen(from)` checks in `_canTransferisFrozenAndRevert` -collapse to the same single revert, so reporting the `from` code is the faithful -reflection of what enforcement does. - -> **⚠ The short-circuit is not unconditionally safe.** Routing `spender == from` to the -> non-spender-aware `detectTransferRestriction` **skips any rule-engine rule that restricts -> the spender as an operator distinct from the owner** (e.g. `RuleSpenderAuthorized`). If -> the enforcement path still applies such a rule when `spender == from`, the short-circuit -> converts a *code-mismatch* into a worse *report-OK-but-revert* divergence. This tension — -> and the fact that the two extension MUSTs (`spender == from` equality vs. `From`-variant -> enforcement consistency) can become mutually unsatisfiable — is analysed in -> [§8](#8-security-analysis--delegating-transferfrom-evaluation-to-the-non-spender-aware-path). -> Apply the short-circuit **only** together with the enforcement guarantee described there. - -**Add a test** asserting, over fuzzed `(from, to, value)` and relevant frozen/rule -states, that `detectTransferRestrictionFrom(x, x, y, v) == detectTransferRestriction(x, y, v)`. - ---- - -## 5. Other observations (informational) - -- **Additional restriction codes for supply-changing ops.** The spec explicitly - permits analogous checks on mint/burn (§Additional Specifications). CMTAT applies them - via `_checkTransferred` on the mint/burn paths (`0_CMTATBaseCommon.sol:128,138`). - Conformant and optional. The `spender` of a mint/burn is not currently threaded into a - `detectTransferRestrictionFrom`-style predictor; the spec says that is a MAY, so no - action required. -- **Interface not inheriting `IERC20`.** `draft-IERC1404.sol:6-9` documents the - deliberate deviation from the original ERC-1404 (which extended `IERC20`). This is - fully aligned with the rework's token-agnostic framing (§Rationale item 4 / §Additional - Specifications: a compliance contract may implement the restriction interface without a - token interface). The concrete CMTAT token still implements ERC-20 via - `ERC20Upgradeable`, so the "MUST implement its underlying token interface" clause holds - at the token level. -- **Determinism.** Every predicate reads issuer-controlled contract state (frozen flags, - pause/deactivate flags, frozen-token balances) — no counterparty-manipulable inputs - (§Security Considerations, flash-loan guidance) — so the determinism SHOULD is met. -- **`value` unused in the base predicate.** `_detectTransferRestriction` - (`ValidationModuleERC1404.sol:142`) ignores `value`; the value-dependent check - (active balance) is correctly layered in the `4_` override (`:98`). Intentional and - fine. - ---- - -## 6. Suggestions - -### 6.1 Implementation -1. **Fix the `spender == from` short-circuit** (§4) and add the equivalence fuzz test. -2. **Encode the detect/enforce equivalence as a tested invariant** (the spec's - Security-Considerations SHOULD): a fuzz test asserting `detectTransferRestriction(...) != 0` - **iff** `transfer(...)` reverts, and likewise for the `From`/`transferFrom` pair. - Because CMTAT uses the "re-evaluate" enforcement strategy, this is the exact drift the - spec warns about; a property test locks it down. -3. **Make the `deactivated`/`paused` coupling explicit** (§2 note): either check - `deactivated` in the standard-transfer enforcement path too, or add an assertion/comment - at the enforcement site referencing the `deactivated ⇒ paused` invariant, so a future - change to `unpause`/`deactivate` can't silently desynchronise reporting from enforcement. -4. **Restriction-code namespacing.** CMTAT reserves `0–6` (`draft-IERC1404.sol:49-57`) - and the rework leaves `7–12` free; rule mocks use `21`. Document the reserved ranges in - one place so composed rule engines don't collide within the 256-value `uint8` space. - -### 6.2 The standard itself -1. **Relax or clarify the `spender == from` MUST.** The current text requires *code - equality* for the degenerate case, which conflicts with the very natural design of - emitting a distinct "spender frozen" reason: an implementation that reports - `SPENDER_FROZEN` when a frozen holder self-initiates a `transferFrom` is arguably more - informative, yet non-conformant. Consider one of: - - weaken the MUST to *reject/allow equivalence* (`== 0` iff base `== 0`) for - `spender == from`, keeping the exact code an implementation detail; **or** - - keep code-equality but add explicit guidance that spender-specific codes MUST NOT be - produced when `spender == from` (i.e. mandate the short-circuit of §4), and show it in - the Reference Implementation. - The CMTAT case is a concrete data point that the current wording is easy to violate. -2. **Guidance for delegating implementations.** Many real tokens (CMTAT included) delegate - `detectTransferRestrictionFrom` to a sub-policy/rule engine. The spec could add a - non-normative note: to guarantee the `spender == from` MUST irrespective of the - sub-policy, resolve the degenerate case at the token layer by calling - `detectTransferRestriction`, rather than passing `spender == from` down to a policy that - may treat the spender dimension independently. -3. **Distinguishable "unknown code" contract for `messageForTransferRestriction`.** The - spec leaves the return for an unrecognised code unspecified; CMTAT returns `"UnknownCode"`. - A one-line SHOULD ("for an unallocated code, implementations SHOULD return a message - distinguishable from any valid restriction message") would help UI builders. -4. **Reserved-range convention.** Given the `uint8` space and the composition pattern - (token-native codes + rule-engine codes), the standard could suggest a lightweight - namespacing convention (e.g. issuer reserves a low range, policies use a high range) to - reduce collision risk it already flags in Security Considerations. - ---- - -## 7. Summary table - -| Requirement | Status | -|-------------|--------| -| `detectTransferRestriction` present, returns `uint8`, `0` = OK | ✅ | -| `messageForTransferRestriction` present, deterministic | ✅ | -| Enforcement consistent with base method (reject iff non-zero) | ✅ (via re-evaluate strategy) | -| ERC-165 `0xab84a5c8` advertised | ✅ (verified) | -| Extension `detectTransferRestrictionFrom` present | ✅ | -| ERC-165 `0x78a8de7d` advertised, computed by explicit XOR (not `type().interfaceId`) | ✅ (verified) | -| Delegated enforcement consistent with `detectTransferRestrictionFrom` | ✅ | -| `spender == from` ⇒ same code as `detectTransferRestriction` | ❌ **Low-severity MUST violation (§4)** | -| Optional mint/burn restriction checks | ✅ (optional) | -| Determinism / no manipulable inputs | ✅ | - ---- - -## 8. Security analysis — delegating `transferFrom` evaluation to the non-spender-aware path - -A delegated transfer (`transferFrom`, executed by a `spender` that may differ from `from`) -can end up evaluated by the **three-argument, non-spender-aware** predictor -`detectTransferRestriction(from, to, value)` instead of the four-argument -`detectTransferRestrictionFrom(spender, from, to, value)`. This happens in two places: - -- **(P1) The `spender == from` short-circuit** recommended in [§4](#4-finding--spender--from-code-equality-must-violation--severity-low): the token resolves the degenerate delegated transfer by calling the non-spender-aware method. -- **(P2) Integrators / integrating contracts** that gate or predict a `transferFrom` by calling the base `detectTransferRestriction` (or `canTransfer`) rather than the spender-aware companion. - -Below is the threat model for both. **None of these is an on-chain enforcement bypass in -CMTAT** — the transfer path itself stays spender-aware (`transferFrom` → -`_checkTransferred(msg.sender, …)` → `_canTransferisFrozenAndRevert(spender,…)` + -`ruleEngine.transferred(spender,…)`, `ValidationModule.sol:143`, -`ValidationModuleRuleEngine.sol:142`) and remains authoritative. The risks are -**mis-prediction, standards non-conformance, and the downstream DoS / UX / integration -failures they cause.** - -### 8.1 Threats - -**T1 — Optimistic mis-prediction → silent DoS (applies to P1 and P2).** -The non-spender-aware method cannot observe a spender-specific restriction (frozen operator, -operator not on an allow-list, per-operator limits). It therefore returns `0` ("no -restriction") for a `transferFrom` that the on-chain path then **reverts**. Consumers that -trust the `0` — exchanges pre-flighting withdrawals, batchers, relayers, aggregators — -submit transactions that fail, wasting gas and, in batched/atomic contexts, reverting -unrelated operations. The spec calls this out directly (Security Considerations: *"Integrators -MUST NOT treat a 0 from `detectTransferRestriction` as a prediction that a `transferFrom` -will succeed"*). - -**T2 — The short-circuit can invert the divergence into report-OK-but-revert (P1).** -The [§4](#4-finding--spender--from-code-equality-must-violation--severity-low) fix makes -`detectTransferRestrictionFrom(from, from, to, v)` return -`detectTransferRestriction(from, to, v)`, which for a *valid holder* is `0`. But CMTAT's -enforcement of that same self-initiated `transferFrom` calls -`ruleEngine.transferred(from, from, to, v)` (the **4-arg**, spender-aware hook). If any rule -restricts `from` **as an operator** (as `RuleSpenderAuthorized` does: only a designated -custodian may initiate a delegated transfer, `RuleSpenderAuthorized.sol:37-47`), enforcement -**reverts** while the predictor now reports `0`. This is strictly worse than the original -code-mismatch: a `0` that precedes a revert is exactly the machine-readable-code failure the -standard exists to prevent, and it violates the **`From`-variant enforcement-consistency -MUST** ("MUST NOT be rejected for restriction reasons when `detectTransferRestrictionFrom` -returns `0`"). - -**T3 — Two extension MUSTs become mutually unsatisfiable under an owner-as-operator policy.** -For a policy that (a) permits `from` to move its own tokens by a direct `transfer` yet (b) -forbids `from` from acting as its own `transferFrom` operator, the extension's two MUSTs -collide: -- *Equality MUST* wants `detectTransferRestrictionFrom(from, from, …) == detectTransferRestriction(from, …) == 0`. -- *`From`-consistency MUST* wants `detectTransferRestrictionFrom(from, from, …) != 0`, because the actual self-`transferFrom` reverts. -No implementation can satisfy both. The existence of such a policy is therefore the real -design decision hiding behind the §4 finding — not a code detail. - -**T4 — False authorization assumption in integrating contracts (P2).** -A contract that treats `canTransfer(from, to, value) == true` as evidence that a *specific -spender* is authorized (then performing privileged bookkeeping, credit, or accounting on that -basis) is reasoning about a predicate that never looked at the spender. In CMTAT the token -transfer still reverts on a frozen/unauthorized spender, so no tokens move — but the -integrator's own state may already have advanced. This is an integration bug, but the -non-spender-aware surface makes it easy to write. - -### 8.2 Why CMTAT core is safe, and where the risk actually lives - -The CMTAT **core** dimensions are safe under the short-circuit because they key on the -*address*, not on an operator role distinct from ownership: -- **Freeze / pause / deactivate / active-balance** — when `spender == from`, freezing `from` - and freezing `from`-as-spender are the same fact, so the non-spender-aware result and the - enforced result agree. `transfer` deliberately passes `spender == address(0)` - (`0_CMTATBaseCommon.sol:75`), so direct transfers are correctly evaluated by the 3-arg hook - with no operator dimension to lose. - -The risk surfaces **only** once a **RuleEngine rule distinguishes the operator identity from -the owner identity** (allow-listed operators, frozen operators, per-operator caps). That is -precisely the class `RuleSpenderAuthorized` represents, and precisely where P1's short-circuit -and P2's mis-prediction bite. - -### 8.3 Recommendations - -1. **Decide the owner-as-operator semantics explicitly — it is a policy choice, not a code - detail.** Answer: *may a token holder always initiate a `transferFrom` of their own tokens - (subject to the normal `from`/`to`/`value` checks and their own allowance)?* - - **If yes** (the spec's assumed model — "a direct transfer is the degenerate delegated - transfer whose initiator is the holder"): adopt the §4 short-circuit **and** make the - enforcement path exempt `spender == from` from operator-only rules — e.g. have every - spender-restricting rule early-return `TRANSFER_OK` when `spender == from` - (`RuleSpenderAuthorized`: add `|| spender == from`). Only with *both* sides exempting the - degenerate case do the equality MUST and the `From`-consistency MUST hold simultaneously. - **Do not ship the reporting-side short-circuit alone** (that is T2). - - **If no** (operator must be a designated custodian even for self-initiated delegated - transfers): **do not** short-circuit; keep `detectTransferRestrictionFrom` fully - spender-aware so it stays consistent with enforcement, accept that the *equality MUST* is - violated for `spender == from`, and pursue the spec relaxation in - [§6.2](#62-the-standard-itself) (weaken equality to reject/allow equivalence). - -2. **Make the choice a tested invariant — assert both MUSTs together.** A single equality - test is insufficient because it hides T2. Fuzz over `(spender, from, to, value)` and rule - state and assert **both**: - - `detectTransferRestrictionFrom(x, x, y, v) == detectTransferRestriction(x, y, v)` (equality), **and** - - `detectTransferRestrictionFrom(s, f, t, v) == 0` **iff** `transferFrom(f, t, v)` by `s` succeeds (`From`-consistency). - If a policy makes these two assertions contradict, the suite fails — which is the correct, - loud signal that the owner-as-operator semantics of recommendation 1 must be settled before - shipping. - -3. **Integrator guidance (P2 / T1 / T4).** To predict or gate a `transferFrom`, integrators - MUST use `detectTransferRestrictionFrom` / `canTransferFrom`, never the 3-arg method. - CMTAT should keep advertising the extension via ERC-165 (`0x78a8de7d`, - `4_CMTATBaseERC1404.sol:80`) so integrators can *discover* the spender-aware predictor with - one `supportsInterface` call; a token that does not expose the extension cannot predict - `transferFrom` on-chain and integrators must fall back to submitting and handling the - revert. `canTransfer`/`detectTransferRestriction` must never be treated as spender - authorization. - -4. **Never widen `transfer` to the 4-arg operator rules, and never narrow `transferFrom` away - from them.** The token's routing (`transfer` → 3-arg `transferred`, `transferFrom` → 4-arg - `transferred`, `ValidationModuleRuleEngine.sol:142`) is attacker-independent and correct; - it must stay that way so operator rules cannot be bypassed by disguising a delegated - transfer as a direct one, nor spuriously applied to genuine direct transfers. diff --git a/doc/ERCSpecification/rework/erc-1404-last.md b/doc/ERCSpecification/rework/erc-1404-last.md deleted file mode 100644 index bb68b720..00000000 --- a/doc/ERCSpecification/rework/erc-1404-last.md +++ /dev/null @@ -1,201 +0,0 @@ -# ERC-1404 (rework, current version) — Final Conformance Analysis - -**Spec analysed:** [`erc-1404.md`](./erc-1404.md) — the updated rework, in which the former -`spender == from` **equality MUST** has been replaced by a **SHOULD** (evaluate the -`spender == from` case through the spender-aware path) plus an **optional skip** for policies -that do not restrict operator identity. The Test Cases table now splits the `spender == from` -row accordingly (spec `:81`, `:143-144`). - -**Supersedes:** [`erc-1404-analysis-rework.md`](./erc-1404-analysis-rework.md) and -[`ruleengine-erc1404-rework.md`](./ruleengine-erc1404-rework.md). See §5 for what changed. - -**Code analysed (unchanged except the mock `supportsInterface` fix already applied):** - -| Layer | File | -|-------|------| -| Interface / extension id | `contracts/interfaces/tokenization/draft-IERC1404.sol`, `contracts/library/ERC1404ExtendInterfaceId.sol` | -| Token reporting | `contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol` | -| Token composition / 165 | `contracts/modules/4_CMTATBaseERC1404.sol` | -| Token enforcement | `ValidationModule.sol`, `0_CMTATBaseCommon.sol`, `3_CMTATBaseRuleEngine.sol`, `internal/ERC20EnforcementModuleInternal.sol` | -| Rule engine | `contracts/mocks/RuleEngine/RuleEngineMock.sol` + rules | - ---- - -## 1. Verdict - -Against the current spec, **both the CMTAT token and the RuleEngine mock are conformant.** - -- The fundamental **enforcement-consistency MUST** (a transfer/`transferFrom` is rejected iff - the corresponding predictor returns non-zero) holds on every path. -- Both ERC-165 identifiers (`0xab84a5c8`, `0x78a8de7d`) are advertised by both contracts. -- The former `spender == from` findings are **resolved by the spec change**: CMTAT and the - operator-restricting rule (`RuleSpenderAuthorized`) correctly evaluate `spender == from` - through the spender-aware path, which the new text explicitly endorses (`:81`). - -One **informational** item remains: the rule engine's `messageForTransferRestriction(0)` -returns `"UnknownRestrictionCode"` rather than a no-restriction string (§4.3 / §3.4 below). -Everything else is a positive. - ---- - -## 2. Effect of the spec change - -The old text required `detectTransferRestrictionFrom(from, from, …) == detectTransferRestriction(from, …)`. -The new text (`:81`) instead: - -- **SHOULD** evaluate `spender == from` through the spender-aware path (treat `transferFrom` as a - delegated transfer even when the initiator equals `from`); -- **MAY** skip the spender-specific checks for `spender == from` **only** when observably - equivalent (no operator-identity restriction); -- **MUST NOT** skip when the policy restricts the operator identity, because skipping would - report `0` for a self-`transferFrom` that reverts. - -Both CMTAT and the mock restrict the operator identity (frozen spender / allow-listed spender), -so the binding rule for them is "**MUST NOT skip**" — and neither skips. What used to be a MUST -violation is now the required behaviour. - ---- - -## 3. CMTAT token - -### 3.1 Mandatory methods — CONFORMANT -- `detectTransferRestriction` (`ValidationModuleERC1404.sol:98`), `messageForTransferRestriction` - (`:52`, override `4_CMTATBaseERC1404.sol:31`). `messageForTransferRestriction(0)` → - `"NoRestriction"` (`:56`). ✓ - -### 3.2 Spender-aware extension & the `spender == from` case — CONFORMANT -`detectTransferRestrictionFrom` (`ValidationModuleERC1404.sol:114`) evaluates -`isFrozen(spender)` first (`:121`), then the base `from`/`to`/`value` conditions (`:124`), then -delegates to `ruleEngine.detectTransferRestrictionFrom(spender, …)` (`:128`). It does **not** -short-circuit `spender == from`, so a self-initiated `transferFrom` by a frozen holder is -reported as `SPENDER_FROZEN` (`:121-122`) — which is exactly what enforcement does (see 3.3). - -This satisfies the new SHOULD (`:81`): CMTAT is an operator-restricting policy (a frozen -`spender` cannot operate), so it is in the "MUST NOT skip" class, and it correctly keeps the -spender-aware path. The divergence from `detectTransferRestriction` for `spender == from` is now -**explicitly permitted** (`:144`). - -> Note: the short-circuit fix recommended in the *previous* analysis is **withdrawn** — under the -> current spec it would be the prohibited skip (`:81`, Security Considerations `:232`), turning a -> permitted code difference into a report-`0`-then-revert divergence. - -### 3.3 Enforcement consistency (the binding MUST) — CONFORMANT -CMTAT enforces by re-evaluating conditions (typed ERC-7943 reverts), the spec's permitted -alternative to calling the detector directly (`:50`). Reporting and enforcement check the same -predicates, so both reject iff any fails: - -| Predicate | `detectTransferRestrictionFrom` | `transferFrom` enforcement | -|-----------|--------------------------------|----------------------------| -| `isFrozen(spender)` | `:121` | `_canTransferisFrozenAndRevert` (`ValidationModule.sol:143`) | -| active balance of `from` | `:124` → `_checkActiveBalance` (`4_CMTATBaseERC1404.sol:98`) | `_checkActiveBalanceAndRevert` (`ERC20EnforcementModuleInternal.sol:140`) | -| paused / deactivated | `:124` (`_detectTransferRestriction`) | `_requireNotPaused` (`ValidationModule.sol:175`); `deactivated ⇒ paused` invariant (`PauseModule.sol:70,86`) | -| `isFrozen(from)` / `isFrozen(to)` | `:124` | `ValidationModule.sol:145,147` | -| rule engine | `ruleEngine.detectTransferRestrictionFrom` (`:128`) | `ruleEngine.transferred(spender,…)` → `detectTransferRestrictionFrom` (`ValidationModuleRuleEngine.sol:143`, `RuleEngineMock.sol:130`) | - -Same for the base pair (`transfer` routes `spender = address(0)` → 3-arg `transferred` → -`detectTransferRestriction`). Reject-iff-non-zero holds; the check *order* differs but the MUST -is about agreement, not code identity. ✓ - -### 3.4 ERC-165 — CONFORMANT (verified) -`supportsInterface` (`4_CMTATBaseERC1404.sol:75`) returns `true` for `type(IERC1404).interfaceId` -(= `0xab84a5c8`, valid because the repo's `IERC1404` does not inherit `IERC20`) and for -`ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID` (`0x78a8de7d`, the hand-computed 3-selector -XOR — correctly *not* `type(IERC1404Extend).interfaceId`, per spec `:91`). Both verified by -recomputation in the prior analysis. ✓ - ---- - -## 4. RuleEngine mock - -The spec (`:101`) explicitly permits a compliance contract to implement the restriction -interface without being a token — which is exactly what `RuleEngineMock` is. - -### 4.1 ERC-165 — CONFORMANT (fix applied) -`supportsInterface` (`RuleEngineMock.sol:177-179`) now returns `true` for -`type(IERC1404).interfaceId` (`0xab84a5c8`), `ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID` -(`0x78a8de7d`), the rule-engine id (`0x20c49ce7`), and ERC-165. The mandatory-id omission flagged -in the previous analysis (§4.1) is **fixed** and covered by a test -(`ValidationModuleSetRuleEngineCommon.js`, `testCanReturnTheRightInterface`). ✓ - -### 4.2 `spender == from` via the rules — CONFORMANT (now intended) -`detectTransferRestrictionFrom` (`RuleEngineMock.sol:82`) iterates each rule's 4-arg form: -- `RuleSpenderAuthorized` (`:37-47`) restricts the operator identity → it does **not** skip - `spender == from`; `detectTransferRestrictionFrom(from, from, …)` returns - `SPENDER_NOT_AUTHORIZED` (21) while `detectTransferRestriction(from, …)` returns `0`. Under the - current spec this divergence is **permitted** (`:144`) and is consistent with enforcement (the - self-`transferFrom` reverts via `transferred` → `canTransferFrom` → 21, `:130`). ✓ -- `RuleMock` / `RuleMockMint` do not restrict operator identity, so they delegate their `From` - variant straight to `detectTransferRestriction` (`RuleMock.sol:44`, `RuleMockMint.sol:43`) — - the allowed optimization skip (`:81`). ✓ - -The previous §4.2 finding is therefore **resolved by the spec change**, not by a code change. - -### 4.3 `messageForTransferRestriction(0)` — INFORMATIONAL (open) -`messageForTransferRestriction` (`RuleEngineMock.sol:151`) has no rule claiming code `0`, so it -falls through to `"UnknownRestrictionCode"` (`:164`). The Test Cases table still expects code `0` -to yield a no-restriction string (`:152`). Masked on the token (which maps `TRANSFER_OK` first), -but the spec allows the engine to be consulted directly (`:101`), where `0` should read as "no -restriction", not "unknown". Deterministic, so **informational**, not a MUST break. - -**Fix:** `if (_restrictionCode == 0) return "NoRestriction";` at the top of the function, plus a -test asserting it. - -### 4.4 Enforcement consistency — CONFORMANT -The engine uses the spec's RECOMMENDED strategy: `transferred` invokes the detector directly -(`RuleEngineMock.sol:130,138`), so reporting and enforcement cannot drift within the engine. ✓ - ---- - -## 5. What changed since the previous analyses - -| Item | Previous verdict | Now | -|------|------------------|-----| -| Token `spender == from` code differs from base (`erc-1404-analysis-rework.md` §4) | ❌ MUST violation | ✅ Conformant — permitted by new `:81`/`:144`; short-circuit fix **withdrawn** | -| Mock `spender == from` via `RuleSpenderAuthorized` (`ruleengine-…` §4.2) | ❌ MUST violation | ✅ Conformant — intended, operator-restricting policy | -| Mock `supportsInterface` missing `0xab84a5c8` (§4.1) | ❌ MUST violation | ✅ **Fixed** in code + test | -| Mock `messageForTransferRestriction(0)` (§4.3) | ⚠ Informational | ⚠ Informational (still open) | - ---- - -## 6. Remaining suggestions - -1. **(Mock, informational)** Return a no-restriction string for code `0` in - `RuleEngineMock.messageForTransferRestriction` (§4.3), with a test. -2. **(Both, robustness)** Add the enforcement-consistency invariant as a fuzz test — the spec's - SHOULD (`:228`): over random `(spender, from, to, value)` and state, assert - `detectTransferRestrictionFrom(s,f,t,v) == 0` **iff** `transferFrom(f,t,v)` by `s` succeeds, - and the base pair likewise. Because CMTAT uses the re-evaluate strategy, this locks the two - codepaths together. (Do **not** assert `spender == from` equality — the spec no longer requires - it, and asserting it would contradict the operator-restricting policies.) -3. **(Both, docs)** Add a one-line comment at `ValidationModuleERC1404.detectTransferRestrictionFrom` - and in `RuleSpenderAuthorized` noting the deliberate non-skip for `spender == from` and citing - spec `:81`, so a future "optimization" doesn't reintroduce the prohibited skip. -4. **(Mock, housekeeping)** Restriction-code namespacing: rules use `13/20/21`, clear of the - reserved `0–12`; keep a single table of allocated codes to avoid collisions in the `uint8` - space (spec `:107`). - ---- - -## 7. Summary tables - -### CMTAT token -| Requirement (current spec) | Status | -|----------------------------|--------| -| `detectTransferRestriction` / `messageForTransferRestriction` present, `0` = OK | ✅ | -| Enforcement consistent with base method | ✅ (re-evaluate strategy) | -| `detectTransferRestrictionFrom` present | ✅ | -| `spender == from` via spender-aware path (SHOULD; MUST NOT skip for operator-restricting policy) | ✅ | -| `detectTransferRestrictionFrom` consistent with `transferFrom` enforcement | ✅ | -| ERC-165 `0xab84a5c8` and `0x78a8de7d` advertised | ✅ (verified) | -| Determinism | ✅ | - -### RuleEngine mock -| Requirement (current spec) | Status | -|----------------------------|--------| -| Restriction interface as a non-token compliance contract | ✅ (`:101`) | -| Three methods present; enforcement invokes detectors directly | ✅ | -| ERC-165 `0xab84a5c8` (mandatory) | ✅ (fixed) | -| ERC-165 `0x78a8de7d` (extension), via explicit XOR constant | ✅ | -| `spender == from` handled per policy, consistent with enforcement | ✅ | -| `messageForTransferRestriction(0)` returns a no-restriction string | ⚠ returns `"UnknownRestrictionCode"` (informational) | -| Determinism / namespaced codes | ✅ | diff --git a/doc/ERCSpecification/rework/erc-1404-proposition.md b/doc/ERCSpecification/rework/erc-1404-proposition.md deleted file mode 100644 index 0dfcd7eb..00000000 --- a/doc/ERCSpecification/rework/erc-1404-proposition.md +++ /dev/null @@ -1,209 +0,0 @@ -# Proposition — ERC-1404 rework: relax the `spender == from` equality requirement - -**Target document:** [`erc-1404.md`](./erc-1404.md) (rework draft, spender-aware extension) -**Related analyses:** [`erc-1404-analysis-rework.md`](./erc-1404-analysis-rework.md) §4 / §8, -[`ruleengine-erc1404-rework.md`](./ruleengine-erc1404-rework.md) §4.2 -**Status:** proposal for discussion -**Type:** editorial + normative change to the OPTIONAL extension section only (no interface-id change) - ---- - -## 1. Summary - -The current extension text requires, as a **MUST**, that when `spender == from` the -spender-aware predictor return the *same code* as the base predictor: - -> MUST, when `spender == from`, return the same code as `detectTransferRestriction(from, to, value)`, -> since a direct transfer is the degenerate delegated transfer whose initiator is the holder. - -This proposition **removes that unconditional equality MUST** and replaces it with: - -- keep the fundamental **enforcement-consistency MUST** for every spender, `spender == from` included; -- **SHOULD** evaluate `spender == from` through the spender-aware path (treat `transferFrom` as a - delegated transfer regardless of whether the initiator happens to equal `from`); -- **MAY** skip the spender-specific checks for `spender == from` **as an optimization**, but only - where that skip is observably equivalent (the policy imposes no operator-identity restriction - beyond ownership). - -Net effect: an implementation that keeps `transferFrom` on the spender-aware path even when -`spender == from` (as CMTAT does) becomes **conformant as written**, and the accidental -report-OK-but-revert trap the equality MUST can create is eliminated. - ---- - -## 2. Motivation - -### 2.0 Worked counterexample — whitelisted-spender policy - -Consider a policy where **every `transferFrom` spender must be whitelisted**, while a direct -`transfer` is unrestricted. Take an address `A` that is **not** a whitelisted spender: - -| Call | Correct result | Reason | -|------|----------------|--------| -| `transfer(to, v)` by `A` | succeeds | direct transfers are unrestricted | -| `detectTransferRestriction(A, to, v)` | `0` | reports that `A`'s direct transfer is allowed | -| `transferFrom(A, to, v)` by `A` | **reverts** | `A` is not a whitelisted spender — even of its own tokens | -| `detectTransferRestrictionFrom(A, A, to, v)` | **non-zero** | must faithfully report the delegated transfer it describes | - -The current equality MUST forces `detectTransferRestrictionFrom(A, A, to, v)` to return `0` (to -match `detectTransferRestriction`). That is not merely over-specified — it is **wrong**: it -predicts success for a `transferFrom` that reverts, and it directly contradicts the -enforcement-consistency MUST in the same section. A policy is entitled to allow an address to -`transfer` but forbid it from acting as a `transferFrom` operator, and the spender-aware -predictor must be free to say so. - -### 2.1 `transferFrom` is a distinct operation - -**`transferFrom` with `spender == from` is not the same operation as `transfer`.** They are -distinct entry points with distinct authorization machinery. Even mechanically, OpenZeppelin's -`transferFrom` runs `_spendAllowance(from, from, value)` (`ERC20Upgradeable.sol:165,319`) and -flows through the allowance path, which `transfer` never touches. The premise behind the -equality MUST — "a direct transfer *is* the degenerate delegated transfer whose initiator is -the holder" — therefore does not hold at the EVM level. A policy is entitled to distinguish -"holder moves own tokens directly" from "a delegated-transfer operator, who happens to be the -holder, moves tokens" (e.g. a compliance regime where any `transferFrom` operator must be a -licensed custodian). - -**Enforcement-consistency is the property integrators actually need — equality can contradict it.** -The spender-aware predictor exists so a caller can predict a *delegated* transfer. Requiring -`detectTransferRestrictionFrom(from, from, …)` to mirror the *direct-transfer* predictor forces -it to misreport the delegated transfer it is describing. Worse, for a policy that restricts the -operator identity, the equality MUST and the enforcement-consistency MUST become **mutually -unsatisfiable**: - -| | wants | -|---|---| -| equality MUST | `detectTransferRestrictionFrom(from, from, …) == detectTransferRestriction(from, …) == 0` | -| enforcement-consistency MUST | `detectTransferRestrictionFrom(from, from, …) != 0`, because the self-`transferFrom` reverts | - -When a derived MUST cannot coexist with the fundamental consistency MUST, the derived one must -give. This proposition resolves the conflict in favour of consistency. - -**What the equality clause was buying is preserved elsewhere.** Its useful effect — preventing a -self-`transferFrom` from silently skipping the `from`/`to`/`value` checks — is already guaranteed -by the extension's third bullet ("the base method continues to describe the `from`/`to`/`value` -conditions; the extension adds only the `spender` dimension"). The extension is a *superset* of -the base conditions, not a replacement, so dropping equality does not reintroduce that footgun. - -**The optimization the equality clause forbids is legitimate and should be explicitly allowed.** -For the common whitelist/freeze-style policies that do *not* single out operator identity, -evaluating `spender == from` through the cheaper non-spender-aware path yields an identical -result. Implementations should be free to take that gas saving — but as a MAY conditioned on -equivalence, not as a blanket MUST that also traps operator-restricting policies. - ---- - -## 3. Proposed specification changes - -### 3.1 Extension section — the three bullets - -**Current** (§ *Extension: spender-aware restriction detection*): - -> An implementation that exposes `detectTransferRestrictionFrom`: -> -> - MUST keep it consistent with delegated-transfer enforcement, in the same sense the base -> method is consistent with the transfer path: a `transferFrom(from, to, value)` executed by -> `spender` MUST be rejected whenever `detectTransferRestrictionFrom(spender, from, to, value)` -> would return a non-zero code, and MUST NOT be rejected for restriction reasons when it would -> return `0`. -> - **MUST, when `spender == from`, return the same code as `detectTransferRestriction(from, to, value)`, -> since a direct transfer is the degenerate delegated transfer whose initiator is the holder.** -> - MUST NOT change the meaning of, or the enforcement consistency required of, -> `detectTransferRestriction`. … - -**Proposed** (replace the middle bullet; the first and third are unchanged): - -> An implementation that exposes `detectTransferRestrictionFrom`: -> -> - MUST keep it consistent with delegated-transfer enforcement … *(unchanged)* -> - **SHOULD evaluate the `spender == from` case through the spender-aware path, because -> `transferFrom` is a distinct delegated-transfer entry point whose authorization may depend on -> the initiating operator even when that operator equals `from`. An implementation MAY instead -> evaluate `spender == from` through the non-spender-aware path — equivalently, skip the -> spender-specific checks — as an optimization, but only when doing so is observably equivalent, -> i.e. its policy imposes no restriction on the initiating operator's identity beyond the -> `from`/`to`/`value` conditions. An implementation whose policy *does* restrict the operator -> identity (for example, an allow-listed or frozen operator set) MUST NOT skip, since skipping -> could return `0` (or an owner-only code) for a self-initiated `transferFrom` that enforcement -> rejects, violating the enforcement-consistency requirement above. When the policy does not -> distinguish operator identity from ownership, `detectTransferRestrictionFrom(from, from, to, value)` -> and `detectTransferRestriction(from, to, value)` return the same code, and skipping is always -> safe.** -> - MUST NOT change the meaning of, or the enforcement consistency required of, -> `detectTransferRestriction`. … *(unchanged)* - -### 3.2 Rationale — item 5 - -**Add** to Rationale item 5 (*Optional spender-aware detection*): - -> The extension does not require `detectTransferRestrictionFrom(from, from, …)` to equal -> `detectTransferRestriction(from, …)`. A `transferFrom` initiated by the holder is still a -> delegated transfer — it flows through the allowance path and is a different entry point than a -> direct `transfer` — so a policy that restricts the initiating operator (even when the operator -> is the holder) is legitimate, and the spender-aware predictor must be free to describe it. The -> only invariant that matters for integrators is that `detectTransferRestrictionFrom` agree with -> `transferFrom` enforcement; requiring it to instead mirror the direct-transfer predictor would -> force it to misreport, and for operator-restricting policies would conflict with that agreement. -> Implementations whose policy does not distinguish operator identity from ownership will observe -> the two predictors coincide for `spender == from` and MAY skip the spender-aware evaluation as -> an optimization. - -### 3.3 Test Cases — `detectTransferRestrictionFrom` table - -**Current** row: - -| Scenario | Expected return | -|---|---| -| `spender == from` | Equal to `detectTransferRestriction(from, to, value)` | - -**Proposed** rows: - -| Scenario | Expected return | -|---|---| -| `spender == from`, policy does **not** restrict operator identity | Equal to `detectTransferRestriction(from, to, value)` | -| `spender == from`, policy **does** restrict the initiating operator | Reflects the delegated-transfer policy for that operator, and is consistent with `transferFrom` enforcement; MAY differ from `detectTransferRestriction(from, to, value)` | - -(The existing "consistent with `transferFrom` enforcement" rows already cover the binding -requirement; these two rows replace the single equality row.) - -### 3.4 Security Considerations — the `spender == from` note - -**Add** a bullet: - -> Because `transferFrom` is a delegated-transfer entry point, an implementation that restricts the -> initiating operator SHOULD evaluate `spender == from` through the spender-aware path rather than -> collapsing it to the direct-transfer predictor. Collapsing it (for example, an unconditional -> `if (spender == from) return detectTransferRestriction(from, to, value);` short-circuit) can make -> `detectTransferRestrictionFrom` return `0` for a self-initiated `transferFrom` that enforcement -> then rejects, reintroducing a reporting/enforcement divergence. The non-spender-aware evaluation -> is a safe optimization *only* for policies that do not restrict operator identity beyond ownership. - ---- - -## 4. Backwards compatibility - -- **No interface-identifier change.** The mandatory id `0xab84a5c8` and the extension id - `0x78a8de7d` are unaffected; method signatures are unchanged. -- **Strictly more permissive.** Any implementation that satisfied the old equality MUST still - conforms (its policy simply does not restrict operator identity, so the two predictors coincide - and the optimization applies trivially). No previously-conformant implementation becomes - non-conformant. -- **Newly-conformant implementations.** Implementations that keep `transferFrom` on the - spender-aware path for `spender == from` — CMTAT and any operator-restricting policy — become - conformant without a code change. - ---- - -## 5. Impact on the CMTAT analyses - -Adopting this proposition reclassifies the prior findings: - -- `erc-1404-analysis-rework.md` §4: from an **implementation MUST violation** to - **conformant as written**. The recommended `spender == from` short-circuit is **withdrawn** — it - is the report-OK-but-revert hazard described in §8 (T2) and §3.4 above. -- `ruleengine-erc1404-rework.md` §4.2: `RuleSpenderAuthorized` rejecting a self-initiated - `transferFrom` is **intended behaviour** under an operator-restricting policy, not a defect. -- The corresponding rows of both summary tables move from ❌ to ✅. - -These reclassifications should be applied to the analysis documents once this proposition is -accepted, with a short note preserving the reasoning trail. diff --git a/doc/ERCSpecification/rework/erc-1404.md b/doc/ERCSpecification/rework/erc-1404.md index 77692574..fd309e50 100644 --- a/doc/ERCSpecification/rework/erc-1404.md +++ b/doc/ERCSpecification/rework/erc-1404.md @@ -33,11 +33,11 @@ Additionally, this standard provides a pattern by which human-readable messages ## 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 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. [ERC-1404](./eip-1404.md) defines a transfer-restriction interface consisting of the two methods below. It is designed to be applied to a fungible token whose transfer moves a single `uint256` amount from one address to another — canonically [ERC-20](./eip-20.md), and equally applicable to compatible token interfaces such as [ERC-777](./eip-777.md). -A token claiming [ERC-1404](./eip-1404.md) compliance MUST implement its underlying token interface (for example, [ERC-20](./eip-20.md)) with all functions, events, and semantics unchanged, and MUST additionally implement the following methods. +A token claiming [ERC-1404](./eip-1404.md) compliance MUST implement the two methods below. It SHOULD preserve the function signatures and events of its underlying token interface (for example, [ERC-20](./eip-20.md)) and SHOULD NOT remove or alter them, so that integrators can continue to treat it as that interface; the restriction logic affects only whether a transfer succeeds, not the interface itself. ### Methods @@ -47,9 +47,16 @@ A token claiming [ERC-1404](./eip-1404.md) compliance MUST implement its underly Enforcement MUST be consistent with `detectTransferRestriction` for the same state and inputs: a transfer MUST be rejected whenever `detectTransferRestriction` would return a non-zero code for that transfer, and MUST NOT be rejected for restriction reasons when it would return `0`. - Implementations MAY satisfy this requirement by invoking `detectTransferRestriction` directly inside the token's transfer entry points (for [ERC-20](./eip-20.md), `transfer` and `transferFrom`; for other token interfaces, the analogous transfer methods, such as [ERC-777](./eip-777.md) `send`) and rejecting on a non-zero code. This is RECOMMENDED, because it guarantees the consistency above by construction. Implementations MAY instead re-evaluate the equivalent conditions in the transfer path — including reverting with typed errors (for example, [ERC-7943](./eip-7943.md)) rather than a restriction code — provided the observable outcome remains consistent with `detectTransferRestriction`. + This requirement binds the contract that advertises `detectTransferRestriction` to callers and performs the transfer, whether it evaluates the policy itself or obtains the decision from one or more separate compliance contracts. Where the decision is obtained externally, that contract's `detectTransferRestriction` MUST report the aggregate outcome of every restriction source its transfer path consults, rather than the outcome of any single source; where its transfer path also rejects for restriction reasons of its own (for example a global transfer pause held by the token), those conditions MUST be reflected in its `detectTransferRestriction` as well. A contract that implements the restriction interface without performing transfers is addressed separately under [Additional Specifications](#additional-specifications). - When a transfer is rejected, reverting is RECOMMENDED; implementations MAY return `false` instead, consistently with the underlying token's transfer expectations. + The requirement is stated over the operation an integrator can describe with the arguments available: `from`, `to`, `value`, and — for the optional extension — `spender`. That tuple does not identify an *entry point*. Where an implementation exposes several entry points that the tuple cannot distinguish, and their restriction conditions differ for the same state, no single return value satisfies the requirement for all of them: a non-zero code asserts that every such entry point rejects the operation, and `0` asserts that none of them rejects it for restriction reasons. Such an implementation SHOULD document which entry points its predictor describes, and integrators MUST NOT rely on a predictor for an entry point outside the set it describes. Widening the tuple is not a general remedy: an operator argument does not identify an entry point either, because one account may be authorized for several. + + - Implementations MAY satisfy this requirement by invoking `detectTransferRestriction` directly inside the token's transfer entry points (for [ERC-20](./eip-20.md), `transfer` and `transferFrom`; for other token interfaces, the analogous transfer methods, such as [ERC-777](./eip-777.md) `send`) and rejecting on a non-zero code. This is RECOMMENDED, because it guarantees the consistency above by construction. + - Implementations MAY instead re-evaluate the equivalent conditions in the transfer path — including reverting with typed errors (for example, [ERC-7943](./eip-7943.md)) rather than a restriction code — provided the observable outcome remains consistent with `detectTransferRestriction`. + - When a transfer is rejected, reverting is RECOMMENDED; implementations MAY return `false` instead, consistently with the underlying token's transfer expectations. + - A rejection that does not arise from the restriction policy — for example an insufficient balance, an insufficient allowance, or a recipient the underlying token interface itself forbids — is not a rejection "for restriction reasons" and does not require a non-zero code. + + `detectTransferRestriction` SHOULD NOT revert. An implementation that cannot evaluate its policy for the given inputs SHOULD return a non-zero restriction code denoting that condition, so that a caller can distinguish a restriction from an evaluation failure without interpreting a revert. Integrators SHOULD treat a reverting predictor as restricted. ```solidity function detectTransferRestriction(address from, address to, uint256 value) external view returns (uint8); @@ -59,13 +66,25 @@ A token claiming [ERC-1404](./eip-1404.md) compliance MUST implement its underly Returns the human-readable message corresponding to `restrictionCode`. + For the reserved code `0`, this SHOULD return a message denoting the absence of a restriction (for example, `"No restriction"`) and SHOULD NOT report `0` as an unknown or invalid code. + + For a code the implementation does not recognize, this SHOULD return a deterministic, non-empty human-readable string indicating that the code is unrecognized, and SHOULD NOT revert, so that a caller enumerating codes to build a display table does not have to interpret a revert. That string SHOULD NOT denote the absence of a restriction: an unrecognized non-zero code still denotes a restriction, one whose meaning the implementation cannot resolve, and presenting it as unrestricted would misreport a blocked transfer as permitted. + + An implementation SHOULD define a message for every code its restriction methods can return. Where a code originates from a separate compliance contract, the implementation that surfaces the code to callers is the one responsible for resolving it to a message; this specification does not prescribe the mechanism by which it does so. + + That responsibility extends to the content of the message, not only to fetching it. An implementation that obtains a message by forwarding the lookup to a restriction source adopts whatever that source returns, so the properties above become conditional on a contract it does not control: a source returning an empty string, or one denoting the absence of a restriction, would make the forwarding implementation report a blocked transfer as permitted. An implementation that forwards SHOULD ensure the string it ultimately returns satisfies the properties above regardless of what the source returns. + ```solidity function messageForTransferRestriction(uint8 restrictionCode) external view returns (string memory); ``` ### Extension: spender-aware restriction detection (OPTIONAL) -`detectTransferRestriction(address,address,uint256)` describes a transfer solely in terms of `from`, `to`, and `value`. It has no `spender` parameter and therefore cannot express a restriction that depends on the party *initiating* a delegated transfer. For [ERC-20](./eip-20.md), `transferFrom` is executed by a `spender` that may differ from `from`; a policy that restricts the spender itself — for example a frozen operator, or an operator that has not passed its own AML/KYC check — is invisible to `detectTransferRestriction`. An integrator that predicts a `transferFrom` outcome by calling only `detectTransferRestriction` will therefore mispredict exactly these cases. +`detectTransferRestriction(address,address,uint256)` describes a transfer solely in terms of `from`, `to`, and `value`. It has no `spender` parameter and therefore cannot express a restriction that depends on the party *initiating* a delegated transfer. + +For [ERC-20](./eip-20.md), `transferFrom` is executed by a `spender` that may differ from `from`; a policy that restricts the spender itself — for example a frozen operator, or an operator that has not passed its own AML/KYC check — is invisible to `detectTransferRestriction`. + +An integrator that predicts a `transferFrom` outcome by calling only `detectTransferRestriction` will therefore mispredict exactly these cases. An implementation MAY expose a spender-aware companion method: @@ -73,56 +92,147 @@ An implementation MAY expose a spender-aware companion method: function detectTransferRestrictionFrom(address spender, address from, address to, uint256 value) external view returns (uint8); ``` -`detectTransferRestrictionFrom` returns a restriction code for the delegated transfer of `value` tokens from `from` to `to` initiated by `spender`, or `0` if the transfer is unrestricted. It shares the restriction code space of `detectTransferRestriction`, and its codes are looked up through the same `messageForTransferRestriction`. +`detectTransferRestrictionFrom` returns a restriction code for the delegated transfer of `value` tokens from `from` to `to` initiated by `spender`, or `0` if the transfer is unrestricted. + +It shares the restriction code space of `detectTransferRestriction`, and its codes are looked up through the same `messageForTransferRestriction`. An implementation that exposes `detectTransferRestrictionFrom`: - MUST keep it consistent with delegated-transfer enforcement, in the same sense the base method is consistent with the transfer path: a `transferFrom(from, to, value)` executed by `spender` MUST be rejected whenever `detectTransferRestrictionFrom(spender, from, to, value)` would return a non-zero code, and MUST NOT be rejected for restriction reasons when it would return `0`. -- SHOULD evaluate the `spender == from` case through the spender-aware path, because `transferFrom` is a distinct delegated-transfer entry point whose authorization may depend on the initiating operator even when that operator equals `from`. An implementation MAY instead evaluate `spender == from` through the non-spender-aware path — equivalently, skip the spender-specific checks — as an optimization, but only when doing so is observably equivalent, i.e. its policy imposes no restriction on the initiating operator's identity beyond the `from`/`to`/`value` conditions. An implementation whose policy *does* restrict the operator identity (for example, an allow-listed or frozen operator set) MUST NOT skip, since skipping could return `0` (or an owner-only code) for a self-initiated `transferFrom` that enforcement rejects, violating the enforcement-consistency requirement above. When the policy does not distinguish operator identity from ownership, `detectTransferRestrictionFrom(from, from, to, value)` and `detectTransferRestriction(from, to, value)` return the same code, and skipping is always safe. +- SHOULD evaluate the `spender == from` case through the spender-aware path, because `transferFrom` is a distinct delegated-transfer entry point whose authorization may depend on the initiating operator even when that operator equals `from`. + - An implementation MAY instead evaluate `spender == from` through the non-spender-aware path — equivalently, skip the spender-specific checks — as an optimization, but only when doing so is observably equivalent, i.e. its policy imposes no restriction on the initiating operator's identity beyond the `from`/`to`/`value` conditions. + - An implementation whose policy *does* restrict the operator identity (for example, an allow-listed or frozen operator set) MUST NOT skip. When the policy does not distinguish operator identity from ownership, `detectTransferRestrictionFrom(from, from, to, value)` and `detectTransferRestriction(from, to, value)` return the same code, and skipping is always safe. The divergence that skipping introduces for operator-restricting policies is described in [Security Considerations](#security-considerations). + - MUST NOT change the meaning of, or the enforcement consistency required of, `detectTransferRestriction`. The base method continues to describe the `from`/`to`/`value` conditions; the extension adds only the `spender` dimension, so a caller that does not care about the spender can keep using the base method unchanged. -The extension is OPTIONAL and does not change the mandatory [ERC-1404](./eip-1404.md) interface identifier `0xab84a5c8`, which is the exclusive-or of the selectors of the two mandatory methods alone. The extension is advertised under a *second, separate* identifier, `0x78a8de7d`, which is the exclusive-or of the selectors of **all three** methods — `detectTransferRestriction`, `messageForTransferRestriction`, and `detectTransferRestrictionFrom`. +The extension is OPTIONAL and does not change the mandatory [ERC-1404](./eip-1404.md) interface identifier `0xab84a5c8`, which is the exclusive-or of the selectors of the two mandatory methods alone. + +The extension is advertised under a *second, separate* identifier, `0x78a8de7d`, which is the exclusive-or of the selectors of **all three** methods — `detectTransferRestriction`, `messageForTransferRestriction`, and `detectTransferRestrictionFrom`. An implementation that exposes `detectTransferRestrictionFrom` and supports [ERC-165](./eip-165.md): - MUST return `true` for `0xab84a5c8`, exactly as a non-extended implementation does — the mandatory interface is still fully present, so a base-only integrator continues to detect it. - MUST return `true` for `0x78a8de7d`, so that an integrator can detect the spender-aware predictor by a single `supportsInterface` call rather than probing for it and interpreting a revert. -The extension identifier deliberately covers all three selectors rather than `detectTransferRestrictionFrom` alone. An identifier over the single added method would let a contract advertise the spender-aware predictor without asserting the mandatory pair it depends on; folding the two base selectors into the extension identifier keeps it self-contained, so `supportsInterface(0x78a8de7d) == true` is sufficient evidence that all three methods are present. Note that computing this identifier requires the exclusive-or of the three selectors explicitly: a language-level construct that derives an interface identifier only from a type's *directly declared* methods (for example Solidity's `type(IExtension).interfaceId` on an interface that inherits the base) would cover only `detectTransferRestrictionFrom` and MUST NOT be used for this purpose. +The extension identifier deliberately covers all three selectors rather than `detectTransferRestrictionFrom` alone. + +- An identifier over the single added method would let a contract advertise the spender-aware predictor without asserting the mandatory pair it depends on; folding the two base selectors into the extension identifier keeps it self-contained, so `supportsInterface(0x78a8de7d) == true` is sufficient evidence that all three methods are present. +- Because it spans all three selectors, this identifier is their explicit exclusive-or, not that of the single added method alone; the [Reference Implementation](#reference-implementation) shows how it is computed and pins the value under test. ### Additional Specifications -- Implementations MAY add [ERC-165](./eip-165.md) interface detection support for [ERC-1404](./eip-1404.md). +These requirements apply alongside the two method definitions above. + +#### Conformance classes + +- A **compliance contract** — one that holds transfer rules and is consulted by a token, rather than holding balances and moving them itself — MAY implement the [ERC-1404](./eip-1404.md) restriction interface without implementing any token interface at all. Deployments call this contract a rule engine, a compliance module, or, in [ERC-3643](./eip-3643.md), the *Compliance* contract bound to a token; the name does not affect what this specification requires of it. Such a contract conforms here as a **restriction source**: `detectTransferRestriction` and `messageForTransferRestriction` MUST behave as specified above, but the enforcement-consistency requirement does not apply to it, because it performs no transfers and therefore has no enforcement path of its own. + +- A contract that performs transfers and advertises [ERC-1404](./eip-1404.md) is a **restricted token** and remains fully bound by the enforcement-consistency requirement, including where it obtains its restriction decisions from one or more compliance contracts acting as restriction sources. Consulting a restriction source does not transfer that obligation to the source: the restricted token is the contract an integrator queries, so it is the contract whose reported code MUST match what its transfer path does. -- 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. Where such checks are applied and the implementation exposes the optional spender-aware extension, the `spender` parameter of [`detectTransferRestrictionFrom`](#extension-spender-aware-restriction-detection-optional) MAY be used to pass the operator initiating the mint or burn, so that the policy can restrict that operator directly. +#### Interface detection + +- Implementations MAY add [ERC-165](./eip-165.md) interface detection support for [ERC-1404](./eip-1404.md). - The [ERC-165](./eip-165.md) interface identifier for [ERC-1404](./eip-1404.md) is `0xab84a5c8` (the two mandatory methods). The identifier for the optional spender-aware extension is `0x78a8de7d` (all three methods, including `detectTransferRestrictionFrom`); an implementation exposing the extension advertises both, as described under [Extension: spender-aware restriction detection](#extension-spender-aware-restriction-detection-optional). -- Compliance-related contracts (for example, a rule engine or compliance module) MAY implement the [ERC-1404](./eip-1404.md) restriction interface without implementing any token interface at all. In such cases, this standard only defines the behavior of `detectTransferRestriction` and `messageForTransferRestriction`, and the contract is expected to be consulted by a token or other caller that performs the actual transfer. +#### Supply-changing operations + +- 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. Where they are applied, the following hold. + + - **Encoding.** An implementation that evaluates a supply-changing operation through the restriction methods of this specification MUST encode a mint as `from == address(0)` and a burn as `to == address(0)`, matching the [ERC-20](./eip-20.md) `Transfer` event convention for issuance and redemption. This makes the operation expressible in the three-parameter signature and lets an off-chain caller construct the same query the token evaluates. An implementation MAY instead expose separate predictors for supply-changing operations, in which case this encoding does not apply to it. + + The encoded party is absent, not present-and-equal-to-`address(0)`. A condition that applies to a sender MUST NOT be applied to the `address(0)` of a mint as though it were a holder, and a condition that applies to a recipient MUST NOT be applied to the `address(0)` of a burn, since neither describes a party to the operation. + + - **Operator.** Where the implementation also exposes the optional spender-aware extension, the `spender` parameter of [`detectTransferRestrictionFrom`](#extension-spender-aware-restriction-detection-optional) MAY carry the operator initiating the mint or burn, so that the policy can restrict that operator directly. + - **Consistency.** The enforcement-consistency requirement of [`detectTransferRestriction`](#methods) applies to these operations as it does to transfers: the operation MUST be rejected whenever the predictor the implementation designates for it would return a non-zero code for the same state and inputs, and MUST NOT be rejected for restriction reasons when that predictor would return `0`. + - **Predictor selection.** Designation is per *entry point*, not per operation kind. An implementation that exposes both predictors MUST document which one governs each supply-changing entry point it opts in for, and enforcement MUST agree with the documented one. The two predictors need not agree with each other: a mint entry point that carries no operator parameter is governed by `detectTransferRestriction(address(0), to, value)`, and predicting it with `detectTransferRestrictionFrom` may report a restriction that the entry point never enforces. + +- An implementation MAY designate **no** predictor for supply-changing operations, and one that has not designated a predictor for a given operation is not opted in for it. In that case the `address(0)`-encoded queries carry no conformance requirement for that implementation, whatever those queries happen to return, and integrators MUST NOT infer a mint or burn outcome from either predictor. An implementation in this position SHOULD document that the encodings are unsupported and SHOULD document the mechanism it offers for predicting those operations instead, if any. Opting in is affirmative: silence means unsupported, not supported. + +- Designating no predictor is the appropriate choice where an implementation exposes more than one entry point for the same operation and their restriction conditions differ — an issuer burn, a delegated burn, and a bridge burn are three different authorizations of "burn", and may be gated differently. Neither the encoding nor the operator argument distinguishes them, so such an implementation SHOULD leave the operation undesignated rather than designate a predictor that is correct only for a subset of its entry points. + +#### Restriction codes and messages - Restriction checks SHOULD be deterministic for the same state and inputs, so that the reporting and enforcement results remain consistent. Guidance on the data a restriction policy relies on is given in [Security Considerations](#security-considerations) and is non-normative. +- This specification reserves only code `0`, which denotes the absence of a restriction. It assigns no meaning to codes `1` through `255`; their interpretation is defined by the issuer's policy and is resolved through `messageForTransferRestriction`. + +- In particular, no code is reserved for the condition "the restriction cannot be determined for this query" — the condition an implementation reports when its policy cannot be evaluated, or when the query describes an operation it does not predict. Reserving a value would retroactively reassign a code that deployed implementations are already free to use for a policy restriction. An implementation that needs to report this condition SHOULD allocate a code for it from its own space, document it, and return a message for that code distinguishing it from both an unrecognized code and a policy restriction. Integrators that recognize such a code SHOULD fail closed and treat the operation as restricted, since the implementation has stated it cannot answer rather than that the operation is permitted. + +- Implementations SHOULD define and manage restriction code allocation carefully, because `uint8` limits the available code space to 256 values (`0` to `255`). The code space cannot be partitioned across independently authored policies, so where a restricted token aggregates several restriction sources, resolving collisions between the codes they return — and mapping each surfaced code back to a message — is the aggregating implementation's responsibility. + - 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`). +#### Obligations on a caller reading a restriction code + +These are stated so that the guarantees the preceding requirements provide are not over-read; the hazards behind each are described in [Security Considerations](#security-considerations). + +- A result obtained before the operation executes is a prediction, not a decision. Integrators MUST treat the on-chain outcome at execution time as authoritative, and MUST NOT treat an earlier reading as binding on it. + +- Integrators MUST NOT treat a `0` from `detectTransferRestriction` as a prediction that a `transferFrom` will succeed, because the base method cannot observe the `spender`. + +- Integrators MUST NOT treat a `0` from a restriction source as a prediction about any particular token's transfer path, and MUST NOT assume that a contract advertising [ERC-1404](./eip-1404.md) is itself a transferable token. + +- Restriction codes are not stable identifiers across time. Integrators MUST NOT cache a mapping from code to meaning, and MUST resolve a code through `messageForTransferRestriction` against the state in which it was obtained. ## Rationale +### The two mandatory methods + The standard proposes two functions on top of an underlying token interface (canonically [ERC-20](./eip-20.md)). The rationale for each is described below. -1. `detectTransferRestriction` - This function encodes the restriction logic of an issuer's 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 to standardize the _result_ that transfer enforcement must agree with, rather than mandating a specific call site: an implementation may invoke it directly inside the transfer path or re-evaluate the equivalent conditions, as long as the outcome is consistent (see Specification). 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. -4. Token-agnostic interface - Although [ERC-1404](./eip-1404.md) was originally designed as an [ERC-20](./eip-20.md) extension, its two methods only assume a transfer that moves a single `uint256` amount between two addresses. The interface is therefore reused unchanged with other compatible token interfaces such as [ERC-777](./eip-777.md), and can be implemented by a standalone compliance contract that is itself not a token. The standard deliberately does not require [ERC-20](./eip-20.md), so that it can describe the restriction behavior independently of the token it is attached to. -5. Optional spender-aware detection - The mandatory `detectTransferRestriction` is kept at three parameters (`from`, `to`, `value`) so that it stays token-agnostic and matches the original [ERC-1404](./eip-1404.md) signature that integrators already call. The `spender` dimension needed to predict a delegated transfer (`transferFrom`) is therefore split into an OPTIONAL extension rather than added to the base method, which would have broken its selector and its [ERC-165](./eip-165.md) identifier and imposed a parameter on the many policies that do not restrict the spender. Splitting it also lets an integrator detect, via a distinct [ERC-165](./eip-165.md) identifier, whether a given token can predict `transferFrom` outcomes at all — a token without the extension simply cannot, and the integrator learns this rather than silently mispredicting. The extension does not require `detectTransferRestrictionFrom(from, from, …)` to equal `detectTransferRestriction(from, …)`. A `transferFrom` initiated by the holder is still a delegated transfer — it flows through the allowance path and is a different entry point than a direct `transfer` — so a policy that restricts the initiating operator (even when the operator is the holder) is legitimate, and the spender-aware predictor must be free to describe it. The only invariant that matters for integrators is that `detectTransferRestrictionFrom` agree with `transferFrom` enforcement; requiring it to instead mirror the direct-transfer predictor would force it to misreport, and for operator-restricting policies would conflict with that agreement. Implementations whose policy does not distinguish operator identity from ownership will observe the two predictors coincide for `spender == from` and MAY skip the spender-aware evaluation as an optimization. +- `detectTransferRestriction` - This function encodes the restriction logic of an issuer's 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 to standardize the _result_ that transfer enforcement must agree with, rather than mandating a specific call site: an implementation may invoke it directly inside the transfer path or re-evaluate the equivalent conditions, as long as the outcome is consistent (see Specification). + - 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. + +- `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. + +### A token-agnostic interface + +Although [ERC-1404](./eip-1404.md) was originally designed as an [ERC-20](./eip-20.md) extension, its two methods only assume a transfer that moves a single `uint256` amount between two addresses. The interface is therefore reused unchanged with other compatible token interfaces such as [ERC-777](./eip-777.md), and can be implemented by a standalone compliance contract that is itself not a token. The standard deliberately does not require [ERC-20](./eip-20.md), so that it can describe the restriction behavior independently of the token it is attached to. + +Interface discovery is kept optional for the same reason the original text left it out: implementations may expose [ERC-165](./eip-165.md) support, and those that predate the identifier remain conformant without it. + +### The spender-aware extension + +The mandatory `detectTransferRestriction` is kept at three parameters (`from`, `to`, `value`) so that it stays token-agnostic and matches the original [ERC-1404](./eip-1404.md) signature that integrators already call. + +- The `spender` dimension needed to predict a delegated transfer (`transferFrom`) is therefore split into an optional extension rather than added to the base method, which would have broken its selector and its [ERC-165](./eip-165.md) identifier and imposed a parameter on the many policies that do not restrict the spender. Splitting it also lets an integrator detect, via a distinct [ERC-165](./eip-165.md) identifier, whether a given token can predict `transferFrom` outcomes at all — a token without the extension simply cannot, and the integrator learns this rather than silently mispredicting. The extension does not require `detectTransferRestrictionFrom(from, from, …)` to equal `detectTransferRestriction(from, …)`. + +- A `transferFrom` initiated by the holder is still a delegated transfer — it flows through the allowance path and is a different entry point than a direct `transfer` — so a policy that restricts the initiating operator (even when the operator is the holder) is legitimate, and the spender-aware predictor must be free to describe it. For an integrator, the invariant that has to hold is that `detectTransferRestrictionFrom` agrees with `transferFrom` enforcement; requiring it to instead mirror the direct-transfer predictor would force it to misreport, and for operator-restricting policies would conflict with that agreement. + +- Implementations whose policy does not distinguish operator identity from ownership will observe the two predictors coincide for `spender == from` and may skip the spender-aware evaluation as an optimization. + +### Restriction sources and aggregation + +The deployed shape of a permissioned token is frequently a token delegating to a separate, independently upgradeable compliance contract, which may itself compose several policies — a rule engine in many deployments, and the modular *Compliance* contract in [ERC-3643](./eip-3643.md). Defining a restriction source as a distinct conformance class keeps that architecture explicitly in scope without weakening the guarantee integrators rely on: the enforcement-consistency requirement stays attached to the contract that actually performs the transfer, because that is the contract an integrator queries and the only one whose report can be checked against an outcome. Requiring the restricted token to report the *aggregate* outcome, rather than the outcome of any single source, keeps the guarantee meaningful once a transfer path consults more than one source — a token that forwards one engine's `0` while its own pause flag blocks the transfer would otherwise be conformant while misreporting. + +- Two possibilities were considered and left out. A reserved code for "cannot be determined" would reassign a value deployed tokens are already free to use, since codes `1`–`255` have been issuer-defined since the original [ERC-1404](./eip-1404.md); the condition is handled instead through a documentation duty and guidance to callers. An entry-point-aware predictor — a fourth method taking, say, a selector — would resolve the many-entry-points case, but at the cost of a third interface identifier and an obligation on each token to publish the selectors it can answer for; a selector also fails to discriminate between entry points that share internal logic. Naming the limitation and requiring implementations to scope their predictors avoids both costs and still tells an integrator what an answer covers. + +- The corollary is that code allocation cannot be solved at the level of this specification. A `uint8` space is not partitionable across policies authored independently of one another, and any allocation convention this specification imposed would be unenforceable and would age badly. The requirement is therefore placed where it can be met and tested: the aggregating implementation resolves collisions within its own deployment and answers for every code it surfaces. + +### Mint and burn + +Restriction checks on supply-changing operations remain optional, because the original [ERC-1404](./eip-1404.md) did not define them and requiring them would strand conformant implementations. But an implementation that opts in and evaluates them through this interface needs a way to express "there is no sender" in a signature that has no room for one, and integrators need to construct the same query the token evaluates. The `address(0)` encoding is not new: [ERC-20](./eip-20.md) already establishes `address(0)` as the mint and burn counterparty in its `Transfer` event, so writing it down here records existing practice. Extending the enforcement-consistency requirement to these operations leaves implementations that do not opt in unaffected, and closes the case where an implementation reports a mint restriction that it does not enforce. ## Backwards Compatibility By design [ERC-1404](./eip-1404.md) only adds new methods and leaves the underlying token interface untouched, so it is interface-compatible with [ERC-20](./eip-20.md) (and other compatible token interfaces such as [ERC-777](./eip-777.md)). Transfer restrictions may, however, introduce behavioral differences, because otherwise-valid transfers can be rejected. +This revision is also compatible with the original [ERC-1404](./eip-1404.md) text: an implementation conformant with that text remains conformant here, and no deployed implementation is invalidated. + +- The two mandatory method signatures are unchanged, so no deployed [ERC-165](./eip-165.md) identifier, ABI, or integration breaks. +- The original required `detectTransferRestriction` to be evaluated inside `transfer` and `transferFrom` and the transaction to be reverted on a non-zero code. An implementation that does so satisfies the enforcement-consistency requirement by construction, and is the aggregate of its own single restriction source, so the requirement on delegating implementations is vacuous for it. +- Every other requirement this revision adds is either a recommendation rather than an absolute requirement — the treatment of unrecognized codes, message coverage, and not reverting from `detectTransferRestriction` — or conditional on a feature the original did not define: [ERC-165](./eip-165.md) signaling, restriction checks on supply-changing operations, and the spender-aware extension. An implementation that uses none of them is unaffected by all of them. +- The original left the meaning of codes other than `0` to the issuer, and this revision states that explicitly rather than narrowing it. No further code is reserved, so no deployed implementation's code allocation is disturbed. +- Opting in to restriction checks on supply-changing operations is affirmative, and an implementation that has not opted in is not required to do anything about the `address(0)`-encoded queries — including implementations that predate the encoding being specified at all. Where this revision constrains that case, it constrains the integrator, who is required not to infer a mint or burn outcome from a predictor that was never designated for one. + +The one substantive obligation this revision adds for existing deployments is directed at implementations the original did not describe: a token that obtains its restriction decisions from a separate compliance contract and reports that contract's code verbatim, while its own transfer path can reject for further reasons, now misreports and must aggregate instead. Such an implementation was outside the original's scope rather than permitted by it. + ## 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. +The following table-driven cases are recommended 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` @@ -132,6 +242,9 @@ The following table-driven cases SHOULD be verified for every implementation. Th | `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 | +| `value` is `0`, and `from` and `to` satisfy the policy | Whatever the implementation's documented policy prescribes; the enforcement path has to agree with it, so a zero-value transfer is rejected if and only if a non-zero code is returned | +| `from == to`, and both satisfy the policy | As above: the returned code and the enforcement outcome have to agree | +| The implementation cannot evaluate its policy for the given inputs | A non-zero code denoting that condition, rather than a revert | ### `detectTransferRestrictionFrom` (optional extension) @@ -141,9 +254,10 @@ For implementations that expose the spender-aware extension: |---|---| | `spender`, `from`, and `to` all satisfy the policy | `0` | | `spender == from`, policy does **not** restrict operator identity | Equal to `detectTransferRestriction(from, to, value)` | -| `spender == from`, policy **does** restrict the initiating operator | Reflects the delegated-transfer policy for that operator, and is consistent with `transferFrom` enforcement; MAY differ from `detectTransferRestriction(from, to, value)` | -| A spender-specific restriction applies (e.g., `spender` is frozen); `from` and `to` satisfy the policy | Non-zero code. Note `detectTransferRestriction(from, to, value)` MAY still return `0` for the same `from`/`to`/`value`, because it cannot observe the spender — this divergence is expected, not a defect | -| `from` or `to` violates the policy | The same non-zero code `detectTransferRestriction` returns for that condition | +| `spender == from`, policy **does** restrict the initiating operator | Reflects the delegated-transfer policy for that operator, and is consistent with `transferFrom` enforcement; may differ from `detectTransferRestriction(from, to, value)` | +| A spender-specific restriction applies (e.g., `spender` is frozen); `from` and `to` satisfy the policy | Non-zero code. Note `detectTransferRestriction(from, to, value)` may still return `0` for the same `from`/`to`/`value`, because it cannot observe the spender — this divergence is expected, not a defect | +| `from` or `to` violates the policy, and no spender-specific restriction applies | The same non-zero code `detectTransferRestriction` returns for that condition | +| Both a spender-specific restriction and a `from`/`to` violation apply | Non-zero; which of the two codes is returned depends on the implementation's evaluation order, as for the base method | ### `messageForTransferRestriction` @@ -151,6 +265,8 @@ For implementations that expose the spender-aware extension: |---|---| | `0` | A deterministic human-readable string indicating no restriction (e.g., `"No restriction"`) | | Any known restriction code | The corresponding deterministic human-readable message | +| Any code the implementation does not recognize | A deterministic, non-empty string marking the code as unrecognized; distinct from the code-`0` message, and not a revert | +| Every code the implementation's restriction methods can return | A message, in each case (no code is surfaced without one) | ### Transfer enforcement @@ -166,6 +282,27 @@ For implementations that expose the optional extension, `transferFrom` enforceme | `detectTransferRestrictionFrom(spender, from, to, value)` returns `0` | `transferFrom` succeeds | | `detectTransferRestrictionFrom(spender, from, to, value)` returns a non-zero code | `transferFrom` reverts (preferred) or returns `false` | +### Supply-changing operations (optional) + +For implementations that apply restriction checks to mint and burn through this interface: + +| Scenario | Expected behavior | +|---|---| +| `detectTransferRestriction(address(0), to, value)` returns `0` | The mint succeeds | +| `detectTransferRestriction(address(0), to, value)` returns a non-zero code | The mint is rejected | +| `detectTransferRestriction(from, address(0), value)` returns `0` | The burn succeeds | +| `detectTransferRestriction(from, address(0), value)` returns a non-zero code | The burn is rejected | +| `to` satisfies the recipient policy but is not otherwise permitted to send | The mint still succeeds — the mint query carries no sender, so a sender-side condition is not applied to `address(0)` as though it were a holder | + +Where the implementation designates the spender-aware predictor for a supply-changing entry point, substitute `detectTransferRestrictionFrom(operator, address(0), to, value)` (mint) or `detectTransferRestrictionFrom(operator, from, address(0), value)` (burn) in the rows above. + +For implementations that designate no predictor for supply-changing operations, the converse case applies: + +| Scenario | Expected behavior | +|---|---| +| The implementation designates no predictor for a supply-changing operation | The `address(0)`-encoded queries carry no conformance requirement; whatever they return is not required to agree with the operation, the fact is documented, and integrators use the mechanism the implementation documents instead | +| Several entry points for the same operation are gated differently | No predictor is designated for that operation, rather than one that is correct for a subset of the entry points | + ### ERC-165 interface detection (optional) For implementations that expose [ERC-165](./eip-165.md) support: @@ -185,7 +322,7 @@ For implementations that also expose the optional spender-aware extension: | `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). +A complete Foundry test suite covering all the cases above is available in the assets folder, split across [`test/ERC1404.t.sol`](../assets/eip-1404/test/ERC1404.t.sol), [`test/ERC1404SpenderAware.t.sol`](../assets/eip-1404/test/ERC1404SpenderAware.t.sol) and [`test/WhitelistRuleEngine.t.sol`](../assets/eip-1404/test/WhitelistRuleEngine.t.sol). ## Reference Implementation @@ -194,10 +331,17 @@ A complete reference implementation built with Foundry and OpenZeppelin Contract | 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 | +| [`src/ERC1404.sol`](../assets/eip-1404/src/ERC1404.sol) | Restricted token — whitelist-based, with [ERC-165](./eip-165.md) support and mint/burn checks | +| [`src/IERC1404SpenderAware.sol`](../assets/eip-1404/src/IERC1404SpenderAware.sol) | Interface for the optional spender-aware extension | +| [`src/ERC1404SpenderAware.sol`](../assets/eip-1404/src/ERC1404SpenderAware.sol) | Restricted token exposing `detectTransferRestrictionFrom` and both interface identifiers | +| [`src/engine/IERC1404Restriction.sol`](../assets/eip-1404/src/engine/IERC1404Restriction.sol) | The two restriction methods without `IERC20` — the restriction-source interface | +| [`src/engine/WhitelistRuleEngine.sol`](../assets/eip-1404/src/engine/WhitelistRuleEngine.sol) | Restriction source — a standalone compliance contract (rule engine) that is not a token | +| [`src/engine/RestrictedToken.sol`](../assets/eip-1404/src/engine/RestrictedToken.sol) | Restricted token delegating to a compliance contract, aggregating it with a policy of its own | | [`test/ERC1404.t.sol`](../assets/eip-1404/test/ERC1404.t.sol) | Foundry test suite covering all mandatory behaviors | +| [`test/ERC1404SpenderAware.t.sol`](../assets/eip-1404/test/ERC1404SpenderAware.t.sol) | Tests for the optional spender-aware extension | +| [`test/WhitelistRuleEngine.t.sol`](../assets/eip-1404/test/WhitelistRuleEngine.t.sol) | Tests for the restriction-source and aggregation 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. +The concrete implementation applies a whitelist policy and defines the following restriction codes. Codes `1` and `2` are specific to this implementation, as [ERC-1404](./eip-1404.md) assigns no meaning to codes other than `0`. | Code | Constant | Message | |------|----------|---------| @@ -210,35 +354,57 @@ 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. +- Mint and burn apply the same policy through `detectTransferRestriction`, using the `address(0)` encoding: a mint is queried as `detectTransferRestriction(address(0), to, value)` and a burn as `detectTransferRestriction(from, address(0), value)`. The policy branches on that encoding rather than requiring `address(0)` to be allow-listed, so issuance never depends on making the zero address an acceptable transfer counterparty. +- `messageForTransferRestriction` returns `"Unknown restriction code"` for any code it does not define, and does not revert. +- `RestrictedToken` shows the aggregation requirement: it holds a pause flag of its own and delegates the address policy to the `WhitelistRuleEngine` compliance contract, so its `detectTransferRestriction` reports the outcome of both sources rather than forwarding the engine's code unchanged, and its `messageForTransferRestriction` resolves its own code before delegating the rest to the engine. - 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 +Normative requirements live in [Specification](#specification). This section explains the hazards behind them, grouped by whether they concern agreement between reporting and enforcement, the scope of a prediction, or the policy that produces it. + +### Divergence between reporting and enforcement + - 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 between the reporting and enforcement paths. -- Because `detectTransferRestriction` is a `view` function, any result obtained off-chain before a transfer is a prediction: the relevant state may change before the transfer executes, so a transfer predicted to succeed may later be rejected (and vice-versa). Implementations and integrators MUST treat the on-chain enforcement at execution time as authoritative, not an earlier off-chain reading. +- When an implementation enforces transfers by re-evaluating the restriction conditions separately rather than calling `detectTransferRestriction` directly (for example, to revert with typed errors such as [ERC-7943](./eip-7943.md)), the reporting function and the enforcement path become two codepaths that can drift apart. If they diverge, `detectTransferRestriction` may return `0` for a transfer that reverts, or a non-zero code for a transfer that succeeds, defeating the purpose of the machine-readable code for exchanges and user interfaces. Such implementations are advised to treat the equivalence between `detectTransferRestriction` and the enforcement path as an invariant and verify it under test — for example, asserting over many inputs that a non-zero code holds if and only if the transfer is rejected. -- The following is informational guidance, not a conformance requirement. Because the policy in `detectTransferRestriction` is defined entirely by the issuer, its security depends on the data that policy reads. A policy that branches on values the transacting party can influence within the transfer transaction — for example a spot price read from an automated market maker, which a flash loan can move and restore in a single transaction — can be forced to evaluate as unrestricted at execution time, even though the check runs during the transfer. Issuers are encouraged to base restriction decisions on state they control (such as whitelist or frozen flags) rather than on inputs a counterparty can manipulate. +- Because `transferFrom` is a delegated-transfer entry point, an implementation that restricts the initiating operator is advised to evaluate `spender == from` through the spender-aware path rather than collapsing it to the direct-transfer predictor. Collapsing it (for example, an unconditional `if (spender == from) return detectTransferRestriction(from, to, value);` short-circuit) can make `detectTransferRestrictionFrom` return `0` for a self-initiated `transferFrom` that enforcement then rejects, reintroducing a reporting/enforcement divergence. The non-spender-aware evaluation is a safe optimization *only* for policies that do not restrict operator identity beyond ownership. -- When an implementation enforces transfers by re-evaluating the restriction conditions separately rather than calling `detectTransferRestriction` directly (for example, to revert with typed errors such as [ERC-7943](./eip-7943.md)), the reporting function and the enforcement path become two codepaths that can drift apart. If they diverge, `detectTransferRestriction` may return `0` for a transfer that reverts, or a non-zero code for a transfer that succeeds, defeating the purpose of the machine-readable code for exchanges and user interfaces. Such implementations SHOULD treat the equivalence between `detectTransferRestriction` and the enforcement path as an invariant and verify it under test (for example, asserting over many inputs that a non-zero code holds if and only if the transfer is rejected). +- A `detectTransferRestriction` that reverts rather than returning a code turns the reporting result into a third outcome that the enforcement-consistency requirement does not describe, and can break a caller that enumerates codes or performs a pre-flight check. This is a realistic failure mode for a token consulting an external restriction source: an unset, paused, or self-destructed source will revert rather than return a code. A caller is advised to fail closed and treat a reverting predictor as restricted, rather than as unrestricted or as an error to ignore. -- `detectTransferRestriction` is blind to the spender of a delegated transfer. A `transferFrom` can be rejected for a spender-specific reason (for example a frozen operator) that `detectTransferRestriction(from, to, value)` cannot see, so it may return `0` for a `transferFrom` that then reverts. This is not a violation of the enforcement-consistency requirement, which is defined over the `from`/`to`/`value` conditions the base method describes; it is a limitation of the three-parameter signature. Integrators MUST NOT treat a `0` from `detectTransferRestriction` as a prediction that a `transferFrom` will succeed. Where spender-aware prediction is required, use the optional `detectTransferRestrictionFrom` extension if the token exposes it; a token that does not expose it cannot predict `transferFrom` outcomes on-chain, and integrators MUST fall back to submitting the transfer and handling the revert. +### Scope and limits of a prediction -- Because `transferFrom` is a delegated-transfer entry point, an implementation that restricts the initiating operator SHOULD evaluate `spender == from` through the spender-aware path rather than collapsing it to the direct-transfer predictor. Collapsing it (for example, an unconditional `if (spender == from) return detectTransferRestriction(from, to, value);` short-circuit) can make `detectTransferRestrictionFrom` return `0` for a self-initiated `transferFrom` that enforcement then rejects, reintroducing a reporting/enforcement divergence. The non-spender-aware evaluation is a safe optimization *only* for policies that do not restrict operator identity beyond ownership. +- Because `detectTransferRestriction` is a `view` function, any result obtained off-chain before a transfer is a prediction: the relevant state may change before the transfer executes, so a transfer predicted to succeed may later be rejected (and vice-versa). The on-chain outcome at execution time is the authoritative one, not an earlier off-chain reading. -- Returning machine-readable codes improves integration, but the string returned by `messageForTransferRestriction` remains informational and is not an authorization primitive. +- `detectTransferRestriction` is blind to the spender of a delegated transfer. A `transferFrom` can be rejected for a spender-specific reason (for example a frozen operator) that `detectTransferRestriction(from, to, value)` cannot see, so it may return `0` for a `transferFrom` that then reverts. This is not a violation of the enforcement-consistency requirement, which is defined over the `from`/`to`/`value` conditions the base method describes; it is a limitation of the three-parameter signature. Where spender-aware prediction is required, use the optional `detectTransferRestrictionFrom` extension if the token exposes it; a token that does not expose it cannot predict `transferFrom` outcomes on-chain, leaving no option but to submit the transfer and handle the revert. -- 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. +- The correspondence between predictor and entry point runs in both directions, and mispredicting is possible either way. The base method under-reports for delegated transfers, as described above. Symmetrically, the spender-aware method over-reports for an entry point that carries no initiating operator distinct from `from` — for example a mint entry point invoked without an operator parameter, whose enforcement consults only `detectTransferRestriction(address(0), to, value)`. Predicting such an operation with `detectTransferRestrictionFrom` can surface an operator restriction that the entry point never applies, causing an integrator to withhold a transaction that would have succeeded. Selecting the predictor the implementation designates for the intended entry point avoids both directions. + +- The same mismatch arises in the opposite shape, and is easier to miss because the predictor answers rather than failing. Where one encoding covers several entry points whose restriction conditions differ, the predictor returns a code that is correct for whichever entry point its author had in mind and silently wrong for the others. A token that permits its issuer to mint while transfers are paused, but stops a bridge mint, cannot express both through `detectTransferRestriction(address(0), to, value)`; whichever answer it gives misdescribes the other path. The failure is invisible on-chain — the query succeeds and returns a plausible code — so it surfaces only as an integrator withholding a transaction that would have succeeded, or submitting one that reverts. Stating which entry points a predictor describes is safer than leaving the scope to be inferred from the fact that it answers. + +- Restriction codes are not stable identifiers across time. Reordering a policy set, replacing one policy with another, or upgrading a restriction source can change which code is returned for the same underlying cause, and the determinism required of restriction checks is defined for the same state and inputs — it does not constrain what happens across state changes. A code-to-meaning mapping cached across time will therefore go stale silently. -- [ERC-1404](./eip-1404.md) interface support alone is not evidence that a contract implements a full token interface such as [ERC-20](./eip-20.md) or [ERC-777](./eip-777.md); a compliance-focused contract can expose the [ERC-1404](./eip-1404.md) restriction interface and interface support while implementing no token transfer behavior at all. Callers MUST NOT assume that a contract reporting [ERC-1404](./eip-1404.md) support is itself a transferable token. +- [ERC-1404](./eip-1404.md) interface support alone is not evidence that a contract implements a full token interface such as [ERC-20](./eip-20.md) or [ERC-777](./eip-777.md); a restriction source can expose the [ERC-1404](./eip-1404.md) restriction interface and interface support while implementing no token transfer behavior at all. A `0` from a restriction source describes only that source's own policy, while the token that consults it may impose others. - 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`. +### Policy design and operational limits + +- The following is informational guidance, not a conformance requirement. Because the policy in `detectTransferRestriction` is defined entirely by the issuer, its security depends on the data that policy reads. A policy that branches on values the transacting party can influence within the transfer transaction — for example a spot price read from an automated market maker, which a flash loan can move and restore in a single transaction — can be forced to evaluate as unrestricted at execution time, even though the check runs during the transfer. Issuers are encouraged to base restriction decisions on state they control (such as whitelist or frozen flags) rather than on inputs a counterparty can manipulate. + +- An implementation that reuses one address-based policy for both transfers and supply-changing operations should be careful about how it makes the mint case pass. Satisfying a sender-side check by adding `address(0)` to an allow-list also makes `address(0)` an acceptable *recipient* under the same policy, so a transfer to `address(0)` is no longer restricted — an unintended burn path on any token that does not independently reject zero-address recipients. Branching on the `address(0)` encoding explicitly avoids this, treating a mint as an operation with no sender rather than as a transfer from a holder that happens to be allow-listed. + +- A restricted token that consults a restriction source inherits that source's evaluation cost on every transfer, and where the source composes several policies that cost is unbounded in the number of policies. An administrator adding policies without bound, or an adversary able to influence how many are evaluated, can push transfers past the block gas limit and halt the token — a denial of service on the transfer path itself, not only on the predictor. Bounding the cost of policy evaluation, and treating unbounded iteration inside the transfer path as a griefing vector, mitigates this. + +- 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. + ## Copyright Copyright and related rights waived via [CC0](../LICENSE.md). diff --git a/doc/ERCSpecification/rework/erc-1643-analysis.md b/doc/ERCSpecification/rework/erc-1643-analysis.md deleted file mode 100644 index 5806fb5e..00000000 --- a/doc/ERCSpecification/rework/erc-1643-analysis.md +++ /dev/null @@ -1,263 +0,0 @@ -# ERC-1643 (rework) — Conformance Analysis of the CMTAT Implementation and Mocks - -**Spec analysed:** [`erc-1643.md`](./erc-1643.md) (rework — adds the `ERC1643InvalidName` / -`ERC1643MissingDocument` custom errors, ERC-165 detection guidance, and precise function -requirements). - -**Files reviewed** - -| Role | File | -|------|------| -| Interface | `contracts/interfaces/tokenization/draft-IERC1643.sol` | -| In-contract module (primary) | `contracts/modules/wrapper/extensions/DocumentERC1643Module.sol` (via `1_CMTATBaseDocument.sol`) | -| ERC-165 registration | `contracts/modules/2_CMTATBaseAccessControl.sol` (`:56`) | -| Engine-delegating module (option) | `contracts/modules/wrapper/options/DocumentEngineModule.sol` | -| Engine interface | `contracts/interfaces/engine/IDocumentEngine.sol` | -| **Mocks** | `contracts/mocks/DocumentEngineMock.sol`, `contracts/mocks/engine/CMTATDocumentEngineModuleMock.sol` | - -CMTAT ships **two** document-management strategies: -- **In-contract** (`DocumentERC1643Module`): stores documents in the token's own ERC-7201 storage. Used by the main deployment variants (reached through `2_CMTATBaseAccessControl → CMTATBaseDocument`). -- **Engine-delegating** (`DocumentEngineModule`): forwards every call to an external `IDocumentEngine` contract. Exercised by `CMTATDocumentEngineModuleMock` + `DocumentEngineMock`. - ---- - -## 1. Verdict - -- **In-contract `DocumentERC1643Module` — CONFORMANT.** All function MUSTs, both events, the - two custom errors, the timestamp rule, and O(1) swap-pop enumeration are correct. ERC-165 id - `0xecfecec8` is advertised. -- **Engine-delegating `DocumentEngineModule` — CONFORMANT as a pass-through**, but its - observable ERC-1643 behaviour (events, error shapes, enumeration correctness) is entirely - inherited from whatever engine is attached. With the shipped `DocumentEngineMock` it is **not** - fully conformant (see §5). -- **`DocumentEngineMock` — NON-CONFORMANT** on two counts (a removal bug that corrupts - enumeration, and non-standard event signatures) plus three minor SHOULD misses. It is a - test-only contract, but it is the reference engine used to exercise the delegating path, so the - defects matter for what the tests actually prove. - ---- - -## 2. Interface and ERC-165 id — CONFORMANT (verified) - -`draft-IERC1643.sol` declares exactly the spec's four functions, both events, and both errors. -`getDocument` returns the **flat** `(string uri, bytes32 documentHash, uint256 lastModified)` -tuple required by the spec `:58` (the internal `struct Document` is storage-only and does not -affect the ABI). - -Recomputed selectors and id: - -| Selector | Value | -|----------|-------| -| `getDocument(bytes32)` | `0xb10d6b41` | -| `getAllDocuments()` | `0x9fa5f50b` | -| `setDocument(bytes32,string,bytes32)` | `0x010648ca` | -| `removeDocument(bytes32)` | `0xc3501848` | -| **`type(IERC1643).interfaceId`** (XOR) | **`0xecfecec8`** ✓ | - -`2_CMTATBaseAccessControl.supportsInterface` (`:56`) returns `true` for -`type(IERC1643).interfaceId` (and ERC-165 via `AccessControlUpgradeable`), satisfying the spec's -ERC-165 SHOULD `:83`. Here `type(IERC1643).interfaceId` is safe because `IERC1643` does not -inherit another interface, so it covers exactly the four selectors. - ---- - -## 3. In-contract `DocumentERC1643Module` — CONFORMANT - -| Spec requirement | Implementation | OK | -|------------------|----------------|----| -| `getDocument` returns latest values | `:28-31` reads the mapping | ✅ | -| `getDocument` returns empty for missing, MUST NOT revert | default struct → `("", 0x0, 0)` | ✅ | -| `setDocument` creates / overwrites | `:40-43` writes fields | ✅ | -| `setDocument` updates last-modified | `:43` `= block.timestamp` | ✅ | -| `setDocument` emits `DocumentUpdated` after state change | `:50` (standard signature) | ✅ | -| `setDocument` SHOULD revert on `name == 0` with `ERC1643InvalidName` | `:38` `require(name != 0, ERC1643InvalidName())` | ✅ | -| `removeDocument` removes the entry | `:53-70` swap-pop + `delete` | ✅ | -| `removeDocument` emits `DocumentRemoved` with removed metadata | `:72` reads `document` **before** delete (`:58`) | ✅ | -| `removeDocument` SHOULD use `ERC1643MissingDocument` when absent | `:56` `require(key != 0, ERC1643MissingDocument())` | ✅ | -| `getAllDocuments` includes added, excludes removed | `_documentNames` maintained on both paths | ✅ | -| Authorization on mutators | `onlyDocumentManager` → `DOCUMENT_ROLE` | ✅ (spec Security Considerations) | - -The removal (`:59-68`) correctly performs the swap-pop **and updates the moved name's index**: -`$._documentKey[movedName] = key;` (`:65`). This is the detail the mock gets wrong (§5.1). - -**No conformance gaps found in the in-contract module.** - ---- - -## 4. Engine-delegating `DocumentEngineModule` — CONFORMANT pass-through, with caveats - -- `getDocument` / `getAllDocuments` return empty values when no engine is set - (`DocumentEngineModule.sol:64-81`) — matches the "empty, do not revert" rule. ✅ -- `setDocument` / `removeDocument` forward to the engine (`:83-91`) under `onlyDocumentManager`. - They perform **no** local `name == 0` or existence checks — correctness (zero-name rejection, - `ERC1643MissingDocument`, event emission, enumeration) is entirely the engine's responsibility. - A conformant engine ⇒ conformant token; the shipped mock engine is not conformant (§5), so the - delegating token inherits those defects. -- **ERC-165 gap in the mock wiring.** `CMTATDocumentEngineModuleMock` extends `CMTATBaseCore` - (whose `supportsInterface`, `0_CMTATBaseCore.sol:173`, does **not** register `0xecfecec8`) and - does not override it. So a token using the engine variant this way exposes all four ERC-1643 - functions but returns `false` for `type(IERC1643).interfaceId` — a SHOULD miss (`:83`) and an - inconsistency with the in-contract variant, which advertises it. Recommendation: have the - engine-variant base register `type(IERC1643).interfaceId` too. - **UPDATE — fixed:** `CMTATDocumentEngineModuleMock` now overrides `supportsInterface` to return - `true` for `type(IERC1643).interfaceId` (`0xecfecec8`), with a test (`testAdvertisesERC1643Interface`). - -### 4.1 [Event/subscription compliance of the delegating token] — FIXED - -ERC-1643 is a **per-contract** interface: `setDocument` MUST emit `DocumentUpdated` (`:96`), -`removeDocument` MUST emit `DocumentRemoved` (`:106`), and implementations MUST support -*subscribing to updates* (`:35`). The event carries **no address field**, so a subscriber is -expected to watch *the contract that exposes `setDocument`* — here, the token. - -Originally the delegating token's `setDocument`/`removeDocument` only forwarded to the engine and -emitted **nothing on the token's own address**. A `DocumentUpdated` log *was* produced in the -transaction, but at the **engine's** address (the `LOG` opcode runs in the engine's frame), so a -standard ERC-1643 subscriber watching the *token* saw nothing — and the addressless event could -not be attributed back to the token if the engine is shared across tokens. Since the token -advertises `type(IERC1643).interfaceId`, it *claims* the interface while only honoring its read -half (`getDocument`/`getAllDocuments` delegate), so this was a genuine conformance gap, not merely -an architectural quirk. - -**UPDATE — fixed (dual emission).** `DocumentEngineModule.setDocument`/`removeDocument` -(`options/DocumentEngineModule.sol`) now re-emit the standard `DocumentUpdated`/`DocumentRemoved` -event on the **token's own address** after forwarding to the engine, so token-address subscribers -observe updates as the standard assumes. `removeDocument` reads `getDocument(name)` before -forwarding to include the removed metadata (`:106`). Both mutators now also revert with -`CMTAT_DocumentEngineModule_NoDocumentEngine` when no engine is set (spec `:97` "MUST revert if the -update cannot be persisted"), which also prevents a false emit. Because the token now emits its own -attributable event, a non-standard `DocumentUpdatedForContract`-style event is unnecessary. -Regression tests: `testTokenReEmitsStandardDocumentEvents`, `testCannotSetDocumentWithoutEngine`. -(The engine also emits on its own address; under the per-contract model the two log streams are -independent and both conformant.) - ---- - -## 5. `DocumentEngineMock` — findings - -> **UPDATE — fixed.** `DocumentEngineMock` has been rewritten to **reuse the production -> `DocumentERC1643Module`** (`contract DocumentEngineMock is DocumentERC1643Module` with a no-op -> `_authorizeDocumentManagement`). This eliminates §5.1 and §5.2 at once — the mock now inherits -> the correct swap-pop-with-key-update enumeration and the standard flat -> `DocumentUpdated`/`DocumentRemoved` events, and also gains the `name == 0` rejection -> (`ERC1643InvalidName`) and `ERC1643MissingDocument` error (resolving §5.3's first two points). -> Two regression tests were added in `test/standard/modules/DocumentModule/DocumentModule.test.js` -> (remove-a-moved-document, and standard-event emission). The findings below are retained for the -> record. - -`DocumentEngineMock` (originally `contracts/mocks/DocumentEngineMock.sol`) implemented -`IERC1643Whole` (`IDocumentEngine` + a struct-based `setDocument(DocumentInfo)`). As a test-only -contract it is not production code, but it is the reference engine behind the delegating path. - -### 5.1 [Bug — enumeration corruption on removal] Severity: High (for a mock) - -`removeDocument` (`:87-97`) swap-pops the names array but **never updates the moved entry's -`documentKey`**: - -```solidity -documentNames[documentKey[name] - 1] = documentNames[documentNames.length - 1]; -documentNames.pop(); -delete documents[name]; -documentKey[name] = 0; -// missing: documentKey[movedName] = documentKey[name]; -``` - -After removing a **non-last** document, the element moved into its slot keeps its *old* index in -`documentKey`. Consequences: -- a subsequent `removeDocument(movedName)` uses the stale index and writes/read at - `documentNames[oldLen-1]`, which is now **out of bounds** → panic revert, so an existing - document **cannot be removed** (violates `removeDocument` MUST, spec `:105`), and -- `getAllDocuments` continues to list a name whose key is desynchronised — breaking the - "enumeration consistency after multiple add/update/remove operations" test case (`:135`). - -Reproduction: `setDocument(A); setDocument(B); setDocument(C); removeDocument(A); removeDocument(C)` → the second removal reverts even though `C` exists. - -**Fix:** mirror the production module (`DocumentERC1643Module.sol:59-68`) — update -`documentKey[movedName]` after the swap: - -```solidity -uint256 key = documentKey[name]; -uint256 index = key - 1; -uint256 lastIndex = documentNames.length - 1; -if (index != lastIndex) { - bytes32 movedName = documentNames[lastIndex]; - documentNames[index] = movedName; - documentKey[movedName] = key; // <-- the missing line -} -documentNames.pop(); -delete documents[name]; -delete documentKey[name]; -``` - -### 5.2 [Non-standard event signatures] Severity: Medium (for a mock) - -`IERC1643Whole` **redefines** the events with a `Document` struct parameter -(`:23-24`): `event DocumentUpdated(bytes32 indexed name, Document doc)` / -`DocumentRemoved(bytes32 indexed name, Document doc)`. The mock's setters/remover emit *these* -(`:63,82,96`), whose `topic0` is `DocumentUpdated(bytes32,(string,bytes32,uint256))` — **different -from** the ERC-1643-mandated `DocumentUpdated(bytes32,string,bytes32)` (`:72`). An integrator -subscribed to the standard event signature will therefore **not** observe document changes made -through this engine, even though the spec makes emitting `DocumentUpdated`/`DocumentRemoved` a -MUST (`:96,106`). Because the delegating token forwards to the engine, the token also emits only -the non-standard event. - -**Fix:** emit the standard flat-parameter events -(`emit DocumentUpdated(name, uri, documentHash);`) and drop the struct-based overloads, so the -engine's observable event stream matches the interface it claims. - -### 5.3 [SHOULD misses] Severity: Low / informational - -- **No `name == bytes32(0)` rejection** in either `setDocument` overload — the spec SHOULD revert - with `ERC1643InvalidName` (`:98,101`). The production module enforces this; the mock does not. -- **Non-recommended removal error:** `removeDocument` reverts with a locally-declared - `DocumentDoesNotExist()` (`:36,89`) rather than the interface's `ERC1643MissingDocument()`. The - spec *permits* a different error (`:109` "MAY use different error names"), so this is allowed but - does not follow the SHOULD (`:108`) and diverges from the production module. -- **No ERC-165 `supportsInterface`** on the engine — spec SHOULD (`:81-83`). Minor for a - standalone engine, but it means a token cannot discover the engine's ERC-1643 support on-chain. - ---- - -## 6. Suggestions - -1. **Fix `DocumentEngineMock.removeDocument`** (§5.1) — the missing `documentKey` update. This is - a genuine correctness bug, not just a style issue, and it can make document-engine tests pass - for the wrong reasons or hide regressions in the delegating path. -2. **Emit standard ERC-1643 events from `DocumentEngineMock`** (§5.2) so the engine variant's - observable behaviour matches the interface. Add a test asserting the token emits - `DocumentUpdated(bytes32,string,bytes32)` (not the struct form) through the engine. -3. **Advertise `type(IERC1643).interfaceId` on the engine variant** (§4) — have the - engine-variant base (or `CMTATDocumentEngineModuleMock`) override `supportsInterface` to - include `0xecfecec8`, matching the in-contract variant and the spec SHOULD. -4. **Align the mock's zero-name and error behaviour** with the production module (§5.3): reject - `name == 0` with `ERC1643InvalidName`, and prefer `ERC1643MissingDocument` on removal, so the - mock models the standard faithfully. -5. **Add the enumeration-consistency test** from the spec Test Cases (`:135`) against **both** - the in-contract module and the engine mock: add A/B/C, remove the first, then remove the moved - element, and assert `getAllDocuments` stays consistent and no removal reverts. This test would - currently pass for the in-contract module and fail for the mock — surfacing §5.1. - ---- - -## 7. Summary tables - -### In-contract `DocumentERC1643Module` (production path) -| Requirement | Status | -|-------------|--------| -| `getDocument` flat return, empty-for-missing, no revert | ✅ | -| `setDocument` create/overwrite, timestamp, event, zero-name revert | ✅ | -| `removeDocument` remove, event w/ metadata, missing-doc error | ✅ | -| `getAllDocuments` enumeration correctness (swap-pop + key update) | ✅ | -| Custom errors `ERC1643InvalidName` / `ERC1643MissingDocument` | ✅ | -| Authorization on mutators (`DOCUMENT_ROLE`) | ✅ | -| ERC-165 `0xecfecec8` advertised | ✅ (verified) | - -### Engine variant + `DocumentEngineMock` (after the fix) -| Requirement | Status | -|-------------|--------| -| `DocumentEngineModule` pass-through, empty-when-unset, no revert | ✅ | -| Delegating token emits standard events on its **own** address (per-contract subscription) | ✅ **fixed** — dual emission (§4.1) | -| Engine `removeDocument` enumeration consistency | ✅ **fixed** — reuses `DocumentERC1643Module` (§5.1) | -| Engine emits standard `DocumentUpdated`/`DocumentRemoved` | ✅ **fixed** — flat events via module reuse (§5.2) | -| Engine zero-name rejection (SHOULD) | ✅ **fixed** — inherits `ERC1643InvalidName` | -| Engine uses `ERC1643MissingDocument` (SHOULD; MAY differ) | ✅ **fixed** — inherits `ERC1643MissingDocument` | -| Engine-variant `supportsInterface` advertises `0xecfecec8` (SHOULD) | ✅ **fixed** — `CMTATDocumentEngineModuleMock.supportsInterface` override (§4) | diff --git a/doc/ERCSpecification/rework/erc-1643.md b/doc/ERCSpecification/rework/erc-1643.md index 20cc0737..83af8c63 100644 --- a/doc/ERCSpecification/rework/erc-1643.md +++ b/doc/ERCSpecification/rework/erc-1643.md @@ -45,34 +45,49 @@ A document entry is identified by a name (`bytes32`) and stores: ```solidity /// @title IERC1643 Document Management interface IERC1643 { + /// @notice Emitted when a document is created or updated. + /// @param name Identifier of the document. + /// @param uri Document location. + /// @param documentHash Hash of the document contents. + event DocumentUpdated(bytes32 indexed name, string uri, bytes32 documentHash); + + /// @notice Emitted when a document is removed. + /// @param name Identifier of the document. + /// @param uri Document location at the time of removal. + /// @param documentHash Hash of the document contents at the time of removal. + event DocumentRemoved(bytes32 indexed name, string uri, bytes32 documentHash); + /// @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. + /// @param name Identifier of the document. + /// @param uri Document location. + /// @param documentHash Hash of the document contents. function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external; /// @notice Removes an existing document entry. /// @dev MUST emit `DocumentRemoved` on success. + /// @param name Identifier of the document to remove. function removeDocument(bytes32 name) external; + /// @notice Returns metadata for a document identified by `name`. + /// @param name Identifier of the document. + /// @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 Returns all document names currently tracked by the contract. + /// @return documentNames Names of all documents that are currently set. 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); } ``` @@ -88,6 +103,7 @@ When ERC-165 is implemented, `supportsInterface` SHOULD return `true` for `type( - 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. + - Implementations SHOULD ensure that a stored entry always has a non-zero `lastModified`, so that `lastModified == 0` identifies an absent entry. Since `uri` and `documentHash` MAY both be empty for a stored document, they cannot distinguish an absent entry from one stored with empty metadata, and `lastModified` is the only value that can. Integrators should treat this as advisory rather than guaranteed when interacting with deployments predating this guidance. - `setDocument`: - MUST create a new entry when `name` is not present. @@ -111,14 +127,14 @@ When ERC-165 is implemented, `supportsInterface` SHOULD return `true` for `type( - `getAllDocuments`: - MUST include every document name added by `setDocument` and not removed by `removeDocument`. - MUST NOT include removed document names. + - The order of the returned names is unspecified. Removing a document MAY change the position of unrelated names, so consumers MUST NOT rely on a stable ordering, and MUST NOT treat a change in position as a change to a document. ## 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. +- 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 @@ -129,6 +145,7 @@ This ERC is additive and does not alter base token transfer semantics. It can be Implementations should verify at least the following: - Adding a new document and reading it through `getDocument`. +- Reading a name that was never set, confirming `getDocument` returns empty values (`""`, `bytes32(0)`, `0`) and does not revert. - 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. @@ -136,7 +153,11 @@ Implementations should verify at least the following: ## 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 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: @@ -149,8 +170,9 @@ The module maintains: - 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. +- `getAllDocuments` returns the entire set of names in a single call, and its response grows with the number of stored documents. It is the only enumeration path defined here, so a contract holding a large document set may produce a call that exceeds the gas limit an `eth_call` provider applies, leaving no standard way to enumerate. Implementations expecting large sets should consider exposing an additional paginated accessor alongside this interface. - 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. +- The custom errors `ERC1643InvalidName()` and `ERC1643MissingDocument()` are defined in this interface but were absent from the earlier draft text of this proposal. 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](./eip-1643.md) 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 diff --git a/doc/ERCSpecification/rework/ruleengine-erc1404-rework.md b/doc/ERCSpecification/rework/ruleengine-erc1404-rework.md deleted file mode 100644 index 55fc863b..00000000 --- a/doc/ERCSpecification/rework/ruleengine-erc1404-rework.md +++ /dev/null @@ -1,250 +0,0 @@ -# RuleEngine Mock — ERC-1404 (rework) Conformance Analysis - -**Scope:** checks whether the reference `RuleEngineMock` (and its rules) correctly -implements [`doc/ERCSpecification/rework/erc-1404.md`](./erc-1404.md), the reworked draft -that adds the optional spender-aware extension. Companion to -[`erc-1404-analysis-rework.md`](./erc-1404-analysis-rework.md) (which covers the CMTAT -token side). - -**Files reviewed** - -| Role | File | -|------|------| -| Aggregating compliance contract | `contracts/mocks/RuleEngine/RuleEngineMock.sol` | -| Rule interface | `contracts/mocks/RuleEngine/interfaces/IRule.sol` (`IRule is IERC1404Extend, IERC3643ComplianceRead`) | -| Rules | `RuleMock.sol`, `RuleMockMint.sol`, `RuleSpenderAuthorized.sol`, `RuleTokenHolderTracker.sol`, `CodeList.sol` | -| Interface ids | `contracts/library/ERC1404ExtendInterfaceId.sol` (`0x78a8de7d`), `RuleEngineInterfaceId.sol` (`0x20c49ce7`) | -| Engine interface | `contracts/interfaces/engine/IRuleEngine.sol` (`IRuleEngineERC1404 is IERC1404Extend, IRuleEngine`) | - -The spec explicitly contemplates this shape (§Additional Specifications): - -> Compliance-related contracts (for example, a rule engine or compliance module) MAY -> implement the ERC-1404 restriction interface without implementing any token interface -> at all … the contract is expected to be consulted by a token or other caller that -> performs the actual transfer. - -So the `RuleEngineMock` is a legitimate "ERC-1404 compliance contract that is not a -token," and the standard's `detectTransferRestriction` / `messageForTransferRestriction` -(and, since it exposes it, `detectTransferRestrictionFrom`) semantics apply to it. - ---- - -## 1. Verdict - -The `RuleEngineMock` implements all three restriction methods and its enforcement hook -(`transferred`) is consistent-by-construction with its reporting methods (it literally -calls them). However there are **two normative (MUST) deviations** from the rework: - -1. **`supportsInterface` does not advertise the mandatory ERC-1404 id `0xab84a5c8`** — it - advertises only the extension id `0x78a8de7d`. (§4.1) -2. **The `spender == from` degenerate case of `detectTransferRestrictionFrom` does not - equal `detectTransferRestriction`**, caused by `RuleSpenderAuthorized`. (§4.2) - -Plus one low/informational issue: `messageForTransferRestriction(0)` does not return a -"no restriction" message. (§4.3) - -Because the reference token (CMTAT) also carries its own copy of both issues (see the -companion analysis), fixing them in the mock keeps the reference material self-consistent. - ---- - -## 2. Mandatory + extension methods — PRESENT - -| Method | Location | Notes | -|--------|----------|-------| -| `detectTransferRestriction(address,address,uint256)` | `RuleEngineMock.sol:62` | Iterates rules, returns first non-zero code, else `TRANSFER_OK` (0). ✓ | -| `messageForTransferRestriction(uint8)` | `RuleEngineMock.sol:150` | Iterates rules via `canReturnTransferRestrictionCode`, deterministic, `"UnknownRestrictionCode"` fallback. (see §4.3) | -| `detectTransferRestrictionFrom(address,address,address,uint256)` | `RuleEngineMock.sol:82` | Iterates rules' 4-arg form, returns first non-zero. (see §4.2) | - -Codes returned by the rules are `13` (`AMOUNT_TOO_HIGH`), `20` (`MINT_TOO_HIGH`), -`21` (`SPENDER_NOT_AUTHORIZED`) — all `≥ 13`, so they avoid the `0–6` range reserved by -`IERC1404Extend.REJECTED_CODE_BASE` and the `7–12` range the interface comment reserves -for CMTAT. Good namespacing within the 256-value `uint8` space (the spec's code-space -caution, §Security Considerations). - ---- - -## 3. Enforcement consistency — CONFORMANT (RECOMMENDED strategy) - -Unlike the token (which re-evaluates conditions), the rule engine uses the spec's -**RECOMMENDED** strategy — enforcement invokes the detector directly, so reporting and -enforcement cannot drift: - -- `transferred(spender, from, to, value)` (`:125`) → `require(canTransferFrom(...))` - (`:130`) → `canTransferFrom` (`:112`) → `detectTransferRestrictionFrom(...) == 0`. -- `transferred(from, to, value)` (`:134`) → `require(canTransfer(...))` (`:138`) → - `canTransfer` (`:104`) → `detectTransferRestriction(...) == 0`. - -The token routes standard transfers to the 3-arg `transferred` (spender `0`) and -`transferFrom` to the 4-arg `transferred` (`ValidationModuleRuleEngine.sol:142`), so the -engine's enforcement matches the correct reporting method in each case. The base -method's "reject iff non-zero code" MUST is satisfied by construction. ✓ - -Checks are `pure`/`view` over rule state only (amount thresholds, immutable authorized -spender, tracked balances) — deterministic, no counterparty-manipulable inputs. ✓ - ---- - -## 4. Findings - -### 4.1 [MUST] `supportsInterface` omits the mandatory ERC-1404 id `0xab84a5c8` — Severity: Low–Medium - -`RuleEngineMock.supportsInterface` (`:166`): - -```solidity -return interfaceId == RuleEngineInterfaceId.RULE_ENGINE_INTERFACE_ID // 0x20c49ce7 - || interfaceId == ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID // 0x78a8de7d - || super.supportsInterface(interfaceId); // ERC165 only -``` - -`super` (`ERC165`) resolves only `0x01ffc9a7`. So: - -| `supportsInterface(id)` | Result | Spec requirement | -|--------------------------|--------|------------------| -| `0x01ffc9a7` (ERC-165) | `true` | ✅ | -| `0x78a8de7d` (extension) | `true` | ✅ | -| `0xab84a5c8` (**mandatory ERC-1404**) | **`false`** | ❌ MUST be `true` | - -The rework is explicit (§Extension): an implementation that exposes -`detectTransferRestrictionFrom` **and** supports ERC-165 - -> - MUST return `true` for `0xab84a5c8`, exactly as a non-extended implementation does — -> the mandatory interface is still fully present, so a base-only integrator continues -> to detect it. -> - MUST return `true` for `0x78a8de7d` … - -The mock satisfies the second MUST but not the first. **Consequence:** an integrator that -only knows the base ERC-1404 (probes `0xab84a5c8`) fails to recognise the rule engine as -ERC-1404-capable, even though it fully implements both mandatory methods — exactly the -regression the spec's dual-id design exists to prevent. Note this also makes the mock -*inconsistent with the CMTAT token*, whose `supportsInterface` correctly returns `true` -for both ids (`4_CMTATBaseERC1404.sol:79-81`). - -**Fix:** - -```solidity -return interfaceId == type(IERC1404).interfaceId // 0xab84a5c8 - || interfaceId == ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID // 0x78a8de7d - || interfaceId == RuleEngineInterfaceId.RULE_ENGINE_INTERFACE_ID - || super.supportsInterface(interfaceId); -``` - -(`type(IERC1404).interfaceId` == `0xab84a5c8` here because the repo's `IERC1404` does not -inherit `IERC20` — same reasoning as on the token side. A literal `0xab84a5c8` is -equivalent.) - -### 4.2 [MUST] `spender == from` code equality violated by `RuleSpenderAuthorized` — Severity: Low - -Spec §Extension (second bullet) and the Test Cases row "`spender == from` → Equal to -`detectTransferRestriction(from, to, value)`" require that, for `spender == from`, the two -predictors return the **same code**. - -`RuleEngineMock.detectTransferRestrictionFrom` (`:82`) iterates each rule's 4-arg form -without special-casing `spender == from`. Most rules are safe — `RuleMock` and -`RuleMockMint` delegate their `From` variant straight to `detectTransferRestriction` -(`RuleMock.sol:44-46`, `RuleMockMint.sol:43-45`), and `RuleTokenHolderTracker` is -permissive. But `RuleSpenderAuthorized` breaks the equality: - -- `RuleSpenderAuthorized.detectTransferRestriction(...)` → always `0` (`:29-35`). -- `RuleSpenderAuthorized.detectTransferRestrictionFrom(spender,...)` → `SPENDER_NOT_AUTHORIZED` - (`21`) when `spender != 0 && spender != authorizedSpender` (`:37-47`). - -So with `spender == from == someHolder` (not the authorized spender): - -- `RuleEngineMock.detectTransferRestrictionFrom(from, from, to, v)` → **21** -- `RuleEngineMock.detectTransferRestriction(from, to, v)` → **0** - -`21 ≠ 0` → **MUST violated.** Unlike the token-side instance (§4 of the companion doc, -which was frozen-holder only), here it has a **behavioural** consequence via enforcement: -a holder calling `transferFrom` on their own tokens (`spender == from`) is *rejected* by -the engine (`transferred` → `canTransferFrom` → `21` → revert), while a plain `transfer` -succeeds. That divergence is invisible to `detectTransferRestriction`, which reports `0`. - -This is still **Low severity** against the *base* method (the base method's consistency is -defined over `from`/`to`/`value` and is explicitly allowed to be blind to the spender), but -it is a clear violation of the *extension's* degenerate-case MUST. - -Root cause: `RuleSpenderAuthorized`'s policy ("only `authorizedSpender` may ever initiate a -delegated transfer") intentionally wants to reject even the holder's own `transferFrom`, -which is fundamentally at odds with the spec's `spender == from` MUST. - -**Fix (choose one):** -- *Aggregator-level (robust, mirrors the recommended token fix):* short-circuit in - `RuleEngineMock.detectTransferRestrictionFrom` — `if (spender == from) return detectTransferRestriction(from, to, value);` - This guarantees the MUST regardless of any rule's spender logic. -- *Rule-level:* in `RuleSpenderAuthorized.detectTransferRestrictionFrom`, also allow - `spender == from` (add `|| spender == _from`). This keeps the rule individually - conformant. - -Add a test asserting `detectTransferRestrictionFrom(x, x, y, v) == detectTransferRestriction(x, y, v)` -over the full rule set. - -### 4.3 [Info] `messageForTransferRestriction(0)` does not return a "no restriction" message — Severity: Informational - -`messageForTransferRestriction` (`:150`) scans rules for one whose -`canReturnTransferRestrictionCode(code)` is `true`; none claims code `0`, so it returns the -`"UnknownRestrictionCode"` fallback (`:163`). The rework Test Cases table expects -`messageForTransferRestriction(0)` to yield "a deterministic human-readable string -indicating no restriction (e.g. `"No restriction"`)". - -On the token this is masked (CMTAT maps `TRANSFER_OK` before delegating, -`ValidationModuleERC1404.sol:56`), but the spec explicitly allows the rule engine to be -consulted *directly* as a standalone compliance contract — and queried directly, code `0` -returns `"UnknownRestrictionCode"`, which reads as an error rather than "no restriction". -It is still deterministic, so this is informational, not a MUST break. - -**Fix:** handle `TRANSFER_OK` first, e.g. -`if (_restrictionCode == 0) return "NoRestriction";` at the top of the function. - ---- - -## 5. Positives - -- All three restriction methods present; enforcement (`transferred`) invokes them - directly — the spec's **RECOMMENDED** consistency-by-construction pattern. -- Correctly uses the hand-computed `ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID` - constant rather than `type(IERC1404Extend).interfaceId`, avoiding the single-selector - trap the spec warns about (§Extension). -- Deterministic, state-only checks; restriction codes namespaced clear of the reserved - `0–12` range. -- Rules that are spender-agnostic (`RuleMock`, `RuleMockMint`) correctly delegate their - `From` variant to the base detector, satisfying `spender == from` trivially. - ---- - -## 6. Suggestions - -### Implementation (mock) -1. Add `0xab84a5c8` to `supportsInterface` (§4.1) — makes the mock match the token and the - spec's dual-id MUST. -2. Short-circuit `spender == from` in `RuleEngineMock.detectTransferRestrictionFrom` - (§4.2), and/or allow `spender == from` in `RuleSpenderAuthorized`. -3. Return a no-restriction message for code `0` in `messageForTransferRestriction` (§4.3). -4. Add tests: `supportsInterface(0xab84a5c8) == true`; the `spender == from` equivalence - over the rule set; `messageForTransferRestriction(0)` is a no-restriction string. - -### Standard -- This mock is a second, independent data point (alongside the token) that the - `spender == from` **code-equality** MUST is easy to violate whenever an implementation - has a genuine "spender frozen / spender not authorized" policy: the natural design wants - to report the spender-specific reason even when the spender happens to be the holder. The - companion analysis §6.2 recommends the spec either relax this to reject/allow equivalence - for `spender == from`, or explicitly mandate the short-circuit and show it in the - reference implementation. `RuleSpenderAuthorized` is a concrete rule whose intended - semantics directly collide with the current wording. - ---- - -## 7. Summary table - -| Requirement (rework) | RuleEngineMock | -|----------------------|----------------| -| `detectTransferRestriction` present, `0` = OK | ✅ | -| `messageForTransferRestriction` present, deterministic | ✅ (but code `0` → `"UnknownRestrictionCode"`, §4.3) | -| `detectTransferRestrictionFrom` present | ✅ | -| Enforcement consistent with reporting (reject iff non-zero) | ✅ (invokes detectors directly) | -| ERC-165 `0x01ffc9a7` | ✅ | -| ERC-165 **mandatory** `0xab84a5c8` | ❌ **MUST violation (§4.1)** | -| ERC-165 **extension** `0x78a8de7d`, via explicit XOR constant | ✅ | -| `spender == from` ⇒ same code as `detectTransferRestriction` | ❌ **MUST violation (§4.2)** | -| Deterministic / namespaced codes | ✅ | diff --git a/doc/README.md b/doc/README.md index fb5b7af3..2bc3e91b 100644 --- a/doc/README.md +++ b/doc/README.md @@ -393,6 +393,18 @@ The CMTAT supports the following optional features: - "Gasless" (MetaTx) transactions with [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771) - Module: ERC2771Module +- Signature-based approvals with [ERC-2612 Permit](https://eips.ethereum.org/EIPS/eip-2612) (approve without an on-chain `approve` transaction) + - Deployment: CMTAT Standalone Permit / CMTAT Upgradeable Permit + - Base: CMTATBaseERC2612 (OpenZeppelin `ERC20PermitUpgradeable`) + +- Batching several calls in a single transaction with [ERC-6357 Multicall](https://eips.ethereum.org/EIPS/eip-6357) + - Deployment: CMTAT Standalone Permit / CMTAT Upgradeable Permit + - Base: CMTATBaseERC2612 (OpenZeppelin `MulticallUpgradeable`) + +- Maintain on-chain the list of addresses holding a non-zero balance (issuer reporting, corporate actions) + - Deployment: CMTAT Standalone HolderList / CMTAT Upgradeable HolderList + - Module: HolderListModule + 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) @@ -419,8 +431,9 @@ Here the list of ERC supported between different version: | [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
(Extensions) | 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
(Extensions) | Draft | |
(through DocumentEngine with small improvement) |
(through DocumentEngine with small improvement) |
(native DocumentERC1643Module + optional engine) | | | | | | +| [ERC-1404](https://github.com/ethereum/eips/issues/1404)
(Simple Restricted Token Standard - original + [reworked](https://github.com/ethereum/ERCs/pull/1701))
base path `detectTransferRestriction` | ValidationModuleERC1404
(Extensions) | Draft | | | | | | | | | | +| ERC-1404 Extension
(only [reworked](https://github.com/ethereum/ERCs/pull/1701), `IERC1404Extend`)
spender path `detectTransferRestrictionFrom` | ValidationModuleERC1404
(Extensions) | Draft | | | | | | | | | | +| [ERC-1643](https://github.com/ethereum/eips/issues/1643) (Document Management Standard - Standard from [ERC-1400 ](https://github.com/ethereum/EIPs/issues/1411)- original + [reworked](https://github.com/ethereum/ERCs/pull/1754)) | DocumentModule
(Extensions) | Draft | |
(through DocumentEngine with small improvement) |
(through DocumentEngine with small improvement) |
(native DocumentERC1643Module + optional engine) | | | | | | | [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 | | | | | | [ERC-8343](https://github.com/ethereum/ERCs/pull/1900)
(Contract deactivation, formerly ICMTATDeactivate) | PauseModule | Draft
(PR #1900) | | | |
(aligned to ERC-8343 draft) | | | | | | @@ -1149,8 +1162,7 @@ Any compromise to the DEFAULT_ADMIN_ROLE account may allow a hacker to take adva ##### 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`. +- Freezing an operator via `setAddressFrozen(operator, true)` does **not** block that operator's `mint` / `batchMint` — minting validates the recipient (and deactivation), not the caller, so a frozen `MINTER_ROLE` holder can still mint. It **does** block the operator's `batchTransfer` / `transfer` / `transferFrom`, where the operator is the sender/spender. To stop a compromised minter, revoke its role. On the Standard version a configured RuleEngine still receives the operator as `spender` and may reject a mint. See [technical/access-control.md](./technical/access-control.md#what-freeze-and-pause-block-per-operation) and the [Enforcement chapter table](#freeze-acts-on-the-senderrecipient-not-on-the-operator). - `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 @@ -1452,6 +1464,45 @@ external view returns (uint8); The ERC-165 interface id for the `IERC1404Extend` interface is `0x78a8de7d` +###### Scope: transfers only, never mint or burn + +> [!IMPORTANT] +> +> `detectTransferRestriction` and `detectTransferRestrictionFrom` describe the **holder transfer +> path only** — `transfer` and `transferFrom`. They do **not** govern the mint and burn entry +> points, and the `address(0)` encoding proposed by the ERC-1404 rework draft +> (`from == address(0)` for a mint, `to == address(0)` for a burn) is **not supported** by CMTAT. +> Such a query is answered as if it were a holder transfer, so it can report a restriction the +> mint/burn path does not enforce — for example `TRANSFER_REJECTED_PAUSED` while a `MINTER_ROLE` +> mint would in fact succeed. +> +> This is structural rather than an omission. CMTAT exposes **several entry points per +> supply-changing operation, and the pause rule differs between them**: +> +> | Operation | Entry point | Blocked while paused? | +> | --- | --- | --- | +> | Mint | `mint`, `batchMint` (`MINTER_ROLE`) | ❌ no | +> | Mint | `crosschainMint` (token bridge) | ✅ yes | +> | Burn | `burn(address,uint256[,bytes])`, `batchBurn` (`BURNER_ROLE`) | ❌ no | +> | Burn | `burnFrom` (`BURNER_FROM_ROLE`) | ✅ yes | +> | Burn | `burn(uint256)` (`BURNER_SELF_ROLE`) | ✅ yes | +> | Burn | `crosschainBurn` (token bridge) | ✅ yes | +> +> `(from, to, value)` — and `(spender, from, to, value)` — carry no entry-point discriminator, and +> the operator address does not identify one either (the same account may hold several burn roles), +> so **no single return value can describe every mint or every burn**. Rather than designate a +> predictor that would be correct for one entry point and wrong for another, CMTAT designates +> **none** for supply-changing operations. Integrators MUST NOT infer a mint or burn outcome from +> either ERC-1404 predictor. +> +> To predict a mint or a burn, use CMTAT's own predicates — `canTransfer(address(0), to, value)` and +> `canTransferFrom(operator, from, address(0), value)` (ERC-3643 / ERC-7551), which branch on the +> `address(0)` encoding through the same helper the enforcement path uses +> (`ValidationModule._canTransferGenericByModule`) — together with the per-entry-point role and +> pause requirements documented in [ERC20Mint](./modules/core/ERC20Mint/ERC20Mint.md), +> [ERC20Burn](./modules/core/ERC20Burn/ERC20Burn.md) and +> [pause.md](./modules/core/Pause/pause.md#what-pause-stops-and-what-it-does-not). + ##### Interface details ###### IRuleEngine @@ -1792,10 +1843,11 @@ Using an external contract provides two advantages: 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) | +| CMTAT version | DocumentEngine | +| --------------------------- | ------------------------------------------------------------ | +| CMTAT v3.3.0 | [DocumentEngine v0.4.0](https://github.com/CMTA/DocumentEngine/releases/tag/v0.4.0) (unaudited) | +| CMTAT v3.0.0 - CMTAT v3.2.0 | Not developed | +| CMTAT v2.5.0 (unaudited) | [DocumentEngine v0.3.0](https://github.com/CMTA/DocumentEngine/releases/tag/v0.3.0) (unaudited) | #### AuthorizationEngine (Deprecated) @@ -1853,6 +1905,20 @@ Due to a limited contract size, there is no batch version with a data parameter 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`. +#### Freeze acts on the sender/recipient, not on the operator + +Freezing blocks an operation only where the frozen address is the **sender, spender or recipient** — never where it is merely the **minter**. In particular, freezing a `MINTER_ROLE` holder does **not** stop that holder from minting: `mint` / `batchMint` validate the recipient (and the contract's deactivation state), not the caller. To stop a compromised minter, revoke its role (`revokeRole(MINTER_ROLE, operator)`). + +By contrast, `batchTransfer` (a `MINTER_ROLE` function that moves the caller's **own** existing tokens) is a transfer, so freezing the caller **does** block it. + +| Operation | Creates tokens? | Freezing the **operator** blocks it? | +| --- | :---: | :---: | +| `mint` / `batchMint` | Yes | **No** — operator not checked (only the recipient is) ¹ | +| `batchTransfer` | No (moves the caller's own) | **Yes** — the operator is the sender | +| `transfer` / `transferFrom` | No | **Yes** — the operator is the sender / spender | + +¹ On the **Standard** version, if a RuleEngine is configured the operator is forwarded to it as the `spender` argument of `transferred(...)`, so a RuleEngine *rule* may reject a mint by a frozen/blocked operator. CMTAT's own freeze logic does not, and the **Light** version has no RuleEngine. See [technical/access-control.md](./technical/access-control.md#what-freeze-and-pause-block-per-operation) for the full per-operation and per-deployment table (pause, deactivation, sender/recipient freeze). + ### ERC20EnforcementModule - A part of the balance of a specific address can be frozen with the following ERC3643 function `freezePartialTokens` and `unfreezePartialTokens` @@ -1921,6 +1987,27 @@ By separating burn/mint from standard transfer, the admin can re-adjust the supp 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. +The dividing line is therefore **who is acting**, not which function is called: pause is an emergency stop on *circulation*, and it leaves the issuer's own control over the instrument intact. + +| Path | Module | Role | While paused | +| --- | --- | --- | --- | +| `mint`, `batchMint` | `ERC20MintModule` (issuer) | `MINTER_ROLE` | **Allowed** | +| `burn`, `batchBurn` | `ERC20BurnModule` (issuer) | `BURNER_ROLE` | **Allowed** | +| `forcedTransfer`, `forcedBurn` | enforcement (issuer) | `DEFAULT_ADMIN_ROLE` | **Allowed** | +| `transfer`, `transferFrom` | `ERC20BaseModule` (holders) | — | **Blocked** — `EnforcedPause()` | +| `burnFrom` | `ERC20CrossChainModule` (third party) | `BURNER_FROM_ROLE` | **Blocked** — `EnforcedPause()` | +| `burn(uint256)` (self-burn) | `ERC20CrossChainModule` (third party) | `BURNER_SELF_ROLE` | **Blocked** — `EnforcedPause()` | +| `crosschainMint`, `crosschainBurn` | `ERC20CrossChainModule` (bridge) | `CROSS_CHAIN_ROLE` | **Blocked** — `EnforcedPause()` | +| `approve(spender, 0)` (revocation) | allowance | — | **Allowed** | +| `approve(spender, n > 0)` | allowance | — | **Blocked** — `EnforcedPause()` | + +Two points worth flagging to integrators: + +- The two burn families share a name. `ERC20BurnModule.burn(address,uint256)` is the **issuer** burn and is not pause-gated; `ERC20CrossChainModule.burn(uint256)` and `burnFrom(address,uint256)` are **third-party** burns and are. +- Setting an allowance to **zero** is always permitted, including while paused or deactivated and when the owner or spender is frozen or off the allowlist: a revocation can only reduce what a spender may move, so a holder can always sever ties with a compromised or sanctioned spender. Non-zero grants remain subject to the usual checks. + +See [modules/core/Pause/pause.md](./modules/core/Pause/pause.md#what-pause-stops-and-what-it-does-not) for the same split at module level. + #### 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. @@ -1948,7 +2035,7 @@ interface IERC8343 { 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. +If a contract is deactivated, holder transfers and standard `burn` / `mint` operations revert with `EnforcedDeactivation`. Privileged enforcement operations — `forcedTransfer`, `forcedBurn` and the freeze setters — **intentionally remain available** so the enforcer/admin can still act on a terminated token (see [Post-deactivation privileged operations](#post-deactivation-privileged-operations) below and [technical/lifecycle.md](./technical/lifecycle.md)). ##### Kill (previous version) @@ -1978,6 +2065,9 @@ The following privileged operations are intentionally post-deactivation-enabled: - `setAddressFrozen` / `batchSetAddressFrozen` (`EnforcementModule`) - `freezePartialTokens` / `unfreezePartialTokens` (`ERC20EnforcementModule`) - `forcedTransfer` and related privileged enforcement paths (`ERC20EnforcementModule` / `ERC20EnforcementERC7551Module`) +- `forcedBurn` (Light / `CMTATBaseCore`) — the Light variant's enforcement burn + +This is intentional: `forcedTransfer` / `forcedBurn` move tokens through the ERC-20 `_update` primitive directly (the enforcer's regulatory tool), so they bypass the pause/deactivation validation applied to holder transfers and standard issuance. Per [ERC-8343](../ERCSpecification/draft-erc-8343-deactivation.md) a named privileged operation may remain available after deactivation (e.g. to sweep a frozen or migrated position). Because `DEFAULT_ADMIN_ROLE` can hold these roles, it can still move tokens after deactivation — protect that key with a multisig/timelock. See also [technical/lifecycle.md](./technical/lifecycle.md) for the consolidated pause/deactivation reference (state machine, what each state blocks, ERC-8343). @@ -2150,6 +2240,24 @@ The CMTAT supports client-side gasless transactions using the standard [ERC-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`. +#### Deployment version support + +The `ERC2771Module` is included in **every deployment variant except Light, Permit, Debt and DebtEngine**, where it is intentionally omitted (Light is minimal by design; Permit, Debt and DebtEngine drop it to keep bytecode under the EIP-170 limit). Both the standalone and upgradeable flavours of each variant behave the same. + +| Deployment variant | MetaTx/Gasless (ERC-2771) | Note | +| --- | :---: | --- | +| Standard | | Via `CMTATBaseERC7551Enforcement` | +| ERC-7551 | | | +| Snapshot | | Via `CMTATBaseERC2771Snapshot` | +| Allowlist | | | +| ERC-1363 | | | +| HolderList | | | +| UUPS | | Via `CMTATBaseERC2771` | +| Light | | Minimal variant (`CMTATBaseCore`), module omitted | +| Permit | | Omitted to keep bytecode lean (EIP-170) | +| Debt | | Omitted (`ERC2771Module` and cross-chain excluded) | +| DebtEngine | | Omitted | + At deployment, the parameter `forwarder` inside the CMTAT contract constructor has to be set with the defined address of the forwarder. After deployment: @@ -2185,7 +2293,9 @@ If you want to track all operations which burn or mint tokens, you can track the | `CrosschainMint(address indexed to, uint256 value, address indexed sender)` | IERC7802 | ERC-7802 | `crosschainMint`
(ERC20CrossChain) | | `CrosschainBurn(address indexed from, uint256 value, address indexed sender)` | IERC7802 | ERC-7802 | `crosschainBurn`
(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)` | +| `Spend(address indexed account, address indexed spender, uint256 value)` | IERC20Allowance | - | `transferFrom` (ERC20BaseModule)
`burnFrom` (ERC20CrossChain)
`forcedTransfer` — on the allowance reduction (ERC20EnforcementModule) | + +> The `Spend` event signals *consumption* of an allowance. It is emitted on every allowance-consuming `transferFrom` / `burnFrom` — **including infinite approvals**, where the allowance is not actually reduced — so `value` is the amount used, not the size of any reduction. `forcedTransfer` also emits it when it reduces a finite allowance. It is **not** a complete ledger of allowance movement: to obtain a current allowance, read `allowance(owner, spender)`, never accumulate `Spend`/`Approval` events. See [technical/allowance-spend-event.md](./technical/allowance-spend-event.md). @@ -2365,9 +2475,36 @@ interface ICMTATBase { #### Additional documents through ERC1643 and DocumentEngine -Additional documents can be added through the `DocumentEngine` +Beyond the single tokenization `terms` above, CMTAT can attach an arbitrary **set** of named [ERC-1643](https://github.com/ethereum/EIPs/issues/1643) documents (each a `bytes32` name → `{uri, documentHash, lastModified}`). There are **two complementary ways** to expose them, both implementing the same `IERC1643` interface, so an off-chain reader calls the same `getDocument` / `getAllDocuments` regardless of where the data lives: + +| Mechanism | Module | Where documents are stored | Availability | +| --- | --- | --- | --- | +| **Native (in-contract)** | [`DocumentERC1643Module`](../contracts/modules/wrapper/extensions/DocumentERC1643Module.sol) | In the token contract's own ERC-7201 storage | New in **v3.3.0**, on the deployment variants that include the document base (`CMTATBaseDocument`, level 1) | +| **External engine** | [`DocumentEngineModule`](./modules/extensions/documentEngine/document.md) | In a separate `DocumentEngine` contract that the token points to | Optional module — currently **not shipped in any deployment variant**, validated through test mocks | + +**Native module — `DocumentERC1643Module`.** Documents are managed on the token itself: + +```solidity +function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) external; // onlyDocumentManager +function removeDocument(bytes32 name) external; // onlyDocumentManager +function getDocument(bytes32 name) external view returns (string memory uri, bytes32 documentHash, uint256 lastModified); +function getAllDocuments() external view returns (bytes32[] memory documentNames_); +``` + +- Writes are gated by the `DOCUMENT_ROLE`; reads are unrestricted. +- `setDocument` emits `DocumentUpdated(name, uri, documentHash)` (both on insert and update); `removeDocument` emits `DocumentRemoved` and reverts `ERC1643MissingDocument` if the name is unknown. `lastModified` is stamped by the contract. +- The zero name is rejected with `ERC1643InvalidName`. A `getDocument` on an unregistered name returns **empty values without reverting**, matching the ERC-1643 ABI. + +**External engine — `DocumentEngineModule`.** Instead of storing documents in the token, the token holds the address of an external `DocumentEngine` (any contract implementing `IERC1643`) and delegates the reads to it: + +```solidity +function setDocumentEngine(IERC1643 documentEngine_) external; // DOCUMENT_ENGINE_ROLE +function documentEngine() external view returns (IERC1643); +``` + +This keeps document logic upgradeable and off the token's bytecode, and lets several tokens share one engine. `getDocument` / `getAllDocuments` on the token forward to the configured engine. -For more information, see the section dedicated to the `DocumentEngine` +Both mechanisms support the **two versions of ERC-1643** CMTAT implements — the *original* (only ever a [GitHub issue](https://github.com/ethereum/EIPs/issues/1643)) and its *rework* draft ["Document Management for Security Tokens" (ethereum/ERCs PR #1754)](https://github.com/ethereum/ERCs/pull/1754) — which share the same `bytes32`-named document model. For the engine contract, its interface, expected roles, and the released `DocumentEngine` versions, see the [DocumentEngine (IERC-1643)](#documentengine-ierc-1643) section. ### Cross-chain transfers (ERC-7802, CCIP-CCT, LayerZero) @@ -2596,6 +2733,13 @@ More information on this standard here: [erc1363.org](https://erc1363.org), [Rar #### Inheritance +The ERC-1363 variant reuses the **Standard** module set and adds the ERC-1363 callback layer on top; the three schemas below read from the shared base down to the two deployable contracts: + +- **`CMTATBaseERC1363`** (level 8, *first schema*) is `abstract` and inherits the full standard base through `CMTATBaseERC7551Enforcement` (level 7 — core modules, RuleEngine, ERC-20 cross-chain and ERC-7551 enforcement), then mixes in OpenZeppelin's `ERC1363Upgradeable`, which brings `transferAndCall` / `approveAndCall`. The extra `CMTATBaseRuleEngine` / `CMTATBaseERC20CrossChain` imports are only there to resolve the diamond (`_update`, `supportsInterface`) overrides. +- **`CMTATStandaloneERC1363`** and **`CMTATUpgradeableERC1363`** (*second and third schemas*) both extend that base and add `ERC2771Module`; they differ **only** in deployment plumbing — the standalone locks its state in a constructor, the upgradeable one is initialised behind a proxy. The functional surface is identical. + +So the diagram widens by exactly one mixin compared with the Standard variant: everything the Standard token can do, plus the ERC-1363 receiver/spender callbacks. + - CMTAT ERC-1363 Base ![surya_inheritance_CMTAT_ERC1363_BASE.sol](./schema/surya_inheritance/surya_inheritance_8_CMTATBaseERC1363.sol.png) @@ -2624,6 +2768,13 @@ It also includes a function `forcedBurn` to allow the admin to burn a token from 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 +Mirroring the ERC-1363 layout, the schemas go from the shared base up to the two deployable contracts — but here the base sits at the **bottom** of the module stack instead of the top: + +- **`CMTATBaseCore`** (level 0, *last schema*) inherits **only the core modules** — ERC-20 base, mint, burn, pause, enforcement, core validation, access control and versioning — with no RuleEngine, cross-chain, snapshot, ERC-2771 or ERC-1363. It adds `forcedBurn` so an admin can still burn from a frozen address without pulling in the heavier `ERC20EnforcementModule`. +- **`CMTATStandaloneLight`** and **`CMTATUpgradeableLight`** (*first two schemas*) extend `CMTATBaseCore` directly and, as with the ERC-1363 pair, differ only in standalone-vs-proxy wiring. + +This is why the Light schema is the shallowest of all variants: it is the one deployment whose base is level 0. + - CMTAT Upgradeable Light ![surya_inheritance_CMTAT_ERC1363_BASE.sol](./schema/surya_inheritance/surya_inheritance_CMTATUpgradeableLight.sol.png) @@ -2763,6 +2914,12 @@ Here are the different fields and functions to read and store the related debt i #### Schema +Both debt variants build on a **RuleEngine-capable** base — not the full standard base — and add debt features plus the snapshot base, but they differ in how the debt data is stored and whether cross-chain is included: + +- **`CMTATBaseDebt`** (level 4, *Debt base schema*) inherits `CMTATBaseRuleEngine` (level 3 — core modules, core validation and the RuleEngine) and mixes in the **internal** `DebtModule` (debt terms and credit events stored in the token) plus `CMTATBaseSnapshot`. It deliberately stops below the cross-chain (level 5) and ERC-2771 (level 6) layers, so the Debt variant has **no** `ERC20CrossChain` and **no** meta-transaction support. +- **`CMTATBaseDebtEngine`** (level 6, *DebtEngine base schema*) instead sits on `CMTATBaseERC20CrossChain` (level 5) and swaps the internal module for the **external** `DebtEngineModule`, so debt data lives in a separate `DebtEngine` contract. Being on the cross-chain base, it keeps `ERC20CrossChain` and the ERC-1404 rule-engine surface; like Debt it omits ERC-2771. +- For each, `CMTATStandalone…` and `CMTATUpgradeable…` (the first two schemas of each block) extend the base and differ only in standalone-vs-proxy wiring. + ##### Debt - CMTAT Standalone Debt @@ -2828,6 +2985,25 @@ The same allowance authorization checks apply to both `approve` and `permit`: This deployment version is useful when a workflow needs gas-sponsored approvals, signature-based UX, or atomic batching of several token operations. +#### Inheritance + +The Permit variant builds on the cross-chain base and adds the two OpenZeppelin mixins that give it its name: + +- **`CMTATBaseERC2612`** (level 6, *base schema*) is `abstract` and inherits `CMTATBaseERC20CrossChain` (level 5 — core modules, validation, RuleEngine and ERC-20 cross-chain), then mixes in OpenZeppelin's `ERC20PermitUpgradeable` (`permit`) and `MulticallUpgradeable` (`multicall`). Unlike the standard base it does **not** pull in `ERC2771Module`, to keep the bytecode lean under EIP-170. +- **`CMTATStandalonePermit`** and **`CMTATUpgradeablePermit`** extend that base and differ only in standalone-vs-proxy wiring. + +- CMTAT Base Permit + +![surya_inheritance_6_CMTATBaseERC2612.sol](./schema/surya_inheritance/surya_inheritance_6_CMTATBaseERC2612.sol.png) + +- CMTAT Standalone Permit + +![surya_inheritance_CMTATStandalonePermit.sol](./schema/surya_inheritance/surya_inheritance_CMTATStandalonePermit.sol.png) + +- CMTAT Upgradeable Permit + +![surya_inheritance_CMTATUpgradeablePermit.sol](./schema/surya_inheritance/surya_inheritance_CMTATUpgradeablePermit.sol.png) + ### Allowlist The Allowlist deployment version allows to restrict transfer to token holders present inside an allowlist (whitelist) maintained inside the smart contract. @@ -2852,6 +3028,11 @@ More information regarding the Ethereum API available in the [Allowlist module d #### Inheritance +The Allowlist variant swaps the RuleEngine branch for an **in-contract whitelist**, which is why it sits at level 3 (parallel to the RuleEngine base) and cannot use a RuleEngine / ERC-1404: + +- **`CMTATBaseAllowlist`** (level 3, *base schema*) inherits `CMTATBaseAccessControl` (level 2) and composes `ValidationModuleAllowlist` (the whitelist check that replaces the RuleEngine validation), `ValidationModuleAllowance`, `ERC2771Module` (so it keeps meta-transactions) and `ERC20EnforcementERC7551Module` (so `forcedTransfer` and the ERC-7551 enforcement surface stay available). +- **`CMTATStandaloneAllowlist`** and **`CMTATUpgradeableAllowlist`** extend that base and differ only in standalone-vs-proxy wiring. + - CMTAT Standalone Allowlist ![surya_inheritance_CMTATStandaloneAllowlist.sol](./schema/surya_inheritance/surya_inheritance_CMTATStandaloneAllowlist.sol.png) @@ -3015,7 +3196,17 @@ A detailed maintainer feedback is available in [SequentReport-feedback.md](./sec ### Tools -Reports and summaries for all static analysis and automated review tools ([Aderyn](https://github.com/Cyfrin/aderyn), [Slither](https://github.com/crytic/slither), Mythril, [Nethermind Audit Agent](https://auditagent.nethermind.io), Wake Arena) are collected in [security/AUDIT.md](./security/AUDIT.md). +Beyond the external human audits above, every CMTAT release is run through static analyzers and AI-assisted review tools. These are **not** a substitute for a formal audit — they surface *candidates* that CMTA maintainers then verify by hand — but they give continuous, per-release coverage between audits. The full reports, per-finding maintainer feedback and dispositions are collected in **[security/AUDIT.md](./security/AUDIT.md)**; the table below summarizes the latest run of each tool. + +| Tool | Type | Latest run | Outcome | +| --- | --- | --- | --- | +| [Aderyn](https://github.com/Cyfrin/aderyn) (Cyfrin) | Static analyzer (Rust) | v3.3.0 (`aderyn 0.6.5`, 2026-07-30 on rc3) | 2 High + 10 Low, all reviewed — **nothing to fix**; the only accept-and-mitigate item is L-1 centralization (mitigated by governance at deployment). | +| [Slither](https://github.com/crytic/slither) (Crytic) | Static analyzer (Python) | v3.3.0 (`slither 0.11.5`, 158 results, 2026-07-30 on rc3) | 0 High; every Medium/Low is a false positive or a documented design choice — **nothing to fix**. | +| [Mythril](https://github.com/Consensys/mythril) | Symbolic execution | v2.5.0 | Last runnable version; on v3.0.0+ the tool hits a fatal `solc` error and cannot complete. | +| [Nethermind AuditAgent](https://auditagent.nethermind.io) | AI-assisted review | v3.3.0-rc2 (Scan ID 9) | 24 findings (1 High / 4 Med / 3 Low / 14 Info / 2 best-practice) → **12 code fixes**, the rest documented or rejected; the High is a false positive; **no open item**. | +| [Wake Arena](https://ackee.xyz) (Ackee Blockchain Security) | AI vulnerability analysis | v3.2.0-rc2 (Feb 2026) | Findings triaged with a per-finding maintainer response. | + +> **On the AI tools.** The AuditAgent and Wake Arena reports are generated by AI and, by the tools' own notices, must be independently verified. The linked feedback files in [security/AUDIT.md](./security/AUDIT.md) are that verification, performed by CMTA maintainers. ### Test @@ -3023,6 +3214,14 @@ A code coverage is available in [index.html](./test/coverage/index.html). ![coverage](./general/coverage.png) +The coverage run (`npm run-script coverage`) uses the `prague` hardfork rather than +the `osaka` one used by the test run: solidity-coverage's instrumented bytecode +exceeds the EIP-7825 per-transaction gas cap on the largest deployment variants. +This concerns the instrumented build only — the deployed contracts use about a third +of that cap. See [USAGE.md](./USAGE.md#coverage) for the measured figures. + +The full test suite is catalogued per feature module and per deployment version in **[test/Test.md](./test/Test.md)** — a hand-maintained map (module × deployment-version coverage matrix, per-module scenario reference) whose purpose is to make **missing tests easy to find**. It must be updated whenever a test is added, changed or removed. + ## Usage More details are available in the file [USAGE.md](./USAGE.md) @@ -3091,7 +3290,7 @@ The project is built with [Hardhat](https://v2.hardhat.org) and uses [OpenZeppel [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/) + - Solidity [v0.8.36](https://docs.soliditylang.org/en/v0.8.36/) - EVM version: Osaka (Fusaka upgrade) - Optimizer: true, 200 runs @@ -3134,7 +3333,7 @@ Alternatively, you can install Hardhat [globally](https://v2.hardhat.org/hardhat npm run-script size ``` -Measured with `solc 0.8.34`, optimizer enabled (200 runs). EVM deployed bytecode limit: **24.576 KiB**. +Measured with `solc 0.8.36`, 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. @@ -3162,6 +3361,10 @@ This section provides an overview of CMTAT-related projects, both official imple ### Official / CMTA-Managed Implementations +#### [CMTAT-Confidential](https://github.com/CMTA/CMTAT-Confidential) + +Confidential version of CMTAT that keeps balances and transfer amounts private using Fully Homomorphic Encryption. It builds on OpenZeppelin's [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) confidential-token standard and [Zama](https://www.zama.ai/)'s FHEVM (encrypted `euint64` balances, transfers validated through zero-knowledge proofs), while preserving CMTAT's compliance features (pause, freeze, forced transfer). Audited by OpenZeppelin (2026). + #### 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. diff --git a/doc/USAGE.md b/doc/USAGE.md index 88d3de68..85240ac5 100644 --- a/doc/USAGE.md +++ b/doc/USAGE.md @@ -12,7 +12,7 @@ are the latest ones that we tested: ### Smart contract - hardhat.config.js - - Solidity [0.8.34](https://www.soliditylang.org/blog/2026/02/18/solidity-0.8.34-release-announcement) (via solc-js) + - Solidity [0.8.36](https://docs.soliditylang.org/en/v0.8.36/) (via solc-js) - EVM version: Osaka (Fusaka upgrade) - Package.json @@ -24,7 +24,7 @@ are the latest ones that we tested: - Node v24.12.0 -- npm 11.11.0 +- npm 12.0.1 - Nomiclabs - Hardhat: ^2.28.5 - **[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/) @@ -224,6 +224,55 @@ Code coverage for Solidity smart-contracts, installed as a hardhat plugin npm run-script coverage ``` +#### Hardfork used by the coverage run + +Coverage runs on the **`prague`** hardfork, while `npm run test` runs on **`osaka`** +(the compiler target set in `hardhat.config.js`). The switch is automatic — the +config selects the hardfork from the Hardhat task being run — and `HARDHAT_HARDFORK` +overrides the choice for either run. + +The reason is [EIP-7825](https://eips.ethereum.org/EIPS/eip-7825), activated in +Osaka, which caps a **single transaction at 2\*\*24 = 16,777,216 gas**, deployments +included. solidity-coverage rewrites every contract before running the suite, +injecting a storage write for each statement, branch and function so it can record +what executed. That instrumented bytecode is far larger and costlier to deploy than +the real thing, and for the largest deployment variants it exceeds the cap, so the +deploys abort with: + +``` +ProviderError: Transaction ran out of gas +``` + +Because the failure happens in a `beforeEach` hook, every test behind it is skipped, +which is why the symptom is a handful of errors plus a sharp drop in the number of +tests reported as passing. Running coverage on `prague` — the last hardfork before +the cap — lets solidity-coverage use its own, much higher gas limit. + +#### This does not affect deployability on Ethereum + +Only the instrumented build exceeds the cap. That build exists solely inside the +coverage run, is never written to an artifact, and is never deployed. The contracts +you ship are comfortably below the limit: + +| Contract | Deploy gas | Share of the EIP-7825 cap | +| --- | ---: | ---: | +| `CMTATStandaloneERC1363` | 5,707,773 | 34.0 % | +| `CMTATStandaloneHolderList` | 5,709,676 | 34.0 % | +| `CMTATStandaloneDebtEngine` | 5,699,492 | 34.0 % | +| `CMTATStandaloneERC7551` | 5,552,282 | 33.1 % | +| `CMTATStandardStandalone` | 5,402,615 | 32.2 % | + +*(measured on the `osaka` hardfork, optimizer enabled with `runs: 200`)* + +Two further checks back this up: `npm run test` deploys these same contracts on +`osaka`, the hardfork that actually enforces the cap, and `contractSizer.strict` +rejects at compile time any non-mock contract above the EIP-170 runtime limit of +24 KB — so a build that compiles is already size-legal. + +Do keep the cap in mind when composing a new deployment variant: at roughly a third +of the budget there is ample headroom today, but EIP-7825 is a hard protocol rule +that a substantially larger variant could approach. + ### [Slither](https://github.com/crytic/slither) @@ -234,6 +283,13 @@ Slither is a Solidity static analysis framework written in Python3 slither . --checklist --filter-paths "mocks|lib/openzeppelin-contracts-upgradeable|openzeppelin-contracts|@openzeppelin|test" > slither-report.md ``` +The versioned reports in [security/AUDIT.md](./security/AUDIT.md) are produced with the shorter equivalent form +(mocks excluded): + +```bash +slither . --checklist --filter-paths "node_modules,lib,test,forge-std,mocks" > doc/security/tools/slither/vX.Y.Z-slither-report.md +``` + ### [Mythril](https://github.com/Consensys/mythril) It seems that Mythril version [v.0.24.8](https://github.com/ConsenSysDiligence/mythril/releases/tag/v0.24.8) does not support custom error or maybe it is an error related to `solc`. @@ -274,6 +330,12 @@ See [Cyfrin/aderyn](https://github.com/Cyfrin/aderyn) aderyn . -x mocks ``` +The versioned reports in [security/AUDIT.md](./security/AUDIT.md) are produced with: + +```bash +aderyn -x mocks --output doc/security/tools/aderyn/vX.Y.Z-aderyn-report.md +``` + ## Others NodeJS tools This part describe the list of libraries present in the file `package.json`. diff --git a/doc/general/coverage.png b/doc/general/coverage.png index b3e93206..f362b33f 100644 Binary files a/doc/general/coverage.png and b/doc/general/coverage.png differ 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 9e890052..5e094801 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 | ef3159d406b8c61dbc2520fb37c0c29c5827d2bc | +| ./modules/0_CMTATBaseCommon.sol | 5bbfcbc4e3092ac28333b1f88f636f3c61c6a7e1 | ### Contracts Description Table @@ -15,7 +15,7 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATBaseCommon** | Implementation | VersionModule, ERC20MintModule, ERC20BurnModule, ERC20BaseModule, ERC20EnforcementModule, ExtraInformationModule, IBurnMintERC20, IERC5679 ||| +| **CMTATBaseCommon** | Implementation | VersionModule, ERC20MintModule, ERC20BurnModule, ERC20BaseModule, TokenAttributeModule, ERC20EnforcementModule, ExtraInformationModule, IBurnMintERC20, IERC5679 ||| | └ | decimals | Public ❗️ | |NO❗️ | | └ | name | Public ❗️ | |NO❗️ | | └ | symbol | Public ❗️ | |NO❗️ | 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 d85109f6..2eda81ee 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 | 6e879243185b8c9f76fcedb367b2aee8b27ba60e | +| ./modules/0_CMTATBaseCore.sol | 5175bf496cd97791fe58958ccea9d528392b1ff6 | ### Contracts Description Table @@ -15,7 +15,7 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATBaseCore** | Implementation | Initializable, ContextUpgradeable, VersionModule, ERC20MintModule, ERC20BurnModule, ValidationModuleAllowance, ERC20BaseModule, AccessControlModule, IForcedBurnERC20, IBurnMintERC20, IERC7551ERC20EnforcementEvent, IERC5679, IERC7943FungibleTransferError ||| +| **CMTATBaseCore** | Implementation | Initializable, ContextUpgradeable, VersionModule, ERC20MintModule, ERC20BurnModule, ValidationModuleAllowance, ERC20BaseModule, TokenAttributeModule, AccessControlModule, IForcedBurnERC20, IBurnMintERC20, IERC7551ERC20EnforcementEvent, IERC5679, IERC7943FungibleTransferError ||| | └ | initialize | Public ❗️ | 🛑 | initializer | | └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | @@ -38,7 +38,7 @@ | └ | _authorizePause | Internal 🔒 | 🛑 | onlyRole | | └ | _authorizeDeactivate | Internal 🔒 | 🛑 | onlyRole | | └ | _authorizeFreeze | Internal 🔒 | 🛑 | onlyRole | -| └ | _authorizeERC20AttributeManagement | Internal 🔒 | 🛑 | onlyRole | +| └ | _authorizeTokenAttributeManagement | Internal 🔒 | 🛑 | onlyRole | ### Legend 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 2484b42a..d8459939 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 | 2db1ecb2c69ee4f60e17917ff565907e44da1daf | +| ./modules/0_CMTATBaseGeneric.sol | a2fc064f435c335de3bfa8482e98a944137a3e6c | ### Contracts Description Table diff --git a/doc/modules/base/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md b/doc/modules/base/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md index 0819ad75..ef1474bd 100644 --- a/doc/modules/base/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md +++ b/doc/modules/base/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/0_CMTATBaseSnapshot.sol | a6d54586c8a7ed63bffceed0c7bd1abe35b5e5cd | +| ./modules/0_CMTATBaseSnapshot.sol | 7f77126b42cceca9ffefa9feed64610ab7f33f46 | ### Contracts Description Table 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 index d85f71c1..ac34eb78 100644 --- a/doc/modules/base/surya_report/surya_report_1_CMTATBaseDocument.sol.md +++ b/doc/modules/base/surya_report/surya_report_1_CMTATBaseDocument.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/1_CMTATBaseDocument.sol | 6d9a534014f54d5736d99d1dc3f7e6d4ba7cb93d | +| ./modules/1_CMTATBaseDocument.sol | 05e7e58efdd455636fcc06c7e89767f7ac70f4d4 | ### Contracts Description Table diff --git a/doc/modules/base/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md b/doc/modules/base/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md index 6e38fe59..a35ab136 100644 --- a/doc/modules/base/surya_report/surya_report_2_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/2_CMTATBaseAccessControl.sol | cf934aa8b26c9bdc2aeb336391b3c4098da70c18 | +| ./modules/2_CMTATBaseAccessControl.sol | 342ba68721bc4c4642a4c29b8dc7aad79051ab65 | ### Contracts Description Table @@ -18,7 +18,7 @@ | **CMTATBaseAccessControl** | Implementation | AccessControlModule, CMTATBaseCommon, CMTATBaseDocument ||| | └ | __CMTAT_commonModules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | | └ | supportsInterface | Public ❗️ | |NO❗️ | -| └ | _authorizeERC20AttributeManagement | Internal 🔒 | 🛑 | onlyRole | +| └ | _authorizeTokenAttributeManagement | Internal 🔒 | 🛑 | onlyRole | | └ | _authorizeMint | Internal 🔒 | 🛑 | onlyRole | | └ | _authorizeBurn | Internal 🔒 | 🛑 | onlyRole | | └ | _authorizeDocumentManagement | Internal 🔒 | 🛑 | onlyRole | diff --git a/doc/modules/base/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md b/doc/modules/base/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md index 93574cec..7f814860 100644 --- a/doc/modules/base/surya_report/surya_report_3_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/3_CMTATBaseAllowlist.sol | 517b746b223a533ad42e9dad2a49520c1fd14d1f | +| ./modules/3_CMTATBaseAllowlist.sol | 3487697f10471c48fbbf710c669b2c2a13e738a3 | ### Contracts Description Table @@ -20,7 +20,7 @@ | └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | -| └ | approve | Public ❗️ | 🛑 | whenNotPaused | +| └ | approve | Public ❗️ | 🛑 |NO❗️ | | └ | transfer | Public ❗️ | 🛑 |NO❗️ | | └ | transferFrom | Public ❗️ | 🛑 |NO❗️ | | └ | decimals | Public ❗️ | |NO❗️ | diff --git a/doc/modules/base/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md b/doc/modules/base/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md index bc23215b..c0d10ed1 100644 --- a/doc/modules/base/surya_report/surya_report_3_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/3_CMTATBaseRuleEngine.sol | b9bc5276aceceae7c6224027123f31f4ed47c61b | +| ./modules/3_CMTATBaseRuleEngine.sol | ce5163631ffba07ac7fab7614890c80ab5117265 | ### Contracts Description Table @@ -22,7 +22,7 @@ | └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_internal_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | -| └ | approve | Public ❗️ | 🛑 | whenNotPaused | +| └ | approve | Public ❗️ | 🛑 |NO❗️ | | └ | canTransfer | Public ❗️ | |NO❗️ | | └ | canTransferFrom | Public ❗️ | |NO❗️ | | └ | _authorizePause | Internal 🔒 | 🛑 | onlyRole | 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 index 8f161dd7..d015a2c2 100644 --- a/doc/modules/base/surya_report/surya_report_4_CMTATBaseDebt.sol.md +++ b/doc/modules/base/surya_report/surya_report_4_CMTATBaseDebt.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/4_CMTATBaseDebt.sol | 593ad8bf57d7bbd52a5ee426a3e0f11d2e2d49c6 | +| ./modules/4_CMTATBaseDebt.sol | b9b2ee6c62a35ed60737592cb48fa8b921bebc4d | ### Contracts Description Table diff --git a/doc/modules/base/surya_report/surya_report_4_CMTATBaseERC1404.sol.md b/doc/modules/base/surya_report/surya_report_4_CMTATBaseERC1404.sol.md index 109c43e4..8594a2ea 100644 --- a/doc/modules/base/surya_report/surya_report_4_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/4_CMTATBaseERC1404.sol | 2f40fd05006c12aae809d94f8db9f500fc0d6eba | +| ./modules/4_CMTATBaseERC1404.sol | 1fd06a9f2ab7cb87189be2eeaf6e9c5aa772d56d | ### Contracts Description Table @@ -19,6 +19,7 @@ | └ | messageForTransferRestriction | Public ❗️ | |NO❗️ | | └ | canTransfer | Public ❗️ | |NO❗️ | | └ | canTransferFrom | Public ❗️ | |NO❗️ | +| └ | supportsInterface | Public ❗️ | |NO❗️ | | └ | _detectTransferRestriction | Internal 🔒 | | | diff --git a/doc/modules/base/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md b/doc/modules/base/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md index 989d2adc..478c55ec 100644 --- a/doc/modules/base/surya_report/surya_report_5_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/5_CMTATBaseERC20CrossChain.sol | 5900451fe62bc9ac7ae8d5ba8b03c8851206fb60 | +| ./modules/5_CMTATBaseERC20CrossChain.sol | 8004dee72cddd763301d2ebc042807edecb06e5e | ### Contracts Description Table 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 index 0ad6c074..61b2837a 100644 --- a/doc/modules/base/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md +++ b/doc/modules/base/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/6_CMTATBaseDebtEngine.sol | bfeb152012d9b39da44296cc36fa90eb0f2b8035 | +| ./modules/6_CMTATBaseDebtEngine.sol | a80e3040a1f615e3edc947bbd3fadbaf21c1e0a1 | ### Contracts Description Table 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 index 80d81a3c..c422e7cf 100644 --- a/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2612.sol.md +++ b/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2612.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/6_CMTATBaseERC2612.sol | 45670849fccf2fa62ef778ee4800b8a0ff0040d9 | +| ./modules/6_CMTATBaseERC2612.sol | 6f2700d7564f507e8abc9c0f2d13c78d4e4d59ef | ### Contracts Description Table diff --git a/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2771.sol.md b/doc/modules/base/surya_report/surya_report_6_CMTATBaseERC2771.sol.md index a0e88367..ec1a2e6d 100644 --- a/doc/modules/base/surya_report/surya_report_6_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/6_CMTATBaseERC2771.sol | f10975c79346dd77a446db967bf938e9de46af36 | +| ./modules/6_CMTATBaseERC2771.sol | 81c99fb86abb86942bce5f7e3dea00826876563f | ### 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 index b0b2ff7d..50e696fc 100644 --- a/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md +++ b/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/7_CMTATBaseERC2771Snapshot.sol | 73abac918adab1aa31671e98a0cecb7e6435cd73 | +| ./modules/7_CMTATBaseERC2771Snapshot.sol | fce93c13e6e7fa1fc69606fc3d3f75fdb8da7e92 | ### Contracts Description Table 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 index cebd5a77..eb7af44c 100644 --- a/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md +++ b/doc/modules/base/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/7_CMTATBaseERC7551Enforcement.sol | 56d471f72113e2f281ea95c65ff066fd8bd44f7c | +| ./modules/7_CMTATBaseERC7551Enforcement.sol | e54d709ba1f4a1d073b6e0cdd22b1f18c6f09783 | ### Contracts Description Table diff --git a/doc/modules/base/surya_report/surya_report_8_CMTATBaseERC1363.sol.md b/doc/modules/base/surya_report/surya_report_8_CMTATBaseERC1363.sol.md index c291424e..867605bb 100644 --- a/doc/modules/base/surya_report/surya_report_8_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/8_CMTATBaseERC1363.sol | 55f464bf7e8bc8fb2ed679b564f13727f61bbf96 | +| ./modules/8_CMTATBaseERC1363.sol | 81c904f794b94bd087c24f409493b6c9e314dd70 | ### Contracts Description Table diff --git a/doc/modules/base/surya_report/surya_report_8_CMTATBaseERC7551.sol.md b/doc/modules/base/surya_report/surya_report_8_CMTATBaseERC7551.sol.md index 83be16aa..8bebeeb0 100644 --- a/doc/modules/base/surya_report/surya_report_8_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/8_CMTATBaseERC7551.sol | ea759e98774152ca4f29fcd2b45e77f401fc6103 | +| ./modules/8_CMTATBaseERC7551.sol | bac70e22260955923825317771a6453ca1654a62 | ### Contracts Description Table diff --git a/doc/modules/base/surya_report/surya_report_8_CMTATBaseHolderList.sol.md b/doc/modules/base/surya_report/surya_report_8_CMTATBaseHolderList.sol.md new file mode 100644 index 00000000..be91b2c1 --- /dev/null +++ b/doc/modules/base/surya_report/surya_report_8_CMTATBaseHolderList.sol.md @@ -0,0 +1,37 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./modules/8_CMTATBaseHolderList.sol | fde61227a31826dc6f4014f5ffa9525335ff872d | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **CMTATBaseHolderList** | Implementation | CMTATBaseERC7551Enforcement, HolderListModule ||| +| └ | transfer | Public ❗️ | 🛑 |NO❗️ | +| └ | transferFrom | Public ❗️ | 🛑 |NO❗️ | +| └ | approve | Public ❗️ | 🛑 |NO❗️ | +| └ | name | Public ❗️ | |NO❗️ | +| └ | symbol | Public ❗️ | |NO❗️ | +| └ | decimals | Public ❗️ | |NO❗️ | +| └ | supportsInterface | Public ❗️ | |NO❗️ | +| └ | _update | Internal 🔒 | 🛑 | | +| └ | _msgSender | Internal 🔒 | | | +| └ | _msgData | Internal 🔒 | | | +| └ | _contextSuffixLength | Internal 🔒 | | | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/controllers/surya_report_ValidationModule.sol.md b/doc/modules/controllers/surya_report_ValidationModule.sol.md index 95922eca..a75a5eff 100644 --- a/doc/modules/controllers/surya_report_ValidationModule.sol.md +++ b/doc/modules/controllers/surya_report_ValidationModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/controllers/ValidationModule.sol | [object Promise] | +| ./modules/wrapper/controllers/ValidationModule.sol | bfa48028212920cc192304bc5e909aff37ada1ee | ### Contracts Description Table @@ -15,9 +15,20 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **ValidationModule** | Implementation | PauseModule, EnforcementModule ||| -| └ | _canMintBurnByModule | Internal 🔒 | | | +| **ValidationModule** | Implementation | PauseModule, EnforcementModule, IERC7943FungibleSendReceiveError, IERC7943FungibleSendReceiveCheck ||| +| └ | canSend | Public ❗️ | |NO❗️ | +| └ | canReceive | Public ❗️ | |NO❗️ | | └ | _canTransferGenericByModule | Internal 🔒 | | | +| └ | _canTransferGenericByModuleAndRevert | Internal 🔒 | | | +| └ | _canMintBurnByModule | Internal 🔒 | | | +| └ | _canMintByModuleAndRevert | Internal 🔒 | | | +| └ | _canBurnByModuleAndRevert | Internal 🔒 | | | +| └ | _canTransferisFrozen | Internal 🔒 | | | +| └ | _canTransferisFrozenAndRevert | Internal 🔒 | | | +| └ | _canTransferStandardByModule | Internal 🔒 | | | +| └ | _canTransferStandardByModuleAndRevert | Internal 🔒 | | | +| └ | _canSend | Internal 🔒 | | | +| └ | _canReceive | Internal 🔒 | | | ### Legend diff --git a/doc/modules/controllers/surya_report_ValidationModuleAllowance.sol.md b/doc/modules/controllers/surya_report_ValidationModuleAllowance.sol.md new file mode 100644 index 00000000..3a12e241 --- /dev/null +++ b/doc/modules/controllers/surya_report_ValidationModuleAllowance.sol.md @@ -0,0 +1,27 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol | 367a48e1124c4b2d20fbc7fbede9b52ac5b55c30 | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **ValidationModuleAllowance** | Implementation | ValidationModuleCore ||| +| └ | _canAuthorizeAllowanceByModuleAndRevert | Internal 🔒 | | | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/controllers/surya_report_ValidationModuleAllowlist.sol.md b/doc/modules/controllers/surya_report_ValidationModuleAllowlist.sol.md index 88109c1e..7393362e 100644 --- a/doc/modules/controllers/surya_report_ValidationModuleAllowlist.sol.md +++ b/doc/modules/controllers/surya_report_ValidationModuleAllowlist.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/controllers/ValidationModuleAllowlist.sol | [object Promise] | +| ./modules/wrapper/controllers/ValidationModuleAllowlist.sol | b48d670fdf8eb25ef742ee9891eab7a8cfa31810 | ### Contracts Description Table @@ -17,7 +17,14 @@ |||||| | **ValidationModuleAllowlist** | Implementation | AllowlistModule, ValidationModule ||| | └ | _canMintBurnByModule | Internal 🔒 | | | -| └ | _canTransferGenericByModule | Internal 🔒 | | | +| └ | _canTransferStandardByModuleAllowlist | Internal 🔒 | | | +| └ | _canTransferStandardByModule | Internal 🔒 | | | +| └ | _canSend | Internal 🔒 | | | +| └ | _canReceive | Internal 🔒 | | | +| └ | _canMintByModuleAndRevert | Internal 🔒 | | | +| └ | _canBurnByModuleAndRevert | Internal 🔒 | | | +| └ | _canTransferStandardByModuleAndRevert | Internal 🔒 | | | +| └ | _canTransferStandardByModuleAllowlistAndRevert | Internal 🔒 | | | ### Legend diff --git a/doc/modules/controllers/surya_report_ValidationModuleCore.sol.md b/doc/modules/controllers/surya_report_ValidationModuleCore.sol.md index 6b5e38b4..28384494 100644 --- a/doc/modules/controllers/surya_report_ValidationModuleCore.sol.md +++ b/doc/modules/controllers/surya_report_ValidationModuleCore.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/ValidationModuleCore.sol | [object Promise] | +| ./modules/wrapper/core/ValidationModuleCore.sol | ca909742bf8fd423e6afb311f8eb5761a3be586f | ### Contracts Description Table diff --git a/doc/modules/controllers/surya_report_ValidationModuleERC1404.sol.md b/doc/modules/controllers/surya_report_ValidationModuleERC1404.sol.md index 7ec693ad..92a5d89b 100644 --- a/doc/modules/controllers/surya_report_ValidationModuleERC1404.sol.md +++ b/doc/modules/controllers/surya_report_ValidationModuleERC1404.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol | [object Promise] | +| ./modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol | 46057556239ebd1034ecd7989d7c8561daa01516 | ### Contracts Description Table diff --git a/doc/modules/controllers/surya_report_ValidationModuleRuleEngine.sol.md b/doc/modules/controllers/surya_report_ValidationModuleRuleEngine.sol.md index 011a88ab..4c9a55ea 100644 --- a/doc/modules/controllers/surya_report_ValidationModuleRuleEngine.sol.md +++ b/doc/modules/controllers/surya_report_ValidationModuleRuleEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol | a19e2c67c3f589d1874f67a4e4b7b6e7d09b7883 | +| ./modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol | c05a0233efc4d0ddd0e3278b58c814834547c2c2 | ### 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❗️ | @@ -25,6 +25,7 @@ | └ | _canTransferWithRuleEngine | Internal 🔒 | | | | └ | _authorizeRuleEngineManagement | Internal 🔒 | 🛑 | | | └ | _transferred | Internal 🔒 | 🛑 | | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | | ### Legend diff --git a/doc/modules/controllers/surya_report_ValidationModuleRuleEngineInternal.sol.md b/doc/modules/controllers/surya_report_ValidationModuleRuleEngineInternal.sol.md index 33d84260..f2fadbbe 100644 --- a/doc/modules/controllers/surya_report_ValidationModuleRuleEngineInternal.sol.md +++ b/doc/modules/controllers/surya_report_ValidationModuleRuleEngineInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/ValidationModuleRuleEngineInternal.sol | [object Promise] | +| ./modules/internal/ValidationModuleRuleEngineInternal.sol | 11acf7327aa8492e7ebcf66aebe10c2ba19f1733 | ### Contracts Description Table diff --git a/doc/modules/controllers/validationAllowlist.md b/doc/modules/controllers/validationAllowlist.md index 14600d9e..07406b94 100644 --- a/doc/modules/controllers/validationAllowlist.md +++ b/doc/modules/controllers/validationAllowlist.md @@ -43,6 +43,32 @@ This check applies to senders, spenders, and burn sources. Identical logic applied to the recipient side (mint targets and transfer recipients). +### `transfer` vs `transferFrom` — who must be allowlisted + +When the allowlist is enabled, a **standard `transfer`** requires the **sender (`from`)** and the +**recipient (`to`)** to be allowlisted. A direct `transfer` has no third-party operator, so no spender is checked +(internally the spender is `address(0)`). + +A **`transferFrom`** additionally requires the **spender** — the `msg.sender` executing the transfer with an +allowance — to be allowlisted. All three of `spender`, `from` and `to` must be on the allowlist; the checks are +evaluated in that order: + +| Party | Not allowlisted → revert | +|---|---| +| `spender` (the `transferFrom` caller) | `ERC7943CannotSend(spender)` | +| `from` (token holder) | `ERC7943CannotSend(from)` | +| `to` (recipient) | `ERC7943CannotReceive(to)` | + +> **This is deliberate.** In a permissioned (allowlist) deployment, the operator executing a delegated transfer is +> itself a transfer participant and must be vetted — an allowance alone does not exempt it. A consequence is that a +> **non-allowlisted contract (e.g. a DEX router or escrow) cannot move allowlisted holders' tokens via +> `transferFrom`**; the operator must be allowlisted first. The mirror behaviour holds for `approve`/`permit` +> (both `owner` and `spender` must pass `_canSend`) — see [Allowance Authorization](#allowance-authorization-validationmoduleallowance). + +Note that **minting is different**: `mint`/`batchMint` validate only the recipient, *not* the operator, so a +non-allowlisted `MINTER_ROLE` holder can still mint to an allowlisted recipient. See +[access-control.md](../../technical/access-control.md#what-freeze-and-pause-block-per-operation). + ### Effect of `enableAllowlist(bool status)` | `status` | `_canSend` / `_canReceive` behaviour | diff --git a/doc/modules/controllers/validationRuleEngine.md b/doc/modules/controllers/validationRuleEngine.md index cba62cf4..1d29dc62 100644 --- a/doc/modules/controllers/validationRuleEngine.md +++ b/doc/modules/controllers/validationRuleEngine.md @@ -26,6 +26,66 @@ This section describes the Ethereum API of the Validation Module. The rules are defined using an (optional) rule engine, set using the `setRuleEngine` method. The `RuleEngine` implementation is not provided along with this implementation but it has to comply with the interface [IRuleEngine](https://github.com/CMTA/CMTAT/blob/master/contracts/interfaces/engine/IRuleEngine.sol). The RuleEngine calls rules that must respect the `IRule` interface defined in the [Rules](https://github.com/CMTA/Rules) repository +## Integration notes for RuleEngine implementers + +### The `transferred` callback is reentrant on some deployment variants + +`transferred(...)` is invoked from `_checkTransferred`, i.e. **after** the active-balance (frozen) check and **before** `ERC20Upgradeable._transfer` moves any balance. That check is not re-evaluated afterwards. + +A RuleEngine that calls back into the token during the callback is therefore validated twice against the *same* pre-transfer snapshot, and the outer and inner transfers can together move more than the holder's unfrozen balance. Measured on an unguarded build: a holder with `balance=100`, `frozenTokens=60` (active 40) lost **80** tokens to an outer `transferFrom(holder, attacker, 40)` plus one nested `transferFrom` of 40, leaving `frozenTokens(60) > balanceOf(20)` — the freeze invariant broken. + +CMTAT wraps the callback in a transient (EIP-1153) reentrancy guard, but **only on the deployment variants that have the bytecode headroom for it**. The guard costs ~195 bytes of deployed bytecode and several variants sit within a few hundred bytes of the EIP-170 24 KiB limit; enabling it there would make them undeployable. + +| Deployment variant | Deployed size (bytes) | Reentrancy guard | +| --- | ---: | :---: | +| `CMTATStandaloneSnapshot` / `CMTATUpgradeableSnapshot` | 22 859 | ✅ | +| `CMTATStandardStandalone` / `CMTATStandardUpgradeable` | 23 039 | ✅ | +| `CMTATStandaloneERC7551` / `CMTATUpgradeableERC7551` | 23 731 | ✅ | +| `CMTATStandaloneDebt` / `CMTATUpgradeableDebt` | 23 805 | ❌ | +| `CMTATStandalonePermit` / `CMTATUpgradeablePermit` | 23 961 | ❌ | +| `CMTATUpgradeableUUPS` | 24 176 | ❌ | +| `CMTATStandaloneDebtEngine` / `CMTATUpgradeableDebtEngine` | 24 429 | ❌ | +| `CMTATStandaloneERC1363` / `CMTATUpgradeableERC1363` | 24 443 | ❌ | +| `CMTATStandaloneHolderList` / `CMTATUpgradeableHolderList` | 24 456 | ❌ | +| `CMTATStandaloneAllowlist`, `CMTATStandaloneLight` (and proxies) | 20 405 / 11 562 | n/a — no RuleEngine | + +> **WARNING — variants without the guard.** On the ❌ rows the trust assumption is load-bearing: the RuleEngine is set by `DEFAULT_ADMIN_ROLE`, is **fully trusted**, and **MUST NOT** transfer control to untrusted code during `transferred(...)`. A rule that calls an arbitrary external address — a hook, a callback, a user-supplied contract — breaks that assumption and re-opens the drain described above. If your rule set needs to call untrusted code, deploy a guarded variant. + +On guarded variants a reentrant callback reverts the whole transaction with OpenZeppelin's `ReentrancyGuardReentrantCall`. The guard is entered only when a RuleEngine is set (a deployment with no engine pays nothing) and released when the callback returns, so batch operations and `burnAndMint`, which invoke the hook several times in one transaction, are unaffected. + +To enable the guard on a variant that currently lacks it, inherit `ReentrancyGuardTransient` in the deployment contract and override `_callRuleEngineTransferred` with `nonReentrant` — see `contracts/deployment/CMTATStandardStandalone.sol` — and re-check the deployed size against the 24 576-byte limit. + +> Reported as NM-7 / NM-9 / NM-11 / NM-16 / NM-18 by [Nethermind AuditAgent](https://auditagent.nethermind.io/) on CMTAT v3.3.0-rc2; see the [maintainer feedback](../../security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md). + +### Zero-value calls to `transferred` are permissionless + +The `transferred(...)` callback can be reached by **anyone**, for an **arbitrary `from`**, with `value == 0` and without any allowance. + +Two ERC-20 properties combine to make this possible, and neither is a defect: + +- ERC-20 requires that *"transfers of 0 values MUST be treated as normal transfers"*, so the token notifies the RuleEngine for them like any other transfer; +- OpenZeppelin's `_spendAllowance` consumes nothing when `value == 0`, so `transferFrom` succeeds with a zero allowance. + +Concretely, any address can call `transferFrom(victim, anyone, 0)` on the token. The call passes the validation gates (the victim must not be frozen, the token must not be paused, ...), emits a zero-value `Transfer`, moves nothing, and still invokes `transferred(attacker, victim, anyone, 0)` on the configured RuleEngine. The 3-argument ERC-3643 overload is reachable the same way through `transfer(to, 0)`. + +CMTAT deliberately does **not** suppress the notification for a zero value: doing so would make the compliance notifications inconsistent with the token's own ERC-20 transfer semantics, and a rule engine that needs to observe every transfer would silently miss a class of them. + +**Requirement.** A RuleEngine — and every `IRule` it calls — **MUST treat `value == 0` as carrying no economic meaning**. Any stateful rule must be a no-op for a zero value, in particular: + +| Rule kind | What a zero-value call must not do | +| --- | --- | +| Cooldown / holding period | Start, extend or reset a timer | +| Quota / volume cap | Consume budget or increment a counter | +| Tax or fee bucket | Accrue or settle anything | +| Holder tracking | Add, remove or reorder a holder | +| Sanction / freeze bookkeeping | Change a participant's status | + +Otherwise an attacker can desynchronize policy state from actual balances, or keep a holder permanently restricted, at no cost beyond gas. + +Implementations that cannot make a rule idempotent at zero should reject the call explicitly (`require(value > 0)` inside that rule) rather than let it mutate state — but note that reverting makes every zero-value transfer of the token revert too, which is not ERC-20 compliant. Preferring a no-op is strongly recommended. + +> Reported as NM-6 by [Nethermind AuditAgent](https://auditagent.nethermind.io/) on CMTAT v3.3.0-rc2 and assessed as a RuleEngine-side responsibility; see the [maintainer feedback](../../security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md). + ### `function setRuleEngine(IRuleEngine ruleEngine_)` Updates the RuleEngine used to enforce validation rules. diff --git a/doc/modules/core/ERC20Base/ERC20base.md b/doc/modules/core/ERC20Base/ERC20base.md index e271f177..ff20116d 100644 --- a/doc/modules/core/ERC20Base/ERC20base.md +++ b/doc/modules/core/ERC20Base/ERC20base.md @@ -131,6 +131,8 @@ Sets the name of the token. | ------ | ------ | ------------------------------------ | | `name` | string | The new name to assign to the token. | +> **ERC-2612 note.** On deployment variants that support `permit`, renaming the token does **not** change the EIP-712 domain separator: the domain name is captured at initialization and `DOMAIN_SEPARATOR()` keeps using it. `permit` continues to work — signers must build the EIP-712 domain from the ERC-5267 `eip712Domain()` function (or `DOMAIN_SEPARATOR()`), never from `name()`. A signature produced with the post-rename `name()` is rejected with `ERC2612InvalidSigner`. See [erc2612.md](../../options/erc2612/erc2612.md#the-eip-712-domain-name-is-fixed-at-deployment). + ------ diff --git a/doc/modules/core/ERC20Base/surya_report_ERC20BaseModule.sol.md b/doc/modules/core/ERC20Base/surya_report_ERC20BaseModule.sol.md index 4b6a9352..8424a02d 100644 --- a/doc/modules/core/ERC20Base/surya_report_ERC20BaseModule.sol.md +++ b/doc/modules/core/ERC20Base/surya_report_ERC20BaseModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/ERC20BaseModule.sol | dbfc430335786836dd8b73e0a34dacc69202aa73 | +| ./modules/wrapper/core/ERC20BaseModule.sol | f6269c10a2defbf54e77ef0032c7534af70ed869 | ### Contracts Description Table @@ -15,16 +15,11 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **ERC20BaseModule** | Implementation | ERC20Upgradeable, IERC20Allowance, IERC3643ERC20Base, IERC20BatchBalance ||| +| **ERC20BaseModule** | Implementation | ERC20Upgradeable, IERC20Allowance, IERC20BatchBalance ||| | └ | __ERC20BaseModule_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | | └ | transferFrom | Public ❗️ | 🛑 |NO❗️ | | └ | decimals | Public ❗️ | |NO❗️ | -| └ | name | Public ❗️ | |NO❗️ | -| └ | symbol | Public ❗️ | |NO❗️ | -| └ | setName | Public ❗️ | 🛑 | onlyERC20AttributeManager | -| └ | setSymbol | Public ❗️ | 🛑 | onlyERC20AttributeManager | | └ | batchBalanceOf | Public ❗️ | |NO❗️ | -| └ | _authorizeERC20AttributeManagement | Internal 🔒 | 🛑 | | | └ | _getERC20BaseModuleStorage | Private 🔐 | | | diff --git a/doc/modules/core/ERC20Burn/ERC20Burn.md b/doc/modules/core/ERC20Burn/ERC20Burn.md index 5553caa3..181694fa 100644 --- a/doc/modules/core/ERC20Burn/ERC20Burn.md +++ b/doc/modules/core/ERC20Burn/ERC20Burn.md @@ -247,7 +247,7 @@ Burns a specific amount of tokens from the given account by sending them to the **Notes**: - Reverts if the account's balance is insufficient. -- Burn can occur even if transfers are paused. +- Burn can occur even if transfers are paused. This applies to the **issuer** burn documented here (`ERC20BurnModule`, `BURNER_ROLE`). The third-party burns exposed by `ERC20CrossChainModule` — `burnFrom(address,uint256)` and `burn(uint256)` — **are** blocked while paused; see [pause.md](../Pause/pause.md#what-pause-stops-and-what-it-does-not). **Emits:** diff --git a/doc/modules/core/ERC20Burn/surya_report_ERC20BurnModule.sol.md b/doc/modules/core/ERC20Burn/surya_report_ERC20BurnModule.sol.md index b5b4cd2b..61b2c31c 100644 --- a/doc/modules/core/ERC20Burn/surya_report_ERC20BurnModule.sol.md +++ b/doc/modules/core/ERC20Burn/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 | 3f109e92e878e64dd13b17eb9c385c19a7c4a3e6 | ### Contracts Description Table diff --git a/doc/modules/core/ERC20Burn/surya_report_ERC20BurnModuleInternal.sol.md b/doc/modules/core/ERC20Burn/surya_report_ERC20BurnModuleInternal.sol.md index 25204f68..6821bc46 100644 --- a/doc/modules/core/ERC20Burn/surya_report_ERC20BurnModuleInternal.sol.md +++ b/doc/modules/core/ERC20Burn/surya_report_ERC20BurnModuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/ERC20BurnModuleInternal.sol | [object Promise] | +| ./modules/internal/ERC20BurnModuleInternal.sol | 6e7e3e3f2e88f75be2a881adf1fa10db6b236b52 | ### Contracts Description Table diff --git a/doc/modules/core/ERC20Mint/ERC20Mint.md b/doc/modules/core/ERC20Mint/ERC20Mint.md index 341661e0..f6e924b0 100644 --- a/doc/modules/core/ERC20Mint/ERC20Mint.md +++ b/doc/modules/core/ERC20Mint/ERC20Mint.md @@ -106,6 +106,7 @@ Creates (`mints`) a specified amount of tokens and assigns them to an account. - Increases the total token supply. - If the interface `{IERC7551Pause}` is implemented, minting is allowed even when transfers are paused. +- Only the **recipient** (and the contract's deactivation state) is validated — not the caller. Freezing a `MINTER_ROLE` holder does **not** prevent it from minting; revoke the role to stop a compromised minter. On the Standard version a configured RuleEngine still receives the minter as `spender` and may reject. See [technical/access-control.md](../../../technical/access-control.md#what-freeze-and-pause-block-per-operation). **Emits** diff --git a/doc/modules/core/ERC20Mint/surya_report_ERC20MintModule.sol.md b/doc/modules/core/ERC20Mint/surya_report_ERC20MintModule.sol.md index 4b2f67d7..efe19b42 100644 --- a/doc/modules/core/ERC20Mint/surya_report_ERC20MintModule.sol.md +++ b/doc/modules/core/ERC20Mint/surya_report_ERC20MintModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/ERC20MintModule.sol | e3290fff19ef1b4b1ea4169f84c401624392deac | +| ./modules/wrapper/core/ERC20MintModule.sol | c9b01932ec4ecb147f0e2ac00324480e9a40a23b | ### Contracts Description Table diff --git a/doc/modules/core/ERC20Mint/surya_report_ERC20MintModuleInternal.sol.md b/doc/modules/core/ERC20Mint/surya_report_ERC20MintModuleInternal.sol.md index cb00982b..697dd55a 100644 --- a/doc/modules/core/ERC20Mint/surya_report_ERC20MintModuleInternal.sol.md +++ b/doc/modules/core/ERC20Mint/surya_report_ERC20MintModuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/ERC20MintModuleInternal.sol | a26c010b8aa47d911b2796cdc806d23cdc390bea | +| ./modules/internal/ERC20MintModuleInternal.sol | 41b2893fb24992819dada2a0eab305e5b0e0efd1 | ### Contracts Description Table diff --git a/doc/modules/core/Enforcement/surya_report_EnforcementModule.sol.md b/doc/modules/core/Enforcement/surya_report_EnforcementModule.sol.md index 4fccf682..e9876622 100644 --- a/doc/modules/core/Enforcement/surya_report_EnforcementModule.sol.md +++ b/doc/modules/core/Enforcement/surya_report_EnforcementModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/EnforcementModule.sol | ffea175fbf940073568bf4414dceefcd5bdefed8 | +| ./modules/wrapper/core/EnforcementModule.sol | 4d80a37d5b8f4b1c675f237e0863cb5dc4cd9c3d | ### Contracts Description Table diff --git a/doc/modules/core/Enforcement/surya_report_EnforcementModuleInternal.sol.md b/doc/modules/core/Enforcement/surya_report_EnforcementModuleInternal.sol.md index 71416c44..18ac7aed 100644 --- a/doc/modules/core/Enforcement/surya_report_EnforcementModuleInternal.sol.md +++ b/doc/modules/core/Enforcement/surya_report_EnforcementModuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/EnforcementModuleInternal.sol | [object Promise] | +| ./modules/internal/EnforcementModuleInternal.sol | e4f8ad6066ed208d03ee4f98168801e6ef9dd55b | ### Contracts Description Table diff --git a/doc/modules/core/Enforcement/surya_report_EnforcementModuleLibrary.sol.md b/doc/modules/core/Enforcement/surya_report_EnforcementModuleLibrary.sol.md index b4955752..22e283cf 100644 --- a/doc/modules/core/Enforcement/surya_report_EnforcementModuleLibrary.sol.md +++ b/doc/modules/core/Enforcement/surya_report_EnforcementModuleLibrary.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/common/EnforcementModuleLibrary.sol | [object Promise] | +| ./modules/internal/common/EnforcementModuleLibrary.sol | b50ff90499b0589e826dc827592c1955e761ae78 | ### Contracts Description Table diff --git a/doc/modules/core/Pause/pause.md b/doc/modules/core/Pause/pause.md index d82b7547..b847e2c9 100644 --- a/doc/modules/core/Pause/pause.md +++ b/doc/modules/core/Pause/pause.md @@ -12,6 +12,38 @@ The PauseModule contract introduces contract pausing functionality into the CMTA However, this is not enforced in the functions that allow to change a user’s allowance. We don't think it is necessary to prevent allowance change while the contract is in the pause state. +Note that setting an allowance to **zero** — a revocation — is always permitted, including while the contract is paused or deactivated and when the owner or spender is frozen or off the allowlist. A revocation can only reduce what a spender may move, and a holder must always be able to sever ties with a compromised or sanctioned spender. Non-zero grants remain subject to the usual checks. + +## What pause stops, and what it does not + +Pause is an emergency stop on **circulation**, not on the issuer's control of the instrument. The dividing line is **who is acting**, not which function is called: + +- **Issuer operations continue while paused.** Minting, issuer burns and enforcement actions express the issuer's own authority over supply. Blocking them would defeat the purpose of being able to pause: the issuer must retain the ability to act on the instrument precisely while circulation is halted. +- **Third-party operations are stopped.** Operations performed by a bridge, or by an operator spending someone else's allowance, are exactly what a pause is meant to halt. In particular, cross-chain settlement must stop rather than keep moving supply between chains against a frozen local state. + +| Path | Module | Role | While paused | +| --- | --- | --- | --- | +| `mint`, `batchMint` | `ERC20MintModule` (issuer) | `MINTER_ROLE` | **Allowed** | +| `burn`, `batchBurn` | `ERC20BurnModule` (issuer) | `BURNER_ROLE` | **Allowed** | +| `forcedTransfer`, `forcedBurn` | enforcement (issuer) | `DEFAULT_ADMIN_ROLE` | **Allowed** | +| `transfer`, `transferFrom` | `ERC20BaseModule` (holders) | — | **Blocked** — `EnforcedPause()` | +| `burnFrom` | `ERC20CrossChainModule` (third party) | `BURNER_FROM_ROLE` | **Blocked** — `EnforcedPause()` | +| `burn(uint256)` (self-burn) | `ERC20CrossChainModule` (third party) | `BURNER_SELF_ROLE` | **Blocked** — `EnforcedPause()` | +| `crosschainMint`, `crosschainBurn` | `ERC20CrossChainModule` (bridge) | `CROSS_CHAIN_ROLE` | **Blocked** — `EnforcedPause()` | +| `approve(spender, 0)` (revocation) | allowance | — | **Allowed** | +| `approve(spender, n > 0)` | allowance | — | **Blocked** — `EnforcedPause()` | + +The two burn families are easy to confuse because they share a name. `ERC20BurnModule.burn(address,uint256)` is the **issuer** burn and is not pause-gated; `ERC20CrossChainModule.burn(uint256)` and `burnFrom(address,uint256)` are **third-party** burns and are. See [ERC20Burn](../ERC20Burn/ERC20Burn.md) and [ERC20CrossChain](../../options/erc20crosschain/ERC20CrossChain.md) for the per-function requirements. + +> **Consequence for ERC-1404 prediction.** Because the pause rule differs *between entry points of +> the same operation* (issuer mint/burn allowed, bridge and third-party mint/burn blocked), a single +> `detectTransferRestriction(address(0), to, value)` / `detectTransferRestriction(from, address(0), value)` +> answer cannot describe every mint or every burn — the ERC-1404 signature carries no entry-point +> discriminator. CMTAT therefore designates **no** ERC-1404 predictor for supply-changing operations: +> those methods cover `transfer` / `transferFrom` only, and mint/burn must be predicted with +> `canTransfer` / `canTransferFrom`. See the +> [ERC-1404 scope note](../../../README.md#scope-transfers-only-never-mint-or-burn). + ## Schema ![PauseUML](../../../schema/plantuml/class/PauseModule.png) diff --git a/doc/modules/core/Pause/surya_report_PauseModule.sol.md b/doc/modules/core/Pause/surya_report_PauseModule.sol.md index eacee83f..4af55690 100644 --- a/doc/modules/core/Pause/surya_report_PauseModule.sol.md +++ b/doc/modules/core/Pause/surya_report_PauseModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/PauseModule.sol | 1af52c2f0a418e75c9db436249ee77f334bf4ed3 | +| ./modules/wrapper/core/PauseModule.sol | 1d64c6a87cf4b13ab7d2a4980b8c1d82a5a29f6c | ### Contracts Description Table @@ -15,7 +15,7 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **PauseModule** | Implementation | PausableUpgradeable, IERC3643Pause, IERC7551Pause, ICMTATDeactivate ||| +| **PauseModule** | Implementation | PausableUpgradeable, IERC3643Pause, IERC7551Pause, IERC8343 ||| | └ | pause | Public ❗️ | 🛑 | onlyPauseManager | | └ | unpause | Public ❗️ | 🛑 | onlyPauseManager | | └ | deactivateContract | Public ❗️ | 🛑 | onlyDeactivateContractManager | @@ -23,6 +23,7 @@ | └ | deactivated | Public ❗️ | |NO❗️ | | └ | _authorizePause | Internal 🔒 | 🛑 | | | └ | _authorizeDeactivate | Internal 🔒 | 🛑 | | +| └ | _requireNotDeactivated | Internal 🔒 | | | | └ | _getPauseModuleStorage | Private 🔐 | | | diff --git a/doc/modules/core/Version/surya_report_VersionModule.sol.md b/doc/modules/core/Version/surya_report_VersionModule.sol.md index aaa3214f..65087cab 100644 --- a/doc/modules/core/Version/surya_report_VersionModule.sol.md +++ b/doc/modules/core/Version/surya_report_VersionModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/VersionModule.sol | 590071ba31401eecc63b1217c575489b64081bf8 | +| ./modules/wrapper/core/VersionModule.sol | 352c8e156b37f01417a778b434083a96f81898ed | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md index 5cdcc0a5..3c90e6d7 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/allowlist/CMTATStandaloneAllowlist.sol | [object Promise] | +| ./deployment/allowlist/CMTATStandaloneAllowlist.sol | 7f3e42d63903a2b02a517bb566689d40c89ef7e3 | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneDebt.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneDebt.sol.md index a24f6dec..42f3df88 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneDebt.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneDebt.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/debt/CMTATStandaloneDebt.sol | [object Promise] | +| ./deployment/debt/CMTATStandaloneDebt.sol | 572f2e447323872a7feb04d9b98462b40a56887b | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneDebtEngine.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneDebtEngine.sol.md new file mode 100644 index 00000000..2551bc3c --- /dev/null +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneDebtEngine.sol.md @@ -0,0 +1,27 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./deployment/debtEngine/CMTATStandaloneDebtEngine.sol | 3f687657c5956ce1a09c8377e965ee042ee24834 | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **CMTATStandaloneDebtEngine** | Implementation | CMTATBaseDebtEngine ||| +| └ | | Public ❗️ | 🛑 |NO❗️ | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneERC1363.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneERC1363.sol.md index f00a007a..4ca7026e 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneERC1363.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneERC1363.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/ERC1363/CMTATStandaloneERC1363.sol | [object Promise] | +| ./deployment/ERC1363/CMTATStandaloneERC1363.sol | 6184f6bf554dd1b05e8761161a061f0dd1e0c548 | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneERC7551.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneERC7551.sol.md index d1b654b0..20178687 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneERC7551.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneERC7551.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/ERC7551/CMTATStandaloneERC7551.sol | [object Promise] | +| ./deployment/ERC7551/CMTATStandaloneERC7551.sol | 5008986183befbd4fce45ad00aa5c34984977e61 | ### Contracts Description Table @@ -15,8 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATStandaloneERC7551** | Implementation | CMTATBaseERC7551 ||| +| **CMTATStandaloneERC7551** | Implementation | CMTATBaseERC7551, ReentrancyGuardTransient ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | ### Legend diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandalone.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneHolderList.sol.md similarity index 78% rename from doc/modules/deployment/surya_report/surya_report_CMTATStandalone.sol.md rename to doc/modules/deployment/surya_report/surya_report_CMTATStandaloneHolderList.sol.md index 2b02b781..b2488eb8 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATStandalone.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneHolderList.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/CMTATStandardStandalone.sol | [object Promise] | +| ./deployment/holderList/CMTATStandaloneHolderList.sol | 87873906f3e506fde4f7cc71f4e03d34e6e2abed | ### Contracts Description Table @@ -15,7 +15,7 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATStandalone** | Implementation | CMTATBaseERC2771 ||| +| **CMTATStandaloneHolderList** | Implementation | CMTATBaseHolderList ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneLight.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneLight.sol.md index 73f17f81..f2afffe9 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneLight.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneLight.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/light/CMTATStandaloneLight.sol | [object Promise] | +| ./deployment/light/CMTATStandaloneLight.sol | 9bb95cd250c6d74f82119bae8c1ff10d13e807d5 | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandalonePermit.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandalonePermit.sol.md new file mode 100644 index 00000000..5e5f8230 --- /dev/null +++ b/doc/modules/deployment/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 | 267828a4702d26a0e0129f9e94f7a133a4d5e924 | + + +### 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/deployment/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md new file mode 100644 index 00000000..5d09baed --- /dev/null +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md @@ -0,0 +1,28 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./deployment/snapshot/CMTATStandaloneSnapshot.sol | 09f8a4b84e23532342765692dccd4f8f409ee0e3 | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **CMTATStandaloneSnapshot** | Implementation | CMTATBaseERC2771Snapshot, ReentrancyGuardTransient ||| +| └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandardStandalone.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandardStandalone.sol.md new file mode 100644 index 00000000..283d0ae6 --- /dev/null +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandardStandalone.sol.md @@ -0,0 +1,28 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./deployment/CMTATStandardStandalone.sol | 0ef9dcd77454b756d96296db37186204a7b1f07c | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **CMTATStandardStandalone** | Implementation | CMTATBaseERC7551Enforcement, ReentrancyGuardTransient ||| +| └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATStandardUpgradeable.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATStandardUpgradeable.sol.md new file mode 100644 index 00000000..367a040e --- /dev/null +++ b/doc/modules/deployment/surya_report/surya_report_CMTATStandardUpgradeable.sol.md @@ -0,0 +1,28 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./deployment/CMTATStandardUpgradeable.sol | 2c4b32a3f9d827707e457bd640e0fa3d6d92397e | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **CMTATStandardUpgradeable** | Implementation | CMTATBaseERC7551Enforcement, ReentrancyGuardTransient ||| +| └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md index 50ec52eb..a19dc4a1 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/allowlist/CMTATUpgradeableAllowlist.sol | [object Promise] | +| ./deployment/allowlist/CMTATUpgradeableAllowlist.sol | 3c5a5ee74c158744094f7b55e186f0b347bb16dc | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableDebt.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableDebt.sol.md index 05f4a3cb..d06eb430 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableDebt.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableDebt.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/debt/CMTATUpgradeableDebt.sol | [object Promise] | +| ./deployment/debt/CMTATUpgradeableDebt.sol | 585643670c531d434c7a58323f978993a1a309a6 | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableDebtEngine.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableDebtEngine.sol.md new file mode 100644 index 00000000..0193c3a5 --- /dev/null +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableDebtEngine.sol.md @@ -0,0 +1,27 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./deployment/debtEngine/CMTATUpgradeableDebtEngine.sol | 8d719c0a5922d1257f64b858640ae7d5b3499baa | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **CMTATUpgradeableDebtEngine** | Implementation | CMTATBaseDebtEngine ||| +| └ | | Public ❗️ | 🛑 |NO❗️ | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableERC1363.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableERC1363.sol.md index 1af752b1..b7d09be5 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableERC1363.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableERC1363.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/ERC1363/CMTATUpgradeableERC1363.sol | [object Promise] | +| ./deployment/ERC1363/CMTATUpgradeableERC1363.sol | d19d1ca2439e20c50a8b1228af60095aa8e68d77 | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableERC7551.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableERC7551.sol.md index bff4b3a5..91d22f56 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableERC7551.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableERC7551.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/ERC7551/CMTATUpgradeableERC7551.sol | [object Promise] | +| ./deployment/ERC7551/CMTATUpgradeableERC7551.sol | 58b04fd3b37fc71e0493930a1759e2420c861416 | ### Contracts Description Table @@ -15,8 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATUpgradeableERC7551** | Implementation | CMTATBaseERC7551 ||| +| **CMTATUpgradeableERC7551** | Implementation | CMTATBaseERC7551, ReentrancyGuardTransient ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | ### Legend diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeable.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableHolderList.sol.md similarity index 78% rename from doc/modules/deployment/surya_report/surya_report_CMTATUpgradeable.sol.md rename to doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableHolderList.sol.md index 006636df..c19fa224 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeable.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableHolderList.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/CMTATStandardUpgradeable.sol | [object Promise] | +| ./deployment/holderList/CMTATUpgradeableHolderList.sol | 99ce545dfee7a132d7f1046b54feb59c986bcf84 | ### Contracts Description Table @@ -15,7 +15,7 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATUpgradeable** | Implementation | CMTATBaseERC2771 ||| +| **CMTATUpgradeableHolderList** | Implementation | CMTATBaseHolderList ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableLight.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableLight.sol.md index 224a895d..6ebb553c 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableLight.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableLight.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/light/CMTATUpgradeableLight.sol | [object Promise] | +| ./deployment/light/CMTATUpgradeableLight.sol | b2bc9fae0c0180f11d4c66de98f16a935a97cad3 | ### Contracts Description Table diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeablePermit.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeablePermit.sol.md new file mode 100644 index 00000000..4f23f0a5 --- /dev/null +++ b/doc/modules/deployment/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 | a51863f9d3c009bae52e18112f8f946e29bcb439 | + + +### 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/modules/deployment/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md new file mode 100644 index 00000000..23aff77f --- /dev/null +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md @@ -0,0 +1,28 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./deployment/snapshot/CMTATUpgradeableSnapshot.sol | 251976b5ca73cdb4ab92f8b825529b3879a33182 | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **CMTATUpgradeableSnapshot** | Implementation | CMTATBaseERC2771Snapshot, ReentrancyGuardTransient ||| +| └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md index 34e9367b..aadbd8cd 100644 --- a/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md +++ b/doc/modules/deployment/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/CMTATUpgradeableUUPS.sol | [object Promise] | +| ./deployment/CMTATUpgradeableUUPS.sol | c566d51d7c5611ac9928a45f9c32b1edc93ed9a0 | ### Contracts Description Table @@ -17,7 +17,6 @@ |||||| | **CMTATUpgradeableUUPS** | Implementation | CMTATBaseERC2771, UUPSUpgradeable ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | -| └ | initialize | Public ❗️ | 🛑 | initializer | | └ | _authorizeUpgrade | Internal 🔒 | 🛑 | onlyRole | diff --git a/doc/modules/extensions/ERC20Enforcement/erc20enforcement.md b/doc/modules/extensions/ERC20Enforcement/erc20enforcement.md index 432ce0c1..cb3e3020 100644 --- a/doc/modules/extensions/ERC20Enforcement/erc20enforcement.md +++ b/doc/modules/extensions/ERC20Enforcement/erc20enforcement.md @@ -183,6 +183,8 @@ The frozen amount may exceed the account's current token balance (over-freezing **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`. This matches `freezePartialTokens` / `unfreezePartialTokens`, and prevents a non-zero frozen amount on `address(0)` from bricking the mint path (a non-zero mint would fail `_checkActiveBalance(address(0), value)`). +- Reverts with `CMTAT_ERC20EnforcementModule_ValueEqualCurrentFrozenTokens` if `value` equals the account's current frozen amount. ------ diff --git a/doc/modules/extensions/ERC20Enforcement/surya_report_ERC20EnforcementModule.sol.md b/doc/modules/extensions/ERC20Enforcement/surya_report_ERC20EnforcementModule.sol.md index bfd46083..1802697d 100644 --- a/doc/modules/extensions/ERC20Enforcement/surya_report_ERC20EnforcementModule.sol.md +++ b/doc/modules/extensions/ERC20Enforcement/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 | f810a3b307c9623245b3fffbe4efb285aa7a08a9 | ### 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/modules/extensions/ERC20Enforcement/surya_report_ERC20EnforcementModuleInternal.sol.md b/doc/modules/extensions/ERC20Enforcement/surya_report_ERC20EnforcementModuleInternal.sol.md index 2462db0f..119e85b1 100644 --- a/doc/modules/extensions/ERC20Enforcement/surya_report_ERC20EnforcementModuleInternal.sol.md +++ b/doc/modules/extensions/ERC20Enforcement/surya_report_ERC20EnforcementModuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/ERC20EnforcementModuleInternal.sol | [object Promise] | +| ./modules/internal/ERC20EnforcementModuleInternal.sol | dfa832cbbd323852a82a39ff84fa6e962086631f | ### Contracts Description Table @@ -15,11 +15,14 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **ERC20EnforcementModuleInternal** | Implementation | ERC20Upgradeable, IERC7551ERC20EnforcementEvent, IERC7551ERC20EnforcementTokenFrozenEvent ||| +| **ERC20EnforcementModuleInternal** | Implementation | ERC20Upgradeable, IERC7943FungibleEnforcementEventAndError ||| +| └ | _setFrozenTokens | Internal 🔒 | 🛑 | | | └ | _freezePartialTokens | Internal 🔒 | 🛑 | | | └ | _unfreezePartialTokens | Internal 🔒 | 🛑 | | | └ | _unfreezeTokens | Internal 🔒 | 🛑 | | | └ | _forcedTransfer | Internal 🔒 | 🛑 | | +| └ | _freezeTokensEmitEvents | Internal 🔒 | 🛑 | | +| └ | _unfreezeTokensEmitEvents | Internal 🔒 | 🛑 | | | └ | _checkActiveBalanceAndRevert | Internal 🔒 | | | | └ | _checkActiveBalance | Internal 🔒 | | | | └ | _getFrozenTokens | Internal 🔒 | | | diff --git a/doc/modules/extensions/ExtraInformation/surya_report_ExtraInformationModule.sol.md b/doc/modules/extensions/ExtraInformation/surya_report_ExtraInformationModule.sol.md index afc3fce7..34c30d64 100644 --- a/doc/modules/extensions/ExtraInformation/surya_report_ExtraInformationModule.sol.md +++ b/doc/modules/extensions/ExtraInformation/surya_report_ExtraInformationModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/extensions/ExtraInformationModule.sol | e4c857f5b5ed57b090a01749604094fb15385d7d | +| ./modules/wrapper/extensions/ExtraInformationModule.sol | 8f6b445e2b0f694afb115819018a66b65ac3ad60 | ### Contracts Description Table @@ -24,6 +24,7 @@ | └ | terms | Public ❗️ | |NO❗️ | | └ | information | Public ❗️ | |NO❗️ | | └ | _setTerms | Internal 🔒 | 🛑 | | +| └ | _setTermsDocument | Internal 🔒 | 🛑 | | | └ | _setTokenId | Internal 🔒 | 🛑 | | | └ | _setTerms | Internal 🔒 | 🛑 | | | └ | _setInformation | Internal 🔒 | 🛑 | | diff --git a/doc/modules/extensions/documentEngine/document.md b/doc/modules/extensions/documentEngine/document.md index e155d3d4..df48187f 100644 --- a/doc/modules/extensions/documentEngine/document.md +++ b/doc/modules/extensions/documentEngine/document.md @@ -181,6 +181,8 @@ returns (bytes32[] memory documentNames_) Returns the list of all registered document names. +> **Note — unbounded read.** `getAllDocuments()` returns the whole set in a single call, so its cost grows with the number of stored documents. Per the [ERC-1643](../../../ERCSpecification/rework/erc-1643.md) security considerations, this is the only enumeration path and it is **not paginated** — CMTAT deliberately keeps it simple because a token's legal/operational document set is expected to stay **small** (a handful of offering documents, legends, disclosures), not to grow adversarially like a holder list. Deployments that expect a large document set should front it with an off-chain index (subscribe to `DocumentUpdated` / `DocumentRemoved`) rather than relying on a single on-chain read. Contrast with [`HolderListModule`](../../options/holderList/holderList.md), whose set *can* grow via dusting and therefore exposes the paginated `holdersInRange`. + ###### Returns | Name | Type | Description | diff --git a/doc/modules/extensions/documentEngine/surya_report_DocumentERC1643Module.sol.md b/doc/modules/extensions/documentEngine/surya_report_DocumentERC1643Module.sol.md new file mode 100644 index 00000000..470fb99c --- /dev/null +++ b/doc/modules/extensions/documentEngine/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 | 84f36862aa1e5dc107647a0bdf38e7294cefc9ae | + + +### 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/modules/extensions/documentEngine/surya_report_DocumentEngineModule.sol.md b/doc/modules/extensions/documentEngine/surya_report_DocumentEngineModule.sol.md index 85345961..a36edcf7 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/options/DocumentEngineModule.sol | 77cab3ff874781c726f136600388038af94ec5fc | +| ./modules/wrapper/options/DocumentEngineModule.sol | 72ee85e9ef88bd4d62d23bce3e868f94224b2087 | ### 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/modules/extensions/snapshotEngine/surya_report_SnapshotEngineModule.sol.md b/doc/modules/extensions/snapshotEngine/surya_report_SnapshotEngineModule.sol.md index 0c7da3fe..b9a2a478 100644 --- a/doc/modules/extensions/snapshotEngine/surya_report_SnapshotEngineModule.sol.md +++ b/doc/modules/extensions/snapshotEngine/surya_report_SnapshotEngineModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/extensions/SnapshotEngineModule.sol | eeae2885a97fa544564445d1b3e1646ff34a12a4 | +| ./modules/wrapper/extensions/SnapshotEngineModule.sol | 97a00d213b2e9d6122c7197f64a7d0d26f0d9adb | ### Contracts Description Table diff --git a/doc/modules/options/allowlist/surya_report_AllowlistModule.sol.md b/doc/modules/options/allowlist/surya_report_AllowlistModule.sol.md index 8ff71cd9..dd78a375 100644 --- a/doc/modules/options/allowlist/surya_report_AllowlistModule.sol.md +++ b/doc/modules/options/allowlist/surya_report_AllowlistModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/AllowlistModule.sol | 8614cd7c3084cf25cbbdf7d0efcb68473054be2a | +| ./modules/wrapper/options/AllowlistModule.sol | 6f01c8e98ebc3a62e0277de391402a527535568e | ### Contracts Description Table diff --git a/doc/modules/options/allowlist/surya_report_AllowlistModuleInternal.sol.md b/doc/modules/options/allowlist/surya_report_AllowlistModuleInternal.sol.md index 1d7e6535..ec4f8cd2 100644 --- a/doc/modules/options/allowlist/surya_report_AllowlistModuleInternal.sol.md +++ b/doc/modules/options/allowlist/surya_report_AllowlistModuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/AllowlistModuleInternal.sol | [object Promise] | +| ./modules/internal/AllowlistModuleInternal.sol | 6523eb6f8af841eec44a50647bde8bfbb119fc3b | ### Contracts Description Table diff --git a/doc/modules/options/ccip/surya_report_CCIPModule.sol.md b/doc/modules/options/ccip/surya_report_CCIPModule.sol.md index 62df21f4..c81197f0 100644 --- a/doc/modules/options/ccip/surya_report_CCIPModule.sol.md +++ b/doc/modules/options/ccip/surya_report_CCIPModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/CCIPModule.sol | dff8ee247784b7f20c0f4adc8b8ce34b2bc52041 | +| ./modules/wrapper/options/CCIPModule.sol | 00e66042e467db70eae11d2f0be12c3e0f9929a4 | ### Contracts Description Table diff --git a/doc/modules/options/debt/surya_report_DebtModule.sol.md b/doc/modules/options/debt/surya_report_DebtModule.sol.md index dc5f0591..27de5280 100644 --- a/doc/modules/options/debt/surya_report_DebtModule.sol.md +++ b/doc/modules/options/debt/surya_report_DebtModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/DebtModule.sol | 7db3012ecd1c49a9175098811c8bc04e6fc2c8f8 | +| ./modules/wrapper/options/DebtModule.sol | b7cd155d99fc2b0a9cf1b0086993eb5e3bbe9d47 | ### Contracts Description Table diff --git a/doc/modules/options/debtEngine/surya_report_DebtEngineModule.sol.md b/doc/modules/options/debtEngine/surya_report_DebtEngineModule.sol.md index 918185a5..9c093979 100644 --- a/doc/modules/options/debtEngine/surya_report_DebtEngineModule.sol.md +++ b/doc/modules/options/debtEngine/surya_report_DebtEngineModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/DebtEngineModule.sol | 72f42ab1a1c2cb14d8073aa0b126aabb6c8989da | +| ./modules/wrapper/options/DebtEngineModule.sol | bec61266986f0577e064bd1a1c86b11dabf7e988 | ### Contracts Description Table @@ -15,12 +15,14 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **DebtEngineModule** | Implementation | DebtModule ||| -| └ | setDebtEngine | Public ❗️ | 🛑 | onlyDebtManager | +| **DebtEngineModule** | Implementation | IDebtEngineModule ||| +| └ | setDebtEngine | Public ❗️ | 🛑 | onlyDebtEngineManager | | └ | creditEvents | Public ❗️ | |NO❗️ | | └ | debt | Public ❗️ | |NO❗️ | | └ | debtEngine | Public ❗️ | |NO❗️ | | └ | _setDebtEngine | Internal 🔒 | 🛑 | | +| └ | _authorizeDebtEngineManagement | Internal 🔒 | 🛑 | | +| └ | _getDebtEngineModuleStorage | Internal 🔒 | | | ### Legend diff --git a/doc/modules/options/erc20crosschain/ERC20CrossChain.md b/doc/modules/options/erc20crosschain/ERC20CrossChain.md index 42214b0c..9ccea0f1 100644 --- a/doc/modules/options/erc20crosschain/ERC20CrossChain.md +++ b/doc/modules/options/erc20crosschain/ERC20CrossChain.md @@ -2,6 +2,8 @@ This document defines the ERC20CrossChain module for the CMTA Token specification. +> **Pause.** Every entry point in this module — `crosschainMint`, `crosschainBurn`, `burnFrom` and `burn(uint256)` — is blocked while the contract is paused (`EnforcedPause()`). These are **third-party** operations, performed by a bridge or by an operator spending someone else's allowance, and are exactly what a pause is meant to halt: cross-chain settlement must stop rather than keep moving supply between chains against a frozen local state. The **issuer** operations (`ERC20BurnModule.burn` with `BURNER_ROLE`, and minting) are *not* pause-gated. Do not confuse `ERC20CrossChainModule.burn(uint256)` with `ERC20BurnModule.burn(address,uint256)`. See [pause.md](../../core/Pause/pause.md#what-pause-stops-and-what-it-does-not). + [TOC] ## Schema @@ -93,6 +95,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. +- The role is checked against the **raw `msg.sender`**, not `_msgSender()`: the call cannot be relayed through the ERC-2771 forwarder, and `CROSS_CHAIN_ROLE` must never be granted to that forwarder. See [cross-chain-bridge-integration.md](../../../technical/cross-chain-bridge-integration.md#the-bridge-gate-uses-msgsender-not-_msgsender). - Compliance path note (CMTAT base integration): operator (`_msgSender()`) is propagated through transfer-compliance checks for spender-aware RuleEngine restriction support. **Emits:** @@ -130,6 +133,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. +- The role is checked against the **raw `msg.sender`**, not `_msgSender()`: the call cannot be relayed through the ERC-2771 forwarder, and `CROSS_CHAIN_ROLE` must never be granted to that forwarder. See [cross-chain-bridge-integration.md](../../../technical/cross-chain-bridge-integration.md#the-bridge-gate-uses-msgsender-not-_msgsender). - 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/erc20crosschain/surya_report_ERC20CrossChainModule.sol.md b/doc/modules/options/erc20crosschain/surya_report_ERC20CrossChainModule.sol.md index 8c206b79..da5685ce 100644 --- a/doc/modules/options/erc20crosschain/surya_report_ERC20CrossChainModule.sol.md +++ b/doc/modules/options/erc20crosschain/surya_report_ERC20CrossChainModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/ERC20CrossChainModule.sol | 3654e689ccdfd665f819c5fde5b7d607b4d74274 | +| ./modules/wrapper/options/ERC20CrossChainModule.sol | 752065916afd944551da8a9c7727c2e26d95beba | ### Contracts Description Table @@ -19,11 +19,13 @@ | └ | crosschainMint | Public ❗️ | 🛑 | onlyTokenBridge | | └ | crosschainBurn | Public ❗️ | 🛑 | onlyTokenBridge | | └ | burnFrom | Public ❗️ | 🛑 | onlyBurnerFrom | -| └ | burn | Public ❗️ | 🛑 | onlyBurnerFrom | +| └ | burn | Public ❗️ | 🛑 | onlySelfBurn | | └ | supportsInterface | Public ❗️ | |NO❗️ | | └ | _burnFrom | Internal 🔒 | 🛑 | | +| └ | _burnFromOperator | Internal 🔒 | 🛑 | | | └ | _checkTokenBridge | Internal 🔒 | 🛑 | | | └ | _authorizeBurnFrom | Internal 🔒 | 🛑 | | +| └ | _authorizeSelfBurn | Internal 🔒 | 🛑 | | ### Legend diff --git a/doc/modules/options/erc2612/erc2612.md b/doc/modules/options/erc2612/erc2612.md index f61889aa..1e4766cc 100644 --- a/doc/modules/options/erc2612/erc2612.md +++ b/doc/modules/options/erc2612/erc2612.md @@ -23,6 +23,27 @@ Inherits from: - `ERC20PermitUpgradeable` (OpenZeppelin) — ERC-2612 implementation - `MulticallUpgradeable` (OpenZeppelin) — ERC-6357 implementation +## The EIP-712 domain name is fixed at deployment + +The EIP-712 domain used by `permit` is built at initialization from the token name passed to the constructor/initializer. It is stored by OpenZeppelin's `EIP712Upgradeable`, whose documentation states that these parameters *"cannot be changed except through a smart contract upgrade"*. + +`TokenAttributeModule.setName(string)` changes what `name()` returns, but it does **not** touch that stored domain name. After a rename: + +| Call | Value | +|---|---| +| `name()` | the **new** name | +| `eip712Domain().name` (ERC-5267) | the **original** name | +| `DOMAIN_SEPARATOR()` | unchanged | + +**`permit` keeps working.** The domain separator stays stable and valid, so previously issued permits remain redeemable and new ones can still be produced. What changes is only how a signer must discover the domain: + +- ✅ build the EIP-712 domain from **`eip712Domain()`** (ERC-5267), or use `DOMAIN_SEPARATOR()` directly — this is the standard, rename-proof way, and is what modern wallets do; +- ❌ do **not** derive it from `name()`. A signature produced with the post-rename `name()` is rejected on-chain with `ERC2612InvalidSigner`. + +Issuers who intend to use `setName` on a Permit deployment should confirm that their integrators read `eip712Domain()`, since an integration hard-coded to `name()` will start producing invalid signatures at the moment of the rename — silently, until a `permit` call reverts. + +> Reported as NM-21 by [Nethermind AuditAgent](https://auditagent.nethermind.io/) on CMTAT v3.3.0-rc2. The report described this as a permanent denial of service for `permit`; verification showed that is not the case — `permit` continues to work through `eip712Domain()`. See the [maintainer feedback](../../../security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md). + ## Deployment Variants | Contract | Type | diff --git a/doc/modules/options/erc2771/surya_report_ERC2771Module.sol.md b/doc/modules/options/erc2771/surya_report_ERC2771Module.sol.md index 391a0042..d462c6e3 100644 --- a/doc/modules/options/erc2771/surya_report_ERC2771Module.sol.md +++ b/doc/modules/options/erc2771/surya_report_ERC2771Module.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/ERC2771Module.sol | a0ddbfdfe60fae05977d7ad9f2bee93913f7f841 | +| ./modules/wrapper/options/ERC2771Module.sol | be7988b0466b42d06b69e7f6eea2d3e35d56927b | ### Contracts Description Table diff --git a/doc/modules/options/erc7551/surya_report_ERC20EnforcementERC7551Module.sol.md b/doc/modules/options/erc7551/surya_report_ERC20EnforcementERC7551Module.sol.md new file mode 100644 index 00000000..a407f3a9 --- /dev/null +++ b/doc/modules/options/erc7551/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 | 24ba941cb5612435aaf0a4ed48031f603c40130e | + + +### 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/modules/options/erc7551/surya_report_ERC7551Module.sol.md b/doc/modules/options/erc7551/surya_report_ERC7551Module.sol.md index 182c2415..9750fa4f 100644 --- a/doc/modules/options/erc7551/surya_report_ERC7551Module.sol.md +++ b/doc/modules/options/erc7551/surya_report_ERC7551Module.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/ERC7551Module.sol | e6319376a45f18a1b83abf255ba00a838c635203 | +| ./modules/wrapper/options/ERC7551Module.sol | 03453db7ac9a1a9abe415a94ed2a263e5dce285f | ### Contracts Description Table diff --git a/doc/modules/options/holderList/surya_report_HolderListModule.sol.md b/doc/modules/options/holderList/surya_report_HolderListModule.sol.md new file mode 100644 index 00000000..511fb194 --- /dev/null +++ b/doc/modules/options/holderList/surya_report_HolderListModule.sol.md @@ -0,0 +1,33 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./modules/wrapper/options/HolderListModule.sol | 97df6e51036140125e4ec455e5bc31b6f10d7f91 | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **HolderListModule** | Implementation | ERC20Upgradeable, IHolderListModule ||| +| └ | holderCount | Public ❗️ | |NO❗️ | +| └ | isHolder | Public ❗️ | |NO❗️ | +| └ | holderByIndex | Public ❗️ | |NO❗️ | +| └ | holders | Public ❗️ | |NO❗️ | +| └ | holdersInRange | Public ❗️ | |NO❗️ | +| └ | _update | Internal 🔒 | 🛑 | | +| └ | _getHolderListModuleStorage | Private 🔐 | | | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/modules/security/surya_report_AccessControlModule.sol.md b/doc/modules/security/surya_report_AccessControlModule.sol.md index 86555b5f..4fa86d77 100644 --- a/doc/modules/security/surya_report_AccessControlModule.sol.md +++ b/doc/modules/security/surya_report_AccessControlModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/security/AccessControlModule.sol | 001735362957300b5fc4b4aa237e6c1d87e5a66f | +| ./modules/wrapper/security/AccessControlModule.sol | 90ddd8d7f6398ef12fae0b487099fbeff388a2f5 | ### Contracts Description Table diff --git a/doc/schema/drawio/architecture-ERC.drawio.png b/doc/schema/drawio/architecture-ERC.drawio.png index 75a4f05c..47af1907 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/surya_graph/surya_graph_0_CMTATBaseCore.sol.png b/doc/schema/surya_graph/surya_graph_0_CMTATBaseCore.sol.png index f3f40bbb..0df25354 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_CMTATStandaloneERC7551.sol.png b/doc/schema/surya_graph/surya_graph_CMTATStandaloneERC7551.sol.png index e73e0f2e..e70716cc 100644 Binary files a/doc/schema/surya_graph/surya_graph_CMTATStandaloneERC7551.sol.png and b/doc/schema/surya_graph/surya_graph_CMTATStandaloneERC7551.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 index 68c26e7e..ab11e314 100644 Binary files a/doc/schema/surya_graph/surya_graph_CMTATStandaloneSnapshot.sol.png 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 index 58147f94..22eb7a48 100644 Binary files a/doc/schema/surya_graph/surya_graph_CMTATStandardStandalone.sol.png 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 index 50bff74c..80d6c86c 100644 Binary files a/doc/schema/surya_graph/surya_graph_CMTATStandardUpgradeable.sol.png and b/doc/schema/surya_graph/surya_graph_CMTATStandardUpgradeable.sol.png differ diff --git a/doc/schema/surya_graph/surya_graph_CMTATUpgradeableERC7551.sol.png b/doc/schema/surya_graph/surya_graph_CMTATUpgradeableERC7551.sol.png index 161a99d8..49a1a6ae 100644 Binary files a/doc/schema/surya_graph/surya_graph_CMTATUpgradeableERC7551.sol.png and b/doc/schema/surya_graph/surya_graph_CMTATUpgradeableERC7551.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 index 0c0c426f..bf37d0cd 100644 Binary files a/doc/schema/surya_graph/surya_graph_CMTATUpgradeableSnapshot.sol.png and b/doc/schema/surya_graph/surya_graph_CMTATUpgradeableSnapshot.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 88592e39..246f09c8 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_ERC7551Module.sol.png b/doc/schema/surya_graph/surya_graph_ERC7551Module.sol.png index 787e055a..97b1274b 100644 Binary files a/doc/schema/surya_graph/surya_graph_ERC7551Module.sol.png and b/doc/schema/surya_graph/surya_graph_ERC7551Module.sol.png differ diff --git a/doc/schema/surya_graph/surya_graph_ExtraInformationModule.sol.png b/doc/schema/surya_graph/surya_graph_ExtraInformationModule.sol.png index e8a73bff..780fa642 100644 Binary files a/doc/schema/surya_graph/surya_graph_ExtraInformationModule.sol.png and b/doc/schema/surya_graph/surya_graph_ExtraInformationModule.sol.png differ diff --git a/doc/schema/surya_graph/surya_graph_RuleEngineReentrantMock.sol.png b/doc/schema/surya_graph/surya_graph_RuleEngineReentrantMock.sol.png new file mode 100644 index 00000000..cb309c10 Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_RuleEngineReentrantMock.sol.png differ diff --git a/doc/schema/surya_graph/surya_graph_RuleEngineSpenderRecorderMock.sol.png b/doc/schema/surya_graph/surya_graph_RuleEngineSpenderRecorderMock.sol.png new file mode 100644 index 00000000..b3ccfb90 Binary files /dev/null and b/doc/schema/surya_graph/surya_graph_RuleEngineSpenderRecorderMock.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 3134263f..1157ac56 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_inheritance/surya_inheritance_CMTATStandaloneERC7551.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandaloneERC7551.sol.png index bbf761e8..ae9f6c54 100644 Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandaloneERC7551.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandaloneERC7551.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 index 9e1aad97..86f4a280 100644 Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandaloneSnapshot.sol.png 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 index 94c37a4f..4adaca4a 100644 Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardStandalone.sol.png 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 index a34d5a5e..6a18ccab 100644 Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardUpgradeable.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_CMTATStandardUpgradeable.sol.png differ diff --git a/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableERC7551.sol.png b/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableERC7551.sol.png index 0d715a60..73ec94fd 100644 Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableERC7551.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableERC7551.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 index c99b7e1f..48a985fc 100644 Binary files a/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableSnapshot.sol.png and b/doc/schema/surya_inheritance/surya_inheritance_CMTATUpgradeableSnapshot.sol.png differ diff --git a/doc/schema/surya_inheritance/surya_inheritance_RuleEngineReentrantMock.sol.png b/doc/schema/surya_inheritance/surya_inheritance_RuleEngineReentrantMock.sol.png new file mode 100644 index 00000000..c468f992 Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_RuleEngineReentrantMock.sol.png differ diff --git a/doc/schema/surya_inheritance/surya_inheritance_RuleEngineSpenderRecorderMock.sol.png b/doc/schema/surya_inheritance/surya_inheritance_RuleEngineSpenderRecorderMock.sol.png new file mode 100644 index 00000000..90e099f2 Binary files /dev/null and b/doc/schema/surya_inheritance/surya_inheritance_RuleEngineSpenderRecorderMock.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 5dee03f4..5e094801 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 | 42637a819a21ccc0ea61a9271932d5b33ef5d6c7 | +| ./modules/0_CMTATBaseCommon.sol | 5bbfcbc4e3092ac28333b1f88f636f3c61c6a7e1 | ### Contracts Description Table 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 6c5eb516..2eda81ee 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 | 3255749e5d23f8ce97bb9626458079dd2e885e96 | +| ./modules/0_CMTATBaseCore.sol | 5175bf496cd97791fe58958ccea9d528392b1ff6 | ### Contracts Description Table 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 2484b42a..d8459939 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 | 2db1ecb2c69ee4f60e17917ff565907e44da1daf | +| ./modules/0_CMTATBaseGeneric.sol | a2fc064f435c335de3bfa8482e98a944137a3e6c | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md b/doc/schema/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md index 0819ad75..ef1474bd 100644 --- a/doc/schema/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md +++ b/doc/schema/surya_report/surya_report_0_CMTATBaseSnapshot.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/0_CMTATBaseSnapshot.sol | a6d54586c8a7ed63bffceed0c7bd1abe35b5e5cd | +| ./modules/0_CMTATBaseSnapshot.sol | 7f77126b42cceca9ffefa9feed64610ab7f33f46 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_1_CMTATBaseDocument.sol.md b/doc/schema/surya_report/surya_report_1_CMTATBaseDocument.sol.md index d85f71c1..ac34eb78 100644 --- a/doc/schema/surya_report/surya_report_1_CMTATBaseDocument.sol.md +++ b/doc/schema/surya_report/surya_report_1_CMTATBaseDocument.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/1_CMTATBaseDocument.sol | 6d9a534014f54d5736d99d1dc3f7e6d4ba7cb93d | +| ./modules/1_CMTATBaseDocument.sol | 05e7e58efdd455636fcc06c7e89767f7ac70f4d4 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md b/doc/schema/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md index ab49ea62..a35ab136 100644 --- a/doc/schema/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md +++ b/doc/schema/surya_report/surya_report_2_CMTATBaseAccessControl.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/2_CMTATBaseAccessControl.sol | dc5874915bc739805ecc0b5e08268c95c8d3ec65 | +| ./modules/2_CMTATBaseAccessControl.sol | 342ba68721bc4c4642a4c29b8dc7aad79051ab65 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md b/doc/schema/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md index afe6dfb4..7f814860 100644 --- a/doc/schema/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md +++ b/doc/schema/surya_report/surya_report_3_CMTATBaseAllowlist.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/3_CMTATBaseAllowlist.sol | 72f3e67b6186b5008f3a6dcf5cabe0e544c8eda9 | +| ./modules/3_CMTATBaseAllowlist.sol | 3487697f10471c48fbbf710c669b2c2a13e738a3 | ### Contracts Description Table @@ -20,7 +20,7 @@ | └ | __CMTAT_init | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | -| └ | approve | Public ❗️ | 🛑 | whenNotPaused | +| └ | approve | Public ❗️ | 🛑 |NO❗️ | | └ | transfer | Public ❗️ | 🛑 |NO❗️ | | └ | transferFrom | Public ❗️ | 🛑 |NO❗️ | | └ | decimals | Public ❗️ | |NO❗️ | diff --git a/doc/schema/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md b/doc/schema/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md index 24c26360..c0d10ed1 100644 --- a/doc/schema/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md +++ b/doc/schema/surya_report/surya_report_3_CMTATBaseRuleEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/3_CMTATBaseRuleEngine.sol | 44eb458e3b333897b5f0ef0c82be9a2a5a010403 | +| ./modules/3_CMTATBaseRuleEngine.sol | ce5163631ffba07ac7fab7614890c80ab5117265 | ### Contracts Description Table @@ -22,7 +22,7 @@ | └ | __CMTAT_openzeppelin_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_internal_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | | └ | __CMTAT_modules_init_unchained | Internal 🔒 | 🛑 | onlyInitializing | -| └ | approve | Public ❗️ | 🛑 | whenNotPaused | +| └ | approve | Public ❗️ | 🛑 |NO❗️ | | └ | 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 index 8f161dd7..d015a2c2 100644 --- a/doc/schema/surya_report/surya_report_4_CMTATBaseDebt.sol.md +++ b/doc/schema/surya_report/surya_report_4_CMTATBaseDebt.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/4_CMTATBaseDebt.sol | 593ad8bf57d7bbd52a5ee426a3e0f11d2e2d49c6 | +| ./modules/4_CMTATBaseDebt.sol | b9b2ee6c62a35ed60737592cb48fa8b921bebc4d | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_4_CMTATBaseERC1404.sol.md b/doc/schema/surya_report/surya_report_4_CMTATBaseERC1404.sol.md index e1ef6b75..8594a2ea 100644 --- a/doc/schema/surya_report/surya_report_4_CMTATBaseERC1404.sol.md +++ b/doc/schema/surya_report/surya_report_4_CMTATBaseERC1404.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/4_CMTATBaseERC1404.sol | 278cb9aa6c4641fa241682be24ffbfb1244e9875 | +| ./modules/4_CMTATBaseERC1404.sol | 1fd06a9f2ab7cb87189be2eeaf6e9c5aa772d56d | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md b/doc/schema/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md index a2363a38..478c55ec 100644 --- a/doc/schema/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md +++ b/doc/schema/surya_report/surya_report_5_CMTATBaseERC20CrossChain.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/5_CMTATBaseERC20CrossChain.sol | adfb29de086e5b1045a9de445282d66b6589978d | +| ./modules/5_CMTATBaseERC20CrossChain.sol | 8004dee72cddd763301d2ebc042807edecb06e5e | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md b/doc/schema/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md index 0ad6c074..61b2837a 100644 --- a/doc/schema/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md +++ b/doc/schema/surya_report/surya_report_6_CMTATBaseDebtEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/6_CMTATBaseDebtEngine.sol | bfeb152012d9b39da44296cc36fa90eb0f2b8035 | +| ./modules/6_CMTATBaseDebtEngine.sol | a80e3040a1f615e3edc947bbd3fadbaf21c1e0a1 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_6_CMTATBaseERC2612.sol.md b/doc/schema/surya_report/surya_report_6_CMTATBaseERC2612.sol.md index 40407e09..c422e7cf 100644 --- a/doc/schema/surya_report/surya_report_6_CMTATBaseERC2612.sol.md +++ b/doc/schema/surya_report/surya_report_6_CMTATBaseERC2612.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/6_CMTATBaseERC2612.sol | d86652c7dd990cfbc47f2f2e48a009f8b77f1b9a | +| ./modules/6_CMTATBaseERC2612.sol | 6f2700d7564f507e8abc9c0f2d13c78d4e4d59ef | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_6_CMTATBaseERC2771.sol.md b/doc/schema/surya_report/surya_report_6_CMTATBaseERC2771.sol.md index a849f177..ec1a2e6d 100644 --- a/doc/schema/surya_report/surya_report_6_CMTATBaseERC2771.sol.md +++ b/doc/schema/surya_report/surya_report_6_CMTATBaseERC2771.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/6_CMTATBaseERC2771.sol | 9425bb8460780c41a4d4bee640ced7c26348f854 | +| ./modules/6_CMTATBaseERC2771.sol | 81c99fb86abb86942bce5f7e3dea00826876563f | ### 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 index b0b2ff7d..50e696fc 100644 --- a/doc/schema/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md +++ b/doc/schema/surya_report/surya_report_7_CMTATBaseERC2771Snapshot.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/7_CMTATBaseERC2771Snapshot.sol | 73abac918adab1aa31671e98a0cecb7e6435cd73 | +| ./modules/7_CMTATBaseERC2771Snapshot.sol | fce93c13e6e7fa1fc69606fc3d3f75fdb8da7e92 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md b/doc/schema/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md index cebd5a77..eb7af44c 100644 --- a/doc/schema/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md +++ b/doc/schema/surya_report/surya_report_7_CMTATBaseERC7551Enforcement.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/7_CMTATBaseERC7551Enforcement.sol | 56d471f72113e2f281ea95c65ff066fd8bd44f7c | +| ./modules/7_CMTATBaseERC7551Enforcement.sol | e54d709ba1f4a1d073b6e0cdd22b1f18c6f09783 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_8_CMTATBaseERC1363.sol.md b/doc/schema/surya_report/surya_report_8_CMTATBaseERC1363.sol.md index 37bdb2af..867605bb 100644 --- a/doc/schema/surya_report/surya_report_8_CMTATBaseERC1363.sol.md +++ b/doc/schema/surya_report/surya_report_8_CMTATBaseERC1363.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/8_CMTATBaseERC1363.sol | 015a6f8872f39bdf9d376bf1c1d589971ceb38d4 | +| ./modules/8_CMTATBaseERC1363.sol | 81c904f794b94bd087c24f409493b6c9e314dd70 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_8_CMTATBaseERC7551.sol.md b/doc/schema/surya_report/surya_report_8_CMTATBaseERC7551.sol.md index 83be16aa..8bebeeb0 100644 --- a/doc/schema/surya_report/surya_report_8_CMTATBaseERC7551.sol.md +++ b/doc/schema/surya_report/surya_report_8_CMTATBaseERC7551.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/8_CMTATBaseERC7551.sol | ea759e98774152ca4f29fcd2b45e77f401fc6103 | +| ./modules/8_CMTATBaseERC7551.sol | bac70e22260955923825317771a6453ca1654a62 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_8_CMTATBaseHolderList.sol.md b/doc/schema/surya_report/surya_report_8_CMTATBaseHolderList.sol.md index 97b5947c..be91b2c1 100644 --- a/doc/schema/surya_report/surya_report_8_CMTATBaseHolderList.sol.md +++ b/doc/schema/surya_report/surya_report_8_CMTATBaseHolderList.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/8_CMTATBaseHolderList.sol | 1c1e81ca1d0dac5bb705b868de775d47085f2310 | +| ./modules/8_CMTATBaseHolderList.sol | fde61227a31826dc6f4014f5ffa9525335ff872d | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_AccessControlModule.sol.md b/doc/schema/surya_report/surya_report_AccessControlModule.sol.md index 1f612f3f..4fa86d77 100644 --- a/doc/schema/surya_report/surya_report_AccessControlModule.sol.md +++ b/doc/schema/surya_report/surya_report_AccessControlModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/security/AccessControlModule.sol | 3de7a7a81a8d30b0bf6758907d4bd9683c12b25b | +| ./modules/wrapper/security/AccessControlModule.sol | 90ddd8d7f6398ef12fae0b487099fbeff388a2f5 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_AllowlistModule.sol.md b/doc/schema/surya_report/surya_report_AllowlistModule.sol.md index 8ff71cd9..dd78a375 100644 --- a/doc/schema/surya_report/surya_report_AllowlistModule.sol.md +++ b/doc/schema/surya_report/surya_report_AllowlistModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/AllowlistModule.sol | 8614cd7c3084cf25cbbdf7d0efcb68473054be2a | +| ./modules/wrapper/options/AllowlistModule.sol | 6f01c8e98ebc3a62e0277de391402a527535568e | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_AllowlistModuleInternal.sol.md b/doc/schema/surya_report/surya_report_AllowlistModuleInternal.sol.md index 153b290f..ec4f8cd2 100644 --- a/doc/schema/surya_report/surya_report_AllowlistModuleInternal.sol.md +++ b/doc/schema/surya_report/surya_report_AllowlistModuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/AllowlistModuleInternal.sol | 64f068f347ac3683f4b30db6a54b34f1ad9f92db | +| ./modules/internal/AllowlistModuleInternal.sol | 6523eb6f8af841eec44a50647bde8bfbb119fc3b | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CCIPModule.sol.md b/doc/schema/surya_report/surya_report_CCIPModule.sol.md index 6c1bec45..c81197f0 100644 --- a/doc/schema/surya_report/surya_report_CCIPModule.sol.md +++ b/doc/schema/surya_report/surya_report_CCIPModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/CCIPModule.sol | c96f695b0715fce5538393cf8bedec6ef4032a22 | +| ./modules/wrapper/options/CCIPModule.sol | 00e66042e467db70eae11d2f0be12c3e0f9929a4 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTATDocumentEngineModuleMock.sol.md b/doc/schema/surya_report/surya_report_CMTATDocumentEngineModuleMock.sol.md index 178518f1..c72336ea 100644 --- a/doc/schema/surya_report/surya_report_CMTATDocumentEngineModuleMock.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATDocumentEngineModuleMock.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/engine/CMTATDocumentEngineModuleMock.sol | 52445c55b4497faea85babb3350bd727c82b8aad | +| ./mocks/engine/CMTATDocumentEngineModuleMock.sol | 30c3746891073a51e89fa7106beb4d4cd5378eda | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTATEngineInitializerMock.sol.md b/doc/schema/surya_report/surya_report_CMTATEngineInitializerMock.sol.md index c290d9cb..34b6a233 100644 --- a/doc/schema/surya_report/surya_report_CMTATEngineInitializerMock.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATEngineInitializerMock.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/engine/CMTATEngineInitializerMock.sol | 639fe248933ed4fb1320877a2ba2115ea7acc60f | +| ./mocks/engine/CMTATEngineInitializerMock.sol | 941044777a8681c3fe59b740a1b23fe01fab79bf | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTATMsgDataMock.sol.md b/doc/schema/surya_report/surya_report_CMTATMsgDataMock.sol.md index 8ec23090..8af999a0 100644 --- a/doc/schema/surya_report/surya_report_CMTATMsgDataMock.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATMsgDataMock.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/CMTATMsgDataMock.sol | 717bd7b3aaa6b7b348909cefaca7a40bbb75e8aa | +| ./mocks/CMTATMsgDataMock.sol | 5c30a05a18b10859647fbdb893eea8e9fcd5b0ba | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneAllowlist.sol.md index d8fc0e26..3c90e6d7 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 | 000d2492d7f98743d07400bae05416775c523983 | +| ./deployment/allowlist/CMTATStandaloneAllowlist.sol | 7f3e42d63903a2b02a517bb566689d40c89ef7e3 | ### 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 75277907..42f3df88 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 | 6db99ab4a6a7860599b98ddd846d146c22c152c3 | +| ./deployment/debt/CMTATStandaloneDebt.sol | 572f2e447323872a7feb04d9b98462b40a56887b | ### 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 b1224101..2551bc3c 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 | 6c6b93452585c9f3e0b49aac84a48a29d50aeb88 | +| ./deployment/debtEngine/CMTATStandaloneDebtEngine.sol | 3f687657c5956ce1a09c8377e965ee042ee24834 | ### 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 74acac5d..4ca7026e 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 | da970ccf28dcced367bc90c3f85e03075d8fffe3 | +| ./deployment/ERC1363/CMTATStandaloneERC1363.sol | 6184f6bf554dd1b05e8761161a061f0dd1e0c548 | ### 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 79f44e2c..20178687 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 | 1b120e793a8075832b795935ed212914d5a42ac8 | +| ./deployment/ERC7551/CMTATStandaloneERC7551.sol | 5008986183befbd4fce45ad00aa5c34984977e61 | ### Contracts Description Table @@ -15,8 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATStandaloneERC7551** | Implementation | CMTATBaseERC7551 ||| +| **CMTATStandaloneERC7551** | Implementation | CMTATBaseERC7551, ReentrancyGuardTransient ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | ### Legend diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneHolderList.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneHolderList.sol.md index e8ab527a..b2488eb8 100644 --- a/doc/schema/surya_report/surya_report_CMTATStandaloneHolderList.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATStandaloneHolderList.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/holderList/CMTATStandaloneHolderList.sol | dfa04371472582cc0ad0d29f93094cebd48517a6 | +| ./deployment/holderList/CMTATStandaloneHolderList.sol | 87873906f3e506fde4f7cc71f4e03d34e6e2abed | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneLight.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneLight.sol.md index 177ba6a5..f2afffe9 100644 --- a/doc/schema/surya_report/surya_report_CMTATStandaloneLight.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATStandaloneLight.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/light/CMTATStandaloneLight.sol | c10b99c33e2f75b98de264ae5e04827b04be6f10 | +| ./deployment/light/CMTATStandaloneLight.sol | 9bb95cd250c6d74f82119bae8c1ff10d13e807d5 | ### 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 index d58ec67d..5e5f8230 100644 --- a/doc/schema/surya_report/surya_report_CMTATStandalonePermit.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATStandalonePermit.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/permit/CMTATStandalonePermit.sol | bd2f7108a6c38f4782ced0ac404679b25068343c | +| ./deployment/permit/CMTATStandalonePermit.sol | 267828a4702d26a0e0129f9e94f7a133a4d5e924 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md b/doc/schema/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md index 6b71f591..5d09baed 100644 --- a/doc/schema/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATStandaloneSnapshot.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/snapshot/CMTATStandaloneSnapshot.sol | 5a2b56bc133d7119e798781364a809c2b600e933 | +| ./deployment/snapshot/CMTATStandaloneSnapshot.sol | 09f8a4b84e23532342765692dccd4f8f409ee0e3 | ### Contracts Description Table @@ -15,8 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATStandaloneSnapshot** | Implementation | CMTATBaseERC2771Snapshot ||| +| **CMTATStandaloneSnapshot** | Implementation | CMTATBaseERC2771Snapshot, ReentrancyGuardTransient ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | ### Legend diff --git a/doc/schema/surya_report/surya_report_CMTATStandardStandalone.sol.md b/doc/schema/surya_report/surya_report_CMTATStandardStandalone.sol.md index 644ac46c..283d0ae6 100644 --- a/doc/schema/surya_report/surya_report_CMTATStandardStandalone.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATStandardStandalone.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/CMTATStandardStandalone.sol | 5bfd01883b5b2efb0304c154db283d25d1897e2c | +| ./deployment/CMTATStandardStandalone.sol | 0ef9dcd77454b756d96296db37186204a7b1f07c | ### Contracts Description Table @@ -15,8 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATStandardStandalone** | Implementation | CMTATBaseERC7551Enforcement ||| +| **CMTATStandardStandalone** | Implementation | CMTATBaseERC7551Enforcement, ReentrancyGuardTransient ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | ### Legend diff --git a/doc/schema/surya_report/surya_report_CMTATStandardUpgradeable.sol.md b/doc/schema/surya_report/surya_report_CMTATStandardUpgradeable.sol.md index 80d675ad..367a040e 100644 --- a/doc/schema/surya_report/surya_report_CMTATStandardUpgradeable.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATStandardUpgradeable.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/CMTATStandardUpgradeable.sol | 111c634b1adf563c6c1462c96c5129e0df16a7f2 | +| ./deployment/CMTATStandardUpgradeable.sol | 2c4b32a3f9d827707e457bd640e0fa3d6d92397e | ### Contracts Description Table @@ -15,8 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATStandardUpgradeable** | Implementation | CMTATBaseERC7551Enforcement ||| +| **CMTATStandardUpgradeable** | Implementation | CMTATBaseERC7551Enforcement, ReentrancyGuardTransient ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | ### Legend diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableAllowlist.sol.md index 15a38759..a19dc4a1 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 | 937c915adc27f04d34800d12c6800b73ac10bcf9 | +| ./deployment/allowlist/CMTATUpgradeableAllowlist.sol | 3c5a5ee74c158744094f7b55e186f0b347bb16dc | ### 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 4df01a28..d06eb430 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 | 38a5a244bd6afb659810b50f39c78d7ea7df9dfc | +| ./deployment/debt/CMTATUpgradeableDebt.sol | 585643670c531d434c7a58323f978993a1a309a6 | ### 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 ee2a0b17..0193c3a5 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 | 4542e03ae84802efbe35a991f883df818ff711da | +| ./deployment/debtEngine/CMTATUpgradeableDebtEngine.sol | 8d719c0a5922d1257f64b858640ae7d5b3499baa | ### 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 3ec619d2..b7d09be5 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 | b5222a85340412d060e6eb8571b9c88fd22d6302 | +| ./deployment/ERC1363/CMTATUpgradeableERC1363.sol | d19d1ca2439e20c50a8b1228af60095aa8e68d77 | ### 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 f0f30506..91d22f56 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 | cd3cc4dcb7a8332128bc4efe1de76a5a3b627dd0 | +| ./deployment/ERC7551/CMTATUpgradeableERC7551.sol | 58b04fd3b37fc71e0493930a1759e2420c861416 | ### Contracts Description Table @@ -15,8 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATUpgradeableERC7551** | Implementation | CMTATBaseERC7551 ||| +| **CMTATUpgradeableERC7551** | Implementation | CMTATBaseERC7551, ReentrancyGuardTransient ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | ### Legend diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableHolderList.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableHolderList.sol.md index 63398c1b..c19fa224 100644 --- a/doc/schema/surya_report/surya_report_CMTATUpgradeableHolderList.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableHolderList.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/holderList/CMTATUpgradeableHolderList.sol | 3d8b815e3defe2547b1c24689ffd995cb7623c72 | +| ./deployment/holderList/CMTATUpgradeableHolderList.sol | 99ce545dfee7a132d7f1046b54feb59c986bcf84 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableLight.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableLight.sol.md index ff987aaf..6ebb553c 100644 --- a/doc/schema/surya_report/surya_report_CMTATUpgradeableLight.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableLight.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/light/CMTATUpgradeableLight.sol | 7655b0f507c280139447798831f192c1fe9ce6cf | +| ./deployment/light/CMTATUpgradeableLight.sol | b2bc9fae0c0180f11d4c66de98f16a935a97cad3 | ### 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 index e2e826bb..4f23f0a5 100644 --- a/doc/schema/surya_report/surya_report_CMTATUpgradeablePermit.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATUpgradeablePermit.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/permit/CMTATUpgradeablePermit.sol | 875f318122e65ed6ec8bbf8fd6ec510582c56c8b | +| ./deployment/permit/CMTATUpgradeablePermit.sol | a51863f9d3c009bae52e18112f8f946e29bcb439 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md index d9b44a82..23aff77f 100644 --- a/doc/schema/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md +++ b/doc/schema/surya_report/surya_report_CMTATUpgradeableSnapshot.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./deployment/snapshot/CMTATUpgradeableSnapshot.sol | d8fb75c0bdcf0cd6a53750b0ce9f6261b8c9b3da | +| ./deployment/snapshot/CMTATUpgradeableSnapshot.sol | 251976b5ca73cdb4ab92f8b825529b3879a33182 | ### Contracts Description Table @@ -15,8 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **CMTATUpgradeableSnapshot** | Implementation | CMTATBaseERC2771Snapshot ||| +| **CMTATUpgradeableSnapshot** | Implementation | CMTATBaseERC2771Snapshot, ReentrancyGuardTransient ||| | └ | | Public ❗️ | 🛑 | ERC2771Module | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | nonReentrant | ### Legend diff --git a/doc/schema/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md b/doc/schema/surya_report/surya_report_CMTATUpgradeableUUPS.sol.md index b644ef85..aadbd8cd 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 | b433edf187002f7d33efde3419c07c0b32a101a8 | +| ./deployment/CMTATUpgradeableUUPS.sol | c566d51d7c5611ac9928a45f9c32b1edc93ed9a0 | ### 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 421d8472..0d2d6734 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 | 75c01c5597d04bc00863a78c109d878cadca89e6 | +| ./mocks/test/proxy/CMTAT_PROXY_TEST.sol | d086dfc659deb9121a6e90b0358124a2c4b83576 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CMTAT_PROXY_TEST_UUPS.sol.md b/doc/schema/surya_report/surya_report_CMTAT_PROXY_TEST_UUPS.sol.md index 813761ed..941b3176 100644 --- a/doc/schema/surya_report/surya_report_CMTAT_PROXY_TEST_UUPS.sol.md +++ b/doc/schema/surya_report/surya_report_CMTAT_PROXY_TEST_UUPS.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/test/proxy/CMTAT_PROXY_TEST_UUPS.sol | fa06f4d41e8ad377639707a7a4b847fc6df53d38 | +| ./mocks/test/proxy/CMTAT_PROXY_TEST_UUPS.sol | b02eb37f977c66ac9667e6910ac535ddaf0267a7 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_CodeList.sol.md b/doc/schema/surya_report/surya_report_CodeList.sol.md index 5258978a..55d79f0d 100644 --- a/doc/schema/surya_report/surya_report_CodeList.sol.md +++ b/doc/schema/surya_report/surya_report_CodeList.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/RuleEngine/CodeList.sol | 582629e0a4c7a608fe082ccefe2d4271d34df1a0 | +| ./mocks/RuleEngine/CodeList.sol | afeef80d013a6e6a36f027a664a8c28df76a8e5b | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_DebtEngineMock.sol.md b/doc/schema/surya_report/surya_report_DebtEngineMock.sol.md index 060bb0b0..d6fc8805 100644 --- a/doc/schema/surya_report/surya_report_DebtEngineMock.sol.md +++ b/doc/schema/surya_report/surya_report_DebtEngineMock.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/DebtEngineMock.sol | a8bacdee9b87f32ec0ffefbada5c953e657668cb | +| ./mocks/DebtEngineMock.sol | e778516332519b3ae3b014b609bc6ecbb2f7f38c | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_DebtEngineModule.sol.md b/doc/schema/surya_report/surya_report_DebtEngineModule.sol.md index b08d9bae..9c093979 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 | 29a73703471628d0643a7ef88501bac44608562d | +| ./modules/wrapper/options/DebtEngineModule.sol | bec61266986f0577e064bd1a1c86b11dabf7e988 | ### 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 35f3efc3..27de5280 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 | 9736762f32486a96d64571276dfc4f727815ade0 | +| ./modules/wrapper/options/DebtModule.sol | b7cd155d99fc2b0a9cf1b0086993eb5e3bbe9d47 | ### 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 index 1f9a9479..470fb99c 100644 --- a/doc/schema/surya_report/surya_report_DocumentERC1643Module.sol.md +++ b/doc/schema/surya_report/surya_report_DocumentERC1643Module.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/extensions/DocumentERC1643Module.sol | 2de2e9da4f8be54bc9615462315116478b1c3066 | +| ./modules/wrapper/extensions/DocumentERC1643Module.sol | 84f36862aa1e5dc107647a0bdf38e7294cefc9ae | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_DocumentEngineMock.sol.md b/doc/schema/surya_report/surya_report_DocumentEngineMock.sol.md index 3d5d34c6..14251988 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 | 308ebbbc8d9070b4c36545a0976d093fc0261cb8 | +| ./mocks/DocumentEngineMock.sol | e94d2d3c8843db8928932c575700debcc9381900 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_DocumentEngineModule.sol.md b/doc/schema/surya_report/surya_report_DocumentEngineModule.sol.md index c11415d8..a36edcf7 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/options/DocumentEngineModule.sol | b2cf06a20a3b044efab8bef9ce4d327e5356c2cf | +| ./modules/wrapper/options/DocumentEngineModule.sol | 72ee85e9ef88bd4d62d23bce3e868f94224b2087 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC1363ReceiverMock.sol.md b/doc/schema/surya_report/surya_report_ERC1363ReceiverMock.sol.md index 97f51bc8..60bc0f39 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 | d1f84a7ad0898829c31a52d18c9420908974311e | +| ./mocks/ERC1363ReceiverMock.sol | cc0f132134a8eab593692490896d43db0b14a551 | ### 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 index 8aa329ff..2c075f57 100644 --- a/doc/schema/surya_report/surya_report_ERC1404ExtendInterfaceId.sol.md +++ b/doc/schema/surya_report/surya_report_ERC1404ExtendInterfaceId.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./library/ERC1404ExtendInterfaceId.sol | d800730a47d9f56318fd0345826318a533448308 | +| ./library/ERC1404ExtendInterfaceId.sol | a2f9b997e784e3d0fe65d252020d4250b24d5813 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC20BaseModule.sol.md b/doc/schema/surya_report/surya_report_ERC20BaseModule.sol.md index 21bc1588..8424a02d 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 | d375266f5e0cbdf31228fd1673a968c4ba464be9 | +| ./modules/wrapper/core/ERC20BaseModule.sol | f6269c10a2defbf54e77ef0032c7534af70ed869 | ### 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 e41506f3..61b2c31c 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 | 557e0b6654ac5f5d442c5186672fbb5cbd03849b | +| ./modules/wrapper/core/ERC20BurnModule.sol | 3f109e92e878e64dd13b17eb9c385c19a7c4a3e6 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC20BurnModuleInternal.sol.md b/doc/schema/surya_report/surya_report_ERC20BurnModuleInternal.sol.md index 236caeb1..6821bc46 100644 --- a/doc/schema/surya_report/surya_report_ERC20BurnModuleInternal.sol.md +++ b/doc/schema/surya_report/surya_report_ERC20BurnModuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/ERC20BurnModuleInternal.sol | b52c5e0870d5f5365b99048f2b81443c21feb52b | +| ./modules/internal/ERC20BurnModuleInternal.sol | 6e7e3e3f2e88f75be2a881adf1fa10db6b236b52 | ### 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 9597fc8c..da5685ce 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 | 6c08dc2d19539886ef2dce29828dda6393da3af0 | +| ./modules/wrapper/options/ERC20CrossChainModule.sol | 752065916afd944551da8a9c7727c2e26d95beba | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC20EnforcementERC7551Module.sol.md b/doc/schema/surya_report/surya_report_ERC20EnforcementERC7551Module.sol.md index 17b5e492..a407f3a9 100644 --- a/doc/schema/surya_report/surya_report_ERC20EnforcementERC7551Module.sol.md +++ b/doc/schema/surya_report/surya_report_ERC20EnforcementERC7551Module.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/ERC20EnforcementERC7551Module.sol | 8cb73e41161a89d4d8d4e95547ac9fce6c84cbaa | +| ./modules/wrapper/options/ERC20EnforcementERC7551Module.sol | 24ba941cb5612435aaf0a4ed48031f603c40130e | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC20EnforcementModule.sol.md b/doc/schema/surya_report/surya_report_ERC20EnforcementModule.sol.md index 540464ad..1802697d 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 | 289591feebe8af7feae0d3382c4e6af23aa951a7 | +| ./modules/wrapper/extensions/ERC20EnforcementModule.sol | f810a3b307c9623245b3fffbe4efb285aa7a08a9 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC20EnforcementModuleInternal.sol.md b/doc/schema/surya_report/surya_report_ERC20EnforcementModuleInternal.sol.md index e8185e0f..119e85b1 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 | 59e7b7d59c34eb71b1db49c32f23c6610d30f803 | +| ./modules/internal/ERC20EnforcementModuleInternal.sol | dfa832cbbd323852a82a39ff84fa6e962086631f | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC20MintModule.sol.md b/doc/schema/surya_report/surya_report_ERC20MintModule.sol.md index 4b2f67d7..efe19b42 100644 --- a/doc/schema/surya_report/surya_report_ERC20MintModule.sol.md +++ b/doc/schema/surya_report/surya_report_ERC20MintModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/ERC20MintModule.sol | e3290fff19ef1b4b1ea4169f84c401624392deac | +| ./modules/wrapper/core/ERC20MintModule.sol | c9b01932ec4ecb147f0e2ac00324480e9a40a23b | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC20MintModuleInternal.sol.md b/doc/schema/surya_report/surya_report_ERC20MintModuleInternal.sol.md index adebcfe1..697dd55a 100644 --- a/doc/schema/surya_report/surya_report_ERC20MintModuleInternal.sol.md +++ b/doc/schema/surya_report/surya_report_ERC20MintModuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/ERC20MintModuleInternal.sol | 716930d665c8e5189385e1384e4435412d42b95f | +| ./modules/internal/ERC20MintModuleInternal.sol | 41b2893fb24992819dada2a0eab305e5b0e0efd1 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC2771Module.sol.md b/doc/schema/surya_report/surya_report_ERC2771Module.sol.md index 391a0042..d462c6e3 100644 --- a/doc/schema/surya_report/surya_report_ERC2771Module.sol.md +++ b/doc/schema/surya_report/surya_report_ERC2771Module.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/ERC2771Module.sol | a0ddbfdfe60fae05977d7ad9f2bee93913f7f841 | +| ./modules/wrapper/options/ERC2771Module.sol | be7988b0466b42d06b69e7f6eea2d3e35d56927b | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ERC721MockUpgradeable.sol.md b/doc/schema/surya_report/surya_report_ERC721MockUpgradeable.sol.md index e6a22128..d43cf4d4 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 | d83ab7d6f2e934f059007b1e4e5a462e139a0ac7 | +| ./mocks/ERC721MockUpgradeable.sol | 2c79ed9fd517cbb4b0b426ad7c0d19efa573d45c | ### 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 33f87f62..9750fa4f 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 | 830414e8ca73ac810caaf673b11e738b825559d4 | +| ./modules/wrapper/options/ERC7551Module.sol | 03453db7ac9a1a9abe415a94ed2a263e5dce285f | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_EnforcementModule.sol.md b/doc/schema/surya_report/surya_report_EnforcementModule.sol.md index 4fccf682..e9876622 100644 --- a/doc/schema/surya_report/surya_report_EnforcementModule.sol.md +++ b/doc/schema/surya_report/surya_report_EnforcementModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/EnforcementModule.sol | ffea175fbf940073568bf4414dceefcd5bdefed8 | +| ./modules/wrapper/core/EnforcementModule.sol | 4d80a37d5b8f4b1c675f237e0863cb5dc4cd9c3d | ### 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 7f1f25a0..18ac7aed 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 | 253e39ce4835aea3feeb357a6710bbbb160c9f22 | +| ./modules/internal/EnforcementModuleInternal.sol | e4f8ad6066ed208d03ee4f98168801e6ef9dd55b | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_EnforcementModuleLibrary.sol.md b/doc/schema/surya_report/surya_report_EnforcementModuleLibrary.sol.md index 62cb5026..22e283cf 100644 --- a/doc/schema/surya_report/surya_report_EnforcementModuleLibrary.sol.md +++ b/doc/schema/surya_report/surya_report_EnforcementModuleLibrary.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/common/EnforcementModuleLibrary.sol | a08da9133886b19a1e792fb69cbd9d6b756db66e | +| ./modules/internal/common/EnforcementModuleLibrary.sol | b50ff90499b0589e826dc827592c1955e761ae78 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ExampleAccessControlERC165.sol.md b/doc/schema/surya_report/surya_report_ExampleAccessControlERC165.sol.md index a6b8b40c..17803cb8 100644 --- a/doc/schema/surya_report/surya_report_ExampleAccessControlERC165.sol.md +++ b/doc/schema/surya_report/surya_report_ExampleAccessControlERC165.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/ERC165Helper/ExampleAccessControlERC165.sol | cab1f8b4a5c82914e99ac2253be4ea21ef5c01d3 | +| ./mocks/ERC165Helper/ExampleAccessControlERC165.sol | a3fcdee5274f988167dcca74d6b6e19baa4d8a4d | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ExampleERC1404ExtendERC165.sol.md b/doc/schema/surya_report/surya_report_ExampleERC1404ExtendERC165.sol.md index cee384e6..270ed98e 100644 --- a/doc/schema/surya_report/surya_report_ExampleERC1404ExtendERC165.sol.md +++ b/doc/schema/surya_report/surya_report_ExampleERC1404ExtendERC165.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/ERC165Helper/ExampleERC1404ExtendERC165.sol | d35271c80968871582dc590336fd3bf0f6d1a6a8 | +| ./mocks/ERC165Helper/ExampleERC1404ExtendERC165.sol | 4c8be8a290b24ec179c32ed3ad5ee11124e55778 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ExampleRuleEngineERC165.sol.md b/doc/schema/surya_report/surya_report_ExampleRuleEngineERC165.sol.md index c633197f..71e9e2c2 100644 --- a/doc/schema/surya_report/surya_report_ExampleRuleEngineERC165.sol.md +++ b/doc/schema/surya_report/surya_report_ExampleRuleEngineERC165.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/ERC165Helper/ExampleRuleEngineERC165.sol | bd4a515cf0948f696bc411e2a16412c1454848ae | +| ./mocks/ERC165Helper/ExampleRuleEngineERC165.sol | e806ee72e5708fb6940700de659217030f75645f | ### 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 fca50d72..34c30d64 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 | b7f6063f1c7bee208cad4f4af3becc2e590aa6af | +| ./modules/wrapper/extensions/ExtraInformationModule.sol | 8f6b445e2b0f694afb115819018a66b65ac3ad60 | ### Contracts Description Table @@ -24,6 +24,7 @@ | └ | terms | Public ❗️ | |NO❗️ | | └ | information | Public ❗️ | |NO❗️ | | └ | _setTerms | Internal 🔒 | 🛑 | | +| └ | _setTermsDocument | Internal 🔒 | 🛑 | | | └ | _setTokenId | Internal 🔒 | 🛑 | | | └ | _setTerms | Internal 🔒 | 🛑 | | | └ | _setInformation | Internal 🔒 | 🛑 | | diff --git a/doc/schema/surya_report/surya_report_HolderListModule.sol.md b/doc/schema/surya_report/surya_report_HolderListModule.sol.md index 8914d5ad..511fb194 100644 --- a/doc/schema/surya_report/surya_report_HolderListModule.sol.md +++ b/doc/schema/surya_report/surya_report_HolderListModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/options/HolderListModule.sol | 04a73f1e2ec08bd00528195809234e176cde7aca | +| ./modules/wrapper/options/HolderListModule.sol | 97df6e51036140125e4ec455e5bc31b6f10d7f91 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IAllowlistModule.sol.md b/doc/schema/surya_report/surya_report_IAllowlistModule.sol.md index 1f42a52b..39a1db72 100644 --- a/doc/schema/surya_report/surya_report_IAllowlistModule.sol.md +++ b/doc/schema/surya_report/surya_report_IAllowlistModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/modules/IAllowlistModule.sol | ed017ace56905c1622bf547e7d03bb6ae1d99dcd | +| ./interfaces/modules/IAllowlistModule.sol | 32338c28c0d6f3bc83a0d72bb663b38bfdd34983 | ### 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 6e6e4178..454886e4 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 | 049a83fb013b5d30613a951d456acfa8a03d86c2 | +| ./interfaces/tokenization/ICMTAT.sol | d185d4bd2ad16af2fb3ce0a4ba575cfefda86786 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ICMTATConstructor.sol.md b/doc/schema/surya_report/surya_report_ICMTATConstructor.sol.md index 7134b554..1c624d90 100644 --- a/doc/schema/surya_report/surya_report_ICMTATConstructor.sol.md +++ b/doc/schema/surya_report/surya_report_ICMTATConstructor.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/technical/ICMTATConstructor.sol | 37b1d13de4f748a6a78e9a8d4c2908ae30551c12 | +| ./interfaces/technical/ICMTATConstructor.sol | b1e27a93de1f1de6380e3ce46ddc7d18a86f8240 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ICMTATSnapshot.sol.md b/doc/schema/surya_report/surya_report_ICMTATSnapshot.sol.md index e0054fb3..35d8e9ea 100644 --- a/doc/schema/surya_report/surya_report_ICMTATSnapshot.sol.md +++ b/doc/schema/surya_report/surya_report_ICMTATSnapshot.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/library/snapshot/ICMTATSnapshot.sol | 7c7a082e98eaf433e4d829814376bc0a6fac006b | +| ./mocks/library/snapshot/ICMTATSnapshot.sol | 05600d5fb1315a776cc06a497a4dc7febdd8e556 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IDebtEngine.sol.md b/doc/schema/surya_report/surya_report_IDebtEngine.sol.md index 8af0ac53..a4eadcef 100644 --- a/doc/schema/surya_report/surya_report_IDebtEngine.sol.md +++ b/doc/schema/surya_report/surya_report_IDebtEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/engine/IDebtEngine.sol | 374878826fce23265716d66168e3b4cd64f1f498 | +| ./interfaces/engine/IDebtEngine.sol | ee1fc20bf8d716426bab3e3a82460c6fe17fb380 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IDebtEngineModule.sol.md b/doc/schema/surya_report/surya_report_IDebtEngineModule.sol.md index 726a15c9..07406a33 100644 --- a/doc/schema/surya_report/surya_report_IDebtEngineModule.sol.md +++ b/doc/schema/surya_report/surya_report_IDebtEngineModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/modules/IDebtEngineModule.sol | 4ad9b598f89c4bd6cc4420c5acf3ad467811710a | +| ./interfaces/modules/IDebtEngineModule.sol | 4cb253262c75adcf690592700299a5b39b2f8f06 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IDebtModule.sol.md b/doc/schema/surya_report/surya_report_IDebtModule.sol.md index 03bd4ea7..de8418c1 100644 --- a/doc/schema/surya_report/surya_report_IDebtModule.sol.md +++ b/doc/schema/surya_report/surya_report_IDebtModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/modules/IDebtModule.sol | 44c6150505a435baea79fcaabc3a93b494506072 | +| ./interfaces/modules/IDebtModule.sol | 7d01e40732e1d1f123097d250793aa87fb2f1e92 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IDocumentEngine.sol.md b/doc/schema/surya_report/surya_report_IDocumentEngine.sol.md index f724d689..f4c983ee 100644 --- a/doc/schema/surya_report/surya_report_IDocumentEngine.sol.md +++ b/doc/schema/surya_report/surya_report_IDocumentEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/engine/IDocumentEngine.sol | 8552dd7a76883a04e844d80a917ff09d1f977814 | +| ./interfaces/engine/IDocumentEngine.sol | 038fa0643e7ad1413d06c266d43148cee333bcc4 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IDocumentEngineModule.sol.md b/doc/schema/surya_report/surya_report_IDocumentEngineModule.sol.md index b94c45ee..ad3d3591 100644 --- a/doc/schema/surya_report/surya_report_IDocumentEngineModule.sol.md +++ b/doc/schema/surya_report/surya_report_IDocumentEngineModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/modules/IDocumentEngineModule.sol | 5dff138e2a131e879ae797b630a8217bea3137bc | +| ./interfaces/modules/IDocumentEngineModule.sol | 5bdcfc50133dab1f058a458189e4721de82a9ac3 | ### 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 a54d2caa..242e8aba 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 | 17476edb94781aa3089e8e5a83f7b6b92760d19c | +| ./interfaces/technical/IERC20Allowance.sol | b70496cfb5ca4d1f3d08b6bd1e065a79e3c1c823 | ### 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 b95bfb2d..cfb218ce 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 | 8358c87ebcdb71cb6a72b342e796ca0a930101f6 | +| ./interfaces/tokenization/IERC3643Partial.sol | e0119b65a7d74bab33bc50e36e31b60bcea8567c | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IERC5679.sol.md b/doc/schema/surya_report/surya_report_IERC5679.sol.md index e981e913..53f70f78 100644 --- a/doc/schema/surya_report/surya_report_IERC5679.sol.md +++ b/doc/schema/surya_report/surya_report_IERC5679.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/technical/IERC5679.sol | a2b67e24965fc5f54e43908693916cdfe76261c9 | +| ./interfaces/technical/IERC5679.sol | b969d68e0243909e6144699bd955c5471cc9569f | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IERC7802.sol.md b/doc/schema/surya_report/surya_report_IERC7802.sol.md index 22d33774..6f778bf7 100644 --- a/doc/schema/surya_report/surya_report_IERC7802.sol.md +++ b/doc/schema/surya_report/surya_report_IERC7802.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/technical/IERC7802.sol | d15ad9680adf4fd33c9816619ded7737c2092eae | +| ./interfaces/technical/IERC7802.sol | 747c67cf1a98a4f0785e6b84e17b6cd09d0c9ff5 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IGetCCIPAdmin.sol.md b/doc/schema/surya_report/surya_report_IGetCCIPAdmin.sol.md index e2388772..dbccabd6 100644 --- a/doc/schema/surya_report/surya_report_IGetCCIPAdmin.sol.md +++ b/doc/schema/surya_report/surya_report_IGetCCIPAdmin.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/technical/IGetCCIPAdmin.sol | d185f90f0daa856e1cde1dd835382aecc9a0a116 | +| ./interfaces/technical/IGetCCIPAdmin.sol | 10c55b7072ea7d286d03dd786df303a9837927f8 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IHolderListModule.sol.md b/doc/schema/surya_report/surya_report_IHolderListModule.sol.md index 3d0f3fc2..74a0c6a1 100644 --- a/doc/schema/surya_report/surya_report_IHolderListModule.sol.md +++ b/doc/schema/surya_report/surya_report_IHolderListModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/modules/IHolderListModule.sol | 0ba1fb830bcc2305cd90ff28c351531ca96ea964 | +| ./interfaces/modules/IHolderListModule.sol | f32792f0033662341dd5cb260eaac170fc3361ec | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IMintBurnToken.sol.md b/doc/schema/surya_report/surya_report_IMintBurnToken.sol.md index ccf8891b..82d85cd7 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 | 5a540785f6e613c68511e0b3a182a0ff95d97be1 | +| ./interfaces/technical/IMintBurnToken.sol | 33910b3acc5e397420887d1ef68794bbc6caaa68 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IRule.sol.md b/doc/schema/surya_report/surya_report_IRule.sol.md index 6c331fbb..eb3f4545 100644 --- a/doc/schema/surya_report/surya_report_IRule.sol.md +++ b/doc/schema/surya_report/surya_report_IRule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/RuleEngine/interfaces/IRule.sol | 4d9eac3f4311f9a868a0dd2368aef9a7d83b792c | +| ./mocks/RuleEngine/interfaces/IRule.sol | c647408a1fc30bdf548e4a47d60245ec68f75ab5 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IRuleEngine.sol.md b/doc/schema/surya_report/surya_report_IRuleEngine.sol.md index 16333041..5e4d8883 100644 --- a/doc/schema/surya_report/surya_report_IRuleEngine.sol.md +++ b/doc/schema/surya_report/surya_report_IRuleEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/engine/IRuleEngine.sol | 772b063712bacef376391827103a66c0192e035e | +| ./interfaces/engine/IRuleEngine.sol | 750dc2e0387b03bff780ebf990f8bf7304f9b474 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_IRuleEngineMock.sol.md b/doc/schema/surya_report/surya_report_IRuleEngineMock.sol.md index a0ce394a..cfc5da52 100644 --- a/doc/schema/surya_report/surya_report_IRuleEngineMock.sol.md +++ b/doc/schema/surya_report/surya_report_IRuleEngineMock.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/RuleEngine/interfaces/IRuleEngineMock.sol | e7ef1a2445d4a7d568ea4ae8ab3340d312b0623b | +| ./mocks/RuleEngine/interfaces/IRuleEngineMock.sol | 0b2b0ca02c7c3f5196a6bc1cf65cfe823784cc9b | ### 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 index da854342..5d374160 100644 --- a/doc/schema/surya_report/surya_report_IRuleTransferHook.sol.md +++ b/doc/schema/surya_report/surya_report_IRuleTransferHook.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/RuleEngine/interfaces/IRuleTransferHook.sol | 859b60c5ee96645445129b103cd836ea646235dd | +| ./mocks/RuleEngine/interfaces/IRuleTransferHook.sol | 9dd54d9b973db5c52acf4d6c2145921941d7e95a | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ISnapshotEngine.sol.md b/doc/schema/surya_report/surya_report_ISnapshotEngine.sol.md index 8a01629a..b048c8de 100644 --- a/doc/schema/surya_report/surya_report_ISnapshotEngine.sol.md +++ b/doc/schema/surya_report/surya_report_ISnapshotEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/engine/ISnapshotEngine.sol | 4e4c11102ebdaefd5a6e2755b5587a1a88fe6ba2 | +| ./interfaces/engine/ISnapshotEngine.sol | 0b4bcd419f94022dc3e69ae3ebcafaefd57ebcea | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ISnapshotEngineModule.sol.md b/doc/schema/surya_report/surya_report_ISnapshotEngineModule.sol.md index 737fb247..4a9607a5 100644 --- a/doc/schema/surya_report/surya_report_ISnapshotEngineModule.sol.md +++ b/doc/schema/surya_report/surya_report_ISnapshotEngineModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/modules/ISnapshotEngineModule.sol | 49f67df2fb6370a737fa1852737ba84c069dd079 | +| ./interfaces/modules/ISnapshotEngineModule.sol | 3e182944d1dc468b14d69213ea7aab7c729d61dc | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_MinimalForwarderMock.sol.md b/doc/schema/surya_report/surya_report_MinimalForwarderMock.sol.md index 04d6f6ac..78f8154d 100644 --- a/doc/schema/surya_report/surya_report_MinimalForwarderMock.sol.md +++ b/doc/schema/surya_report/surya_report_MinimalForwarderMock.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/MinimalForwarderMock.sol | f4c000bf1144538f63ba92c99ff57b1e793f1fbf | +| ./mocks/MinimalForwarderMock.sol | 725839a0fdc25f10e52d4dcca9421bd200b5ce8e | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_PauseModule.sol.md b/doc/schema/surya_report/surya_report_PauseModule.sol.md index ca641514..4af55690 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 | 9c29b98667b896b61d8e37f59b3dadc89d8549ef | +| ./modules/wrapper/core/PauseModule.sol | 1d64c6a87cf4b13ab7d2a4980b8c1d82a5a29f6c | ### 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 index bc1a9180..3e1fa21a 100644 --- a/doc/schema/surya_report/surya_report_RuleEngineInterfaceId.sol.md +++ b/doc/schema/surya_report/surya_report_RuleEngineInterfaceId.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./library/RuleEngineInterfaceId.sol | 4090104820c3f97398174965e58b1b1fc61cb8ed | +| ./library/RuleEngineInterfaceId.sol | 975cc5e9553b06174f6594db00639868403dd156 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_RuleEngineMock.sol.md b/doc/schema/surya_report/surya_report_RuleEngineMock.sol.md index db2010d1..35db90ac 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 | 2ad951c59fda06402560dad07a2d0f1282983cfe | +| ./mocks/RuleEngine/RuleEngineMock.sol | ae0a662c300a7085ae9c95018b92d77b13639aae | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_RuleEngineReentrantMock.sol.md b/doc/schema/surya_report/surya_report_RuleEngineReentrantMock.sol.md new file mode 100644 index 00000000..4a1b32a4 --- /dev/null +++ b/doc/schema/surya_report/surya_report_RuleEngineReentrantMock.sol.md @@ -0,0 +1,34 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./mocks/RuleEngine/RuleEngineReentrantMock.sol | 7ff1a36f6b383ad5d5b1550cd8b94786cc4d3e72 | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **RuleEngineReentrantMock** | Implementation | ERC165, IRuleEngine ||| +| └ | setBubbleRevert | External ❗️ | 🛑 |NO❗️ | +| └ | arm | External ❗️ | 🛑 |NO❗️ | +| └ | transferred | Public ❗️ | 🛑 |NO❗️ | +| └ | transferred | Public ❗️ | 🛑 |NO❗️ | +| └ | canTransfer | Public ❗️ | |NO❗️ | +| └ | canTransferFrom | Public ❗️ | |NO❗️ | +| └ | supportsInterface | Public ❗️ | |NO❗️ | +| └ | _attack | Internal 🔒 | 🛑 | | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/schema/surya_report/surya_report_RuleEngineSpenderRecorderMock.sol.md b/doc/schema/surya_report/surya_report_RuleEngineSpenderRecorderMock.sol.md new file mode 100644 index 00000000..83d101c8 --- /dev/null +++ b/doc/schema/surya_report/surya_report_RuleEngineSpenderRecorderMock.sol.md @@ -0,0 +1,31 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./mocks/RuleEngine/RuleEngineSpenderRecorderMock.sol | 601a9c378dbefa63f117c04734c3a82cac14294d | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **RuleEngineSpenderRecorderMock** | Implementation | ERC165, IRuleEngine ||| +| └ | transferred | Public ❗️ | 🛑 |NO❗️ | +| └ | transferred | Public ❗️ | 🛑 |NO❗️ | +| └ | canTransfer | Public ❗️ | |NO❗️ | +| └ | canTransferFrom | Public ❗️ | |NO❗️ | +| └ | supportsInterface | Public ❗️ | |NO❗️ | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/schema/surya_report/surya_report_RuleMock.sol.md b/doc/schema/surya_report/surya_report_RuleMock.sol.md index 55221c9d..964ed2d0 100644 --- a/doc/schema/surya_report/surya_report_RuleMock.sol.md +++ b/doc/schema/surya_report/surya_report_RuleMock.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/RuleEngine/RuleMock.sol | 40030471bdd44cd1be252ff25c3c6068f91e7995 | +| ./mocks/RuleEngine/RuleMock.sol | e741812ab333dd3e5320fadc5c11e703c0c85d22 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_RuleMockMint.sol.md b/doc/schema/surya_report/surya_report_RuleMockMint.sol.md index e89fb4ea..ab57087e 100644 --- a/doc/schema/surya_report/surya_report_RuleMockMint.sol.md +++ b/doc/schema/surya_report/surya_report_RuleMockMint.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/RuleEngine/RuleMockMint.sol | b3ec682b2788e641641cd6840daba4fe9a507a1c | +| ./mocks/RuleEngine/RuleMockMint.sol | 49b97e7e18bcefb0bc7a219be0d31b76611a6615 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_RuleSpenderAuthorized.sol.md b/doc/schema/surya_report/surya_report_RuleSpenderAuthorized.sol.md index 5e2b3584..ef550b0b 100644 --- a/doc/schema/surya_report/surya_report_RuleSpenderAuthorized.sol.md +++ b/doc/schema/surya_report/surya_report_RuleSpenderAuthorized.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/RuleEngine/RuleSpenderAuthorized.sol | 498f27e9d42bb5ecb81647c185055ee085376c3b | +| ./mocks/RuleEngine/RuleSpenderAuthorized.sol | a971dac231847665500903fa091800a865365a05 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_RuleTokenHolderTracker.sol.md b/doc/schema/surya_report/surya_report_RuleTokenHolderTracker.sol.md index fa887b3c..4077672b 100644 --- a/doc/schema/surya_report/surya_report_RuleTokenHolderTracker.sol.md +++ b/doc/schema/surya_report/surya_report_RuleTokenHolderTracker.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/RuleEngine/RuleTokenHolderTracker.sol | 389c2c6c2709dee695c05844a4386ad229b0ef4b | +| ./mocks/RuleEngine/RuleTokenHolderTracker.sol | 085be6be69be856daa0f15807c93d700dedc6755 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_SnapshotEngineMock.sol.md b/doc/schema/surya_report/surya_report_SnapshotEngineMock.sol.md index 880bba74..3ef5ff8c 100644 --- a/doc/schema/surya_report/surya_report_SnapshotEngineMock.sol.md +++ b/doc/schema/surya_report/surya_report_SnapshotEngineMock.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/SnapshotEngineMock.sol | 38a5618b9d68f1221176d5c247b590d1065c0c31 | +| ./mocks/SnapshotEngineMock.sol | 6a3f7d58163a1da7d3cecad6b14a0276c70b5b07 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_SnapshotEngineModule.sol.md b/doc/schema/surya_report/surya_report_SnapshotEngineModule.sol.md index 9f856d8a..b9a2a478 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 | 1f97921c2fb50a51d8af7fd623dbe21b6d687ad2 | +| ./modules/wrapper/extensions/SnapshotEngineModule.sol | 97a00d213b2e9d6122c7197f64a7d0d26f0d9adb | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_SnapshotErrors.sol.md b/doc/schema/surya_report/surya_report_SnapshotErrors.sol.md index 93f75120..8a34808f 100644 --- a/doc/schema/surya_report/surya_report_SnapshotErrors.sol.md +++ b/doc/schema/surya_report/surya_report_SnapshotErrors.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/library/snapshot/SnapshotErrors.sol | 09481e30dbfb17bd805b09da945be04ae5af1ad7 | +| ./mocks/library/snapshot/SnapshotErrors.sol | 190e0edf6c58c5ce33bf8914e60efcdb5e9b53b8 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_SnapshotModuleBase.sol.md b/doc/schema/surya_report/surya_report_SnapshotModuleBase.sol.md index db28bfe8..dcf748fa 100644 --- a/doc/schema/surya_report/surya_report_SnapshotModuleBase.sol.md +++ b/doc/schema/surya_report/surya_report_SnapshotModuleBase.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./mocks/library/snapshot/SnapshotModuleBase.sol | a5d3aad7662179b4d735239ec4db643c35f347bc | +| ./mocks/library/snapshot/SnapshotModuleBase.sol | 4882381048da33ecf6a714c8df449209308f5077 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_TokenAttributeModule.sol.md b/doc/schema/surya_report/surya_report_TokenAttributeModule.sol.md index a4865f4c..cd113492 100644 --- a/doc/schema/surya_report/surya_report_TokenAttributeModule.sol.md +++ b/doc/schema/surya_report/surya_report_TokenAttributeModule.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/TokenAttributeModule.sol | de60d9cb13d34bd78647777a55e3ebaff3c323a4 | +| ./modules/wrapper/core/TokenAttributeModule.sol | 18f449c5b71414aee542323edc7f2d80e1e6808e | ### 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 8451d4c3..a75a5eff 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 | e6c271b7c96e5dd9cfa71a9932088eb7174dc5b5 | +| ./modules/wrapper/controllers/ValidationModule.sol | bfa48028212920cc192304bc5e909aff37ada1ee | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ValidationModuleAllowance.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleAllowance.sol.md index 5670a347..3a12e241 100644 --- a/doc/schema/surya_report/surya_report_ValidationModuleAllowance.sol.md +++ b/doc/schema/surya_report/surya_report_ValidationModuleAllowance.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol | 6305cf0201a987b2fa3222c72f27989833dc4cfb | +| ./modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol | 367a48e1124c4b2d20fbc7fbede9b52ac5b55c30 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ValidationModuleAllowlist.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleAllowlist.sol.md index 9fdf74a1..7393362e 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 | 8d8146cd8751ad173c9c5d8e99e3c6e4f00b3743 | +| ./modules/wrapper/controllers/ValidationModuleAllowlist.sol | b48d670fdf8eb25ef742ee9891eab7a8cfa31810 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ValidationModuleCore.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleCore.sol.md index ddab6ef6..28384494 100644 --- a/doc/schema/surya_report/surya_report_ValidationModuleCore.sol.md +++ b/doc/schema/surya_report/surya_report_ValidationModuleCore.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/core/ValidationModuleCore.sol | 1514e87997631ca22184d238f0da5d065d3234aa | +| ./modules/wrapper/core/ValidationModuleCore.sol | ca909742bf8fd423e6afb311f8eb5761a3be586f | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ValidationModuleERC1404.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleERC1404.sol.md index 63c61471..92a5d89b 100644 --- a/doc/schema/surya_report/surya_report_ValidationModuleERC1404.sol.md +++ b/doc/schema/surya_report/surya_report_ValidationModuleERC1404.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol | 6341799677440a5a556dfcfe480136077b96b878 | +| ./modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol | 46057556239ebd1034ecd7989d7c8561daa01516 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_ValidationModuleRuleEngine.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleRuleEngine.sol.md index f997ec92..4c9a55ea 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 | 81c68ccc0b558c936e79aca880f811ac85311489 | +| ./modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol | c05a0233efc4d0ddd0e3278b58c814834547c2c2 | ### Contracts Description Table @@ -25,6 +25,7 @@ | └ | _canTransferWithRuleEngine | Internal 🔒 | | | | └ | _authorizeRuleEngineManagement | Internal 🔒 | 🛑 | | | └ | _transferred | Internal 🔒 | 🛑 | | +| └ | _callRuleEngineTransferred | Internal 🔒 | 🛑 | | ### Legend diff --git a/doc/schema/surya_report/surya_report_ValidationModuleRuleEngineInternal.sol.md b/doc/schema/surya_report/surya_report_ValidationModuleRuleEngineInternal.sol.md index 5e6a4919..f2fadbbe 100644 --- a/doc/schema/surya_report/surya_report_ValidationModuleRuleEngineInternal.sol.md +++ b/doc/schema/surya_report/surya_report_ValidationModuleRuleEngineInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/internal/ValidationModuleRuleEngineInternal.sol | c550d9b4c62e621e62d3117a30afe2cd657d67d3 | +| ./modules/internal/ValidationModuleRuleEngineInternal.sol | 11acf7327aa8492e7ebcf66aebe10c2ba19f1733 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_VersionModule.sol.md b/doc/schema/surya_report/surya_report_VersionModule.sol.md index aced9750..65087cab 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 | 466d048b80417180bd3a23a1ebac2f7faaa44a13 | +| ./modules/wrapper/core/VersionModule.sol | 352c8e156b37f01417a778b434083a96f81898ed | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_draft-IERC1404.sol.md b/doc/schema/surya_report/surya_report_draft-IERC1404.sol.md index 03601849..0f1bd66e 100644 --- a/doc/schema/surya_report/surya_report_draft-IERC1404.sol.md +++ b/doc/schema/surya_report/surya_report_draft-IERC1404.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/tokenization/draft-IERC1404.sol | 6ec30f404c67da47fa853e792201c85010f53631 | +| ./interfaces/tokenization/draft-IERC1404.sol | e4a68e0d9f1cab14ce986cf7eb539e0c4b756d9f | ### 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 e96d39c7..714a960c 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 | 430d6604bc3ff3b5fb36c541aac376e3d9b39c26 | +| ./interfaces/tokenization/draft-IERC1643.sol | 2469665c062e69afcb9316e596222fe724dfb1d1 | ### Contracts Description Table 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 bd39c2c3..e3591b64 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 | 11856388fcb0cbf7182cff41314ffc03c602eb01 | +| ./interfaces/tokenization/draft-IERC1643CMTAT.sol | f0425c6399ffe2f692326b8d5c16d2365293af73 | ### 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 c07d8b39..b61725be 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 | 293d5f5a08b58a7d74a511dc903fea659bcc905a | +| ./interfaces/tokenization/draft-IERC7551.sol | 37fb7ee2c0c49fd86ef9ecec500aedc65366e490 | ### 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 da580d00..10ac260d 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 | 93a6a2a87297d7f4f18a64ef3fdf4257280fa7e8 | +| ./interfaces/tokenization/draft-IERC7943.sol | f57a0ab1a8eff5680da9e649a3f0fd364f144ae1 | ### Contracts Description Table diff --git a/doc/schema/surya_report/surya_report_draft-IERC8343.sol.md b/doc/schema/surya_report/surya_report_draft-IERC8343.sol.md index 8e4f1110..df7c96ac 100644 --- a/doc/schema/surya_report/surya_report_draft-IERC8343.sol.md +++ b/doc/schema/surya_report/surya_report_draft-IERC8343.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/tokenization/draft-IERC8343.sol | 85e73523ee34aefeb3c971597984aa8dfe8e74ac | +| ./interfaces/tokenization/draft-IERC8343.sol | 34c69fe05afdf40c4bc44c7b868136131cbf4326 | ### Contracts Description Table diff --git a/doc/security/AUDIT.md b/doc/security/AUDIT.md index 42d06e2a..292b63c3 100644 --- a/doc/security/AUDIT.md +++ b/doc/security/AUDIT.md @@ -11,7 +11,7 @@ Here are the reports produced by [Aderyn](https://github.com/Cyfrin/aderyn): | v3.3.0 | [v3.3.0-aderyn-report.md](./tools/aderyn/v3.3.0-aderyn-report.md)
[v3.3.0-aderyn-feedback.md](./tools/aderyn/v3.3.0-aderyn-feedback.md) | | v3.0.0 | [v3.0.0-aderyn-report.md](./tools/aderyn/archive/v3.0.0-aderyn-report.md) | -Summary (v3.3.0 — refreshed 2026-07-22, `aderyn 0.6.5`, mocks excluded, 101 files / 3736 nSLOC): +Summary (v3.3.0 — refreshed 2026-07-30 on the rc3 source, `aderyn 0.6.5`, mocks excluded, 101 files / 3826 nSLOC): | Category | Tool Severity | Count | CMTAT Maintainer Assessment | Status | | ------- | ------------- | ----- | --------------------------- | ------ | @@ -30,19 +30,19 @@ Here are the reports produced by [Slither](https://github.com/crytic/slither): | v3.0.0 | [v3.0.0-slither-report.md](./tools/slither/archive/v3.0.0-slither-report.md) | | v2.3.0 | [v2.3.0-slither-report.md](./tools/slither/archive/v2.3.0-slither-report.md) | -Summary (v3.3.0 — refreshed 2026-07-22, `slither 0.11.5`, mocks excluded, 110 results): +Summary (v3.3.0 — refreshed 2026-07-30 on the rc3 source, `slither 0.11.5`, mocks excluded, 158 results): | Detector | Tool Severity | Count | CMTAT Maintainer Assessment | Status | | ------- | ------------- | ----- | --------------------------- | ------ | | `uninitialized-local` | Medium | 1 | False positive (local defaults to `0`, intentional) | Closed | | `unused-return` | Medium | 2 | False positive (DocumentEngine forwards / intentionally discards `lastModified`) | Closed | -| `calls-loop` | Low | 28 | Design choice (batch/hook external calls) | Accepted | +| `calls-loop` | Low | 76 | Design choice (batch/hook external calls: 64 RuleEngine `transferred`, 12 snapshot `operateOnTransfer`) | Accepted | | `reentrancy-events` | Low | 2 | Design choice (ERC-1643 dual-emit after trusted engine call) | Accepted | | `assembly` | Informational | 16 | Expected pattern (ERC-7201 slots) | Accepted | | `dead-code` | Informational | 1 | False positive (mandatory `_msgData` override) | Closed | | `naming-convention` | Informational | 60 | Style-only | Closed | -**Nothing to fix** — 0 High; both Medium and both Low categories are false positives or documented design choices. The two new detectors vs the prior snapshot (`unused-return`, `reentrancy-events`) both stem from the intentional ERC-1643 document-engine dual-emission. See [feedback](./tools/slither/v3.3.0-slither-feedback.md). +**Nothing to fix** — 0 High; both Medium and both Low categories are false positives or documented design choices. No detector was added or removed vs the prior snapshot; `calls-loop` rose 28 → 76 only because the RuleEngine `transferred` hook was factored into the `virtual` `_callRuleEngineTransferred` (so it can be wrapped in `nonReentrant`), which makes Slither enumerate each batch call stack reaching the same single external call. See [feedback](./tools/slither/v3.3.0-slither-feedback.md). ## [Mythril](https://github.com/Consensys/mythril) @@ -57,10 +57,66 @@ Here are the reports produced by Mythril: Here are the reports produced by [Nethermind Audit Agent](https://auditagent.nethermind.io): -| Version | File | -| ---------- | ------------------------------------------------------------ | -| v3.1.0 | [nethermind-audit-agent/v3.1.0](./tools/nethermind-audit-agent/v3.1.0) | -| v3.0.0-rc5 | [nethermind-audit-agent/v3.0.0-rc5](./tools/nethermind-audit-agent/v3.0.0-rc5) | +> **Note: these scans were performed by an AI-powered automated tool, not a formal human-led audit.** AuditAgent's +> own notice states the report is "generated entirely by AI … not a full security audit … must be independently +> verified". The linked feedback files are that independent verification by CMTA maintainers. + +| Version | File | +| ------------ | ------------------------------------------------------------ | +| v3.3.0-rc2 | [audit_agent_report_v3.3.0-rc2.pdf](./tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2.pdf)
[audit_agent_report_v3.3.0-rc2-feedback.md](./tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md) | +| v3.1.0 | [nethermind-audit-agent/v3.1.0](./tools/nethermind-audit-agent/v3.1.0) | +| v3.0.0-rc5 | [nethermind-audit-agent/v3.0.0-rc5](./tools/nethermind-audit-agent/v3.0.0-rc5) | + +### Results by version + +| Version | High | Medium | Low | Info | Best practices | Anything to fix? | +| ------- | ---: | -----: | --: | ---: | -------------: | ---------------- | +| v3.3.0-rc2 | 1 | 4 | 3 | 14 | 2 | **12 code fixes**: zero-address guard (NM-15/17), allowance revocation (NM-3/8), ERC-7551 terms name (NM-22), `forcedTransfer` `Spend` + NatSpec (NM-24), Light minter-transfer alignment (NM-5), RuleEngine reentrancy guard where size permits (NM-7/9/11/16/18). NM-4/6/20/21 documented. Nothing exploitable; the High is a false positive; **no open item**. | +| v3.1.0 | 2 | 2 | 10 | — | — | No — 7 invalid, 7 design choices. | + +### v3.3.0-rc2 (Scan ID 9, 2026-07-23, commit `35d8940b…9d92e4ae`) + +**24 findings** (1 high, 4 medium, 3 low, 14 info, 2 best practices) across 100 contracts / 8067 LoC. Triage +outcome: **12 fixed in code · 8 accepted as design (5 with new documentation) · 4 rejected (false positive / +false premise)**. The 12 code fixes cover the zero-address guard (NM-15/17), allowance revocation (NM-3/8), the +ERC-7551 `setTerms` name (NM-22), `forcedTransfer` `Spend` + NatSpec (NM-24), the Light minter-transfer alignment +(NM-5), and the RuleEngine reentrancy guard on the size-permitting variants (NM-7/9/11/16/18). No item is left +open. + +| ID | Title | Severity (tool → CMTA) | Disposition | +| --- | --- | --- | --- | +| NM-1 | Uninitialized proxy can be seized by the first caller to `initialize` | High → Info | Rejected (false positive) | +| NM-2 | Anyone can claim an uninitialized proxy by calling `initialize` first | Medium → Info | Rejected (duplicate of NM-1) | +| NM-3 | Paused/restricted holders cannot revoke stale allowances | Medium → Low | **Fixed** | +| NM-4 | Inconsistent context resolution (`msg.sender` vs `_msgSender()`) in the bridge gate | Medium → Info | Rejected (intentional) — **deployment constraint documented** (never grant `CROSS_CHAIN_ROLE` to the ERC-2771 forwarder) | +| NM-5 | Missing freeze enforcement on `spender` for `burnFrom` / minter transfers | Medium → Info | Design choice; **Light `_minterTransferOverride` aligned** to pass `_msgSender()` like the full base (behaviour-neutral). Freeze stays a holder-level control, `revokeRole` is the operator lever | +| NM-6 | Zero-value delegated transfers mutate RuleEngine state | Low → Info | Design choice (RuleEngine responsibility) — **documented** in `IRuleEngine` NatSpec + RuleEngine integration notes | +| NM-7, NM-9, NM-11, NM-16, NM-18 | RuleEngine callback runs before balance effects (reentrancy ordering) | Low / Info ×4 → Low | **Partially fixed** — OZ `ReentrancyGuardTransient` on variants with bytecode headroom (Standard, Snapshot, ERC-7551); others documented (trusted RuleEngine) | +| NM-8 | Allowance revocation blocked for frozen/non-allowlisted spenders | Low → Low | **Fixed** (same change as NM-3) | +| NM-10 | Documented two-step default-admin protection is absent | Info → Info | Rejected (false premise — quotes OpenZeppelin's own comment) | +| NM-12 | `setDocument` emits raw inputs instead of the engine post-state | Info → Info | Design choice (documented dual-emission) | +| NM-13, NM-14, NM-19 | Engine setters accept `address(this)` / non-compliant addresses | Info ×3 → Info | Design choice (privileged, recoverable) — ERC-165 hardening tracked in [#395](https://github.com/CMTA/CMTAT/issues/395) | +| **NM-15, NM-17** | **`setFrozenTokens` can freeze the zero address and brick all mint paths** | **Info ×2 → Low** | **Fixed** | +| NM-20 | Pausing disables privileged burn interfaces | Info → Info | Design choice — **documented**; pause stops **third-party/bridge** supply ops (`burnFrom`, self-burn, `crosschainMint/Burn`), **issuer** ops (`BURNER_ROLE` burn, mint, enforcement) survive | +| NM-21 | Mutable token name desynchronizes the EIP-712 domain separator | Info → Info | Design choice — **documented**; probed: `permit` still works via ERC-5267 `eip712Domain()`, so the reported DoS does not occur | +| **NM-22** | **ERC-7551 `setTerms` overload silently erases the document name** | **Info → Info** | **Fixed** | +| NM-23 | `detectTransferRestrictionFrom` reports `SPENDER_FROZEN` before deactivated/paused | Best practice → Info | Design choice (reporting nit, no bypass) | +| **NM-24** | **Unconditional `Spend` emission contradicts `IERC20Allowance` NatSpec** | **Best practice → Info** | **Fixed (doc-only)** — NatSpec corrected; consistency improvement in [allowance-spend-event.md](../technical/allowance-spend-event.md) | + +**Nothing exploitable by an unprivileged actor and no funds at risk.** The single High and its Medium duplicate +are false positives (implementations call `_disableInitializers()`; proxies are initialized atomically). The last +best-practice item, the stale `IERC20Allowance.Spend` NatSpec (NM-24), has been corrected (doc-only), leaving **no +open item**. Full rationale per finding: [feedback](./tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md). + +**Substantive findings addressed in this release:** + +| ID | Fix | Files / tests | +| --- | --- | --- | +| NM-3 / NM-8 | `_canAuthorizeAllowanceByModuleAndRevert` now takes the allowance `value` and returns early when it is zero, so setting an allowance to zero — a revocation, which can only reduce a spender's reach — is always authorized, including while paused/deactivated or when the owner or spender is frozen or off the allowlist. Non-zero grants stay gated exactly as before; the redundant `whenNotPaused` modifier was removed from the two `approve` overrides (the pause check lives inside the internal function). | `contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol`, `0_CMTATBaseCore.sol`, `3_CMTATBaseRuleEngine.sol`, `3_CMTATBaseAllowlist.sol`, `6_CMTATBaseERC2612.sol` (`permit`); 7 regression tests across `test/common/{PauseModuleCommon,EnforcementModuleCommon,AllowlistModuleCommon}.js`, including two negative guards. | +| NM-22 | The ERC-7551 `setTerms(bytes32,string)` overload — whose signature carries no document name — now updates only the document (`uri`, `documentHash`, `lastModified`) via a new internal `_setTermsDocument`, instead of forwarding an empty name through `_setTerms` and silently erasing a name set through the `ICMTATBase` overload. | `contracts/modules/wrapper/extensions/ExtraInformationModule.sol`, `contracts/modules/wrapper/options/ERC7551Module.sol`; `testERC7551SetTermsPreservesDocumentName` in `test/common/ERC7551ModuleCommon.js` (the pre-existing `testAdminCanUpdateTerms` had encoded the erasure and was corrected). | +| NM-15 / NM-17 | `_setFrozenTokens` now rejects `address(0)` with `CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed()`, matching `_freezePartialTokens` / `_unfreezePartialTokens` and `EnforcementModule`'s full-address freeze. Prevents an `ERC20ENFORCER_ROLE` holder from bricking every mint path (`mint`, `batchMint`, `crosschainMint`, the mint leg of `burnAndMint`) with a single call. | `contracts/modules/internal/ERC20EnforcementModuleInternal.sol`; 5 regression tests in `test/common/ERC20EnforcementModuleCommon.js` (a pre-existing test that pinned the buggy behaviour under the misleading name `testSetFrozenTokensOnZeroAddressDoesNotBreakMintFlow` was removed). | + +### v3.1.0 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. diff --git a/doc/security/tools/aderyn/v3.3.0-aderyn-feedback.md b/doc/security/tools/aderyn/v3.3.0-aderyn-feedback.md index d10c76f6..64da1cff 100644 --- a/doc/security/tools/aderyn/v3.3.0-aderyn-feedback.md +++ b/doc/security/tools/aderyn/v3.3.0-aderyn-feedback.md @@ -1,17 +1,20 @@ # CMTAT Maintainer Feedback - Aderyn v3.3.0 -Date: 2026-07-22 +Date: 2026-07-30 Source report: [v3.3.0-aderyn-report.md](./v3.3.0-aderyn-report.md) ## Scope -CMTA maintainer assessment of Aderyn findings for CMTAT **v3.3.0** (final), run on the current source. +CMTA maintainer assessment of Aderyn findings for CMTAT **v3.3.0**, run on the v3.3.0-rc3 source (`dev`). - Tool: `aderyn 0.6.5` - Command: `aderyn -x mocks --output doc/security/tools/aderyn/v3.3.0-aderyn-report.md` -- Scope: production contracts, **mocks excluded**. 101 `.sol` files, 3736 nSLOC. +- Scope: production contracts, **mocks excluded**. 101 `.sol` files, 3826 nSLOC. +- Build: solc 0.8.36, EVM target `osaka`. -> This refreshes the earlier v3.3.0 snapshot (2026-05-20) against the final v3.3.0 code (adds `HolderListModule`, `TokenAttributeModule`, ERC-8343 `IERC8343`, and the ERC-1643 document-engine dual-emission). There is no rc-specific report; this is the v3.3.0 record. +> Refreshes the 2026-07-22 snapshot against the rc3 code (RuleEngine reentrancy guard, `forcedTransfer` allowance +> `Spend`, `setTerms` name preservation, `_setFrozenTokens` zero-address guard, Light minter-transfer spender). +> The finding set and every instance count are unchanged; only the codebase size grew. ## Report Snapshot @@ -28,7 +31,7 @@ CMTA maintainer assessment of Aderyn findings for CMTAT **v3.3.0** (final), run | H-2 | Contract locks Ether without a withdraw function | High | 1 | Design choice | Payable UUPS upgrade path only; no ETH custody in the token layer | Accepted | | L-1 | Centralization Risk | Low | 33 | Valid | Known RBAC governance tradeoff for regulated token operations | Accepted | | L-2 | Unsafe ERC20 Operation | Low | 27 | Invalid (false positive) | Core paths delegate to OpenZeppelin ERC-20 behavior | Closed | -| L-3 | Unspecific Solidity Pragma | Low | 98 | Design choice | Library-style `^0.8.20` policy; compiler pinned (0.8.34) in tooling | Accepted | +| L-3 | Unspecific Solidity Pragma | Low | 98 | Design choice | Library-style `^0.8.24` policy (raised from `^0.8.20`); compiler pinned (0.8.36) in tooling | Accepted | | L-4 | PUSH0 Opcode | Low | 101 | Valid (environmental) | Deployment-compatibility note for pre-Shanghai chains | Accepted | | L-5 | Modifier Invoked Only Once | Low | 8 | Invalid (style-only) | Intentional readability/access-control structure | Closed | | L-6 | Empty Block | Low | 33 | Invalid (style-only) | Intentional `_authorize*` override stubs | Closed | @@ -52,7 +55,9 @@ CMTAT is role-driven by design (pause, deactivate, freeze, mint/burn, rule manag Flagged functions wrap OpenZeppelin ERC-20 operations; behaviour follows inherited semantics. No code change. ### L-3: Unspecific Solidity Pragma — Design choice -CMTAT uses a floating `^0.8.20` pragma as a library/reference implementation, while the deployment compiler is pinned (0.8.34) in `hardhat.config.js` / `foundry.toml`. +CMTAT uses a floating pragma as a library/reference implementation, while the deployment compiler is pinned (0.8.36) in `hardhat.config.js` / `foundry.toml`. + +The floor was raised from `^0.8.20` to **`^0.8.24`** across all contracts when the RuleEngine reentrancy guard (NM-7 cluster) introduced OpenZeppelin's `ReentrancyGuardTransient`, which requires EIP-1153 transient storage and declares `pragma solidity ^0.8.24`. Since the project can no longer be compiled at 0.8.20–0.8.23, every file now declares the real floor rather than a version the build does not support. ### L-4: PUSH0 Opcode — Valid (environmental) PUSH0 (Shanghai) is emitted. v3.3.0 targets the **Osaka (Fusaka)** EVM version, which includes PUSH0. Issuers deploying to chains that predate Shanghai should lower the EVM target accordingly. @@ -72,11 +77,15 @@ Potential micro-optimizations (e.g. caching lengths). No correctness impact; not ### L-10: Unchecked Return — Invalid (false positive) `_grantRole(...)` returns a `bool` intentionally ignored in the initializer flow (the role is always newly granted). No code change. -## Delta from the 2026-05-20 v3.3.0 snapshot +## Delta from the 2026-07-22 v3.3.0 snapshot -- Same finding **categories** (H-1..H-2, L-1..L-10); no new or removed detector. -- Instance counts grew with the new modules: files 94 → **101**, nSLOC 3507 → **3736**; e.g. L-1 Centralization, L-4 PUSH0, L-6 Empty Block increased proportionally. -- L-4 rationale updated: EVM target moved from Prague to **Osaka (Fusaka)**. +- **No change in findings**: same categories (H-1..H-2, L-1..L-10) and **identical instance counts** for all + twelve — including L-1 (33), L-3 (98), L-4 (101) and L-6 (33). +- **Size**: files 101 (unchanged), nSLOC 3736 → **3826** (+90) from the rc3 code — the reentrancy guard and + `_callRuleEngineTransferred` extraction, the `forcedTransfer` `Spend` accounting, the `setTerms` name + preservation and the `_setFrozenTokens` zero-address guard, plus the accompanying NatSpec. +- **No new detector fired against the reentrancy guard**: the `ReentrancyGuardTransient` inheritance and the + `nonReentrant` overrides introduce no Aderyn finding. ## Executive triage diff --git a/doc/security/tools/aderyn/v3.3.0-aderyn-report.md b/doc/security/tools/aderyn/v3.3.0-aderyn-report.md index ddabad8f..9a4bcb02 100644 --- a/doc/security/tools/aderyn/v3.3.0-aderyn-report.md +++ b/doc/security/tools/aderyn/v3.3.0-aderyn-report.md @@ -3,8 +3,9 @@ - **Tool**: `aderyn 0.6.5` - **Command**: `aderyn -x mocks --output doc/security/tools/aderyn/v3.3.0-aderyn-report.md` -- **Scope**: production contracts — **mocks excluded** (`-x mocks`). 101 `.sol` files, 3736 nSLOC. +- **Scope**: production contracts — **mocks excluded** (`-x mocks`). 101 `.sol` files, 3826 nSLOC. - **Severity tally**: **2 High · 0 Medium · 10 Low · 0 Informational** +- **Run**: 2026-07-30, on the v3.3.0-rc3 source (`dev`), EVM target `osaka`, solc 0.8.36. - **Feedback (dispositions)**: [v3.3.0-aderyn-feedback.md](./v3.3.0-aderyn-feedback.md) · **Overview**: [AUDIT.md](../../AUDIT.md) | ID | Finding | Severity | Instances | Assessment | @@ -13,7 +14,7 @@ | H-2 | Contract locks Ether without a withdraw function | High | 1 | By design — payable UUPS upgrade path; no ETH custody in the token layer | | L-1 | Centralization risk | Low | 33 | By design — RBAC for a regulated token; mitigate with multisig/timelock at deployment | | L-2 | Unsafe ERC-20 operation | Low | 27 | False positive — wrappers over OpenZeppelin ERC-20 semantics | -| L-3 | Unspecific Solidity pragma | Low | 98 | By design — `^0.8.20` library policy; compiler pinned in tooling (0.8.34) | +| L-3 | Unspecific Solidity pragma | Low | 98 | By design — `^0.8.24` library policy; compiler pinned in tooling (0.8.36) | | L-4 | PUSH0 opcode | Low | 101 | Environment — compiled for the **Osaka (Fusaka)** EVM target; note pre-Shanghai chains | | L-5 | Modifier invoked only once | Low | 8 | Cosmetic — intentional access-control structure | | L-6 | Empty block | Low | 33 | Cosmetic — intentional `_authorize*` override stubs | @@ -22,7 +23,7 @@ | L-9 | Costly operations inside loop | Low | 5 | Optimization only — no correctness impact | | L-10 | Unchecked return | Low | 1 | False positive — `_grantRole` return intentionally ignored in the initializer | -**Nothing requires a code fix.** Every finding is a false positive, a documented design choice, an environment note, a cosmetic item, or an optimization. See the feedback file for per-finding rationale grounded in the source. +**Nothing requires a code fix.** Identical finding set and instance counts to the 2026-07-22 snapshot; only the size grew (3736 → 3826 nSLOC) with the rc3 fixes. Every finding is a false positive, a documented design choice, an environment note, a cosmetic item, or an optimization. See the feedback file for per-finding rationale grounded in the source. @@ -58,20 +59,20 @@ This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a stati | Key | Value | | --- | --- | | .sol Files | 101 | -| Total nSLOC | 3736 | +| Total nSLOC | 3826 | ## Files Details | Filepath | nSLOC | | --- | --- | -| contracts/deployment/CMTATStandardStandalone.sol | 20 | -| contracts/deployment/CMTATStandardUpgradeable.sol | 10 | +| contracts/deployment/CMTATStandardStandalone.sol | 32 | +| contracts/deployment/CMTATStandardUpgradeable.sol | 22 | | 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/ERC7551/CMTATStandaloneERC7551.sol | 32 | +| contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol | 22 | | contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol | 18 | | contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol | 8 | | contracts/deployment/debt/CMTATStandaloneDebt.sol | 18 | @@ -84,8 +85,8 @@ This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a stati | 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/deployment/snapshot/CMTATStandaloneSnapshot.sol | 32 | +| contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol | 22 | | contracts/interfaces/engine/IDebtEngine.sol | 4 | | contracts/interfaces/engine/IDocumentEngine.sol | 4 | | contracts/interfaces/engine/IRuleEngine.sol | 10 | @@ -150,11 +151,11 @@ This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a stati | contracts/modules/wrapper/core/VersionModule.sol | 8 | | contracts/modules/wrapper/extensions/DocumentERC1643Module.sol | 59 | | contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol | 46 | -| contracts/modules/wrapper/extensions/ExtraInformationModule.sol | 81 | +| contracts/modules/wrapper/extensions/ExtraInformationModule.sol | 88 | | contracts/modules/wrapper/extensions/SnapshotEngineModule.sol | 44 | -| contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol | 16 | +| contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol | 20 | | contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol | 110 | -| contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol | 96 | +| contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol | 105 | | contracts/modules/wrapper/options/AllowlistModule.sol | 43 | | contracts/modules/wrapper/options/CCIPModule.sol | 30 | | contracts/modules/wrapper/options/DebtEngineModule.sol | 49 | @@ -163,10 +164,10 @@ This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a stati | 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/options/ERC7551Module.sol | 37 | | contracts/modules/wrapper/options/HolderListModule.sol | 58 | | contracts/modules/wrapper/security/AccessControlModule.sol | 22 | -| **Total** | **3736** | +| **Total** | **3826** | ## Issue Summary @@ -198,7 +199,7 @@ Passing an arbitrary `from` address to `transferFrom` (or `safeTransferFrom`) ca return ERC20BaseModule.transferFrom(from, to, value); ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 143](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L143) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 147](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L147) ```solidity return CMTATBaseCommon.transferFrom(from, to, value); @@ -210,7 +211,7 @@ Passing an arbitrary `from` address to `transferFrom` (or `safeTransferFrom`) ca return CMTATBaseCommon.transferFrom(from, to, value); ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 42](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L42) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 44](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L44) ```solidity return CMTATBaseCommon.transferFrom(from, to, value); @@ -222,7 +223,7 @@ Passing an arbitrary `from` address to `transferFrom` (or `safeTransferFrom`) ca return CMTATBaseERC20CrossChain.transferFrom(from, to, value); ``` -- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 88](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L88) +- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 97](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L97) ```solidity return CMTATBaseERC20CrossChain.transferFrom(sender, recipient, amount); @@ -240,7 +241,7 @@ Passing an arbitrary `from` address to `transferFrom` (or `safeTransferFrom`) ca return CMTATBaseERC20CrossChain.transferFrom(from, to, value); ``` -- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 63](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol#L63) +- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 65](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol#L65) ```solidity return CMTATBaseERC7551Enforcement.transferFrom(sender, recipient, amount); @@ -294,43 +295,43 @@ Contracts have owners with privileged rights to perform admin tasks and need to function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyRole(PROXY_UPGRADE_ROLE) {} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 272](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L272) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 280](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L280) ```solidity function _authorizeForcedBurn() internal virtual onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 274](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L274) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 282](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L282) ```solidity function _authorizeMint() internal virtual override(ERC20MintModule) onlyRole(MINTER_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 276](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L276) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 284](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L284) ```solidity function _authorizeBurn() internal virtual override(ERC20BurnModule) onlyRole(BURNER_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 278](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L278) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 286](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L286) ```solidity function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 279](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L279) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 287](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L287) ```solidity function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 281](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L281) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 289](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L289) ```solidity function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 283](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L283) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 291](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L291) ```solidity function _authorizeTokenAttributeManagement() internal virtual override(TokenAttributeModule) onlyRole(DEFAULT_ADMIN_ROLE){} @@ -390,49 +391,49 @@ Contracts have owners with privileged rights to perform admin tasks and need to function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 215](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L215) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 219](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L219) ```solidity function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 216](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L216) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 220](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L220) ```solidity function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 218](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L218) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 222](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L222) ```solidity function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 220](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L220) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 224](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L224) ```solidity function _authorizeAllowlistManagement() internal virtual override(AllowlistModule) onlyRole(ALLOWLIST_ROLE) {} ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 170](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L170) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 174](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L174) ```solidity function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 171](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L171) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 175](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L175) ```solidity function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 173](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L173) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 177](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L177) ```solidity function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 175](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L175) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 179](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L179) ```solidity function _authorizeRuleEngineManagement() internal virtual override(ValidationModuleRuleEngine) onlyRole(DEFAULT_ADMIN_ROLE){} @@ -450,19 +451,19 @@ Contracts have owners with privileged rights to perform admin tasks and need to function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {} ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 116](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L116) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 118](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L118) ```solidity function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {} ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 136](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L136) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 138](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L138) ```solidity function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{} ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 143](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L143) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 145](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L145) ```solidity function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{} @@ -515,19 +516,19 @@ ERC20 functions may not behave as expected. For example: return values are not a return ERC20BaseModule.transferFrom(from, to, value); ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 125](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L125) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 129](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L129) ```solidity return ERC20Upgradeable.approve(spender, value); ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 134](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L134) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 138](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L138) ```solidity return CMTATBaseCommon.transfer(to, value); ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 131](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L131) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 135](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L135) ```solidity return ERC20Upgradeable.approve(spender, value); @@ -545,13 +546,13 @@ ERC20 functions may not behave as expected. For example: return values are not a return CMTATBaseCommon.transfer(to, value); ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 24](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L24) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 26](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L26) ```solidity return CMTATBaseRuleEngine.approve(spender, value); ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 27](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L27) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 29](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L29) ```solidity return CMTATBaseCommon.transfer(to, value); @@ -575,19 +576,19 @@ ERC20 functions may not behave as expected. For example: return values are not a return CMTATBaseERC20CrossChain.approve(spender, value); ``` -- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 62](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L62) +- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 71](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L71) ```solidity return CMTATBaseERC20CrossChain.approve(spender, value); ``` -- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 72](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L72) +- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 81](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L81) ```solidity return CMTATBaseERC20CrossChain.transfer(to, value); ``` -- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 88](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L88) +- Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 97](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L97) ```solidity return CMTATBaseERC20CrossChain.transferFrom(sender, recipient, amount); @@ -629,13 +630,13 @@ ERC20 functions may not behave as expected. For example: return values are not a return CMTATBaseERC20CrossChain.approve(spender, value); ``` -- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 40](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol#L40) +- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 42](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol#L42) ```solidity return CMTATBaseERC7551Enforcement.approve(spender, value); ``` -- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 47](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol#L47) +- Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 49](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol#L49) ```solidity return CMTATBaseERC7551Enforcement.transfer(to, value); @@ -673,589 +674,589 @@ Consider using a specific version of Solidity in your contracts instead of a wid - Found in contracts/deployment/CMTATStandardStandalone.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardStandalone.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/CMTATStandardUpgradeable.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardUpgradeable.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/CMTATUpgradeableUUPS.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/debt/CMTATStandaloneDebt.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/debt/CMTATUpgradeableDebt.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/holderList/CMTATStandaloneHolderList.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATStandaloneHolderList.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/holderList/CMTATUpgradeableHolderList.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/light/CMTATStandaloneLight.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/light/CMTATUpgradeableLight.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLight.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/permit/CMTATStandalonePermit.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATStandalonePermit.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/permit/CMTATUpgradeablePermit.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATUpgradeablePermit.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/engine/IDebtEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDebtEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/engine/IDocumentEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDocumentEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/engine/IRuleEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IRuleEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/engine/ISnapshotEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/ISnapshotEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IAllowlistModule.sol [Line: 4](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IAllowlistModule.sol#L4) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IDebtEngineModule.sol [Line: 4](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDebtEngineModule.sol#L4) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IDebtModule.sol [Line: 4](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDebtModule.sol#L4) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IDocumentEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDocumentEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IHolderListModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IHolderListModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/ISnapshotEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/ISnapshotEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/ICMTATConstructor.sol [Line: 2](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/ICMTATConstructor.sol#L2) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IERC20Allowance.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC20Allowance.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IERC5679.sol [Line: 2](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC5679.sol#L2) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IERC7802.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC7802.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IGetCCIPAdmin.sol [Line: 2](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IGetCCIPAdmin.sol#L2) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IMintBurnToken.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IMintBurnToken.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/ICMTAT.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/ICMTAT.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/IERC3643Partial.sol [Line: 10](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/IERC3643Partial.sol#L10) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC1404.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1404.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC1643.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1643.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC7551.sol [Line: 5](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC7551.sol#L5) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC7943.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC7943.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC8343.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC8343.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/0_CMTATBaseCommon.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/0_CMTATBaseCore.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/0_CMTATBaseGeneric.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseGeneric.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/0_CMTATBaseSnapshot.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseSnapshot.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/1_CMTATBaseDocument.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/1_CMTATBaseDocument.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAccessControl.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseDebt.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/4_CMTATBaseERC1404.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC1404.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseDebtEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/6_CMTATBaseERC2771.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2771.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/7_CMTATBaseERC7551Enforcement.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC7551Enforcement.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/8_CMTATBaseERC7551.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC7551.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/8_CMTATBaseHolderList.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseHolderList.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/AllowlistModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/ERC20BurnModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/ERC20EnforcementModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/ERC20MintModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/EnforcementModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/ValidationModuleRuleEngineInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/controllers/ValidationModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/ERC20BaseModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/ERC20BurnModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/ERC20MintModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/EnforcementModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/PauseModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/TokenAttributeModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/TokenAttributeModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/ValidationModuleCore.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/VersionModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/VersionModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/DocumentERC1643Module.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ExtraInformationModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/SnapshotEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/AllowlistModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/AllowlistModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/CCIPModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/CCIPModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/DebtEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/DebtModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/DocumentEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DocumentEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/ERC2771Module.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC2771Module.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/ERC7551Module.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC7551Module.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/HolderListModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/HolderListModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/security/AccessControlModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` @@ -1272,607 +1273,607 @@ Solc compiler version 0.8.20 switches the default target EVM version to Shanghai - Found in contracts/deployment/CMTATStandardStandalone.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardStandalone.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/CMTATStandardUpgradeable.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardUpgradeable.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/CMTATUpgradeableUUPS.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/debt/CMTATStandaloneDebt.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/debt/CMTATUpgradeableDebt.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/holderList/CMTATStandaloneHolderList.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATStandaloneHolderList.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/holderList/CMTATUpgradeableHolderList.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/light/CMTATStandaloneLight.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/light/CMTATUpgradeableLight.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLight.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/permit/CMTATStandalonePermit.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATStandalonePermit.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/permit/CMTATUpgradeablePermit.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATUpgradeablePermit.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/engine/IDebtEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDebtEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/engine/IDocumentEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDocumentEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/engine/IRuleEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IRuleEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/engine/ISnapshotEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/ISnapshotEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IAllowlistModule.sol [Line: 4](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IAllowlistModule.sol#L4) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IDebtEngineModule.sol [Line: 4](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDebtEngineModule.sol#L4) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IDebtModule.sol [Line: 4](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDebtModule.sol#L4) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IDocumentEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IDocumentEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/IHolderListModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IHolderListModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/modules/ISnapshotEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/ISnapshotEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/ICMTATConstructor.sol [Line: 2](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/ICMTATConstructor.sol#L2) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IERC20Allowance.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC20Allowance.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IERC5679.sol [Line: 2](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC5679.sol#L2) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IERC7802.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IERC7802.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IGetCCIPAdmin.sol [Line: 2](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IGetCCIPAdmin.sol#L2) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/technical/IMintBurnToken.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/technical/IMintBurnToken.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/ICMTAT.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/ICMTAT.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/IERC3643Partial.sol [Line: 10](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/IERC3643Partial.sol#L10) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC1404.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1404.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC1643.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1643.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC1643CMTAT.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC7551.sol [Line: 5](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC7551.sol#L5) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC7943.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC7943.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/interfaces/tokenization/draft-IERC8343.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC8343.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/library/ERC1404ExtendInterfaceId.sol [Line: 2](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/library/ERC1404ExtendInterfaceId.sol#L2) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/library/RuleEngineInterfaceId.sol [Line: 2](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/library/RuleEngineInterfaceId.sol#L2) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/0_CMTATBaseCommon.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/0_CMTATBaseCore.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/0_CMTATBaseGeneric.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseGeneric.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/0_CMTATBaseSnapshot.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseSnapshot.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/1_CMTATBaseDocument.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/1_CMTATBaseDocument.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/2_CMTATBaseAccessControl.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAccessControl.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/4_CMTATBaseDebt.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseDebt.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/4_CMTATBaseERC1404.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC1404.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/6_CMTATBaseDebtEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseDebtEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/6_CMTATBaseERC2612.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/6_CMTATBaseERC2771.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2771.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/7_CMTATBaseERC2771Snapshot.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC2771Snapshot.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/7_CMTATBaseERC7551Enforcement.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC7551Enforcement.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/8_CMTATBaseERC1363.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/8_CMTATBaseERC7551.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC7551.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/8_CMTATBaseHolderList.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseHolderList.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/AllowlistModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/ERC20BurnModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/ERC20EnforcementModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/ERC20MintModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/EnforcementModuleInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/ValidationModuleRuleEngineInternal.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/internal/common/EnforcementModuleLibrary.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/common/EnforcementModuleLibrary.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/controllers/ValidationModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/ERC20BaseModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/ERC20BurnModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/ERC20MintModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/EnforcementModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/PauseModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/TokenAttributeModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/TokenAttributeModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/ValidationModuleCore.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/core/VersionModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/VersionModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/DocumentERC1643Module.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ExtraInformationModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/SnapshotEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/AllowlistModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/AllowlistModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/CCIPModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/CCIPModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/DebtEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/DebtModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DebtModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/DocumentEngineModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DocumentEngineModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/ERC2771Module.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC2771Module.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/ERC7551Module.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC7551Module.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/options/HolderListModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/HolderListModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` - Found in contracts/modules/wrapper/security/AccessControlModule.sol [Line: 3](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol#L3) ```solidity - pragma solidity ^0.8.20; + pragma solidity ^0.8.24; ``` @@ -1904,7 +1905,7 @@ Consider removing the modifier or inlining the logic into the calling function. modifier onlySnapshooter() { ``` -- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol [Line: 27](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L27) +- Found in contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol [Line: 28](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L28) ```solidity modifier onlyRuleEngineManager() { @@ -1922,13 +1923,13 @@ Consider removing the modifier or inlining the logic into the calling function. modifier onlyDebtEngineManager { ``` -- Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 38](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L38) +- Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 44](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L44) ```solidity modifier onlyBurnerFrom() { ``` -- Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 44](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L44) +- Found in contracts/modules/wrapper/options/ERC20CrossChainModule.sol [Line: 50](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L50) ```solidity modifier onlySelfBurn() { @@ -1951,43 +1952,43 @@ Consider removing empty blocks. function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyRole(PROXY_UPGRADE_ROLE) {} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 272](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L272) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 280](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L280) ```solidity function _authorizeForcedBurn() internal virtual onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 274](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L274) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 282](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L282) ```solidity function _authorizeMint() internal virtual override(ERC20MintModule) onlyRole(MINTER_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 276](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L276) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 284](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L284) ```solidity function _authorizeBurn() internal virtual override(ERC20BurnModule) onlyRole(BURNER_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 278](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L278) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 286](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L286) ```solidity function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 279](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L279) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 287](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L287) ```solidity function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 281](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L281) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 289](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L289) ```solidity function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){} ``` -- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 283](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L283) +- Found in contracts/modules/0_CMTATBaseCore.sol [Line: 291](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol#L291) ```solidity function _authorizeTokenAttributeManagement() internal virtual override(TokenAttributeModule) onlyRole(DEFAULT_ADMIN_ROLE){} @@ -2047,49 +2048,49 @@ Consider removing empty blocks. function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 215](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L215) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 219](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L219) ```solidity function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 216](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L216) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 220](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L220) ```solidity function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 218](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L218) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 222](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L222) ```solidity function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 220](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L220) +- Found in contracts/modules/3_CMTATBaseAllowlist.sol [Line: 224](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol#L224) ```solidity function _authorizeAllowlistManagement() internal virtual override(AllowlistModule) onlyRole(ALLOWLIST_ROLE) {} ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 170](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L170) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 174](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L174) ```solidity function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 171](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L171) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 175](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L175) ```solidity function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 173](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L173) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 177](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L177) ```solidity function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){} ``` -- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 175](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L175) +- Found in contracts/modules/3_CMTATBaseRuleEngine.sol [Line: 179](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol#L179) ```solidity function _authorizeRuleEngineManagement() internal virtual override(ValidationModuleRuleEngine) onlyRole(DEFAULT_ADMIN_ROLE){} @@ -2107,19 +2108,19 @@ Consider removing empty blocks. function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) onlyRole(SNAPSHOOTER_ROLE) {} ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 116](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L116) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 118](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L118) ```solidity function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {} ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 136](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L136) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 138](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L138) ```solidity function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_FROM_ROLE) whenNotPaused{} ``` -- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 143](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L143) +- Found in contracts/modules/5_CMTATBaseERC20CrossChain.sol [Line: 145](../../../../../home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol#L145) ```solidity function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) onlyRole(BURNER_SELF_ROLE) whenNotPaused{} diff --git a/doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md b/doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md new file mode 100644 index 00000000..b6a231da --- /dev/null +++ b/doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md @@ -0,0 +1,1158 @@ +# CMTAT Maintainer Feedback — Nethermind AuditAgent v3.3.0-rc2 + +Date: 2026-07-24 +Source report: [audit_agent_report_v3.3.0-rc2.pdf](./audit_agent_report_v3.3.0-rc2.pdf) + +## Tool + +[**Nethermind AuditAgent**](https://auditagent.nethermind.io/) — an AI-powered automated code-scanning tool. + +> **This scan was performed by an AI-powered automated tool, not a formal human-led audit.** +> The report carries Nethermind's own *Important Notice*: it "has been generated entirely by AI and has not been +> manually reviewed by Nethermind's security team. It does not constitute a full security audit … All findings, +> observations, and recommendations may contain errors or omissions and must be independently verified by a +> qualified human reviewer before being acted upon." +> Per Nethermind's terms, this run **must not** be represented as "audited by Nethermind". +> This file is that independent verification: every finding below was re-read against the actual source. + +## Scan metadata + +| Field | Value | +| --- | --- | +| Scan ID | 9 | +| Date | July 23, 2026 | +| Organization | CMTA | +| Repository | CMTAT | +| Branch | `master` | +| Commit hash | `35d8940b…9d92e4ae` | +| Contracts scanned | 100 | +| Lines of code | 8067 | +| Findings | 24 | + +Scope covered the full production surface: all `contracts/deployment/*` variants (Standard, UUPS, Allowlist, +Debt, DebtEngine, HolderList, Permit, Snapshot, ERC-1363, ERC-7551, Light), `contracts/modules/*` (base levels +0–8, `internal/`, `wrapper/{core,extensions,options,controllers,security}`), `contracts/interfaces/*` and +`contracts/library/*`. + +> **Commit note.** The scanned commit `35d8940b…` is not present in this working tree (local `HEAD` is +> `7316f96` on `dev`; `VersionModule.VERSION == "3.3.0"`). Verification below was performed against the current +> v3.3.0 source. Every cited code path was located and matches the report's excerpts, so the delta between the +> scanned commit and the verified tree does not affect any disposition. + +## Report snapshot (tool-reported counts) + +- High Risk: **1** +- Medium Risk: **4** +- Low Risk: **3** +- Info: **14** +- Best Practices: **2** +- **Total: 24** + +## Outcome + +**12 fixed in code · 8 accepted as design (5 with new documentation) · 4 rejected (false positive / false premise)** = 24. + +The **12 code fixes** (counting the duplicate pairs and the reentrancy cluster individually): +- the zero-address freeze guard on `_setFrozenTokens` (**NM-15 / NM-17**); +- allowance revocation always allowed while paused or restricted (**NM-3 / NM-8**); +- the ERC-7551 `setTerms` name-preservation (**NM-22**); +- `forcedTransfer` now emitting `Spend`, plus the corrected `IERC20Allowance.Spend` NatSpec (**NM-24** — a behaviour + change *and* a doc fix); +- the Light minter-transfer spender alignment (**NM-5**, behaviour-neutral); +- the RuleEngine reentrancy guard on the size-permitting variants (**NM-7 / NM-9 / NM-11 / NM-16 / NM-18**). + +The **8 accepted as design** (no code change): **NM-6**, **NM-20** and **NM-21** gained new documentation; +**NM-13 / NM-14 / NM-19** are accepted with optional ERC-165 hardening tracked in +[#395](https://github.com/CMTA/CMTAT/issues/395); **NM-12** and **NM-23** stand as design (NM-23 with two code +variants written up but not applied). The **4 rejected** are false positives or a misconfiguration precondition: +**NM-1**, **NM-2**, **NM-4** (which also gained a documented deployment constraint) and **NM-10**. + +**No item is left open**, and none of the 24 findings is exploitable by an unprivileged actor. + +## Findings triage + +| ID | Severity (tool → ours) | Disposition | Status | +| --- | --- | --- | --- | +| NM-1 | High → Informational | Rejected (false positive) | Closed | +| NM-2 | Medium → Informational | Rejected (duplicate of NM-1) | Closed | +| NM-3 | Medium → Low | **Fixed** | **Fixed** — revocation (`value == 0`) always authorized | +| NM-4 | Medium → Informational | Rejected (design; misconfiguration precondition) — **documented** | Closed — deployment constraint documented | +| NM-5 | Medium → Informational | Accepted as design — Light minter-transfer spender **aligned** with the full base (behaviour-neutral) | Partially addressed (see follow-up on `access-control.md`) | +| NM-6 | Low → Informational | Accepted as design (RuleEngine responsibility) — **documented** | Accepted — doc + NatSpec added | +| NM-7 | Low → Low | **Partially fixed** — guard on variants with size headroom | **Fixed (guarded variants)** / documented elsewhere | +| NM-8 | Low → Low | **Fixed (same change as NM-3)** | **Fixed** | +| NM-9 | Info → Low | **Partially fixed (same change as NM-7)** | **Fixed (guarded variants)** | +| NM-10 | Info → Informational | Rejected (false premise) | Closed | +| NM-11 | Info → Low | **Partially fixed (same change as NM-7)** | **Fixed (guarded variants)** | +| NM-12 | Info → Informational | Accepted as design | Accepted | +| NM-13 | Info → Informational | Accepted as design — hardening tracked | Accepted ([#395](https://github.com/CMTA/CMTAT/issues/395)) | +| NM-14 | Info → Informational | Accepted as design — hardening tracked | Accepted ([#395](https://github.com/CMTA/CMTAT/issues/395)) | +| **NM-15** | **Info → Low** | **Fixed** | **Fixed** — zero-address guard in `_setFrozenTokens` | +| NM-16 | Info → Low | **Partially fixed (same change as NM-7)** | **Fixed (guarded variants)** | +| **NM-17** | **Info → Low** | **Fixed (same defect as NM-15)** | **Fixed** | +| NM-18 | Info → Informational | **Partially fixed (same change as NM-7)** | **Fixed (guarded variants)** | +| NM-19 | Info → Informational | Accepted as design — hardening tracked | Accepted ([#395](https://github.com/CMTA/CMTAT/issues/395)) | +| NM-20 | Info → Informational | Accepted as design — issuer vs third-party split, probed — **documented** | Accepted — rationale documented | +| NM-21 | Info → Informational | Accepted as design (claim overstated) — **documented** | Accepted — doc + NatSpec added | +| **NM-22** | **Info → Informational** | **Fixed** | **Fixed** — ERC-7551 overload preserves the name | +| NM-23 | Best Practices → Informational | Accepted as design — reorder options + drawbacks documented | Accepted (Variant 1 suggested, not applied) | +| **NM-24** | **Best Practices → Informational** | **Fixed (doc-only)** — NatSpec corrected; consistency improvement recorded in technical doc | **Fixed (documented)** | + +--- + +## Detailed assessment + +### NM-1 — Uninitialized proxy can be seized by the first caller to `initialize` (High → Informational) + +**Claim.** `initialize(...)` is `public` and guarded only by OpenZeppelin's `initializer` modifier, so on a fresh +proxy any account can win the first call, obtain `DEFAULT_ADMIN_ROLE`, and — because `hasRole` treats the default +admin as holding every role — take over the token. + +**Verdict — rejected (false positive).** Every implementation contract disables initialization in its +constructor (`_disableInitializers()`; e.g. `contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol:19`, +`contracts/deployment/CMTATStandardUpgradeable.sol`, `contracts/deployment/CMTATUpgradeableUUPS.sol`), so the +implementation itself cannot be claimed. For the proxy, the deployment contract must be created and initialized +**in the same transaction** — the standard OpenZeppelin proxy-deployment requirement, satisfied by +`ERC1967Proxy`/`TransparentUpgradeableProxy` constructor calldata and by the CMTAT deployment tooling. The +report concedes the precondition itself: *"The deployment process can deploy a Transparent or Beacon proxy +without constructor/deployment calldata that atomically invokes `initialize`; this is not demonstrated by the +supplied deployment scripts."* Same disposition as AuditAgent v3.1.0 finding #2 (Invalid). + +*Action taken:* none in code. The atomic-initialization requirement is a deployment-integration property; see the +deployment documentation. + +### NM-2 — Anyone can claim an uninitialized proxy by calling `initialize` first (Medium → Informational) + +**Claim.** Same as NM-1, cited on `contracts/modules/0_CMTATBaseCore.sol`. + +**Verdict — rejected (duplicate of NM-1).** The report even notes the implementation is protected by +`_disableInitializers()` and that the assessment "assumes deployments can actually leave a proxy uninitialized". + +### NM-3 — Paused or restricted holders cannot revoke stale allowances (Medium → Low — **FIXED**) + +**Claim.** `_canAuthorizeAllowanceByModuleAndRevert(owner, spender)` does not receive `value`, so +`approve(spender, 0)` is rejected under the same conditions as a new grant: while paused, while either party is +frozen, or (Allowlist variant) while either party is off the allowlist. A holder therefore cannot use the +zero-first mitigation during a restriction window, and a compromised spender can back-run the restoration. + +**Verdict — VALID. Fixed.** The behaviour was real: +`contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol` calls `_requireNotPaused()` +and `_canSend(owner)` / `_canSend(spender)` unconditionally, and `approve` carries `whenNotPaused` in +`3_CMTATBaseRuleEngine.sol` / `3_CMTATBaseAllowlist.sol`. This is the direct consequence of the fix CMTA applied +in v3.2.0 to the previous AuditAgent finding #13 (*"approve not protected by pause"*) — the two requests point in +opposite directions, and CMTA chose "pause freezes the whole allowance surface". + +The residual exposure is narrow — while the restriction holds, `transferFrom` is blocked by the same gates, so no +allowance can be consumed, and the only window is the instant of restoration. CMTA nonetheless decided to close +it: a holder must always be able to sever ties with a compromised or sanctioned spender. + +**Resolution — fixed.** + +- **Confirmation before fixing.** Six tests were added first and the four revocation cases confirmed **failing** + on the unfixed code (`approve(spender, 0)` reverted with `EnforcedPause` / `ERC7943CannotSend`), while the two + "must stay blocked" cases already passed. +- **Fix.** `_canAuthorizeAllowanceByModuleAndRevert` now takes the allowance `value` and returns early when it is + zero: + - `contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol` — signature becomes + `(address owner, address spender, uint256 value)`, with `if (value == 0) { return; }` before the + pause/`canSend` checks. Setting an allowance to zero is a **revocation**: it can only reduce what a spender + may move, so it is always authorized. + - Call sites updated to pass `value`: `0_CMTATBaseCore.sol` (`approve`), `3_CMTATBaseRuleEngine.sol` + (`approve`), `3_CMTATBaseAllowlist.sol` (`approve`), `6_CMTATBaseERC2612.sol` (`permit` — a gasless + revocation must work for the same reason). + - The redundant `whenNotPaused` modifier was removed from the `approve` overrides in `3_CMTATBaseRuleEngine.sol` + and `3_CMTATBaseAllowlist.sol`. It would have rejected the revocation before the internal check ran; the pause + enforcement it provided is unchanged, because `_canAuthorizeAllowanceByModuleAndRevert` already calls + `_requireNotPaused()` for every non-zero value. +- **Non-zero grants are unaffected.** While paused, or when the owner/spender is frozen or off the allowlist, + `approve(spender, n > 0)` and `permit` with a non-zero value still revert exactly as before — covered by the two + negative tests below and by the pre-existing + `testCannotApproveWhenOwnerIsNotAllowlisted` / `testCannotApproveWhenSpenderIsNotAllowlisted`. +- **Tests.** + - `test/common/PauseModuleCommon.js` — `testCanRevokeAllowanceWhenPaused`, + `testCanRevokeAllowanceWhenDeactivated`, `testCannotGrantAllowanceWhenPaused` (negative guard). + - `test/common/EnforcementModuleCommon.js` — `testCanRevokeAllowanceWhenSpenderIsFrozen`, + `testCanRevokeAllowanceWhenOwnerIsFrozen`, `testCannotGrantAllowanceWhenSpenderIsFrozen` (negative guard). + - `test/common/AllowlistModuleCommon.js` — `testCanRevokeAllowanceWhenSpenderIsNotAllowlisted`. + - `test/common/PermitModuleCommon.js` — the `permit` twin of the carve-out (added in the audit-verification + follow-up, since `permit` shares `_canAuthorizeAllowanceByModuleAndRevert` with `approve`): zero-value permit + revocation *"while paused / when the owner is frozen / when the spender is frozen"*. +- **Verification.** The revocation tests went from failing to passing on the fix; the negative guards passed + throughout. Validated in the full suite — **5998 passing / 0 failing** on the current tree (after all fixes). +- **Note for integrators.** This reverses the v3.2.0 response to AuditAgent v3.1.0 finding #13 *for the zero value + only*. `approve` remains pause-gated for every non-zero amount; only revocation was opened. The `whenNotPaused` + modifier no longer appears on the `approve` signatures, but the pause enforcement it provided is unchanged. + +### NM-4 — Inconsistent context resolution allows role spoofing and unlimited minting (Medium → Informational) + +**Claim.** `onlyTokenBridge` resolves the caller with raw `msg.sender` while every other role gate uses +`_msgSender()`. An administrator "fixing" a forwarder-relayed bridge by granting `CROSS_CHAIN_ROLE` to the trusted +forwarder would let any user meta-transact `crosschainMint` and mint arbitrarily. Separately, a compromised +forwarder can append any admin address and impersonate role holders. + +**Verdict — rejected (intentional, and the precondition is an administrator doing what the code warns against).** +The `msg.sender` choice is deliberate and documented in-line at +`contracts/modules/wrapper/options/ERC20CrossChainModule.sol` (modifier `onlyTokenBridge`): *"Token bridge should +never be impersonated using a relayer/forwarder. Using `msg.sender` is preferable to `_msgSender()` for security +reasons."* This mirrors OpenZeppelin v5.4.0 `draft-ERC20Bridgeable.sol`. The described mint escalation requires +`CROSS_CHAIN_ROLE` to be granted to the ERC-2771 forwarder — precisely the configuration the comment forbids. + +The second half restates the inherent ERC-2771 trust model: a trusted forwarder can, by construction, assert any +`_msgSender()`. This is already documented (`doc/technical/stablecoin.md:197` — *"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"*), and the forwarder is immutable (constructor-set), so it cannot be swapped post-deployment. + +**Resolution — documented (no behaviour change).** The disposition stands: `msg.sender` is the correct check and +the code was already right. What was missing is that the *deployment constraint* it implies was only discoverable +by reading a comment inside a modifier. It is now stated where an integrator will meet it: + +- `doc/technical/cross-chain-bridge-integration.md` — new subsection *"The bridge gate uses `msg.sender`, not + `_msgSender()`"* under the Access Control Summary. It gives the rationale (a bridge holds unbounded mint + authority and must not be impersonable through a relayer), then the two practical consequences: a bridge must + call `crosschainMint` / `crosschainBurn` **directly**, and `CROSS_CHAIN_ROLE` **must never** be granted to the + ERC-2771 forwarder — spelling out that doing so would let any user mint arbitrarily through a relayed call, and + that the forwarder is irrevocable in standalone deployments so the only remedy is revoking the role. It + generalizes the rule: `CROSS_CHAIN_ROLE` must be held only by contracts whose call *is* the authorization + decision. +- `doc/technical/access-control.md` — a Role Interaction Note recording that `CROSS_CHAIN_ROLE` is the only role + gate checked against the raw `msg.sender`, with a link to the section above. +- `doc/modules/options/erc20crosschain/ERC20CrossChain.md` — the requirement lists for `crosschainMint` and + `crosschainBurn` now state that the call cannot be relayed through the forwarder. +- `contracts/modules/wrapper/options/ERC20CrossChainModule.sol` — the `onlyTokenBridge` comment was extended with + an explicit `DEPLOYMENT CONSTRAINT` paragraph. Comment-only; the bytecode is unchanged. + +Note that the *first* consequence is the trap that leads to the second: an integrator whose relayed bridge call +reverts is being told, correctly, that the bridge must call directly — and the natural but catastrophic +"fix" is to grant the role to the forwarder. Documenting the revert without documenting why the obvious +workaround is unsafe would have left the finding's attack path open, which is why both are stated together. + +### NM-5 — Missing freeze enforcement on `spender` for `burnFrom` and minter transfers (Medium → Informational — **partially addressed**) + +**Claim.** Burn routing checks only `from`; `CMTATBaseCore._minterTransferOverride` hardcodes `address(0)` as the +spender; `CMTATBaseCommon._checkTransferred` ignores its `spender` argument entirely. + +**Verdict — accepted as design; the Light-variant inconsistency was aligned.** All three observations are factually +correct. The one that was a genuine *inconsistency* — `CMTATBaseCore` (Light) hardcoding `address(0)` where the +full base passes `_msgSender()` — has been fixed for uniformity (see Resolution below). The rest stands as +design. + +- `contracts/modules/0_CMTATBaseCore.sol` — `_minterTransferOverride` **now** calls + `ValidationModule._canTransferGenericByModuleAndRevert(_msgSender(), from, to)` (was `address(0)`). +- `contracts/modules/0_CMTATBaseCommon.sol` — `_checkTransferred(address /*spender*/, …)` only calls + `_checkActiveBalanceAndRevert(from, value)`; the spender-aware checks are layered by the derived modules + (`3_CMTATBaseRuleEngine.sol`, `3_CMTATBaseAllowlist.sol`), which do pass `spender` through to + `_canTransferGenericByModuleAndRevert`. +- `burnFrom` (`ERC20CrossChainModule`) routes to `_canBurnByModuleAndRevert(from)`, which checks the burn target, + not the operator. + +The rationale is unchanged from AuditAgent v3.1.0 findings #3 and #10: mint/burn/minter-transfer have **no +spender** in the ERC-20 sense — the actor is a `MINTER_ROLE` / `BURNER_ROLE` / `BURNER_FROM_ROLE` holder, and +account freezing is a *holder*-level control, not an operator-level one. The control for a compromised operator is +role revocation (`revokeRole`), which is immediate and total; freezing was never intended to demote a role holder. + +#### What mint and burn actually pass as `spender` + +Because the finding turns on this, the argument was traced end to end. The two hierarchies differ. + +**`CMTATBaseCommon` (all full variants) — passes `_msgSender()`:** + +| Path | Call | `spender` | +| --- | --- | --- | +| `_mintOverride` | `_checkTransferred(_msgSender(), address(0), account, value)` | the minter | +| `_burnOverride` | `_checkTransferred(_msgSender(), account, address(0), value)` | the burner | +| `_minterTransferOverride` | `_checkTransferred(_msgSender(), from, to, value)` | the minter | + +**`CMTATBaseCore` (Light variants):** + +| Path | Call | `spender` | +| --- | --- | --- | +| `_mintOverride` | `_canMintByModuleAndRevert(account)` | n/a — not a spender-parameterized function | +| `_burnOverride` | `_canBurnByModuleAndRevert(account)` | n/a | +| `_minterTransferOverride` | `_canTransferGenericByModuleAndRevert(_msgSender(), from, to)` | the minter *(aligned — was `address(0)`)* | + +The report's specific claim about `CMTATBaseCore._minterTransferOverride` hardcoding `address(0)` was accurate at +triage. It has since been changed to pass `_msgSender()`, matching `CMTATBaseCommon` (see Resolution). The mint and +burn overrides remain `spender`-free by structure, as in the full base. + +#### Where the spender goes after that + +Propagating the operator is not the same as checking it. `ValidationModule._canTransferGenericByModuleAndRevert` +routes on `from`/`to`: + +```solidity +if (from == address(0)) _canMintByModuleAndRevert(to); // mint -> spender DROPPED +else if (to == address(0)) _canBurnByModuleAndRevert(from); // burn -> spender DROPPED +else _canTransferStandardByModuleAndRevert(spender, from, to); // spender USED +``` + +`_canMintByModuleAndRevert` and `_canBurnByModuleAndRevert` take a **single address** in every variant, including +the `ValidationModuleAllowlist` overrides. On mint and burn the spender is therefore carried all the way in and +then discarded at the routing step — the freeze check never sees it. + +It is not discarded everywhere: in the RuleEngine variant, `ValidationModuleRuleEngine._transferred` branches on +`spender != address(0)`, so mint and burn reach the **4-argument** `ruleEngine_.transferred(spender, from, to, +value)` with the minter/burner as `spender`. The RuleEngine is told who the operator is; CMTAT's own freeze logic +does not use it. + +#### Empirical confirmation + +Probed on `CMTATStandardStandalone` (throwaway test, not retained): + +| Scenario | Result | +| --- | --- | +| Frozen `MINTER_ROLE` holder calls `mint` | **Succeeds** — recipient balance 10 | +| Frozen `BURNER_ROLE` holder calls `burn` on a non-frozen holder | **Succeeds** — holder balance 100 → 90 | +| Burn targeting a frozen holder | Reverts `ERC7943CannotSend(holder)` ✓ | + +Freezing an operator does not stop them minting or burning; freezing a holder does stop tokens being burned from +them. This matches the design rationale above, and confirms the disposition: the lever against a compromised +operator is `revokeRole`, not `setAddressFrozen`. + +#### Follow-up: a documentation statement this contradicts + +`doc/technical/access-control.md` currently states, under *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`. + +The probe contradicts this: the frozen minter minted successfully. The first half is right that the operator is +*passed* as `spender`, but the mint routing drops it before any freeze check, so no `ERC7943CannotSend` is raised. +The statement could only hold if a configured RuleEngine chose to reject the spender — which is not what the text +says, and is not true of the base contracts or of a deployment without a RuleEngine. + +This is **not** part of NM-5 (the tool did not report it, and the contract behaviour is intended). It was a +documented security control that did not exist as described — a reader could have frozen a compromised minter and +believed issuance was stopped. + +**Resolved (documentation).** CMTA chose to keep the minter behaviour unchanged (freezing is holder-level; +`revokeRole` is the operator lever) and correct the documentation instead. `doc/technical/access-control.md` now +states that freezing an operator does **not** block `mint`/`batchMint` (only the recipient and deactivation are +checked), that it **does** block the operator's `batchTransfer`/`transfer`/`transferFrom` (operator is the +sender/spender), and that on the Standard version a configured RuleEngine still receives the operator as `spender` +and may reject. A per-operation × per-deployment table was added there, with condensed versions in `doc/README.md` +(Enforcement chapter), the `ERC20Mint` module page and `doc/technical/cross-chain-bridge-integration.md` (the last +of which previously overstated that freezing blocks mint). + +#### Resolution — Light minter-transfer aligned with the full base (no behaviour change) + +`contracts/modules/0_CMTATBaseCore.sol` — `_minterTransferOverride` now passes `_msgSender()` as the spender +instead of a hardcoded `address(0)`, matching `CMTATBaseCommon._minterTransferOverride` and the `transferFrom` +path. This removes the one genuine *inconsistency* the finding pointed at (the Light base treated its minter +transfers differently from every other base). + +The change is **behaviour-neutral**. `_minterTransferOverride` is only ever reached from +`ERC20MintModuleInternal._batchTransfer`, which passes `from = _msgSender()`, so `spender == from` on this path. +In `_canTransferisFrozenAndRevert` the spender is checked before `from`, but both are the same address, so the +revert (a frozen minter → `ERC7943CannotSend(minter)`) and the outcome are identical to before; only the argument +is now threaded consistently. Light adds no bytecode (`CMTATStandaloneLight` unchanged at 11 562 bytes). It does +**not** change the mint/burn paths — those remain `spender`-free by structure in both bases, so the +freeze-does-not-block-a-minter behaviour probed above is unchanged, as is the `access-control.md` follow-up. + +Regression tests (`test/common/ERC20MintModuleCommon.js`): `testCannotBatchTransferIfMinterIsFrozen` asserts a +frozen minter's `batchTransfer` reverts with `ERC7943CannotSend(minter)`; `testFrozenMinterCanStillMint` / +`testFrozenMinterCanStillBatchMint` assert a frozen minter's `mint`/`batchMint` still **succeed** — locking in the +documented freeze-does-not-block-issuance behaviour — verified on Standard, Light and Allowlist. The analogous +allowlist case (a non-allowlisted minter can mint to an allowlisted recipient) is covered by +`testMinterNotAllowlistedCanStillMint` in `test/common/AllowlistModuleCommon.js`. + +### NM-6 — Zero-value delegated transfers can mutate RuleEngine state (Low → Informational) + +**Claim.** OpenZeppelin's `_spendAllowance` treats `value == 0` as needing no allowance, so anyone can call +`transferFrom(victim, victim, 0)` and still trigger `ruleEngine.transferred(spender, from, to, 0)`, letting an +attacker poke stateful compliance accounting for arbitrary holders. + +**Verdict — accepted as design; this is the RuleEngine's responsibility.** The path is real +(`0_CMTATBaseCommon.transferFrom` → `_checkTransferred` → `ValidationModuleRuleEngine._transferred` → +`ruleEngine_.transferred(...)`). But ERC-20 mandates that *"transfers of 0 values MUST be treated as normal +transfers"*, so suppressing the callback for `value == 0` would make the token's compliance notifications +inconsistent with its own transfer semantics. The report's own severity note lists the required precondition: +*"the RuleEngine does not independently reject zero-value events, self-transfers, or callbacks from an unapproved +spender."* A rule that meters quotas or cooldowns must be a no-op at `value == 0` — a requirement on the +`IRule`/`IRuleEngine` implementation, which is out of scope of this repository. + +**Resolution — documented (no code change).** The requirement is now written down for RuleEngine implementers, +in the two places they actually read: + +- `contracts/interfaces/engine/IRuleEngine.sol` — the NatSpec on the spender-aware + `transferred(address spender, address from, address to, uint256 value)` now carries an explicit warning that + zero-value calls are **permissionless** (any address can reach the callback for an arbitrary `from`, as + `spender`, with no allowance, via `transferFrom(victim, anyone, 0)`), states why the token does not suppress + them, and requires implementations to treat `value == 0` as carrying no economic meaning. It also notes that the + 3-argument ERC-3643 overload is reachable the same way through `transfer(to, 0)`. +- `doc/modules/controllers/validationRuleEngine.md` — a new *"Integration notes for RuleEngine implementers"* + section explains the two ERC-20 properties that combine to allow it, gives the concrete call, and tabulates what + a zero-value call must not do (cooldown timers, quotas, tax buckets, holder tracking, sanction bookkeeping). It + also warns that rejecting zero-value calls outright (`require(value > 0)`) would make every zero-value transfer + of the token revert, which is not ERC-20 compliant — a no-op is the recommended handling. + +`IERC3643IComplianceContract.transferred` (the 3-argument overload) was intentionally left untouched: it is the +ERC-3643 standard interface definition, and CMTAT keeps those faithful to the specification. The zero-value +guidance for both overloads lives on CMTAT's own `IRuleEngine` instead. + +### NM-7 / NM-9 / NM-11 / NM-16 / NM-18 — Reentrant RuleEngine callback before balance effects (Low ×1, Info ×4 → Low, one cluster) + +**Claim (five reports of one structure).** In RuleEngine deployments the transfer path is +`_checkTransferred(...)` → `_checkActiveBalanceAndRevert(from, value)` (frozen-balance check) → +`ValidationModuleRuleEngine._transferred(...)` → **external** `ruleEngine_.transferred(...)` → and only then +`ERC20Upgradeable._transfer(...)`. Because the active-balance check runs before the external call and is never +re-evaluated after it, a RuleEngine that reenters `transferFrom` sees the same pre-transfer +`balanceOf`/`frozenTokens` snapshot in every frame; the final `_transfer` only validates *total* balance, so +stacked nested frames can move more than the unfrozen amount. Reported against `8_CMTATBaseERC1363.sol` (NM-7), +`0_CMTATBaseCommon.sol`/`3_CMTATBaseRuleEngine.sol` (NM-9), `5_CMTATBaseERC20CrossChain.sol` (NM-11), +`8_CMTATBaseHolderList.sol` (NM-16), and as a general checks-effects-interactions / read-only-reentrancy note +(NM-18). + +**Verdict — accepted as design (trusted-RuleEngine model); ordering confirmed, exploitability requires an +untrusted engine.** The ordering is exactly as described — verified in +`contracts/modules/3_CMTATBaseRuleEngine.sol` (`_checkTransferred` calls `CMTATBaseCommon._checkTransferred` then +`ValidationModuleRuleEngine._transferred`) and in +`contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol` (`_transferred` makes the +external call). The wrapper variants (ERC-1363, HolderList, CrossChain) inherit it unchanged, so the tool is right +that all of them share the ordering. + +Exploitation requires the configured RuleEngine to reenter, or to call attacker-controlled code during +`transferred(...)`. The RuleEngine is set exclusively by `DEFAULT_ADMIN_ROLE` (`setRuleEngine`, see +`doc/modules/controllers/validationRuleEngine.md`) and is, by construction, a **fully trusted** component: it +already decides whether *any* transfer is permitted, and a malicious engine can block every transfer or +whitelist arbitrary ones without needing reentrancy. Rules called by the CMTA RuleEngine are likewise +admin-registered (`IRule`, [CMTA/Rules](https://github.com/CMTA/Rules)). With a rule set that does not call +untrusted code — the intended configuration — there is no reentrancy vector. This is consistent with the existing +Slither disposition for `reentrancy-events` on the document engine (design choice, admin-set trusted engine). + +NM-18's read-only-reentrancy variant is the same precondition seen from outside: a third-party protocol reading +`balanceOf`/`totalSupply` *during* a RuleEngine callback observes pre-transfer state. That again requires the +trusted engine to hand control to untrusted code mid-callback. + +#### Reproduction — the exploit is real, given its precondition + +The cluster was reproduced end to end before deciding anything, with a purpose-built malicious engine +(`contracts/mocks/RuleEngine/RuleEngineReentrantMock.sol`) that performs one nested `transferFrom` during the +`transferred` callback. + +A first attempt **failed**, and the failure is informative: the engine called +`transferFrom(victim, attacker, 40)` and got `ERC20InsufficientAllowance(engine, 0, 40)`. The nested call executes +with the *engine* as `msg.sender`, so the engine — not the attacker — needs the allowance. Reentrancy alone is not +enough; the reentering party must already be authorized. That is exactly the precondition NM-9 states (*"if the +rule-engine address has spender allowance from a partially frozen holder"*), and NM-16's variant (an engine that +calls attacker-controlled code, letting the attacker's own allowance be used) is the other way to satisfy it. + +With the precondition satisfied, on an unguarded build: + +| | `balanceOf(victim)` | `frozenTokens` | attacker received | `frozenTokens <= balanceOf` | +| --- | ---: | ---: | ---: | :---: | +| Before | 100 | 60 (active 40) | — | holds | +| After outer `transferFrom(victim, attacker, 40)` + one nested 40 | **20** | 60 | **80** | **BROKEN** | + +80 tokens moved on a 40-token unfrozen allowance, and the freeze invariant was left violated. With the guard the +same scenario moves exactly 40 and the invariant holds. + +**Resolution — guard added, on the variants that can carry it.** + +- `ValidationModuleRuleEngine` now isolates the external call in an `internal virtual` + `_callRuleEngineTransferred(...)`. The base implementation is **unguarded**. +- Deployment variants with bytecode headroom inherit OpenZeppelin's `ReentrancyGuardTransient` and override that + function with `nonReentrant`. The **transient (EIP-1153)** guard is used rather than the storage-based one so no + storage slot is added: existing upgradeable proxies keep their layout and no initializer has to run. +- The guard is entered **only when a RuleEngine is set**, and released when the callback returns, so deployments + without an engine pay nothing and sequential hooks (`batchMint`, `burnAndMint`) are unaffected. + +**Why not everywhere — measured.** The guard costs ~195 bytes of deployed bytecode. Several variants are within a +few hundred bytes of the EIP-170 24 576-byte limit, and enabling it there makes them **undeployable**: + +| Variant | Unguarded | Guard | Result | +| --- | ---: | :---: | --- | +| `CMTATStandaloneSnapshot` / `CMTATUpgradeableSnapshot` | 22 664 | ✅ | 22 859 | +| `CMTATStandardStandalone` / `CMTATStandardUpgradeable` | 22 844 | ✅ | 23 039 | +| `CMTATStandaloneERC7551` / `CMTATUpgradeableERC7551` | 23 536 | ✅ | 23 731 | +| `CMTATStandaloneDebt` / `CMTATUpgradeableDebt` | 23 805 | ❌ | — | +| `CMTATStandalonePermit` / `CMTATUpgradeablePermit` | 23 961 | ❌ | — | +| `CMTATUpgradeableUUPS` | 24 176 | ❌ | — | +| `CMTATStandaloneDebtEngine` / `CMTATUpgradeableDebtEngine` | 24 429 | ❌ | would be 24 624 — **over limit** | +| `CMTATStandaloneERC1363` / `CMTATUpgradeableERC1363` | 24 443 | ❌ | would be 24 638 — **over limit** | +| `CMTATStandaloneHolderList` / `CMTATUpgradeableHolderList` | 24 456 | ❌ | would be 24 651 — **over limit** | +| Allowlist / Light variants | 20 405 / 11 562 | n/a | no RuleEngine — never reach this code | + +The selection rule applied is *unguarded size below 23 KiB*. An earlier iteration used a hand-rolled inline +transient guard (119 bytes instead of 195) to fit more variants; it was **rejected** in favour of the audited +OpenZeppelin library, because the 76 bytes saved still left `HolderList` at 1 byte of headroom — not a real margin +— and because the hand-rolled version used `tload`/`tstore` under a `^0.8.20` pragma, which would have failed with +a confusing assembly error on 0.8.20–0.8.23 instead of a clean pragma error. + +- **Tests.** `test/common/ValidationModule/RuleEngineReentrancyCommon.js` — 7 tests run against a guarded + standalone and a guarded proxy variant: the drain is blocked, the nested call is rejected, the reentrant call + reverts with `ReentrancyGuardReentrantCall` when the engine propagates it, the direct `transfer` path is guarded + too, and normal transfers / consecutive transfers / `batchMint` still work (proving the guard does not leak + across sequential callbacks). +- **Compiler floor raised.** `ReentrancyGuardTransient` requires EIP-1153 transient storage and declares + `pragma solidity ^0.8.24`, so the project can no longer be compiled at 0.8.20–0.8.23. All **128** contract files + were moved from `^0.8.20` (and one stray `^0.8.0`) to **`^0.8.24`**, so every file declares the real floor + instead of a version the build does not support. The pinned compiler is unchanged (0.8.36 in `hardhat.config.js` + and `foundry.toml`), and the Aderyn L-3 *"Unspecific Solidity Pragma"* disposition was updated to match. +- **Documentation.** `doc/modules/controllers/validationRuleEngine.md` gained a section with the per-variant table + and an explicit **WARNING** that on unguarded variants the trust assumption is load-bearing: the RuleEngine is + set by `DEFAULT_ADMIN_ROLE`, is fully trusted, and **MUST NOT** transfer control to untrusted code during + `transferred(...)`. It also explains how to enable the guard on another variant and to re-check the size. + +**Residual risk.** On the ❌ variants the behaviour is unchanged and the finding stands as originally triaged — +accepted as design, mitigated by the trust assumption, now documented rather than implied. NM-18's read-only +reentrancy (a third-party protocol reading `balanceOf` during the callback) is likewise unchanged on those +variants. + +### NM-8 — Allowance revocation blocked for frozen or non-allowlisted spenders (Low → Low — **FIXED**) + +**Verdict — VALID (duplicate of NM-3). Fixed by the same change.** The `value == 0` early return in +`_canAuthorizeAllowanceByModuleAndRevert` covers the frozen-spender and non-allowlisted-spender cases as well as +the paused case; see the Resolution under NM-3 and the regression tests +`testCanRevokeAllowanceWhenSpenderIsFrozen`, `testCanRevokeAllowanceWhenOwnerIsFrozen` and +`testCanRevokeAllowanceWhenSpenderIsNotAllowlisted`. + +### NM-10 — Documented two-step default-admin protection is absent (Info → Informational) + +**Claim.** *"The documented access-control model states that `DEFAULT_ADMIN_ROLE` is protected by OpenZeppelin's +`AccessControlDefaultAdminRules`"*, but `AccessControlModule` inherits plain `AccessControlUpgradeable`, so an +admin handover is immediate and unguarded — amplified by the `hasRole` override that grants the default admin every +role, including `PROXY_UPGRADE_ROLE` on `CMTATUpgradeableUUPS`. + +**Verdict — rejected (false premise); the described behaviour is accurate and intentional.** No CMTAT +documentation claims `AccessControlDefaultAdminRules`. The only occurrences in the repository are inside +**OpenZeppelin's own source comments** carried into `doc/hardhat-compilation/v3.0.0/flatten/*.sol` (*"We recommend +using {AccessControlDefaultAdminRules}"*) — an OZ recommendation, not a CMTAT specification. The tool read a +vendored library comment as a project commitment. + +The behaviour itself is by design: `contracts/modules/wrapper/security/AccessControlModule.sol` deliberately +overrides `hasRole` so that *"The Default Admin has all roles"*, and the initializer rejects `address(0)`. The +resulting centralization is the known, accepted governance trade-off for a regulated security token — the same +item tracked as Aderyn **L-1 Centralization Risk**, mitigated operationally at deployment (multisig / timelock / +separation of duties), not in code. + +### NM-12 — `setDocument` emits raw user inputs instead of the engine's post-state (Info → Informational) + +**Verdict — accepted as design; deliberate and already documented in code.** +`contracts/modules/wrapper/options/DocumentEngineModule.sol` carries an explicit comment explaining the choice: +the call is forwarded to the engine first (*"which reverts on invalid input"*), then the standard ERC-1643 event +is re-emitted **on the token's own address**, because ERC-1643 is a per-contract interface and integrators +subscribe to the token that exposes `setDocument` — without the re-emission the update would only be observable on +the engine's address. The engine emits on its own address as well. `removeDocument` reads the pre-state first +precisely because the spec requires the removed metadata in the event. This dual-emission is also the source of +the accepted Slither `reentrancy-events` / `unused-return` results. A document engine that silently normalizes or +ignores input would produce a divergent event — an engine-implementation contract, not a token defect. + +### NM-13 / NM-14 / NM-19 — Engine setters accept `address(this)` and non-compliant addresses (Info ×3 → Informational) + +**Claim.** `setDocumentEngine`, `setDebtEngine` and `setRuleEngine` validate only "different from the current +value"; they do not check for code, for `address(this)`, or for interface support. Setting the engine to +`address(this)` makes the delegated getters recurse until out of gas; setting it to an EOA makes reads revert on +ABI decoding, and (for ERC-1404) can make `_transferred` silently succeed against an EOA while `canTransfer` +reverts. + +**Verdict — accepted as design.** Confirmed in +`contracts/modules/wrapper/options/DocumentEngineModule.sol`, `.../DebtEngineModule.sol` and +`.../extensions/ValidationModule/ValidationModuleRuleEngine.sol` — the only guard is +`CMTAT_*_SameValue()`. This is the same disposition as AuditAgent v3.1.0 finding #4 (*"Missing contract validation +for RuleEngine address"* — design choice: full validation is unreliable, and contract operators are expected to +know what they configure). Two properties bound the impact: the role required is a privileged one +(`DOCUMENT_ENGINE_ROLE` / `DEBT_ENGINE_ROLE` / `DEFAULT_ADMIN_ROLE`), and the misconfiguration is **always +recoverable** — the setters write storage without calling the engine, so a bad engine can be replaced at any time. + +*Optional (cheap) hardening, not applied:* reject `address(this)` in the three setters. It closes the +self-recursion footgun for one comparison, without pretending to validate interface conformance. + +**Tracked for a possible future release:** [CMTA/CMTAT#395](https://github.com/CMTA/CMTAT/issues/395) — validate +engines with ERC-165 in `setRuleEngine` / `setDocumentEngine` / `setDebtEngine`. Two notes from scoping that issue: + +- The RuleEngine case is nearly free — `IRuleEngine` **already extends `IERC165`**, and + `RuleEngineInterfaceId.RULE_ENGINE_INTERFACE_ID` / `ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID` already + exist as libraries, with `RuleEngineMock` and `contracts/mocks/ERC165Helper/` already implementing them. Only the + setter check is missing. It is also the highest-value case: an EOA rule engine makes `transferred(...)` succeed + silently, so transfers proceed with **all compliance rules bypassed** — the only one of the three that fails + *open*. +- `IERC1643` and `IDebtEngine` do **not** extend `IERC165`, so requiring it there is a breaking change for + already-deployed engines, and the check would add code to variants that have under 1 KiB of headroom against the + EIP-170 limit (`CMTATStandaloneHolderList` 23.870 KiB, `CMTATStandaloneERC1363` 23.857 KiB, + `CMTATStandaloneDebtEngine` 23.844 KiB). + +### NM-15 / NM-17 — `setFrozenTokens` can freeze the zero address and brick every mint path (Info ×2 → **Low — FIXED**) + +**Claim.** `_setFrozenTokens(account, value)` writes `_frozenTokens[account]` without rejecting +`account == address(0)`, unlike `_freezePartialTokens` / `_unfreezePartialTokens`, which explicitly do. Once +`getFrozenTokens(address(0))` is non-zero, every non-zero mint fails: the common mint path validates via +`_checkTransferred(_msgSender(), address(0), account, value)` → `_checkActiveBalanceAndRevert(address(0), value)`, +and since `balanceOf(address(0)) == 0`, the `frozenTokensLocal >= balance` branch returns `false` for any +`value > 0`. + +**Verdict — VALID. This is the one substantive finding in the report, and it should be fixed.** Verified +end-to-end: + +- `contracts/modules/internal/ERC20EnforcementModuleInternal.sol` — `_setFrozenTokens` has **no** zero-address + guard, while `_freezePartialTokens` and `_unfreezePartialTokens` both open with + `if (account == address(0)) revert CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed();`. The inconsistency is + internal to the same file. +- `_checkActiveBalance(address(0), value)`: `frozenTokensLocal > 0`, `balance == 0`, so `frozenTokensLocal >= + balance` holds and the function returns `(false, 0)` for every `value > 0`. +- `contracts/modules/0_CMTATBaseCommon.sol` — `_mintOverride` calls `_checkTransferred(_msgSender(), address(0), + account, value)`, which reaches `_checkActiveBalanceAndRevert(address(0), value)`. + +**Impact.** A single `setFrozenTokens(address(0), 1)` disables `mint`, `batchMint`, `crosschainMint` and the mint +leg of `burnAndMint` across every `CMTATBaseCommon`-derived variant (Standard, Allowlist, RuleEngine, CrossChain, +ERC-1363, HolderList, Snapshot, Debt, Permit, ERC-7551). Primary issuance stops and inbound bridge settlement +stalls until it is cleared. The Light variants (`CMTATBaseCore`) are unaffected — they do not include +`ERC20EnforcementModule`, and their mint path calls `_canMintByModuleAndRevert` instead. + +**Bounding it honestly.** This is *not* reachable by an unprivileged actor: `setFrozenTokens` is gated by +`onlyERC20Enforcer` (`ERC20ENFORCER_ROLE`). It is also fully self-recoverable — `setFrozenTokens(address(0), 0)` +takes the unfreeze branch and restores minting — and it destroys no funds. That is why it is Low, not Medium. But +it is a trivially avoidable footgun, it contradicts the guard already present two functions away in the same file, +and one operator typo (or one compromised enforcer key) halts issuance protocol-wide. + +**Note on the sibling path.** `setAddressFrozen` (full-address freeze, `EnforcementModule`) is **not** affected: +`EnforcementModuleInternal._addAddressToTheList` already rejects `address(0)` with +`CMTAT_Enforcement_ZeroAddressNotAllowed()`. The defect was confined to the *partial*-freeze path, which made the +asymmetry within the enforcement modules the clearest evidence that this was an oversight rather than a decision. + +**Resolution — fixed.** + +- **Confirmation before fixing.** The behaviour was reproduced first. The repository already contained a test, + `testSetFrozenTokensOnZeroAddressDoesNotBreakMintFlow`, whose **name asserted the opposite of its body**: it + passed by requiring `mint` to revert with `ERC7943InsufficientUnfrozenBalance(address(0), 1, 0)` after + `setFrozenTokens(address(0), 1)`. In other words the mint DoS was already pinned as expected behaviour under a + reassuring name. Four new regression tests asserting the *correct* behaviour were added and confirmed **failing** + on the unfixed code (`setFrozenTokens(address(0), 1)` did not revert). +- **Fix.** `contracts/modules/internal/ERC20EnforcementModuleInternal.sol` — `_setFrozenTokens` now opens with the + same guard as its siblings: + `if (account == address(0)) revert CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed();`. + The guard is placed before the value comparison so that `setFrozenTokens(address(0), 0)` also reports the + zero-address error rather than `CMTAT_ERC20EnforcementModule_ValueEqualCurrentFrozenTokens`. +- **Tests.** `test/common/ERC20EnforcementModuleCommon.js` — added + `testCannotSetFrozenTokensOnZeroAddress`, `testSetFrozenTokensOnZeroAddressCannotBrickMint`, + `testSetFrozenTokensOnZeroAddressCannotBrickBatchMint`, + `testCannotSetFrozenTokensOnZeroAddressEvenToZero` and `testSetFrozenTokensStillWorksOnRegularAddress` (the last + one guards against regressing the normal path). The superseded + `testSetFrozenTokensOnZeroAddressDoesNotBreakMintFlow` was **removed**: it asserted the pre-fix behaviour, and + its stated intent is now covered — correctly — by `testSetFrozenTokensOnZeroAddressCannotBrickMint`. +- **Verification.** The new tests run through both the standalone and proxy enforcement suites + (`test/standard/modules/ERC20EnforcementModule.test.js`, `test/proxy/modules/ERC20EnforcementModule.test.js`) — + 116 passing. + +### NM-20 — Pausing disables privileged burn interfaces (Info → Informational — **DOCUMENTED**) + +> **Summary:** correct behaviour. Pause stops **third-party / bridge** supply operations and leaves **issuer** +> operations available. The rationale was already in `doc/README.md`; the gap was module-level scoping in +> `ERC20Burn.md`, now fixed. + +**Claim.** Documentation says pausing blocks standard transfers but not privileged burns, yet +`_authorizeBurnFrom` and `_authorizeSelfBurn` carry `whenNotPaused`, so `burnFrom` and `burn(value)` revert while +paused even for role holders. + +**Verdict — accepted as design; the "documentation says otherwise" premise is not backed by a CMTAT document.** +The behaviour is confirmed in `contracts/modules/5_CMTATBaseERC20CrossChain.sol`: `_authorizeBurnFrom`, +`_authorizeSelfBurn` and `_checkTokenBridge` are all `whenNotPaused` — intentionally, because pause is the +emergency stop for allowance-based and bridge-mediated supply movement. The issuer-controlled reduction path is +**not** blocked: the standard `BURNER_ROLE` burn (`ERC20BurnModule.burn`) routes to `_canBurnByModuleAndRevert`, +which checks deactivation and the target's frozen status but **not** pause, so it remains available while paused. +The report's premise conflates that path with the cross-chain overloads. + +#### The split is issuer operations vs third-party (bridge) operations + +The distinction the report missed is not "some burns are gated and some are not" — it is **who is acting**: + +- **Issuer operations** (`ERC20BurnModule`, `ERC20MintModule`, enforcement) express the issuer's own control over + supply. Pause is an emergency stop on *circulation*, not on the issuer's ability to manage the instrument, so + these must keep working while paused — that is the whole point of being able to pause. +- **Third-party operations** (`ERC20CrossChainModule`) are performed by a **bridge or an allowance-holding + operator**, not by the issuer. `burnFrom` spends someone else's allowance; `burn(uint256)` is a self-burn by a + bridge-side actor holding `BURNER_SELF_ROLE`; `crosschainMint` / `crosschainBurn` are the ERC-7802 bridge + entry points. These are exactly the flows a pause is meant to halt: while the token is paused, cross-chain + settlement must stop rather than continue moving supply between chains against a frozen local state. + +Read that way, `whenNotPaused` on `_authorizeBurnFrom`, `_authorizeSelfBurn` and `_checkTokenBridge` is not an +inconsistency with the issuer burn path — it is the line between the two categories, drawn deliberately. + +#### Measured behaviour + +Probed on `CMTATStandardStandalone` with the contract paused (throwaway test, not retained): + +| Path | Module | Role | While paused | +| --- | --- | --- | --- | +| `burn(address,uint256)` | `ERC20BurnModule` (issuer) | `BURNER_ROLE` | **Allowed** | +| `batchBurn(address[],uint256[])` | `ERC20BurnModule` (issuer) | `BURNER_ROLE` | **Allowed** | +| `mint(address,uint256)` | `ERC20MintModule` (issuer) | `MINTER_ROLE` | **Allowed** | +| `forcedTransfer(...)` | `ERC20EnforcementModule` (issuer/enforcement) | `DEFAULT_ADMIN_ROLE` | **Allowed** | +| `burnFrom(address,uint256)` | `ERC20CrossChainModule` (third party) | `BURNER_FROM_ROLE` | **Blocked** — `EnforcedPause()` | +| `burn(uint256)` self-burn | `ERC20CrossChainModule` (third party) | `BURNER_SELF_ROLE` | **Blocked** — `EnforcedPause()` | +| `crosschainBurn(address,uint256)` | `ERC20CrossChainModule` (bridge) | `CROSS_CHAIN_ROLE` | **Blocked** — `EnforcedPause()` | +| `crosschainMint(address,uint256)` | `ERC20CrossChainModule` (bridge) | `CROSS_CHAIN_ROLE` | **Blocked** — `EnforcedPause()` | + +The split is clean along the issuer / third-party line, with no exceptions. (`forcedBurn` is a `CMTATBaseCore` +function and is therefore absent from the full variants; on the Light variants it is gated only by +`DEFAULT_ADMIN_ROLE`, so it too survives pause — consistent with the issuer-operation rule.) + +#### Is this already documented? Yes — including the rationale + +The behaviour **and** its rationale were already written down. `doc/README.md`, under *Pause & Deactivate contract +(PauseModule) → Note*, states both halves explicitly: + +> 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. […] 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**. + +That last clause is precisely the issuer-vs-third-party principle. The per-function facts are documented too: + +| Statement | Where | +| --- | --- | +| Rationale — issuer supply management vs cross-chain bridge functions | `doc/README.md` (*Pause & Deactivate → Note*) | +| *"Burn can occur even if transfers are paused."* | `doc/modules/core/ERC20Burn/ERC20Burn.md` | +| *"If the interface `{IERC7551Pause}` is implemented, minting is allowed even when transfers are paused."* | `doc/modules/core/ERC20Mint/ERC20Mint.md` | +| *"The contract must not be paused — error: `EnforcedPause()`"* on `crosschainMint`, `crosschainBurn`, `burnFrom` and `burn(uint256)` | `doc/modules/options/erc20crosschain/ERC20CrossChain.md` | + +So the report's premise — that documentation promises privileged burns remain available — is **half true** in a +narrower sense than first assessed: `doc/README.md` is correct and complete, but the *module-level* page +`ERC20Burn.md` states "burn can occur even if transfers are paused" without scoping it to `ERC20BurnModule`. An +integrator reading only that page and then calling `ERC20CrossChainModule.burnFrom` would be surprised. Given the +two functions share the name `burn`, that is the most plausible route to the finding. + +> **Correction.** An earlier revision of this entry stated that the rationale was undocumented. That was wrong — +> it is in `doc/README.md`, which the initial search did not cover. The gap was narrower: module-level scoping, +> not a missing rationale. + +**Resolution — documented (no behaviour change).** Since `doc/README.md` already carried the rationale, the work +was to propagate it to the module pages where the ambiguity actually bites, and to remove the over-promise. + +- `doc/modules/core/ERC20Burn/ERC20Burn.md` — **the important edit.** The *"Burn can occur even if transfers are + paused"* note is now scoped to the issuer burn it documents, and states that the `ERC20CrossChainModule` burns + are blocked. This is the sentence that most plausibly produced the finding. +- `doc/modules/core/Pause/pause.md` — new section *"What pause stops, and what it does not"*, stating the + issuer-vs-third-party principle and tabulating every affected path (mint, issuer burn, enforcement, holder + transfers, the four `ERC20CrossChainModule` entry points, and both `approve` cases), closing on the `burn` + name collision. The Rationale section also gained a sentence on the NM-3 revocation carve-out, which the pause + documentation still described in pre-v3.2.0 terms. +- `doc/modules/options/erc20crosschain/ERC20CrossChain.md` — a note directly under the title covering all four + entry points, with the reason and the same warning about the two `burn` overloads. +- `doc/README.md` — the existing *Pause & Deactivate → Note* was **extended in place** (not duplicated elsewhere) + with the per-path table, the `burn` name-collision warning and the allowance-revocation carve-out. + +The per-function requirement lists were not changed — they were already accurate. + +### NM-21 — Mutable token name desynchronizes the EIP-712 domain separator (Info → Informational — **DOCUMENTED**) + +**Claim.** `TokenAttributeModule.setName()` changes `name()`, but the EIP-712 domain separator was built from the +initial name and OpenZeppelin provides no way to update it, so `permit` suffers "a permanent denial of service" +after a rename. + +**Verdict — accepted as design; accurate mechanism, overstated impact.** The mechanism is confirmed: +`contracts/modules/6_CMTATBaseERC2612.sol` initializes with `__EIP712_init_unchained(ERC20Attributes_.name, "1")`, +`EIP712Upgradeable` stores that name in its own ERC-7201 storage, and OZ documents that *"These parameters cannot +be changed except through a smart contract upgrade."* `setName` writes `TokenAttributeModule`'s storage only. + +But `permit` does **not** break. The domain separator stays stable and valid, and the contract exposes ERC-5267 +`eip712Domain()` (via `ERC20PermitUpgradeable` → `EIP712Upgradeable` → `IERC5267`), which returns the name +actually in use. Wallets and dApps that build the domain the standard way — from `eip712Domain()` — are unaffected. +Only integrators that derive the domain from `name()` would produce signatures that fail. So this is an +integration caveat, not a denial of service. + +**Empirical confirmation.** Probed on `CMTATStandalonePermit` (throwaway test, not retained), calling +`setName("RENAMED TOKEN")` on a token deployed as `CMTA Token`: + +| Observation | Result | +| --- | --- | +| `name()` after the rename | `RENAMED TOKEN` | +| `eip712Domain().name` after the rename | `CMTA Token` (unchanged) | +| `DOMAIN_SEPARATOR()` | unchanged | +| `permit` signed with the **new** `name()` | Reverts `ERC2612InvalidSigner` | +| `permit` signed with `eip712Domain().name` | **Succeeds** | + +This settles the severity question: `permit` is **not** disabled by a rename. The report's *"permanent denial of +service for the `permit` functionality"* is incorrect — the function keeps working for any signer that discovers +the domain the standard way. Only an integration that hard-codes the domain from `name()` breaks, and it breaks +silently at the moment of the rename until a `permit` call reverts. That is an integration caveat worth +documenting, not a defect to fix. (Note that CMTAT's own `test/common/PermitModuleCommon.js` builds its domain +from `await this.cmtat.name()` — correct in the tests, since they never rename, but a fair illustration of how +natural the wrong pattern is.) + +**Resolution — documented (no behaviour change).** + +- `contracts/modules/wrapper/core/TokenAttributeModule.sol` — a `WARNING` block on `setName` states that the + EIP-712 domain separator is not updated by a rename, that permits stay valid, and that signers must use + `eip712Domain()` / `DOMAIN_SEPARATOR()` rather than `name()`, naming the `ERC2612InvalidSigner` failure mode. +- `contracts/modules/6_CMTATBaseERC2612.sol` — the same point, briefly, on `permit`. +- `doc/modules/options/erc2612/erc2612.md` — new section *"The EIP-712 domain name is fixed at deployment"* with + the before/after table, the do/don't for building the domain, and a note for issuers who intend to use + `setName` on a Permit deployment to confirm their integrators read `eip712Domain()`. +- `doc/modules/core/ERC20Base/ERC20base.md` — a cross-referencing note on the `setName(string)` reference entry. + +The Solidity edits are comments only; the bytecode is unchanged. + +### NM-22 — ERC-7551 `setTerms` overload silently erases the document name (Info → **Informational — FIXED**) + +**Claim.** `ERC7551Module.setTerms(bytes32 hash_, string calldata uri_)` constructs +`IERC1643CMTAT.DocumentInfo("", uri_, hash_)` and forwards it to `_setTerms`, which overwrites the whole terms +struct — wiping a `name` previously set through `ExtraInformationModule.setTerms(DocumentInfo)`. + +**Verdict — VALID (minor). Fixed.** Confirmed in +`contracts/modules/wrapper/options/ERC7551Module.sol` (the `""` literal) and +`contracts/modules/wrapper/extensions/ExtraInformationModule.sol`, where `_setTerms` unconditionally assigns +`$._terms.name = terms_.name`. The ERC-7551 signature carries no name, so the overload cannot supply one; the +result is silent data loss in on-chain terms metadata that off-chain legal/compliance references may rely on. No +funds or transfer logic are affected, and the name can be restored via the `DocumentInfo` overload — hence +Informational. + +**Resolution — fixed.** + +- **Confirmation before fixing.** As with NM-15, the repository already **pinned the erasure in a test**: + `testAdminCanUpdateTerms` (`test/common/ERC7551ModuleCommon.js`) asserted the resulting name was `''` after an + ERC-7551 `setTerms`, even though the token is deployed with the terms name `'doc1'`. A new test asserting the + name is preserved was added first and confirmed **failing** (`expected '' to equal 'doc1'`). +- **Fix.** + - `contracts/modules/wrapper/extensions/ExtraInformationModule.sol` — new internal + `_setTermsDocument(bytes32 documentHash_, string memory uri_)` updates only the document part + (`uri`, `documentHash`, `lastModified`) and emits the same `Terms($._terms)` event, leaving `$._terms.name` + untouched. + - `contracts/modules/wrapper/options/ERC7551Module.sol` — `setTerms(bytes32,string)` now calls + `_setTermsDocument(hash_, uri_)` instead of building a `DocumentInfo("", uri_, hash_)` and routing it through + `_setTerms`. The now-unused `IERC1643CMTAT` import was removed. + - The `ICMTATBase` overload `setTerms(IERC1643CMTAT.DocumentInfo)` is unchanged: supplying a name explicitly + still sets it, including to the empty string if that is what the caller passes. + - Both events are still emitted exactly as before (`ICMTATBase.Terms(CMTATTerms)` from the module, + `IERC7551Document.Terms(bytes32,string)` from the overload). +- **Tests.** `test/common/ERC7551ModuleCommon.js` — added `testERC7551SetTermsPreservesDocumentName` (asserts the + uri and hash update while the name survives). The pre-existing `testAdminCanUpdateTerms` was updated: its + expected name changed from `''` to `TERMS[0]`, since it had encoded the erasure as expected behaviour. +- **Verification.** ERC-7551 standalone + upgradeable suites: 476 passing. Full suite (current tree): **5998 passing / 0 failing**. + +### NM-23 — `detectTransferRestrictionFrom` reports `SPENDER_FROZEN` before deactivated/paused (Best Practices → Informational) + +**Claim.** ERC-1404 restriction-code ordering requires `DEACTIVATED`, then `PAUSED`, then participant-frozen +codes. `ValidationModuleERC1404.detectTransferRestrictionFrom` evaluates `isFrozen(spender)` first, so a +deactivated-or-paused contract with a frozen spender returns code 5 instead of 1 or 2. + +**Verdict — accepted as design (valid nit, no impact).** Confirmed in +`contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol`: the `isFrozen(spender)` +branch precedes `_detectTransferRestriction`, which is where the `deactivated()` / `paused()` checks live. The +report itself concludes correctly: *"because bad codes are non-zero, the transfer is still correctly predicted to +be blocked, so this is a reporting/state-drift inconsistency, not a bypass."* Only the *reason* an integrator +displays differs from the reason the enforcement path (`_canTransferStandardByModuleAndRevert`, which reverts on +pause first) would raise. + +#### What the fix would change in code + +Today `detectTransferRestrictionFrom` checks the spender first, then delegates the rest to +`_detectTransferRestriction`, which holds the deactivated/paused checks: + +```solidity +function detectTransferRestrictionFrom(address spender, address from, address to, uint256 value) ... { + if (isFrozen(spender)) { // <-- evaluated before deactivated/paused + return TRANSFER_REJECTED_SPENDER_FROZEN; // (code 5) + } else { + uint8 codeReturn = _detectTransferRestriction(from, to, value); // deactivated(1) → paused(2) → from(3) → to(4) + ... + } +} +``` + +The required order is deactivated (1) → paused (2) → **then** the frozen-participant codes. Two ways to get there, +each with a different trade-off: + +**Variant 1 — delegate first, check the spender last (smallest, reorders among the frozen codes).** + +```solidity +uint8 codeReturn = _detectTransferRestriction(from, to, value); // deactivated → paused → from → to +if (codeReturn != TRANSFER_OK) { + return codeReturn; +} else if (isFrozen(spender)) { + return TRANSFER_REJECTED_SPENDER_FROZEN; +} else if (address(ruleEngine_) != address(0)) { + return ruleEngine_.detectTransferRestrictionFrom(spender, from, to, value); +} else { + return TRANSFER_OK; +} +``` + +This satisfies the invariant (deactivated/paused always precede `SPENDER_FROZEN`) with essentially no size change, +but it also moves the spender-frozen code from *first* to *last* among the frozen codes: when the spender **and** +`from`/`to` are all frozen, the function now returns `FROM_FROZEN`/`TO_FROZEN` instead of `SPENDER_FROZEN`. That is +a second, subtler change to the reported reason. + +**Variant 2 — evaluate deactivated/paused inline before the spender branch (preserves spender-first, costs a little +size).** + +```solidity +if (deactivated()) return TRANSFER_REJECTED_DEACTIVATED; +else if (paused()) return TRANSFER_REJECTED_PAUSED; +else if (isFrozen(spender)) return TRANSFER_REJECTED_SPENDER_FROZEN; +else { uint8 codeReturn = _detectTransferRestriction(from, to, value); ... } +``` + +This keeps `SPENDER_FROZEN` ahead of `FROM_FROZEN`/`TO_FROZEN`, but the `deactivated()`/`paused()` checks now run +**twice** (again inside `_detectTransferRestriction`) — two redundant `SLOAD`s and a few extra bytes of bytecode +on contracts (`ERC1363`, `HolderList`, `DebtEngine`) that are already within a few hundred bytes of the EIP-170 +limit. `detectTransferRestrictionFrom` is a `view`, so the gas is only paid by off-chain callers, but the size is +paid at deploy time regardless. + +#### Drawbacks common to both + +- **It is an observable change to a returned value.** For the specific state (contract deactivated or paused **and** + the spender frozen) the function returns a different non-zero code than before. No transfer outcome changes — the + transfer is still predicted blocked, and the enforcement path is untouched — but any off-chain integrator + (exchange, wallet) that keys UI or logic on the exact code sees a different reason. That is precisely the class + of consumer ERC-1404 restriction codes exist for, so it is not purely internal. +- **No on-chain benefit.** The write path (`_canTransferStandardByModuleAndRevert`) already reverts on pause before + any frozen check, so the fix only aligns the *predicted* reason with the *enforced* reason; it removes a + reporting/state-drift inconsistency, nothing more. +- `messageForTransferRestriction` needs no change — the code *values* are unchanged, only which one is returned in + the overlap case. + +**Recommendation.** Low priority; if applied, prefer **Variant 1** — it matches the invariant the finding asks for +with no size cost, and the spender-vs-from/to reordering it introduces is within the "frozen participant" group the +spec does not order internally. Because it is nonetheless an observable code change for integrators, it is best +bundled into a release that already touches the ERC-1404 surface rather than shipped on its own. Left unapplied by +this triage. + +### NM-24 — Unconditional `Spend` emission contradicts the interface documentation (Best Practices → **Informational — FIXED (doc-only)**) + +**Claim.** `ERC20BaseModule.transferFrom` emits `Spend` on every successful transfer, and +`ERC20CrossChainModule._burnFrom` emits it immediately after `_spendAllowance`, without suppressing the +infinite-allowance case — contradicting the documented semantics and poisoning event-driven allowance accounting. + +**Verdict — VALID as a documentation defect. Recommended for fixing (NatSpec, not behaviour).** The two are in +direct contradiction: + +- `contracts/interfaces/technical/IERC20Allowance.sol` — the `Spend` NatSpec states *"This event is **NOT** + emitted when the allowance is infinite (`type(uint256).max`), because in that case OpenZeppelin does not reduce + the allowance."* +- `contracts/modules/wrapper/core/ERC20BaseModule.sol` — `transferFrom` emits `Spend` whenever the transfer + succeeds, with an inline comment saying the opposite: *"emit Spend does not necessarily imply an allowance + reduction. This is the case if the allowance is set to `uint256.max`."* +- `contracts/modules/wrapper/options/ERC20CrossChainModule.sol` — `_burnFrom` likewise emits unconditionally. + +The **implementation comment is correct and the interface NatSpec is stale.** This is the tail of Wake Arena +finding L1 (*"Misleading `Spend` event emitted on `transferFrom` when allowance is infinite"*, acknowledged with a +comment added): the comment landed in `ERC20BaseModule`, but the interface documentation that states the opposite +was never updated. An integrator reading the interface — the natural place to look — gets the wrong contract. + +#### `transferFrom` vs `burnFrom` — the two emit sites differ + +There are exactly two `Spend` emit sites in the codebase. They agree on the defect but differ in three ways that +matter to an indexer. + +| | `ERC20BaseModule.transferFrom` | `ERC20CrossChainModule._burnFrom` | +| --- | --- | --- | +| Available on | every variant with an allowance surface | CrossChain-derived variants only | +| Allowance spent by | `ERC20Upgradeable.transferFrom` (internally) | an explicit `ERC20Upgradeable._spendAllowance(account, sender, value)` | +| Emitted | **after** the transfer completes | **between** `_spendAllowance` and the burn | +| Guarded | `if (result) { … }` | unconditional | +| Spender argument | `_msgSender()`, read at emit time | the `sender` parameter, captured in `burnFrom` as `_msgSender()` | +| Event order in the receipt | `Transfer` → `Spend` | `Spend` → `Transfer` → `BurnFrom` | + +The **event ordering is inverted** between the two paths, confirmed by probe (throwaway test, not retained): + +``` +transferFrom (infinite): [Transfer -> Spend] +burnFrom (infinite): [Spend -> Transfer -> BurnFrom] +transferFrom (finite) : [Transfer -> Spend] +burnFrom (finite) : [Spend -> Transfer -> BurnFrom] +``` + +This falls out of where each site sits: `ERC20BaseModule` wraps the OpenZeppelin call and emits once it returns, +whereas `_burnFrom` emits between spending the allowance and performing the burn. An indexer that pairs a `Spend` +with the *following* `Transfer` will mis-associate them on one of the two paths. Neither ordering is wrong, but +they are not consistent with each other, and nothing documents that. + +The `if (result)` guard on `transferFrom` is vacuous — `ERC20Upgradeable.transferFrom` either returns `true` or +reverts — so both sites are unconditional in practice. The difference is cosmetic but makes one site *look* +conditional and the other not. + +The self-burn path `burn(uint256)` correctly emits **no** `Spend`: it calls `_burnFromOperator` directly, without +`_spendAllowance`, because no allowance is involved. + +#### The report found half of the accounting drift + +Probed on `CMTATStandardStandalone`: + +| Path | Allowance actually reduced? | `Spend` emitted? | Result | +| --- | --- | --- | --- | +| `transferFrom`, finite allowance | Yes | Yes | Correct | +| `transferFrom`, infinite allowance | **No** (stays `type(uint256).max`) | **Yes** | **Over-reports** — the NM-24 case | +| `burnFrom`, finite allowance | Yes | Yes | Correct | +| `burnFrom`, infinite allowance | **No** (stays `type(uint256).max`) | **Yes** | **Over-reports** — the NM-24 case | +| `forcedTransfer` against an existing allowance | **Yes** (500 → 490) | **No** | **Under-reports** — not in the report | + +The last row is the mirror image of the finding and the tool did not surface it. +`ERC20EnforcementModuleInternal._forcedTransfer` reduces the owner→recipient allowance when one exists, using +`ERC20Upgradeable._approve(from, to, …, false)`. The trailing `false` suppresses the `Approval` event, and no +`Spend` is emitted either, so a forced transfer silently consumes allowance with **no allowance-related event at +all** — the observed receipt is `[Transfer -> ForcedTransfer]` while the allowance moves from 500 to 490. + +> **Update (applied):** the `forcedTransfer` row above describes the state at triage. It has since been fixed — +> `_forcedTransfer` now emits `Spend` on the allowance reduction (see Resolution below), so that path no longer +> under-reports. The `transferFrom`/`burnFrom` over-report on infinite approvals is unchanged. + +So an integrator reconstructing allowances purely from events drifts in *both* directions: too low after an +infinite-approval `transferFrom`/`burnFrom`, and too high after a `forcedTransfer`. Any correct integration must +read `allowance()` rather than accumulate events — which is the substantive guidance, and is what the corrected +NatSpec should say. + +The `forcedTransfer` behaviour is arguably intended (an enforcement action is not a spend by the spender, and the +suppressed `Approval` avoids implying the *owner* re-approved), but it is undocumented, and it is the more +surprising of the two directions. + +#### Making the two paths consistent — options, drawbacks, recommendation + +If CMTA wants `transferFrom` and `burnFrom` to emit `Spend` **identically** (same ordering, same +infinite-allowance handling), there are three ways to get there. They differ in how much behaviour they change and +what they cost. + +**Option A — emit `Spend` from a single overridden `_spendAllowance` (behaviour change; reconciles code with the +interface).** Both paths already funnel their allowance spend through OpenZeppelin's +`ERC20Upgradeable._spendAllowance(owner, spender, value)` — `transferFrom` calls it internally, `_burnFrom` calls +it explicitly. That function reduces the allowance **only when it is finite** (`currentAllowance < type(uint256).max`). +Overriding it once, emitting `Spend` inside that same finite branch, and deleting the two explicit `emit Spend` +statements would make the two paths identical *and* make the behaviour match what `IERC20Allowance.Spend` already +claims — no `Spend` on an infinite allowance: + +```solidity +function _spendAllowance(address owner, address spender, uint256 value) internal virtual override { + if (allowance(owner, spender) != type(uint256).max) { + emit IERC20Allowance.Spend(owner, spender, value); + } + super._spendAllowance(owner, spender, value); +} +``` + +- *Upside:* one emit site, one ordering (`Spend` → `Transfer` on both paths), and the interface NatSpec becomes + true as written instead of needing correction. +- *Drawbacks:* (1) it is an **observable behaviour change** — `Spend` stops being emitted for infinite-allowance + spends, and the `transferFrom` order flips from `Transfer → Spend` to `Spend → Transfer`; any existing indexer + keyed on either is broken, so this belongs in a **major version**, not a patch. (2) The `allowance(...)` read in + the override is an **extra `SLOAD` on every `transferFrom`** — the hottest path in the token — unless + `_spendAllowance` is fully re-implemented to reuse the value it already loads, which means diverging from the + audited OpenZeppelin body. (3) It removes the "a delegated spend happened" signal that infinite-approval + integrators may currently rely on. (4) It does **not** address the `forcedTransfer` gap (that path never touches + `_spendAllowance`). + +**Option B — reorder `_burnFrom` so its `Spend` is emitted after the burn (ordering only).** Move the `emit Spend` +in `ERC20CrossChainModule._burnFrom` to after `_burnFromOperator`, giving `Transfer → BurnFrom → Spend` so that +`Spend` is last on both paths. + +- *Upside:* cheapest possible change — no gas cost, no size cost, no infinite-allowance semantics change. +- *Drawbacks:* it only aligns the *ordering*, so the actual NM-24 contradiction (emission on infinite allowance) + is untouched and still needs the NatSpec fix anyway; it decouples the `Spend` event from the `_spendAllowance` + call it represents, so the code reads less obviously; and it is still an observable change for any indexer keyed + on the current order. Cosmetic alignment for cosmetic inconsistency — little is actually bought. + +**Option 0 — document only (no code change).** Correct the `IERC20Allowance.Spend` NatSpec, and note the ordering +difference and the `forcedTransfer` gap. + +- *Upside:* no gas, no bytecode, no behaviour change, nothing broken for existing integrators. The one piece of + guidance that actually matters — *reconstruct allowances from `allowance()`, never by summing `Spend` events* — + is a documentation fix in every option, so it fully resolves the integrator-facing problem on its own. +- *Drawback:* the two paths stay cosmetically inconsistent (different event order); integrators have to read the + note rather than infer a single rule from behaviour. + +**Recommendation — Option 0 (document only).** The inconsistency is real but harmless: no funds, no accounting +error for anyone who reads `allowance()`, and the two "wrong" directions (over-report on infinite approvals, +under-report on `forcedTransfer`) are both event-only. Every code option imposes an observable behaviour change — +and Option A additionally adds an `SLOAD` to the busiest function in the contract and risks the EIP-170 size limit +on the variants that are already within a few hundred bytes of it. Spending gas and a breaking change to make a +cosmetic difference disappear is a poor trade when the correctness guidance is a doc fix regardless. If CMTA does +want the interface's current "no `Spend` on infinite" wording to become literally true, that is **Option A, +deferred to a major version**, done together with the same treatment for `forcedTransfer`. + +**Resolution — documentation, plus one small behaviour change to close the `forcedTransfer` under-report.** + +- `contracts/modules/internal/ERC20EnforcementModuleInternal.sol` — **behaviour change.** `_forcedTransfer` now + emits `IERC20Allowance.Spend(from, to, spentAllowance)` when it reduces a finite, non-zero `from`→`to` allowance + (`spentAllowance = min(currentAllowance, value)`). This closes the under-report row above: the reduction is no + longer silent. The allowance-reduction logic is unchanged (the `_approve(..., false)` still suppresses + `Approval`); only the `Spend` emission is added. Measured cost: +72 bytes on the tightest variant + (`CMTATStandaloneHolderList`, now 24 528 / 24 576 — 48 bytes of headroom), within limit on all variants. +- `contracts/interfaces/technical/IERC20Allowance.sol` — the `Spend` NatSpec was corrected. It previously claimed + the event is *not* emitted for infinite allowances (the reverse of the implementation); it now states that + `Spend` **is** emitted on every allowance-consuming `transferFrom`/`burnFrom` including infinite approvals, that + `value` is the amount used rather than any reduction, that `forcedTransfer` now emits `Spend` on the reduction it + performs (finite non-zero allowance only), and that integrators must read `allowance(owner, spender)` rather than + accumulate `Spend`/`Approval` events. +- `doc/technical/allowance-spend-event.md` (new) — a cross-cutting reference covering the three emit sites, the + ordering difference, the residual over-report on infinite approvals, the read-`allowance()` guidance, and a + **"Possible improvement — making the emit sites consistent"** section describing the single-`_spendAllowance` + unification (Option A above), its drawbacks, and why the `transferFrom`/`burnFrom` half is deferred. Linked from + the README technical index. +- Tests — `test/common/ERC20EnforcementModuleCommon.js`: the two allowance-reducing `forcedTransfer` tests now + assert the `Spend` amount (full and partial consumption), plus two new tests asserting **no** `Spend` when there + is no allowance and when the allowance is infinite. + +Only the `forcedTransfer` under-report was closed in behaviour; the remaining `transferFrom`/`burnFrom` +inconsistencies (ordering, emission on infinite approvals) stay documentation-only, recorded in the technical doc +as a possible future improvement rather than scheduled work. + +--- + +## Delta from AuditAgent v3.1.0 + +The previous run (14 findings: 2 High, 2 Medium, 10 Low) was triaged as 7 invalid / 7 design choices, with no code +fix required; one item was later fixed anyway (v3.1.0 #13 → `approve` gained `whenNotPaused` in v3.2.0). + +| Aspect | v3.1.0 | v3.3.0-rc2 | +| --- | --- | --- | +| Findings | 14 | 24 | +| Distribution | 2 H / 2 M / 10 L | 1 H / 4 M / 3 L / 14 Info / 2 BP | +| Fix required | none | 3 distinct items (NM-15/17, NM-22, NM-24) | + +- **Carried over unchanged.** NM-1/NM-2 restate v3.1.0 #2 (proxy front-running — rejected then and now). NM-5 + restates #3 and #10 (spender not checked on mint/burn paths — design). NM-13/NM-14/NM-19 restate #4 (engine + address not validated — design). +- **Caused by the v3.1.0 → v3.2.0 fix, and now reconciled.** NM-3 and NM-8 are the mirror image of v3.1.0 #13: + having added `whenNotPaused` to `approve`, the tool now reports that holders cannot revoke allowances while + restricted. The two runs ask for opposite behaviour, and both are right about their own case — so the fix splits + them on the value: non-zero grants stay blocked (v3.1.0 #13 upheld), zero-value revocation is always allowed + (NM-3/NM-8 fixed). +- **New surface, new findings.** The reentrancy-ordering cluster (NM-7/9/11/16/18) is reported for the first time + and now spans the v3.3.0 additions (HolderList, ERC-1363, CrossChain wrappers). NM-15/NM-17, NM-22 and NM-24 are + new and are the only items with a recommended code or documentation change. +- **Resolved from v3.1.0.** #1 (partial-freeze not enforced), #7 (unfreeze/balance reentrancy window), #9 + (SnapshotEngine hook bypass), #11 (forced transfers), #12 (deactivation handling) and #14 (ERC-2771 forwarder) + do not reappear. + +## Executive triage + +**Nothing in this report is exploitable by an unprivileged actor, and no funds are at risk.** The single High +(NM-1) and its Medium duplicate (NM-2) are false positives — implementations call `_disableInitializers()` and +proxies are initialized atomically, a precondition the report itself admits it did not demonstrate. Of the +remaining three Mediums, NM-4 requires an administrator to grant `CROSS_CHAIN_ROLE` to the ERC-2771 forwarder — +the exact configuration the code comment forbids — and NM-3/NM-5 are documented design positions. + +**All actionable items have been resolved. No item remains open.** The four defects and the reentrancy cluster +were fixed in code where warranted; the rest were documented. Summary: + +1. **NM-15 / NM-17 — `_setFrozenTokens` missing the zero-address guard** (`ERC20EnforcementModuleInternal.sol`). + An `ERC20ENFORCER_ROLE` holder could halt all minting protocol-wide with one call. **FIXED** — guard added + (matching the sibling functions), 5 regression tests; the pre-existing test that pinned the bug under a + misleading name was removed. +2. **NM-3 / NM-8 — allowance revocation blocked while paused or restricted** (`ValidationModuleAllowance.sol` + + 4 call sites). **FIXED** — `value == 0` is always authorized; non-zero grants remain gated exactly as before + (7 `approve` revocation tests plus 3 `permit` revocation tests; two negative guards). +3. **NM-24 — `Spend` event contradicts its NatSpec, and `forcedTransfer` consumed allowance silently.** **FIXED** — + the `IERC20Allowance.Spend` NatSpec was corrected, and `_forcedTransfer` now emits `Spend` on the allowance + reduction (4 regression tests). The residual `transferFrom`/`burnFrom` cosmetic inconsistency is documented in + `doc/technical/allowance-spend-event.md` as an optional future improvement. +4. **NM-22 — ERC-7551 `setTerms` overload wiped the terms document name.** **FIXED** — name-preserving overload + (`_setTermsDocument`), 1 regression test; the test that pinned the erasure was corrected. +5. **NM-7 / NM-9 / NM-11 / NM-16 / NM-18 — RuleEngine callback reentrancy.** **FIXED where it fits** — the external + callback is isolated in a `virtual` `_callRuleEngineTransferred`, wrapped in OpenZeppelin's + `ReentrancyGuardTransient` (`nonReentrant`) on the deployment variants with bytecode headroom (Standard, + Snapshot, ERC-7551). The variants without headroom stay unguarded **by design**, and the trust assumption (the + `DEFAULT_ADMIN_ROLE`-set RuleEngine must not hand control to untrusted code) is now documented with a + per-variant table in + [`doc/modules/controllers/validationRuleEngine.md`](../../../../modules/controllers/validationRuleEngine.md). + Malicious-engine mock + 7 regression tests. + +**The NM-5 documentation follow-up is also resolved.** `doc/technical/access-control.md` previously claimed a +frozen operator cannot mint. Probing showed the opposite — CMTAT's own freeze checks the recipient, not the +operator, so a frozen `MINTER_ROLE` holder mints successfully (a configured RuleEngine may still reject via the +spender it receives; the Light variant has no RuleEngine). The behaviour is intended and unchanged; the +documentation was corrected across `access-control.md` (with a per-operation/per-deployment table), `doc/README.md`, +`ERC20Mint.md` and `cross-chain-bridge-integration.md`, and locked in by tests (`testFrozenMinterCanStillMint` / +`…BatchMint`, verified on Standard, Light and Allowlist; `testMintPropagatesSpenderToRuleEngine` for the RuleEngine +rejection path). The Light `_minterTransferOverride` was additionally aligned to pass `_msgSender()` (behaviour- +neutral). diff --git a/doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2.pdf b/doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2.pdf new file mode 100644 index 00000000..683fdfb7 Binary files /dev/null and b/doc/security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2.pdf differ diff --git a/doc/security/tools/slither/v3.3.0-slither-feedback.md b/doc/security/tools/slither/v3.3.0-slither-feedback.md index c4696923..79860690 100644 --- a/doc/security/tools/slither/v3.3.0-slither-feedback.md +++ b/doc/security/tools/slither/v3.3.0-slither-feedback.md @@ -1,22 +1,25 @@ # CMTAT Maintainer Feedback - Slither v3.3.0 -Date: 2026-07-22 +Date: 2026-07-30 Source report: [v3.3.0-slither-report.md](./v3.3.0-slither-report.md) ## Scope -CMTA maintainer assessment of Slither findings for CMTAT **v3.3.0** (final), run on the current source. +CMTA maintainer assessment of Slither findings for CMTAT **v3.3.0**, run on the v3.3.0-rc3 source (`dev`). - Tool: `slither 0.11.5` - Command: `slither . --checklist --filter-paths "node_modules,lib,test,forge-std,mocks"` -- Scope: production contracts, **mocks excluded**. 221 contracts analyzed, 110 results. +- Scope: production contracts, **mocks excluded**. 225 contracts analyzed, 158 results. +- Build: solc 0.8.36, EVM target `osaka`. -> Refreshes the earlier v3.3.0 snapshot (2026-05-20) against the final v3.3.0 code. Two new detectors appear (`unused-return`, `reentrancy-events`) — both stem from the intentional ERC-1643 document-engine dual-emission; `unindexed-event-address` no longer fires. +> Refreshes the 2026-07-22 snapshot against the rc3 code (RuleEngine reentrancy guard, `forcedTransfer` allowance +> `Spend`, `setTerms` name preservation, `_setFrozenTokens` zero-address guard, Light minter-transfer spender). +> The same seven detectors fire; only `calls-loop` changed count, and for a call-graph reason (see the delta). ## Report Snapshot - Medium: 2 categories (`uninitialized-local` 1, `unused-return` 2) -- Low: 2 categories (`calls-loop` 28, `reentrancy-events` 2) +- Low: 2 categories (`calls-loop` 76, `reentrancy-events` 2) - Informational: 3 categories (`assembly` 16, `dead-code` 1, `naming-convention` 60) - High: 0 @@ -26,7 +29,7 @@ CMTA maintainer assessment of Slither findings for CMTAT **v3.3.0** (final), run |---|---|---|---:|---|---|---| | S-1 | `uninitialized-local` | Medium | 1 | Invalid (false positive) | `_unfreezeTokens.activeBalance` defaults to `0` intentionally (frozen ≥ balance branch) | Closed | | S-2 | `unused-return` | Medium | 2 | Invalid (false positive) | `DocumentEngineModule` forwards `getDocument` and intentionally discards `lastModified` | Closed | -| S-3 | `calls-loop` | Low | 28 | Design choice | External calls in batch/hook loops are expected | Accepted | +| S-3 | `calls-loop` | Low | 76 | Design choice | External compliance/snapshot hooks in batch loops are expected | Accepted | | S-4 | `reentrancy-events` | Low | 2 | Design choice | `DocumentEngineModule` re-emits after the admin-set, trusted engine call; no exploitable state | Accepted | | S-5 | `assembly` | Informational | 16 | Valid (expected) | ERC-7201 namespaced storage-slot access | Accepted | | S-6 | `dead-code` | Informational | 1 | Invalid (false positive) | `CMTATBaseHolderList._msgData()` override required for `Context`/`ERC2771` disambiguation | Closed | @@ -35,35 +38,72 @@ CMTA maintainer assessment of Slither findings for CMTAT **v3.3.0** (final), run ## Detailed Assessment ### S-1: `uninitialized-local` (Medium) — Invalid (false positive) -`ERC20EnforcementModuleInternal._unfreezeTokens(...).activeBalance` (`ERC20EnforcementModuleInternal.sol#L91`). In Solidity a local `uint256` defaults to `0`; `activeBalance == 0` is the intended value for the branch where frozen balance ≥ wallet balance (ERC-7943 permissive frozen model). No functional fix; an explicit `= 0` is an optional readability tweak. +`ERC20EnforcementModuleInternal._unfreezeTokens(...).activeBalance` (`ERC20EnforcementModuleInternal.sol#L100`, +was `#L91` before the rc3 edits). The source carries the explicit comment `// default value is 0 for +uninitialized variable`: a local `uint256` defaults to `0`, which is the intended value for the branch where the +frozen balance ≥ wallet balance (ERC-7943 permissive frozen model; `activeBalance` is only assigned when +`frozenTokensLocal < balance`). No functional fix; an explicit `= 0` would be a readability tweak only. ### S-2: `unused-return` (Medium) — Invalid (false positive) Both instances are in `DocumentEngineModule` (`options/DocumentEngineModule.sol`): -- `getDocument` (L64-71) — Slither reports the engine's `getDocument(name)` return as ignored, but it is **forwarded** via `return $._documentEngine.getDocument(name)`. Tool imprecision on a tuple-returning delegation. -- `removeDocument` (L95-105) — `(uri, documentHash, ) = $._documentEngine.getDocument(name)` **intentionally discards** the third value (`lastModified`); `uri`/`documentHash` are captured to re-emit `DocumentRemoved` with the removed metadata. +- `getDocument` (L64-71) — Slither reports the engine's `getDocument(name)` return as ignored, but it is + **forwarded** via `return $._documentEngine.getDocument(name)`. Tool imprecision on a tuple-returning delegation. +- `removeDocument` (L95-105) — `(uri, documentHash, ) = $._documentEngine.getDocument(name)` **intentionally + discards** the third value (`lastModified`); `uri`/`documentHash` are captured to re-emit `DocumentRemoved` + with the removed metadata. + No code change. ### S-3: `calls-loop` (Low) — Design choice -Instances come from batch operations that must run compliance/snapshot hooks per item, and are intentionally atomic. Accepted with operational guidance (gas budgeting, trusted-module assumptions). +76 instances, all reaching one of two external hooks: +- **64 × `ruleEngine_.transferred(...)`** via + `ValidationModuleRuleEngine._callRuleEngineTransferred` (`ValidationModuleRuleEngine.sol#L182-L194`), reached + from `batchMint` / `batchBurn` / `batchTransfer` across the deployment variants; +- **12 × `snapshotEngineLocal.operateOnTransfer(...)`** via `CMTATBaseSnapshot._update`. + +Batch operations must run the compliance/snapshot hook per item and are intentionally atomic. Accepted with the +existing operational guidance (gas budgeting, trusted-engine assumption). The rise from 28 is a call-graph +artefact, not new behaviour — see the delta section. ### S-4: `reentrancy-events` (Low) — Design choice -`DocumentEngineModule.setDocument`/`removeDocument` re-emit `DocumentUpdated`/`DocumentRemoved` **after** forwarding to the external document engine (the ERC-1643 dual-emission that makes the *token's own address* observable). The engine is set by `DEFAULT_ADMIN_ROLE`/`DOCUMENT_ENGINE_ROLE` (trusted), the emitted data mirrors the forwarded call, and no fund- or access-affecting state follows the call — so the "event after external call" pattern is benign. No code change. +`DocumentEngineModule.setDocument` (L83-93) / `removeDocument` (L95-105) re-emit `DocumentUpdated` / +`DocumentRemoved` **after** forwarding to the external document engine (the ERC-1643 dual-emission that makes the +*token's own address* observable). The engine is set by `DEFAULT_ADMIN_ROLE`/`DOCUMENT_ENGINE_ROLE` (trusted), the +emitted data mirrors the forwarded call, and no fund- or access-affecting state follows the call — so the +"event after external call" pattern is benign. No code change. ### S-5: `assembly` (Informational) — Valid but expected -Assembly is used only for ERC-7201 storage-slot placement (16 instances; +2 vs the prior snapshot from the new `TokenAttributeModule` and `HolderListModule` slots). No change required. +Assembly is used only for ERC-7201 storage-slot placement (16 instances, unchanged). No change required. ### S-6: `dead-code` (Informational) — Invalid (false positive) -`CMTATBaseHolderList._msgData()` (`8_CMTATBaseHolderList.sol#L136-142`) is an override required to disambiguate `ContextUpgradeable` / `ERC2771ContextUpgradeable` multiple inheritance; it is mandatory for compilation even though Slither sees no direct caller. No change. +`CMTATBaseHolderList._msgData()` (`8_CMTATBaseHolderList.sol`) is an override required to disambiguate +`ContextUpgradeable` / `ERC2771ContextUpgradeable` multiple inheritance; it is mandatory for compilation even +though Slither sees no direct caller. No change. ### S-7: `naming-convention` (Informational) — Style-only 60 style warnings (e.g. ERC-7201 storage-location constants, `__X_init_unchained` mixedCase). No security impact. -## Delta from the 2026-05-20 v3.3.0 snapshot - -- **New**: `unused-return` (2, Medium) and `reentrancy-events` (2, Low) — both from the intentional `DocumentEngineModule` dual-emission added in v3.3.0. Assessed false positive / by design. -- **Removed**: `unindexed-event-address` (was 1) no longer fires. -- **Changed counts**: `assembly` 14 → 16, `naming-convention` 57 → 60 (new modules); `calls-loop` 28 (unchanged), `dead-code` 1 (now the HolderList `_msgData` override). +## Delta from the 2026-07-22 v3.3.0 snapshot + +- **Same seven detectors**; none added, none removed. High stays at 0. +- **`calls-loop` 28 → 76** (+48), entirely from the RuleEngine hook (16 → 64; the snapshot hook is unchanged at + 12). Cause: the NM-7 reentrancy-guard work factored the `transferred` call out of `_transferred` into the + dedicated `_callRuleEngineTransferred`, declared `virtual` so size-unconstrained variants can override it with + `nonReentrant` (OpenZeppelin `ReentrancyGuardTransient`). Slither now attributes one instance per batch call + stack that reaches that single external call, where it previously collapsed them onto `_transferred`. **No new + external call and no new loop** — same design, finer-grained reporting. Disposition unchanged (by design). +- **Contracts analyzed 221 → 225.** No new CMTAT production contract (this cycle's two new `.sol` files are + mocks, excluded from scope); the delta is the newly imported OpenZeppelin transient-storage dependencies + (`ReentrancyGuardTransient`, `TransientSlot`) entering the analysis unit. +- **Line references shifted** on unchanged findings (e.g. S-1 `#L91` → `#L100`) from the `^0.8.24` pragma bump and + added NatSpec. +- All other counts identical: `uninitialized-local` 1, `unused-return` 2, `reentrancy-events` 2, `assembly` 16, + `dead-code` 1, `naming-convention` 60. ## Executive triage -**No High findings; nothing requires a code fix.** The two Medium categories are false positives (`uninitialized-local`, `unused-return`) and the two Low categories are documented design choices (`calls-loop`, `reentrancy-events`). Informational items are expected ERC-7201 assembly, a mandatory inheritance-disambiguation override, and naming style. +**No High findings; nothing requires a code fix.** The two Medium categories are false positives +(`uninitialized-local`, `unused-return`) and the two Low categories are documented design choices (`calls-loop`, +`reentrancy-events`). Informational items are expected ERC-7201 assembly, a mandatory inheritance-disambiguation +override, and naming style. Notably, Slither reports **no finding against the new reentrancy guard or the other +rc3 fixes** — the only visible effect is the finer-grained `calls-loop` accounting described above. diff --git a/doc/security/tools/slither/v3.3.0-slither-report.md b/doc/security/tools/slither/v3.3.0-slither-report.md index 55c6abfa..6d823e57 100644 --- a/doc/security/tools/slither/v3.3.0-slither-report.md +++ b/doc/security/tools/slither/v3.3.0-slither-report.md @@ -3,21 +3,22 @@ - **Tool**: `slither 0.11.5` - **Command**: `slither . --checklist --filter-paths "node_modules,lib,test,forge-std,mocks"` -- **Scope**: production contracts — **mocks excluded**. 221 contracts analyzed, **110 results**. -- **Severity tally**: **3 Medium · 30 Low · 77 Informational** (0 High) +- **Scope**: production contracts — **mocks excluded**. 225 contracts analyzed, **158 results**. +- **Severity tally**: **3 Medium · 78 Low · 77 Informational** (0 High) +- **Run**: 2026-07-30, on the v3.3.0-rc3 source (`dev`), EVM target `osaka`, solc 0.8.36. - **Feedback (dispositions)**: [v3.3.0-slither-feedback.md](./v3.3.0-slither-feedback.md) · **Overview**: [AUDIT.md](../../AUDIT.md) | ID | Detector | Severity | Instances | Assessment | |---|---|---|---:|---| | S-1 | `uninitialized-local` | Medium | 1 | False positive — `_unfreezeTokens.activeBalance` intentionally defaults to `0` (frozen ≥ balance branch) | | S-2 | `unused-return` | Medium | 2 | False positive — `DocumentEngineModule` forwards `getDocument` and intentionally discards `lastModified` | -| S-3 | `calls-loop` | Low | 28 | By design — batch operations execute compliance/snapshot hooks per item | +| S-3 | `calls-loop` | Low | 76 | By design — compliance/snapshot hooks run per item in batch loops (64 × RuleEngine `transferred`, 12 × snapshot `operateOnTransfer`) | | S-4 | `reentrancy-events` | Low | 2 | By design — `DocumentEngineModule` re-emits `DocumentUpdated`/`DocumentRemoved` after the (admin-set, trusted) engine call; no exploitable state | | S-5 | `assembly` | Informational | 16 | By design — ERC-7201 namespaced storage-slot access | | S-6 | `dead-code` | Informational | 1 | False positive — `CMTATBaseHolderList._msgData()` override is mandatory for `Context`/`ERC2771` multiple-inheritance | | S-7 | `naming-convention` | Informational | 60 | Cosmetic — style warnings, no security impact | -**Nothing requires a code fix.** No High findings; the two Medium and both Low categories are false positives or documented design choices (the two new detectors vs the earlier snapshot — `unused-return`, `reentrancy-events` — both stem from the intentional `DocumentEngineModule` dual-emission). See the feedback file for per-finding rationale. +**Nothing requires a code fix.** No High findings; the same seven detectors as the 2026-07-22 snapshot fire, all previously triaged as false positives or documented design choices. The only material change is `calls-loop` 28 → 76: the RuleEngine `transferred` hook was factored into the dedicated `_callRuleEngineTransferred` (made `virtual` so variants can wrap it in `nonReentrant`), so Slither now enumerates every batch call stack reaching the same single external call. No new external call was introduced. See the feedback file for per-finding rationale. @@ -25,7 +26,7 @@ Summary - [uninitialized-local](#uninitialized-local) (1 results) (Medium) - [unused-return](#unused-return) (2 results) (Medium) - - [calls-loop](#calls-loop) (28 results) (Low) + - [calls-loop](#calls-loop) (76 results) (Low) - [reentrancy-events](#reentrancy-events) (2 results) (Low) - [assembly](#assembly) (16 results) (Informational) - [dead-code](#dead-code) (1 results) (Informational) @@ -34,9 +35,9 @@ Summary Impact: Medium Confidence: Medium - [ ] ID-0 -[ERC20EnforcementModuleInternal._unfreezeTokens(address,uint256).activeBalance](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L91) is a local variable never initialized +[ERC20EnforcementModuleInternal._unfreezeTokens(address,uint256).activeBalance](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L100) is a local variable never initialized -contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L91 +contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L100 ## unused-return @@ -58,18 +59,33 @@ contracts/modules/wrapper/options/DocumentEngineModule.sol#L64-L71 Impact: Low Confidence: Medium - [ ] 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(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143) +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - [ ] ID-4 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardStandalone._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-5 [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[]) @@ -83,18 +99,35 @@ contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine 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) + - [ ] ID-6 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) Calls stack containing the loop: - ERC20BurnModule.batchBurn(address[],uint256[]) + ERC20MintModule.batchTransfer(address[],uint256[]) + ERC20MintModuleInternal._batchTransfer(address[],uint256[]) + CMTATBaseERC20CrossChain._minterTransferOverride(address,address,uint256) + CMTATBaseCommon._minterTransferOverride(address,address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-7 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-6 + - [ ] 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: ERC20MintModule.batchMint(address[],uint256[]) @@ -108,31 +141,155 @@ contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 - - [ ] ID-7 -[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) + - [ ] ID-9 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + Calls stack containing the loop: + ERC20BurnModule.batchBurn(address[],uint256[]) + ERC20BurnModuleInternal._batchBurn(address[],uint256[]) + CMTATBaseCommon._burnOverride(address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-10 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-8 -[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) + - [ ] ID-11 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-12 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-13 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + Calls stack containing the loop: + ERC20MintModule.batchTransfer(address[],uint256[]) + ERC20MintModuleInternal._batchTransfer(address[],uint256[]) + CMTATBaseCommon._minterTransferOverride(address,address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-14 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardStandalone._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-15 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardUpgradeable._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-16 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-17 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-9 + - [ ] ID-18 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-19 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-20 [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[]) @@ -146,7 +303,20 @@ contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 - - [ ] ID-10 + - [ ] ID-21 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-22 [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) @@ -159,7 +329,7 @@ contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 - - [ ] ID-11 + - [ ] 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[]) @@ -173,7 +343,7 @@ contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 - - [ ] ID-12 + - [ ] ID-24 [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[]) @@ -187,7 +357,126 @@ contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 - - [ ] ID-13 + - [ ] ID-25 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + Calls stack containing the loop: + ERC20MintModule.batchTransfer(address[],uint256[]) + ERC20MintModuleInternal._batchTransfer(address[],uint256[]) + CMTATBaseCommon._minterTransferOverride(address,address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-26 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardUpgradeable._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-27 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-28 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + Calls stack containing the loop: + ERC20MintModule.batchMint(address[],uint256[]) + ERC20MintModuleInternal._batchMint(address[],uint256[]) + CMTATBaseCommon._mintOverride(address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-29 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-30 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + Calls stack containing the loop: + ERC20MintModule.batchMint(address[],uint256[]) + ERC20MintModuleInternal._batchMint(address[],uint256[]) + CMTATBaseCommon._mintOverride(address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-31 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardStandalone._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-32 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-33 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-34 [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[]) @@ -201,18 +490,102 @@ contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 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(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145) + - [ ] ID-35 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-15 + - [ ] ID-36 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + Calls stack containing the loop: + ERC20BurnModule.batchBurn(address[],uint256[],bytes) + ERC20BurnModuleInternal._batchBurn(address[],uint256[]) + CMTATBaseCommon._burnOverride(address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-37 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-38 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-39 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-40 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-41 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-42 [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) @@ -226,149 +599,446 @@ contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 - - [ ] 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(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143) + - [ ] ID-43 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-44 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardUpgradeable._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-45 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-46 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-47 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-48 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-49 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-50 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardStandalone._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-51 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-52 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardUpgradeable._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-53 +[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-54 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-55 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-56 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-57 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardStandalone._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-58 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-59 +[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-60 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-61 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) Calls stack containing the loop: - ERC20MintModule.batchTransfer(address[],uint256[]) - ERC20MintModuleInternal._batchTransfer(address[],uint256[]) - CMTATBaseERC20CrossChain._minterTransferOverride(address,address,uint256) - CMTATBaseCommon._minterTransferOverride(address,address,uint256) + ERC20BurnModule.batchBurn(address[],uint256[],bytes) + ERC20BurnModuleInternal._batchBurn(address[],uint256[]) + CMTATBaseERC20CrossChain._burnOverride(address,uint256) + CMTATBaseCommon._burnOverride(address,uint256) CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardUpgradeable._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-17 -[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) + - [ ] ID-62 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardUpgradeable._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] 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(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L145) + - [ ] ID-63 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardUpgradeable._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] 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) + - [ ] ID-64 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) 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) + ERC20BurnModule.batchBurn(address[],uint256[]) + ERC20BurnModuleInternal._batchBurn(address[],uint256[]) + CMTATBaseERC20CrossChain._burnOverride(address,uint256) + CMTATBaseCommon._burnOverride(address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) -contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] 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) + - [ ] ID-65 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-21 -[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) + - [ ] ID-66 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) 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) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) -contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] 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) + - [ ] ID-67 +[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) - CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + 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/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 - - [ ] ID-23 -[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) + - [ ] ID-68 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) Calls stack containing the loop: - ERC20MintModule.batchMint(address[],uint256[]) - ERC20MintModuleInternal._batchMint(address[],uint256[]) - CMTATBaseCommon._mintOverride(address,uint256) + ERC20BurnModule.batchBurn(address[],uint256[],bytes) + ERC20BurnModuleInternal._batchBurn(address[],uint256[]) + CMTATBaseCommon._burnOverride(address,uint256) CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] 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(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L143) + - [ ] ID-69 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardStandalone._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-25 -[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) + - [ ] ID-70 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) 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) - CMTATBaseDebt._update(address,address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-26 -[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) + - [ ] ID-71 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATUpgradeableERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-72 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardStandalone._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] 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) + - [ ] ID-73 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) Calls stack containing the loop: - ERC20MintModule.batchTransfer(address[],uint256[]) - ERC20MintModuleInternal._batchTransfer(address[],uint256[]) - CMTATBaseCommon._minterTransferOverride(address,address,uint256) + ERC20MintModule.batchMint(address[],uint256[]) + ERC20MintModuleInternal._batchMint(address[],uint256[]) + CMTATBaseERC20CrossChain._mintOverride(address,uint256) + CMTATBaseCommon._mintOverride(address,uint256) CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardStandalone._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-28 + - [ ] ID-74 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-75 [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) @@ -382,33 +1052,52 @@ contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine contracts/modules/0_CMTATBaseSnapshot.sol#L19-L30 - - [ ] ID-29 -[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) + - [ ] ID-76 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(spender,from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L190) 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneSnapshot._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 - - [ ] ID-30 -[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) + - [ ] ID-77 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) Calls stack containing the loop: - ERC20BurnModule.batchBurn(address[],uint256[],bytes) + ERC20MintModule.batchMint(address[],uint256[]) + ERC20MintModuleInternal._batchMint(address[],uint256[]) + CMTATBaseERC20CrossChain._mintOverride(address,uint256) + CMTATBaseCommon._mintOverride(address,uint256) + CMTATBaseRuleEngine._checkTransferred(address,address,address,uint256) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandaloneERC7551._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) + +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 + + + - [ ] ID-78 +[ValidationModuleRuleEngine._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194) has external calls inside a loop: [ruleEngine_.transferred(from,to,value)](contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L192) + 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) + ValidationModuleRuleEngine._transferred(address,address,address,uint256) + CMTATStandardUpgradeable._callRuleEngineTransferred(IRuleEngine,address,address,address,uint256) -contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L138-L148 +contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol#L182-L194 ## reentrancy-events Impact: Low Confidence: Medium - - [ ] ID-31 + - [ ] ID-79 Reentrancy in [DocumentEngineModule.setDocument(bytes32,string,bytes32)](contracts/modules/wrapper/options/DocumentEngineModule.sol#L83-L93): External calls: - [$._documentEngine.setDocument(name,uri,documentHash)](contracts/modules/wrapper/options/DocumentEngineModule.sol#L91) @@ -418,7 +1107,7 @@ Reentrancy in [DocumentEngineModule.setDocument(bytes32,string,bytes32)](contrac contracts/modules/wrapper/options/DocumentEngineModule.sol#L83-L93 - - [ ] ID-32 + - [ ] ID-80 Reentrancy in [DocumentEngineModule.removeDocument(bytes32)](contracts/modules/wrapper/options/DocumentEngineModule.sol#L95-L105): External calls: - [$._documentEngine.removeDocument(name)](contracts/modules/wrapper/options/DocumentEngineModule.sol#L103) @@ -431,122 +1120,122 @@ contracts/modules/wrapper/options/DocumentEngineModule.sol#L95-L105 ## assembly Impact: Informational Confidence: High - - [ ] ID-33 -[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-34 + - [ ] ID-81 [DocumentEngineModule._getDocumentEngineModuleStorage()](contracts/modules/wrapper/options/DocumentEngineModule.sol#L135-L139) uses assembly - [INLINE ASM](contracts/modules/wrapper/options/DocumentEngineModule.sol#L136-L138) contracts/modules/wrapper/options/DocumentEngineModule.sol#L135-L139 - - [ ] ID-35 + - [ ] ID-82 [EnforcementModuleInternal._getEnforcementModuleInternalStorage()](contracts/modules/internal/EnforcementModuleInternal.sol#L64-L68) uses assembly - [INLINE ASM](contracts/modules/internal/EnforcementModuleInternal.sol#L65-L67) contracts/modules/internal/EnforcementModuleInternal.sol#L64-L68 - - [ ] ID-36 -[TokenAttributeModule._getTokenAttributeModuleStorage()](contracts/modules/wrapper/core/TokenAttributeModule.sol#L104-L108) uses assembly - - [INLINE ASM](contracts/modules/wrapper/core/TokenAttributeModule.sol#L105-L107) - -contracts/modules/wrapper/core/TokenAttributeModule.sol#L104-L108 - - - - [ ] ID-37 + - [ ] ID-83 [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-38 + - [ ] ID-84 +[ExtraInformationModule._getExtraInformationModuleStorage()](contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L172-L176) uses assembly + - [INLINE ASM](contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L173-L175) + +contracts/modules/wrapper/extensions/ExtraInformationModule.sol#L172-L176 + + + - [ ] ID-85 [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-39 + - [ ] ID-86 [DocumentERC1643Module._getDocumentERC1643ModuleStorage()](contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L77-L81) uses assembly - [INLINE ASM](contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L78-L80) contracts/modules/wrapper/extensions/DocumentERC1643Module.sol#L77-L81 - - [ ] ID-40 + - [ ] ID-87 +[ERC7551Module._getERC7551ModuleStorage()](contracts/modules/wrapper/options/ERC7551Module.sol#L83-L87) uses assembly + - [INLINE ASM](contracts/modules/wrapper/options/ERC7551Module.sol#L84-L86) + +contracts/modules/wrapper/options/ERC7551Module.sol#L83-L87 + + + - [ ] ID-88 [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-41 + - [ ] ID-89 [ERC20BaseModule._getERC20BaseModuleStorage()](contracts/modules/wrapper/core/ERC20BaseModule.sol#L96-L100) uses assembly - [INLINE ASM](contracts/modules/wrapper/core/ERC20BaseModule.sol#L97-L99) contracts/modules/wrapper/core/ERC20BaseModule.sol#L96-L100 - - [ ] ID-42 + - [ ] ID-90 [AllowlistModuleInternal._getAllowlistModuleInternalStorage()](contracts/modules/internal/AllowlistModuleInternal.sol#L86-L90) uses assembly - [INLINE ASM](contracts/modules/internal/AllowlistModuleInternal.sol#L87-L89) contracts/modules/internal/AllowlistModuleInternal.sol#L86-L90 - - [ ] ID-43 -[HolderListModule._getHolderListModuleStorage()](contracts/modules/wrapper/options/HolderListModule.sol#L118-L122) uses assembly - - [INLINE ASM](contracts/modules/wrapper/options/HolderListModule.sol#L119-L121) + - [ ] ID-91 +[HolderListModule._getHolderListModuleStorage()](contracts/modules/wrapper/options/HolderListModule.sol#L120-L124) uses assembly + - [INLINE ASM](contracts/modules/wrapper/options/HolderListModule.sol#L121-L123) -contracts/modules/wrapper/options/HolderListModule.sol#L118-L122 +contracts/modules/wrapper/options/HolderListModule.sol#L120-L124 - - [ ] ID-44 -[CCIPModule._getCCIPModuleStorage()](contracts/modules/wrapper/options/CCIPModule.sol#L67-L71) uses assembly - - [INLINE ASM](contracts/modules/wrapper/options/CCIPModule.sol#L68-L70) + - [ ] ID-92 +[TokenAttributeModule._getTokenAttributeModuleStorage()](contracts/modules/wrapper/core/TokenAttributeModule.sol#L113-L117) uses assembly + - [INLINE ASM](contracts/modules/wrapper/core/TokenAttributeModule.sol#L114-L116) -contracts/modules/wrapper/options/CCIPModule.sol#L67-L71 +contracts/modules/wrapper/core/TokenAttributeModule.sol#L113-L117 - - [ ] ID-45 -[ERC7551Module._getERC7551ModuleStorage()](contracts/modules/wrapper/options/ERC7551Module.sol#L82-L86) uses assembly - - [INLINE ASM](contracts/modules/wrapper/options/ERC7551Module.sol#L83-L85) + - [ ] ID-93 +[CCIPModule._getCCIPModuleStorage()](contracts/modules/wrapper/options/CCIPModule.sol#L67-L71) uses assembly + - [INLINE ASM](contracts/modules/wrapper/options/CCIPModule.sol#L68-L70) -contracts/modules/wrapper/options/ERC7551Module.sol#L82-L86 +contracts/modules/wrapper/options/CCIPModule.sol#L67-L71 - - [ ] ID-46 + - [ ] ID-94 [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-47 -[ERC20EnforcementModuleInternal._getEnforcementModuleStorage()](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L190-L194) uses assembly - - [INLINE ASM](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L191-L193) - -contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L190-L194 - - - - [ ] ID-48 + - [ ] ID-95 [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 + - [ ] ID-96 +[ERC20EnforcementModuleInternal._getEnforcementModuleStorage()](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L204-L208) uses assembly + - [INLINE ASM](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L205-L207) + +contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L204-L208 + + ## dead-code Impact: Informational Confidence: Medium - - [ ] ID-49 + - [ ] ID-97 [CMTATBaseHolderList._msgData()](contracts/modules/8_CMTATBaseHolderList.sol#L136-L142) is never used and should be removed contracts/modules/8_CMTATBaseHolderList.sol#L136-L142 @@ -555,361 +1244,361 @@ contracts/modules/8_CMTATBaseHolderList.sol#L136-L142 ## naming-convention Impact: Informational Confidence: High - - [ ] ID-50 + - [ ] ID-98 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-51 + - [ ] ID-99 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-52 + - [ ] ID-100 Constant [EnforcementModuleInternal.EnforcementModuleInternalStorageLocation](contracts/modules/internal/EnforcementModuleInternal.sol#L22) is not in UPPER_CASE_WITH_UNDERSCORES contracts/modules/internal/EnforcementModuleInternal.sol#L22 - - [ ] ID-53 + - [ ] ID-101 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-54 + - [ ] ID-102 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-55 + - [ ] ID-103 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-56 + - [ ] ID-104 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-57 + - [ ] ID-105 Constant [AllowlistModuleInternal.AllowlistModuleInternalStorageLocation](contracts/modules/internal/AllowlistModuleInternal.sol#L19) is not in UPPER_CASE_WITH_UNDERSCORES contracts/modules/internal/AllowlistModuleInternal.sol#L19 - - [ ] ID-58 + - [ ] ID-106 Parameter [CMTATBaseCore.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/0_CMTATBaseCore.sol#L90) is not in mixedCase contracts/modules/0_CMTATBaseCore.sol#L90 - - [ ] ID-59 + - [ ] ID-107 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-60 + - [ ] ID-108 Parameter [CMTATBaseAccessControl.__CMTAT_commonModules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/2_CMTATBaseAccessControl.sol#L34) is not in mixedCase contracts/modules/2_CMTATBaseAccessControl.sol#L34 - - [ ] ID-61 + - [ ] ID-109 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-62 + - [ ] ID-110 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-63 + - [ ] ID-111 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-64 + - [ ] ID-112 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-65 + - [ ] ID-113 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-66 + - [ ] ID-114 Enum [IERC1404Extend.REJECTED_CODE_BASE](contracts/interfaces/tokenization/draft-IERC1404.sol#L50-L58) is not in CapWords contracts/interfaces/tokenization/draft-IERC1404.sol#L50-L58 - - [ ] ID-67 + - [ ] ID-115 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-68 + - [ ] ID-116 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-69 + - [ ] ID-117 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-70 + - [ ] ID-118 Function [AllowlistModuleInternal.__Allowlist_init_unchained()](contracts/modules/internal/AllowlistModuleInternal.sol#L29-L33) is not in mixedCase contracts/modules/internal/AllowlistModuleInternal.sol#L29-L33 - - [ ] ID-71 + - [ ] ID-119 Parameter [CMTATBaseAccessControl.__CMTAT_commonModules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ExtraInformationModuleAttributes_](contracts/modules/2_CMTATBaseAccessControl.sol#L34) is not in mixedCase contracts/modules/2_CMTATBaseAccessControl.sol#L34 - - [ ] ID-72 + - [ ] ID-120 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-73 + - [ ] ID-121 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-74 + - [ ] ID-122 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-75 + - [ ] ID-123 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-76 -Constant [ERC7551Module.ERC7551ModuleStorageLocation](contracts/modules/wrapper/options/ERC7551Module.sol#L20) is not in UPPER_CASE_WITH_UNDERSCORES + - [ ] ID-124 +Constant [ERC7551Module.ERC7551ModuleStorageLocation](contracts/modules/wrapper/options/ERC7551Module.sol#L19) is not in UPPER_CASE_WITH_UNDERSCORES -contracts/modules/wrapper/options/ERC7551Module.sol#L20 +contracts/modules/wrapper/options/ERC7551Module.sol#L19 - - [ ] ID-77 -Parameter [CMTATBaseERC20CrossChain.supportsInterface(bytes4)._interfaceId](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L75) is not in mixedCase + - [ ] ID-125 +Parameter [CMTATBaseERC20CrossChain.supportsInterface(bytes4)._interfaceId](contracts/modules/5_CMTATBaseERC20CrossChain.sol#L77) is not in mixedCase -contracts/modules/5_CMTATBaseERC20CrossChain.sol#L75 +contracts/modules/5_CMTATBaseERC20CrossChain.sol#L77 - - [ ] ID-78 + - [ ] ID-126 Function [CMTATBaseCore.__CMTAT_openzeppelin_init_unchained()](contracts/modules/0_CMTATBaseCore.sol#L109-L113) is not in mixedCase contracts/modules/0_CMTATBaseCore.sol#L109-L113 - - [ ] ID-79 + - [ ] ID-127 Constant [ERC20BaseModule.ERC20BaseModuleStorageLocation](contracts/modules/wrapper/core/ERC20BaseModule.sol#L22) is not in UPPER_CASE_WITH_UNDERSCORES contracts/modules/wrapper/core/ERC20BaseModule.sol#L22 - - [ ] ID-80 + - [ ] ID-128 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-81 + - [ ] ID-129 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-82 + - [ ] ID-130 Constant [ValidationModuleRuleEngineInternal.ValidationModuleRuleEngineStorageLocation](contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L28) is not in UPPER_CASE_WITH_UNDERSCORES contracts/modules/internal/ValidationModuleRuleEngineInternal.sol#L28 - - [ ] ID-83 + - [ ] ID-131 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-84 + - [ ] ID-132 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-85 + - [ ] ID-133 Function [ERC20BaseModule.__ERC20BaseModule_init_unchained(uint8)](contracts/modules/wrapper/core/ERC20BaseModule.sol#L35-L40) is not in mixedCase contracts/modules/wrapper/core/ERC20BaseModule.sol#L35-L40 - - [ ] ID-86 -Constant [HolderListModule.HolderListModuleStorageLocation](contracts/modules/wrapper/options/HolderListModule.sol#L28) is not in UPPER_CASE_WITH_UNDERSCORES + - [ ] ID-134 +Constant [HolderListModule.HolderListModuleStorageLocation](contracts/modules/wrapper/options/HolderListModule.sol#L30) is not in UPPER_CASE_WITH_UNDERSCORES -contracts/modules/wrapper/options/HolderListModule.sol#L28 +contracts/modules/wrapper/options/HolderListModule.sol#L30 - - [ ] ID-87 + - [ ] ID-135 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-88 + - [ ] ID-136 Function [CMTATBaseAccessControl.__CMTAT_commonModules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/2_CMTATBaseAccessControl.sol#L34-L42) is not in mixedCase contracts/modules/2_CMTATBaseAccessControl.sol#L34-L42 - - [ ] ID-89 + - [ ] ID-137 Parameter [CMTATBaseCore.initialize(address,ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/0_CMTATBaseCore.sol#L76) is not in mixedCase contracts/modules/0_CMTATBaseCore.sol#L76 - - [ ] ID-90 + - [ ] ID-138 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-91 + - [ ] ID-139 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-92 -Parameter [ERC20CrossChainModule.supportsInterface(bytes4)._interfaceId](contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L103) is not in mixedCase + - [ ] ID-140 +Parameter [ERC20CrossChainModule.supportsInterface(bytes4)._interfaceId](contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L109) is not in mixedCase -contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L103 +contracts/modules/wrapper/options/ERC20CrossChainModule.sol#L109 - - [ ] ID-93 + - [ ] ID-141 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-94 + - [ ] ID-142 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-95 + - [ ] ID-143 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-96 + - [ ] ID-144 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-97 + - [ ] ID-145 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-98 + - [ ] ID-146 Function [CMTATBaseCore.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes)](contracts/modules/0_CMTATBaseCore.sol#L119-L124) is not in mixedCase contracts/modules/0_CMTATBaseCore.sol#L119-L124 - - [ ] ID-99 + - [ ] ID-147 Constant [TokenAttributeModule.TokenAttributeModuleStorageLocation](contracts/modules/wrapper/core/TokenAttributeModule.sol#L29) is not in UPPER_CASE_WITH_UNDERSCORES contracts/modules/wrapper/core/TokenAttributeModule.sol#L29 - - [ ] ID-100 + - [ ] ID-148 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-101 + - [ ] ID-149 Function [TokenAttributeModule.__TokenAttributeModule_init_unchained(string,string)](contracts/modules/wrapper/core/TokenAttributeModule.sol#L47-L54) is not in mixedCase contracts/modules/wrapper/core/TokenAttributeModule.sol#L47-L54 - - [ ] ID-102 + - [ ] ID-150 Parameter [CMTATBaseCore.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/0_CMTATBaseCore.sol#L119) is not in mixedCase contracts/modules/0_CMTATBaseCore.sol#L119 - - [ ] ID-103 + - [ ] ID-151 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-104 + - [ ] ID-152 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-105 + - [ ] ID-153 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-106 + - [ ] ID-154 Function [CMTATBaseCore.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes)](contracts/modules/0_CMTATBaseCore.sol#L88-L104) is not in mixedCase contracts/modules/0_CMTATBaseCore.sol#L88-L104 - - [ ] ID-107 + - [ ] ID-155 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-108 -Constant [ERC20EnforcementModuleInternal.ERC20EnforcementModuleStorageLocation](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L25) is not in UPPER_CASE_WITH_UNDERSCORES + - [ ] ID-156 +Constant [ERC20EnforcementModuleInternal.ERC20EnforcementModuleStorageLocation](contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L27) is not in UPPER_CASE_WITH_UNDERSCORES -contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L25 +contracts/modules/internal/ERC20EnforcementModuleInternal.sol#L27 - - [ ] ID-109 + - [ ] ID-157 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/technical/access-control.md b/doc/technical/access-control.md index a1b0dc02..22627699 100644 --- a/doc/technical/access-control.md +++ b/doc/technical/access-control.md @@ -89,13 +89,56 @@ See also [docs.openzeppelin.com - AccessControl](https://docs.openzeppelin.com/c ## Input Guards - `EnforcementModule.setAddressFrozen(...)` and `batchSetAddressFrozen(...)` reject `address(0)` (`CMTAT_Enforcement_ZeroAddressNotAllowed`). -- `ERC20EnforcementModule.freezePartialTokens(...)` and `unfreezePartialTokens(...)` reject `address(0)` (`CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed`). +- `ERC20EnforcementModule.freezePartialTokens(...)`, `unfreezePartialTokens(...)` and `setFrozenTokens(...)` 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`. +- Freezing an operator with `setAddressFrozen(operator, true)` does **not** block that operator's `mint` / `batchMint`. Minting validates the **recipient** (and the contract's deactivation state), not the caller: a frozen `MINTER_ROLE` holder can still mint. It **does** block that operator's `batchTransfer`, `transfer` and `transferFrom`, because there the operator is the sender/spender (`ERC7943CannotSend(operator)`). To stop a compromised minter from minting, revoke its role (`revokeRole(MINTER_ROLE, operator)`) — freezing is a holder-level control, not an operator-level one. See [the freeze-vs-operation table below](#what-freeze-and-pause-block-per-operation). + - Caveat (RuleEngine deployments, e.g. Standard): the operator **is** passed to a configured RuleEngine as the `spender` argument of `transferred(spender, from, to, value)`, so a RuleEngine *rule* may choose to reject a mint by a frozen/blocked operator. CMTAT's own freeze logic does not; the Light variant has no RuleEngine, so no such hook exists there. - `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`. +- `CROSS_CHAIN_ROLE` is checked against the **raw `msg.sender`**, not `_msgSender()` — the only role gate in CMTAT that does so, and deliberately (a bridge holds unbounded mint authority and must not be impersonable through a relayer). A bridge must therefore call `crosschainMint` / `crosschainBurn` directly, and **`CROSS_CHAIN_ROLE` must never be granted to the ERC-2771 forwarder**: it would let any user mint arbitrarily through a relayed call. See [cross-chain-bridge-integration.md](./cross-chain-bridge-integration.md#the-bridge-gate-uses-msgsender-not-_msgsender). + +## What freeze and pause block, per operation + +The key distinction is between **minting** (creating tokens, validated on the *recipient*) and **transfers** +including `batchTransfer` (moving existing tokens, validated on the *sender/spender*). Freezing an address only +blocks operations where that address is the sender, spender or recipient — never where it is merely the *minter*. + +| Operation | Role | Creates tokens? | Blocked while **paused**? | Blocked while **deactivated**? | **Operator** (caller) frozen → blocked? | **Recipient** frozen → blocked? | **Sender/spender** frozen → blocked? | +| --- | --- | :---: | :---: | :---: | :---: | :---: | :---: | +| `mint` / `batchMint` | `MINTER_ROLE` | Yes | No | Yes | **No** | Yes (`ERC7943CannotReceive`) | n/a | +| `batchTransfer` | `MINTER_ROLE` | No (moves caller's own) | Yes | Yes | **Yes** (`ERC7943CannotSend`) | Yes | operator **is** the sender | +| `transfer` | — | No | Yes | Yes | n/a | Yes | Yes (sender) | +| `transferFrom` | — | No | Yes | Yes | n/a | Yes | Yes (both spender and `from`) | + +Notes: +- `batchTransfer` also requires the caller's **unfrozen** balance to cover the amount (partial freeze limits it), and + reverts with `ERC7943InsufficientUnfrozenBalance` otherwise. +- `forcedTransfer` / `forcedBurn` (`DEFAULT_ADMIN` / `ERC20ENFORCER_ROLE`) deliberately **bypass** these + restrictions — that is their purpose (moving or burning frozen holders' tokens). + +### Does freezing the *operator* block it, by deployment version? + +The freeze behaviour above is identical across deployment versions. The only per-version difference is the optional +**RuleEngine**, which the Standard version consults (if one is set) and the Light version does not have at all. + +| Operation | Standard | Light | Notes | +| --- | :---: | :---: | --- | +| `mint` / `batchMint` | **No** ¹ | **No** | Operator/minter is not checked; only the recipient and deactivation are. | +| `batchTransfer` | **Yes** | **Yes** | Operator is the sender (`from`). | +| `transfer` / `transferFrom` | **Yes** | **Yes** | Operator is the sender / spender. | + +¹ **Standard only:** although CMTAT's own freeze logic does not block a mint by a frozen operator, the operator is +passed to a configured RuleEngine as the `spender` argument of `transferred(spender, from, to, value)` (and to +`canTransferFrom` in the read path). A RuleEngine *rule* may therefore choose to reject a mint by a frozen or +otherwise-restricted operator. This is a RuleEngine responsibility, not a base-contract guarantee; the Light +version has no RuleEngine hook. + +The Allowlist variant additionally requires the recipient (mint) or both parties (transfer) to be allowlisted when +the allowlist is enabled; that is orthogonal to the freeze behaviour above. + +**Takeaway:** to stop a compromised minter from minting, **revoke its `MINTER_ROLE`** — freezing the address will +not prevent minting (only a RuleEngine rule can, on the Standard version). ## Key Management diff --git a/doc/technical/allowance-spend-event.md b/doc/technical/allowance-spend-event.md new file mode 100644 index 00000000..317515a4 --- /dev/null +++ b/doc/technical/allowance-spend-event.md @@ -0,0 +1,85 @@ +# The `Spend` allowance event + +CMTAT emits a custom `IERC20Allowance.Spend(account, spender, value)` event whenever a spender consumes an owner's +allowance. It complements the standard ERC-20 `Approval` event (which signals *granting* an allowance) by signalling +its *consumption*. + +```solidity +event Spend(address indexed account, address indexed spender, uint256 value); +``` + +## Where it is emitted + +There are two emit sites, and they behave slightly differently. + +| | `transferFrom` (`ERC20BaseModule`) | `burnFrom` (`ERC20CrossChainModule`) | `forcedTransfer` (`ERC20EnforcementModule`) | +| --- | --- | --- | --- | +| Available on | every variant with an allowance surface | cross-chain variants only | every variant with enforcement | +| Allowance spent by | `ERC20Upgradeable.transferFrom` (internally) | an explicit `_spendAllowance(...)` | manual `_approve(from, to, reduced, false)` | +| `Spend` emitted | **after** the transfer completes | **between** `_spendAllowance` and the burn | when a finite non-zero `from`→`to` allowance is reduced | +| Event order in the receipt | `Transfer` → `Spend` | `Spend` → `Transfer` → `BurnFrom` | `Spend` → `Transfer` → `ForcedTransfer` | + +The self-burn `burn(uint256)` emits **no** `Spend` — it consumes no allowance. + +## What `Spend` does and does not tell you + +- **It does not imply the allowance decreased.** On `transferFrom` / `burnFrom`, `Spend` is emitted on every + successful call, including when the allowance is infinite (`type(uint256).max`), where OpenZeppelin leaves the + allowance unchanged. `value` is the amount *used*, not the size of any reduction. +- **`forcedTransfer` emits `Spend` only when it actually reduces the allowance** — i.e. when the `from`→`to` + allowance is finite and non-zero. `value` is then the amount taken from it (capped by the allowance). It does + **not** emit `Approval` for that reduction, so `Spend` is the only signal of it. + +Net effect for an integrator that reconstructs allowances purely from events: the figure still drifts **too low** +after an infinite-approval `transferFrom`/`burnFrom` (a `Spend` with no matching reduction). The former +`forcedTransfer` *under*-report is gone — the reduction now emits `Spend`. + +> **Guidance.** To obtain a spender's current allowance, always read `allowance(owner, spender)` on-chain. Never +> accumulate `Spend` (or `Approval`) events as a substitute — the infinite-allowance case alone makes event-summing +> wrong. + +## Possible improvement — making the emit sites consistent + +`forcedTransfer` now emits `Spend` when it reduces a finite allowance, so it is no longer a silent consumer. The +two remaining `transferFrom` / `burnFrom` sites are consistent enough to be usable but not identical: they differ +in event ordering, and both emit even on infinite approvals (which the older `IERC20Allowance` NatSpec incorrectly +claimed they did not — that NatSpec has been corrected). A future release could unify them. This is **not planned** +and would be a behaviour change, so it is recorded here as an option rather than a commitment. + +The cleanest unification emits `Spend` from a single overridden `_spendAllowance`, through which **both** paths +already route their allowance spend: + +```solidity +function _spendAllowance(address owner, address spender, uint256 value) internal virtual override { + if (allowance(owner, spender) != type(uint256).max) { + emit IERC20Allowance.Spend(owner, spender, value); + } + super._spendAllowance(owner, spender, value); +} +``` + +with the two explicit `emit Spend` statements removed. This would give one emit site, one ordering +(`Spend` → `Transfer` on both paths), and would make the event actually skip the infinite-allowance case. + +**Drawbacks — why it is not applied:** + +- It is an **observable behaviour change**: `Spend` would stop firing for infinite-allowance spends, and the + `transferFrom` order would flip from `Transfer → Spend` to `Spend → Transfer`. Any indexer keyed on either + breaks, so it belongs in a **major version**, not a patch. +- The `allowance(...)` read in the override is an **extra `SLOAD` on every `transferFrom`** — the hottest path in + the token — unless `_spendAllowance` is fully re-implemented to reuse the value it already loads, which means + diverging from the audited OpenZeppelin body. +- Several deployment variants are within a few hundred bytes of the EIP-170 24 KiB limit, so even a small net + addition must be measured before it can ship. + +A cheaper, ordering-only variant (moving `burnFrom`'s `emit Spend` to after the burn so `Spend` is last on both +paths) aligns the receipts but leaves the infinite-allowance emission untouched, so it does not remove the +substantive inconsistency and is not worth a breaking change on its own. + +**Current position:** `forcedTransfer` now emits `Spend` on the allowance reduction (so its former under-report is +closed); the `transferFrom`/`burnFrom` unification remains documentation-only. The `IERC20Allowance.Spend` NatSpec +has been corrected to describe the real behaviour, and the guidance above (read `allowance()`, do not sum events) +is the durable fix for integrators. + +> Origin: Nethermind AuditAgent v3.3.0-rc2 finding NM-24. See the +> [maintainer feedback](../security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md). diff --git a/doc/technical/guideline-new-blockchain.md b/doc/technical/cmtat-specification-analyse.md similarity index 87% rename from doc/technical/guideline-new-blockchain.md rename to doc/technical/cmtat-specification-analyse.md index e9b37b61..8ce998d6 100644 --- a/doc/technical/guideline-new-blockchain.md +++ b/doc/technical/cmtat-specification-analyse.md @@ -1,6 +1,8 @@ -### Guideline +# CMTAT specification vs implementation -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. +This document maps the **CMTAT framework specification** (the functional requirements defined by CMTA) to the features of **this Solidity reference implementation**, so the two can be compared function by function. + +> Porting CMTAT to another blockchain is out of scope here. For a correspondence table between the CMTAT framework and a non-Solidity implementation, see [CMTAT/CMTAT-equivalency-assessment](https://github.com/CMTA/CMTAT-equivalency-assessment). #### CMTAT framework @@ -25,14 +27,7 @@ In the below table, the CMTAT framework required features are mapped to Solidity **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) -``` +To be compatible with [ERC-3643](https://eips.ethereum.org/EIPS/eip-3643), the specification's separate *freeze* and *unfreeze* capabilities are implemented with a single function: `setAddressFrozen`, which takes the target address and the frozen status (true/false). #### CMTAT extended @@ -54,7 +49,7 @@ In the below table, the CMTAT framework extendedfeatures are mapped to Solidity 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. +This is what is done for the CMTAT light version, which does not include `forcedTransfer`. In this implementation, when `forcedTransfer` is available, `forcedBurn` is not implemented, to reduce smart contract code size (EIP-170). #### Implementation details @@ -70,6 +65,4 @@ This is what is done for the CMTAT light version which does not include `forcedT 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 +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. \ No newline at end of file diff --git a/doc/technical/cross-chain-bridge-integration.md b/doc/technical/cross-chain-bridge-integration.md index b1a9d125..d09f899f 100644 --- a/doc/technical/cross-chain-bridge-integration.md +++ b/doc/technical/cross-chain-bridge-integration.md @@ -35,7 +35,7 @@ function setCCIPAdmin(address newAdmin) public virtual // DEFAULT_ADMIN_ROLE 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. +Freezing the pool's address with `setAddressFrozen` does **not** block its `mint` / `crosschainMint`: CMTAT's own freeze logic checks the *recipient*, not the operator, so a frozen minter can still mint. On a RuleEngine deployment (e.g. Standard) the operator is forwarded to the configured RuleEngine as the `spender` argument of `transferred(...)`, so a RuleEngine *rule* may reject the mint on that basis — but the base contract does not, and the Light variant has no RuleEngine. To stop a compromised pool from minting, **revoke its `MINTER_ROLE`**. See [access-control.md](./access-control.md#what-freeze-and-pause-block-per-operation). #### Why the cross-chain path is pause-gated (but issuer mint/burn is not) @@ -98,6 +98,19 @@ Choose the adapter that matches the interface used by the LayerZero pool. | `mint(address, uint256)` | `MINTER_ROLE` | Grant to CCIP pool | | `setCCIPAdmin(address)` | `DEFAULT_ADMIN_ROLE` | Manage CCIP registration | +### The bridge gate uses `msg.sender`, not `_msgSender()` + +`crosschainMint` and `crosschainBurn` are guarded by the `onlyTokenBridge` modifier, which authorizes the **raw `msg.sender`** — deliberately, and unlike every other role gate in CMTAT, which resolves the caller through `_msgSender()` (ERC-2771 aware). CMTAT follows OpenZeppelin's `draft-ERC20Bridgeable` here: a token bridge holds an unbounded mint authority, so it must never be impersonable through a relayer. + +Two consequences for integrators: + +- **A bridge cannot relay its calls through the ERC-2771 forwarder.** It must call `crosschainMint` / `crosschainBurn` **directly**, as `msg.sender`. A meta-transaction relayed by the forwarder reverts, because the forwarder — not the bridge — is the raw caller and does not hold `CROSS_CHAIN_ROLE`. +- **Never grant `CROSS_CHAIN_ROLE` to the ERC-2771 forwarder.** This is the tempting "fix" for the point above, and it is a critical misconfiguration: granting it would make **every relayed call pass the gate**, since `onlyTokenBridge` only ever inspects the raw caller. Any user could then submit a meta-transaction through the forwarder and mint an arbitrary amount to any address — the token's supply control would be gone. The forwarder is set at construction and is irrevocable in standalone deployments, so this cannot be undone by re-pointing it; the only remedy is revoking the role. + +> The same reasoning applies to any contract that can be made to call the token on a third party's behalf: `CROSS_CHAIN_ROLE` must be held only by contracts whose call to `crosschainMint` / `crosschainBurn` is itself the authorization decision. + +Reported as NM-4 by [Nethermind AuditAgent](https://auditagent.nethermind.io/) on CMTAT v3.3.0-rc2 and assessed as intended behaviour with a deployment constraint; see the [maintainer feedback](../security/tools/nethermind-audit-agent/v3.3.0-rc2/audit_agent_report_v3.3.0-rc2-feedback.md). + ## RuleEngine Operator Semantics - `burnFrom` uses allowance and now propagates `_msgSender()` into the compliance hook, so spender-aware RuleEngine checks are applied. diff --git a/doc/technical/holder-list.md b/doc/technical/holder-list.md index 1ce49711..21356c07 100644 --- a/doc/technical/holder-list.md +++ b/doc/technical/holder-list.md @@ -80,7 +80,14 @@ Revert rules: ## Gas -The first transfer crediting a **new** address writes two storage slots (the `EnumerableSet` stores the value and its index); the transfer that empties an account clears them. Transfers between existing holders that leave both balances non-zero cost nothing extra for this module. +The first transfer crediting a **new** address writes two storage slots (the `EnumerableSet` stores the value and its index); the transfer that empties an account clears them. + +A transfer between two existing holders that leaves both balances non-zero performs **no storage write** to the holder set (no `add`/`remove`, no `HolderAdded`/`HolderRemoved` event) — but it is **not free**. After the base ERC-20 transfer, `_update` still: + +- reads `balanceOf(from)` — one `SLOAD` (the slot is warm, just written by the transfer). Since it is non-zero, the `remove(from)` branch short-circuits and the holder set is not touched on the sender side. +- reads `balanceOf(to)` — one `SLOAD` (also warm). Since it is non-zero, it calls `EnumerableSet.add(to)`, which performs **one membership-check `SLOAD`** (the recipient's index slot, typically cold), finds `to` already present, and returns `false` without writing. + +So the marginal cost of this module on such a transfer is roughly **two warm `SLOAD`s + one (usually cold) `SLOAD` + the branch logic — no `SSTORE`**. The expensive part (the two storage writes) only occurs when an address *becomes* a holder or *stops being* one. ## Security Considerations @@ -89,4 +96,9 @@ The first transfer crediting a **new** address writes two storage slots (the `En ## Use Case -The on-chain holder set supports issuer reporting and corporate actions (e.g. enumerating shareholders for a distribution or a vote) without reconstructing the list from the full transfer history off-chain. For dividend-style *balance-at-a-block* queries, use the [Snapshot Engine](./snapshot.md) instead — the holder list tracks *current* membership, not historical balances. +The on-chain holder set supports issuer reporting and corporate actions (e.g. enumerating shareholders for a distribution or a vote) without reconstructing the list from the full transfer history off-chain. + +For dividend-style *balance-at-a-block* queries, the holder list itself only tracks **current** membership, not historical balances — so the right tool depends on *where* the query runs: + +- **Off-chain** (indexers, distribution scripts, reporting): you do **not** need the Snapshot Engine. Call the read functions with `eth_call` pinned to a historical block number — `balanceOf`, `holdersInRange`, `holderCount` all return the state as of that block. This gives a consistent balance-at-a-block view for free, and is the recommended approach for off-chain dividend computation. Read the whole set at a single fixed block for a coherent snapshot (see [Security Considerations](#security-considerations) on windowed reads). +- **On-chain** (a contract that must act on a past balance during execution — e.g. an on-chain dividend or voting contract that reads a snapshot value): historical state is not available to the EVM, so use the [Snapshot Engine](./snapshot.md) / [CMTA/SnapshotEngine](https://github.com/CMTA/SnapshotEngine), which records balances at scheduled points and exposes them on-chain. diff --git a/doc/technical/ruleengine-integration.md b/doc/technical/ruleengine-integration.md index 62206490..12a0efc8 100644 --- a/doc/technical/ruleengine-integration.md +++ b/doc/technical/ruleengine-integration.md @@ -40,6 +40,18 @@ Minimum RuleEngine target interface in CMTAT: > - the **original** ERC-1404, which was only ever published as a [GitHub issue](https://github.com/ethereum/EIPs/issues/1404) and never became a merged EIP — covered by `IERC1404` (`detectTransferRestriction(from, to, value)` + `messageForTransferRestriction(code)`); > - its **current rework**, the draft proposal ["Simple Restricted Token" (ethereum/ERCs PR #1701)](https://github.com/ethereum/ERCs/pull/1701), still **open/draft**, which brings ERC-1404 into the canonical format — covered by `IERC1404Extend`, adding the spender-aware `detectTransferRestrictionFrom(spender, from, to, value)` that pairs with CMTAT's `canTransferFrom` / spender-aware paths. +> **Scope — transfers only.** Both `detectTransferRestriction*` methods describe `transfer` / +> `transferFrom`. CMTAT does **not** support the rework draft's `address(0)` encoding for mint/burn +> prediction, because its pause rule differs *between entry points of the same operation* +> (`MINTER_ROLE` mint and `BURNER_ROLE` burn proceed while paused; `crosschainMint`, +> `crosschainBurn`, `burnFrom` and `burn(uint256)` do not), and the ERC-1404 signature carries no +> entry-point discriminator. Use `canTransfer` / `canTransferFrom` for mint and burn prediction. See +> the [ERC-1404 scope note](../README.md#scope-transfers-only-never-mint-or-burn). +> +> A RuleEngine still receives mint/burn notifications through `transferred(...)` with the +> `address(0)` encoding — that is the *enforcement* path and is unaffected by the above. What is +> not supported is *predicting* a mint or burn through the ERC-1404 read methods. + ## Configuration Lifecycle RuleEngine is optional and can be zero-address. @@ -126,12 +138,26 @@ Use deployment summary in [doc/SUMMARY.md](../SUMMARY.md) and deployment tables - 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*`. +6. `messageForTransferRestriction(code)` must return a **non-empty** string for every code the engine can return, + and that string must never denote the absence of a restriction (`"No restriction"`, `""`, …) for a non-zero + code. The token resolves its own codes (`0`–`6`) and **forwards every other code to the engine verbatim**, so + the engine's string is what integrators and user interfaces display. An empty or misleading string therefore + surfaces a blocked transfer as if it were permitted — see the ERC-1404 rework draft, + `messageForTransferRestriction`. The token does not inspect the forwarded value: the RuleEngine is + `DEFAULT_ADMIN_ROLE`-set and trusted, and a length check would guard only the least harmful failure while + costing bytecode on variants already close to the EIP-170 limit. +7. The engine must implement `IRuleEngineERC1404` if the token exposes ERC-1404. `detectTransferRestriction` / + `messageForTransferRestriction` on the token forward to the engine unguarded, so an engine without those + methods makes both token view functions revert (the enforcement path, which calls `transferred(...)`, is + unaffected). See design choice 1 below: the engine type is not validated at set-time. ## 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. +4. The token does not sanitise what the engine returns — neither the restriction code nor the message. Both are + forwarded as-is, consistent with the trusted-engine assumption stated above and with design choice 1. ## Cross-References diff --git a/doc/technical/stablecoin.md b/doc/technical/stablecoin.md index c51472f8..3c596762 100644 --- a/doc/technical/stablecoin.md +++ b/doc/technical/stablecoin.md @@ -128,7 +128,8 @@ If you need to *move* the tokens to another address instead of burning them, Lig ### Deactivation `deactivateContract()` (requires `DEFAULT_ADMIN_ROLE`, contract must be paused first) permanently disables the contract. After deactivation: -- All state-changing operations revert. +- Holder transfers and standard `mint` / `burn` revert with `EnforcedDeactivation`. +- Privileged enforcement operations still work by design: `forcedBurn` (Light) / `forcedTransfer` (Standard) and the freeze setters remain available to the admin/enforcer, so a terminated position can still be swept. See [lifecycle.md](./lifecycle.md). - Read functions still work. - The state is irreversible. diff --git a/doc/test/Test.md b/doc/test/Test.md new file mode 100644 index 00000000..5e52accb --- /dev/null +++ b/doc/test/Test.md @@ -0,0 +1,192 @@ +# CMTAT Test Catalogue + +This file catalogues the CMTAT test suite **per feature module and per deployment version**, so that missing +coverage is easy to spot. It is a map, not a copy of the tests — it is maintained by hand and **must be updated +whenever a test is added, changed or removed** (see [Maintenance](#maintenance)). + +- Run everything: `npm run test` (or `DeactivateReportGas=true npx hardhat test` if the gas reporter errors). +- Coverage report: `npm run coverage`. +- Scale: **~486 distinct `it(...)` definitions**, executed across the deployment variants for roughly **6 000 + test cases** (`5998 passing / 87 pending` on the current tree). + +## Test architecture + +CMTAT is a modular framework, and the tests mirror that. There are two layers: + +1. **Shared behaviour modules** — `test/common/**` — each exports a function (e.g. `ERC20MintModuleCommon()`) that + registers a `context(...)` of `it(...)` cases for one feature. These contain the actual assertions and are + **deployment-agnostic**. +2. **Deployment wirings** — the shared modules are invoked against a concrete deployment: + - `test/standard/modules/**` — one file per module, wired to the **standalone Standard** deployment. + - `test/proxy/modules/**` — the same, wired to the **Transparent-proxy** deployment. + - `test/deployment//**` — one entry file per variant (standalone + upgradeable) that includes the + subset of shared modules that variant supports, plus variant-specific inline tests. + +So a single `it(...)` in `test/common/**` runs on every deployment version that includes its module. To find a +gap, ask: *does this module run on this version?* — the [coverage matrix](#coverage-matrix) answers that. + +## Deployment versions + +| Version | Base contract | Deploy helper (standalone / proxy) | Entry tests | +| --- | --- | --- | --- | +| **Light** | `CMTATBaseCore` | `deployCMTATLightStandalone` / `deployCMTATLightProxy` | `test/deployment/light/*` | +| **Standard** | `CMTATBaseERC7551Enforcement` | `deployCMTATStandalone` / `deployCMTATProxy` | `test/standard/modules/*`, `test/proxy/modules/*` | +| **Allowlist** | `CMTATBaseAllowlist` | `deployCMTATAllowlistStandalone` / `…Proxy` | `test/deployment/allowlist/*` | +| **ERC-7551** | `CMTATBaseERC7551` | `deployCMTATERC7551Standalone` / `…Proxy` | `test/deployment/erc7551/*` | +| **Permit** | `CMTATBaseERC2612` | `deployCMTATPermitStandalone` / `…Proxy` | `test/deployment/permit/*` | +| **Snapshot** | `CMTATBaseERC2771Snapshot` | `deployCMTATSnapshotStandalone` / `…Proxy` | `test/deployment/snapshot/*` | +| **Debt** | `CMTATBaseDebt` | `deployCMTATDebtStandalone` / `…Proxy` | `test/deployment/debt/*` | +| **DebtEngine** | `CMTATBaseDebtEngine` | `deployCMTATDebtEngineStandalone` / `…Proxy` | `test/deployment/debtEngine/*` | +| **HolderList** | `CMTATBaseHolderList` | `deployCMTATHolderListStandalone` / `…Proxy` | `test/deployment/…`, `test/{standard,proxy}/modules/HolderListModule*` | +| **ERC-1363** | `CMTATBaseERC1363` | `deployCMTATERC1363Standalone` / `…Proxy` | `test/deployment/ERC1363/*` | +| **UUPS** | `CMTATUpgradeableUUPS` | `deployCMTATUUPSProxy` | `test/deployment/deploymentUpgradeableUUPS*.test.js` | + +> The **Standard** version is the reference: `test/standard/modules/**` and `test/proxy/modules/**` exercise the +> full module set (below). The other variants run the subset of modules they support. + +## Coverage matrix + +Which feature module runs on which deployment version. `✓` = the module's shared tests run on that version; +`—` = not applicable (the version does not include that feature); `(std)` = covered only via the full Standard / +Proxy module suites, not the variant entry file. + +| Feature module (common) | Light | Standard | Allowlist | ERC-7551 | Permit | Snapshot | Debt | DebtEngine | ERC-1363 | UUPS | +| --- | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | +| Version | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Pause / Deactivate | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| ERC20Base (transfer/approve/allowance) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| ERC20Mint (mint/batchMint/batchTransfer) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| ERC20Burn (burn/batchBurn/burnAndMint) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Enforcement (address freeze) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| ERC20Enforcement (partial freeze / forcedTransfer) | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| ERC20Enforcement ERC-7551 (bytes overloads) | — | ✓ | ✓ | ✓ | — | — | — | — | ✓ | — | +| Validation — Core (`canTransfer`, pause/freeze) | ✓ | ✓ | ✓ | (std) | (std) | (std) | ✓ | ✓ | (std) | (std) | +| Validation — RuleEngine (full, ERC-1404) | — | ✓ | — | (std) | (std) | (std) | — | — | (std) | (std) | +| Validation — RuleEngine reentrancy (NM-7) | — | ✓ | — | — | — | — | — | — | — | — | +| Validation — RuleEngine spender dispatch | — | ✓ | — | — | — | — | — | — | — | — | +| Allowlist | — | (std) | ✓ | — | — | — | — | — | — | — | +| Document (ERC-1643) | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| DocumentEngine | — | ✓ | — | — | — | — | — | — | — | — | +| ExtraInformation (tokenId/terms/info) | — | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| ERC-7551 (metadata/terms overloads) | — | ✓ | — | ✓ | — | — | — | — | — | — | +| Snapshot (schedule/reschedule/unschedule/reads) | — | ✓ | — | — | — | ✓ | (engine) | (engine) | — | — | +| SnapshotEngine (setSnapshotEngine) | — | ✓ | — | — | — | ✓ | ✓ | ✓ | — | — | +| Debt (debt/creditEvents) | — | — | — | — | — | — | ✓ | (engine) | — | — | +| DebtEngine (setDebtEngine) | — | — | — | — | — | — | — | ✓ | — | — | +| CrossChain (ERC-7802 crosschainMint/Burn, burnFrom) | — | ✓ | — | ✓ | ✓ | ✓ | — | — | ✓ | ✓ | +| CCIP (setCCIPAdmin) | — | ✓ | — | ✓ | ✓ | ✓ | — | — | ✓ | ✓ | +| Permit (ERC-2612) | — | — | — | — | ✓ | — | — | — | — | — | +| Multicall (ERC-6357) | — | — | — | — | ✓ | — | — | — | — | — | +| MetaTx (ERC-2771, `_msgSender`/`_msgData`) | — | ✓ | ✓ (msgData) | — | — | ✓ (msgData) | — | — | ✓ (msgData) | ✓ (UUPS) | +| HolderList | — | ✓ | — | — | — | — | — | — | — | — | +| Authorization (RBAC grant/revoke) | (inline) | ✓ | (std) | (std) | (std) | (std) | (std) | (std) | (std) | (std) | +| CMTAT integration (end-to-end) | — | ✓ | — | — | — | — | — | — | — | — | + +Notes: +- **Light** deliberately has the smallest surface: core ERC-20 + address-freeze + pause + core validation. It has + **no** RuleEngine, partial-freeze, allowlist, document, snapshot, debt, cross-chain, permit or ERC-7551 tests — + by design (see [`doc/technical/deployment.md`]). Light additionally has inline `forcedBurn` and ERC-165 tests in + `test/deployment/light/*`. +- The **RuleEngine reentrancy** guard is only present on size-permitting variants (Standard, Snapshot, ERC-7551); + `RuleEngineReentrancyCommon` is wired into the Standard standalone + proxy suites. See + [`doc/modules/controllers/validationRuleEngine.md`] for the per-variant table. + +## Test module reference + +Each shared module (`test/common/**`), its `it(...)` count, and what it covers. Counts are indicative; the +scenarios list the `context(...)` groups. + +### Core ERC-20 & supply +| Module | File | `it` | Covers | +| --- | --- | --: | --- | +| Version | `VersionModuleCommon.js` | 1 | `version()` returns the SemVer string. | +| ERC20Base | `ERC20BaseModuleCommon.js` | 25 | Token structure, name/symbol, decimals, balance, `approve`/allowance, `transfer`, `transferFrom`. | +| ERC20Mint | `ERC20MintModuleCommon.js` | 34 | `mint`, `batchMint`, `batchTransfer`; recipient-frozen blocks; **frozen minter can still mint** (`testFrozenMinterCanStillMint`/`…BatchMint`); frozen minter's `batchTransfer` blocked; RuleEngine spender propagation. | +| ERC20Burn | `ERC20BurnModuleCommon.js` | 30 | `burn`, `batchBurn`, `burnAndMint`. | + +### Enforcement & validation +| Module | File | `it` | Covers | +| --- | --- | --: | --- | +| Enforcement | `EnforcementModuleCommon.js` | 21 | `setAddressFrozen`/`batchSetAddressFrozen`, `isFrozen`; frozen sender/spender/recipient block transfers; zero-address rejected; allowance revocation while frozen (NM-3/8). | +| ERC20Enforcement | `ERC20EnforcementModuleCommon.js` | 56 | `freezePartialTokens`/`unfreezePartialTokens`/`setFrozenTokens`; `forcedTransfer`/forced burn; active-balance checks; **`setFrozenTokens(address(0))` rejected + minting unaffected** (NM-15/17); **`forcedTransfer` emits `Spend` on the allowance reduction, none for zero/infinite** (NM-24). | +| ERC20Enforcement-7551 | `ERC20EnforcementERC7551ModuleCommon.js` | 4 | ERC-7551 `bytes`-data enforcement overloads. | +| Validation (Core) | `ValidationModule/ValidationModuleCommonCore.js` | 4 | `canTransfer`/`canTransferFrom` against pause + freeze, no RuleEngine. | +| Validation (RuleEngine) | `ValidationModule/ValidationModuleCommon.js` | 27 | RuleEngine transfer/transferFrom/mint gating, mint/burn frozen, send/receive checks (ERC-1404 + ERC-7943). | +| Validation setRuleEngine | `ValidationModule/ValidationModuleSetRuleEngineCommon.js` | 6 | `setRuleEngine` access control + same-value revert. | +| Validation reentrancy | `ValidationModule/RuleEngineReentrancyCommon.js` | 7 | Malicious reentrant RuleEngine cannot drain frozen tokens; guard reverts `ReentrancyGuardReentrantCall`; normal/batch flows unaffected (NM-7/9/11/16/18). | +| Validation spender dispatch | `ValidationModule/RuleEngineSpenderDispatchCommon.js` | 2 | `transferFrom` routes to the spender-aware 4-arg `transferred(spender,…)` overload and forwards the real spender; a direct `transfer` routes to the legacy 3-arg overload (spender `address(0)`). Uses `RuleEngineSpenderRecorderMock`; kills the `spender != address(0)` dispatch mutant. | +| Allowlist | `AllowlistModuleCommon.js` | 36 | `setAddressAllowlist`/batch/`enableAllowlist`; allowlisted send/receive; `transferFrom` requires spender **and** from/to allowlisted (`testCannotTransferTokenWhenSpenderIsNotAllowlistWithTransferFrom`); **minter need not be allowlisted to mint** (`testMinterNotAllowlistedCanStillMint`/`…BatchMint`); approve while not allowlisted; revocation carve-out. | + +### Documents, metadata, holder list +| Module | File | `it` | Covers | +| --- | --- | --: | --- | +| Document | `DocumentModule/DocumentModuleCommon.js` | 13 | ERC-1643 `setDocument`/`removeDocument`/`getDocument`/`getAllDocuments`; `DocumentUpdated`/`DocumentRemoved` event emission; `ERC1643InvalidName` on zero name; `ERC1643MissingDocument` on absent remove. Runs on both the native `DocumentERC1643Module` and the external `DocumentEngineModule`. | +| DocumentEngine | `DocumentModule/DocumentModuleSetDocumentEngineCommon.js` | 10 | `setDocumentEngine`, initializer, delegated reads. | +| ExtraInformation | `ExtraInfoModuleCommon.js` | 8 | `setTokenId`/`setTerms`/`setInformation`. | +| ERC-7551 | `ERC7551ModuleCommon.js` | 6 | `setMetaData`, `setTerms(bytes32,string)`; **name-preserving overload** (`testERC7551SetTermsPreservesDocumentName`, NM-22). | +| HolderList | `HolderListModuleCommon.js` | 24 | Holder enumeration, range reads, zero-address never added. | + +### Snapshot +| Module | File | `it` | Covers | +| --- | --- | --: | --- | +| Snapshot scheduling | `SnapshotModuleCommon/SnapshotModuleCommonScheduling.js` | 11 | Schedule (optimized + not). | +| Snapshot rescheduling | `…/SnapshotModuleCommonRescheduling.js` | 11 | Reschedule. | +| Snapshot unscheduling | `…/SnapshotModuleCommonUnschedule.js` | 12 | Unschedule. | +| Snapshot get-next | `…/SnapshotModuleCommonGetNextSnapshot.js` | 4 | `getNextSnapshots`. | +| Snapshot global | `…/global/SnapshotModule{Multiple,OnePlanned,ZeroPlanned}*.js` | 8 | Balance-at-snapshot with 0/1/many planned. | +| SnapshotEngine | `…/SnapshotModuleSetSnapshotEngineCommon.js` | 6 | `setSnapshotEngine`, initializer. | + +### Options: debt, cross-chain, permit, meta-tx +| Module | File | `it` | Covers | +| --- | --- | --: | --- | +| Debt | `DebtModule/DebtModuleCommon.js` | 5 | `debt`/`creditEvents` values. | +| Debt setDebtEngine | `DebtModule/DebtModuleSetDebtEngineCommon.js` | 4 | `setDebtEngine`. | +| DebtEngine | `DebtModule/DebtEngineModuleCommon.js` | 3 | Delegated debt reads via engine. | +| CrossChain | `ERC20CrossChainModuleCommon.js` | 32 | ERC-7802 `crosschainMint`/`crosschainBurn`, `burnFrom`, self-burn; `onlyTokenBridge`; RuleEngine spender propagation. | +| CCIP | `CCIPModuleCommon.js` | 3 | `setCCIPAdmin` access control. | +| Permit | `PermitModuleCommon.js` | 8 | ERC-2612 `permit` (valid, expired, paused, owner/spender frozen); **zero-value permit revocation allowed while paused / owner or spender frozen** (NM-3/8). | +| Multicall | `MulticallModuleCommon.js` | 2 | ERC-6357 batching. | +| MetaTx | `MetaTxModuleCommon.js` + `MetaTxMsgDataCommon.js` | 4 | ERC-2771 gasless (`_msgSender`), `_msgData` coverage. | + +### Security, RBAC, integration, engines-as-mocks +| Module | File | `it` | Covers | +| --- | --- | --: | --- | +| Authorization | `AuthorizationModule/AuthorizationModuleCommon.js` | 5 | RBAC grant/revoke, admin-has-all-roles. | +| CMTAT integration | `CMTATIntegrationCommon.js` | 4 | End-to-end multi-module flows. | +| Proxy security | `test/proxy/general/Proxy.test.js` | — | Proxy init / front-running / storage. | +| Upgrade | `test/proxy/general/Upgrade*.test.js` | — | Transparent + UUPS upgrade paths. | +| RuleEngine stateful | `test/standard/modules/RuleEngineMockStatefulRule.test.js` | — | Stateful holder-tracking rule via `transferred`. | + +## Deployment-specific & cross-cutting test files + +Not everything is a shared module. These entry files add variant-specific or cross-cutting coverage: +- `test/deployment/deployment.test.js` — constructor/initializer parameter validation. +- `test/deployment/light/*` — Light inline: `forcedBurn` when frozen, ERC-165 interface set (no ERC-1404/1363). +- `test/deployment/allowlist/deploymentStandaloneDisableAllowlist.test.js` — allowlist-disabled behaviour. +- `test/deployment/debt/…DebtSnapshot`, `debtEngine/…Snapshot` — debt + snapshot combined. +- `test/deployment/ERC1363/deploymentERC1363ProxyValidation.test.js` — ERC-1363 + RuleEngine validation. +- `test/deployment/deploymentUpgradeableUUPSManual.test.js` — manual UUPS deployment. +- `test/standard/modules/MetaTx*` and `MetaTxMsgData*` — ERC-2771 across Allowlist / ERC-1363 / Snapshot / UUPS. +- `test/standard/modules/ValidationModule/ValidationModuleConstructor.test.js` — RuleEngine set at construction. + +## How to find missing coverage + +1. In the [coverage matrix](#coverage-matrix), a `—` where a feature *should* exist on a version is a gap + (e.g. a new option added to Light but not tested there). +2. In the [module reference](#test-module-reference), any behaviour described in `doc/**` with no matching `it` + is a gap. Known open example: **Permit zero-value revocation** (⚠️ above). +3. A new deployment variant needs its own entry file wiring the applicable shared modules **and** a new matrix + column here. + +## Maintenance + +**This file is hand-maintained. Update it in the same change that touches the tests:** +- **Test added** → add/adjust the `it` count and scenario in the [module reference](#test-module-reference); if it + covers a new feature, add a matrix row/column. +- **Test removed** → remove it here; if it was the only coverage of a behaviour, note the resulting gap. +- **New deployment variant** → add a [Deployment versions](#deployment-versions) row and a + [coverage matrix](#coverage-matrix) column. +- **New shared module** → add it to the [module reference](#test-module-reference) and the matrix. + +Keeping this current is what makes missing tests findable at a glance — an out-of-date catalogue is worse than +none. diff --git a/doc/test/coverage.json b/doc/test/coverage.json index 75d57a92..03f8e13d 100644 --- a/doc/test/coverage.json +++ b/doc/test/coverage.json @@ -1 +1 @@ -{"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 +{"contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol":{"l":{"28":458},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol","s":{"1":458},"b":{},"f":{"1":458},"fnMap":{"1":{"name":"constructor","line":26,"loc":{"start":{"line":21,"column":4},"end":{"line":33,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":1208}}},"branchMap":{}},"contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol":{"l":{"20":247},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol","s":{"1":247},"b":{},"f":{"1":247},"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":{"34":344,"63":142},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardStandalone.sol","s":{"1":344,"2":142},"b":{"1":[142,4]},"f":{"1":344,"2":142},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":26,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":62,"loc":{"start":{"line":56,"column":4},"end":{"line":64,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1664}},"2":{"start":{"line":63,"column":8},"end":{"line":63,"column":78}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":32},"end":{"line":62,"column":32}},{"start":{"line":62,"column":32},"end":{"line":62,"column":32}}]}}},"contracts/deployment/CMTATStandardUpgradeable.sol":{"l":{"25":367,"49":237},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardUpgradeable.sol","s":{"1":367,"2":237},"b":{"1":[237,4]},"f":{"1":367,"2":237},"fnMap":{"1":{"name":"constructor","line":23,"loc":{"start":{"line":21,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":48,"loc":{"start":{"line":42,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":29}},"2":{"start":{"line":49,"column":8},"end":{"line":49,"column":78}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":32},"end":{"line":48,"column":32}},{"start":{"line":48,"column":32},"end":{"line":48,"column":32}}]}}},"contracts/deployment/CMTATUpgradeableUUPS.sol":{"l":{"22":484},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol","s":{"1":484},"b":{"1":[2,1]},"f":{"1":484,"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":482},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.sol","s":{"1":482},"b":{},"f":{"1":482},"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":1033}}},"branchMap":{}},"contracts/deployment/debt/CMTATUpgradeableDebt.sol":{"l":{"16":492},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt.sol","s":{"1":492},"b":{},"f":{"1":492},"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":486},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol","s":{"1":486},"b":{},"f":{"1":486},"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":1057}}},"branchMap":{}},"contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol":{"l":{"16":222},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol","s":{"1":222},"b":{},"f":{"1":222},"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":245},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol","s":{"1":245},"b":{},"f":{"1":245},"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":285},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol","s":{"1":285},"b":{},"f":{"1":285},"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":{"33":248,"67":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol","s":{"1":248,"2":22},"b":{"1":[22,0]},"f":{"1":248,"2":22},"fnMap":{"1":{"name":"constructor","line":31,"loc":{"start":{"line":25,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":66,"loc":{"start":{"line":60,"column":4},"end":{"line":68,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":1614}},"2":{"start":{"line":67,"column":8},"end":{"line":67,"column":78}}},"branchMap":{"1":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":32},"end":{"line":66,"column":32}},{"start":{"line":66,"column":32},"end":{"line":66,"column":32}}]}}},"contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol":{"l":{"24":248,"48":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol","s":{"1":248,"2":22},"b":{"1":[22,0]},"f":{"1":248,"2":22},"fnMap":{"1":{"name":"constructor","line":22,"loc":{"start":{"line":20,"column":4},"end":{"line":25,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":47,"loc":{"start":{"line":41,"column":4},"end":{"line":49,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":29}},"2":{"start":{"line":48,"column":8},"end":{"line":48,"column":78}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":32},"end":{"line":47,"column":32}},{"start":{"line":47,"column":32},"end":{"line":47,"column":32}}]}}},"contracts/deployment/holderList/CMTATStandaloneHolderList.sol":{"l":{"31":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATStandaloneHolderList.sol","s":{"1":24},"b":{},"f":{"1":24},"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":1345}}},"branchMap":{}},"contracts/deployment/holderList/CMTATUpgradeableHolderList.sol":{"l":{"22":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol","s":{"1":24},"b":{},"f":{"1":24},"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/light/CMTATStandaloneLight.sol":{"l":{"23":134},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight.sol","s":{"1":134},"b":{},"f":{"1":134},"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":131},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLight.sol","s":{"1":131},"b":{},"f":{"1":131},"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":248},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATStandalonePermit.sol","s":{"1":248},"b":{},"f":{"1":248},"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":250},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATUpgradeablePermit.sol","s":{"1":250},"b":{},"f":{"1":250},"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":{"34":344,"63":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol","s":{"1":344,"2":22},"b":{"1":[22,0]},"f":{"1":344,"2":22},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":26,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":62,"loc":{"start":{"line":56,"column":4},"end":{"line":64,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1669}},"2":{"start":{"line":63,"column":8},"end":{"line":63,"column":78}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":32},"end":{"line":62,"column":32}},{"start":{"line":62,"column":32},"end":{"line":62,"column":32}}]}}},"contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol":{"l":{"25":369,"49":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol","s":{"1":369,"2":22},"b":{"1":[22,0]},"f":{"1":369,"2":22},"fnMap":{"1":{"name":"constructor","line":23,"loc":{"start":{"line":21,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":48,"loc":{"start":{"line":42,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":29}},"2":{"start":{"line":49,"column":8},"end":{"line":49,"column":78}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":32},"end":{"line":48,"column":32}},{"start":{"line":48,"column":32},"end":{"line":48,"column":32}}]}}},"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/IHolderListModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IHolderListModule.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/draft-IERC8343.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC8343.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":{"53":22,"61":88,"68":70,"74":442,"75":442,"76":252,"77":190,"92":306,"93":174,"110":110,"111":66,"118":8968,"129":6737,"130":6571,"140":1169,"141":957,"151":314,"152":199},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol","s":{"1":22,"2":88,"3":70,"4":442,"5":442,"6":252,"7":190,"8":306,"9":174,"10":110,"11":66,"12":8968,"13":6737,"14":6571,"15":1169,"16":957,"17":314,"18":199},"b":{},"f":{"1":22,"2":88,"3":70,"4":442,"5":306,"6":110,"7":8968,"8":6737,"9":1169,"10":314},"fnMap":{"1":{"name":"decimals","line":46,"loc":{"start":{"line":46,"column":4},"end":{"line":54,"column":4}}},"2":{"name":"name","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":62,"column":4}}},"3":{"name":"symbol","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":69,"column":4}}},"4":{"name":"transfer","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"transferFrom","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":94,"column":4}}},"6":{"name":"burnAndMint","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":112,"column":4}}},"7":{"name":"_checkTransferred","line":117,"loc":{"start":{"line":117,"column":4},"end":{"line":119,"column":4}}},"8":{"name":"_mintOverride","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":131,"column":4}}},"9":{"name":"_burnOverride","line":139,"loc":{"start":{"line":139,"column":4},"end":{"line":142,"column":4}}},"10":{"name":"_minterTransferOverride","line":150,"loc":{"start":{"line":150,"column":4},"end":{"line":153,"column":4}}}},"statementMap":{"1":{"start":{"line":53,"column":8},"end":{"line":53,"column":41}},"2":{"start":{"line":61,"column":8},"end":{"line":61,"column":42}},"3":{"start":{"line":68,"column":8},"end":{"line":68,"column":44}},"4":{"start":{"line":74,"column":9},"end":{"line":74,"column":36}},"5":{"start":{"line":75,"column":8},"end":{"line":75,"column":53}},"6":{"start":{"line":76,"column":8},"end":{"line":76,"column":50}},"7":{"start":{"line":77,"column":8},"end":{"line":77,"column":19}},"8":{"start":{"line":92,"column":8},"end":{"line":92,"column":55}},"9":{"start":{"line":93,"column":8},"end":{"line":93,"column":60}},"10":{"start":{"line":110,"column":8},"end":{"line":110,"column":53}},"11":{"start":{"line":111,"column":8},"end":{"line":111,"column":51}},"12":{"start":{"line":118,"column":8},"end":{"line":118,"column":79}},"13":{"start":{"line":129,"column":8},"end":{"line":129,"column":66}},"14":{"start":{"line":130,"column":8},"end":{"line":130,"column":60}},"15":{"start":{"line":140,"column":8},"end":{"line":140,"column":67}},"16":{"start":{"line":141,"column":8},"end":{"line":141,"column":60}},"17":{"start":{"line":151,"column":8},"end":{"line":151,"column":55}},"18":{"start":{"line":152,"column":8},"end":{"line":152,"column":71}}},"branchMap":{}},"contracts/modules/0_CMTATBaseCore.sol":{"l":{"61":4,"62":3,"78":265,"94":318,"97":318,"100":318,"103":318,"111":318,"112":318,"121":318,"122":318,"123":318,"148":2,"156":6,"163":6,"175":19,"183":26,"184":26,"185":16,"186":10,"193":54,"194":44,"209":18,"210":14,"227":10,"228":6,"245":3,"247":2,"248":2,"257":368,"258":360,"263":76,"264":66,"275":20,"276":12},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol","s":{"1":4,"2":265,"3":318,"4":318,"5":318,"6":318,"7":318,"8":318,"9":318,"10":318,"11":318,"12":2,"13":6,"14":6,"15":19,"16":26,"17":26,"18":16,"19":10,"20":54,"21":44,"22":18,"23":14,"24":10,"25":6,"26":3,"27":2,"28":2,"29":368,"30":360,"31":76,"32":66,"33":20,"34":12},"b":{"1":[265,0],"2":[318,0],"3":[318,0],"4":[318,0],"5":[2,2],"6":[2,5],"7":[3,1],"8":[2,1],"9":[3,1],"10":[298,6],"11":[54,8],"12":[56,4],"13":[22,2],"14":[65,6],"15":[4,4]},"f":{"1":4,"2":265,"3":318,"4":318,"5":318,"6":2,"7":6,"8":6,"9":19,"10":26,"11":54,"12":18,"13":10,"14":3,"15":368,"16":76,"17":20,"18":3,"19":298,"20":54,"21":56,"22":22,"23":65,"24":4},"fnMap":{"1":{"name":"onlyERC20ForcedBurnManager","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":63,"column":4}}},"2":{"name":"initialize","line":77,"loc":{"start":{"line":74,"column":4},"end":{"line":82,"column":4}}},"3":{"name":"__CMTAT_init","line":91,"loc":{"start":{"line":88,"column":4},"end":{"line":104,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":109,"loc":{"start":{"line":109,"column":4},"end":{"line":113,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":119,"loc":{"start":{"line":119,"column":4},"end":{"line":124,"column":4}}},"6":{"name":"decimals","line":141,"loc":{"start":{"line":141,"column":4},"end":{"line":149,"column":4}}},"7":{"name":"name","line":155,"loc":{"start":{"line":155,"column":4},"end":{"line":157,"column":4}}},"8":{"name":"symbol","line":162,"loc":{"start":{"line":162,"column":4},"end":{"line":164,"column":4}}},"9":{"name":"supportsInterface","line":174,"loc":{"start":{"line":174,"column":4},"end":{"line":176,"column":4}}},"10":{"name":"transfer","line":182,"loc":{"start":{"line":182,"column":4},"end":{"line":187,"column":4}}},"11":{"name":"approve","line":192,"loc":{"start":{"line":192,"column":4},"end":{"line":195,"column":4}}},"12":{"name":"transferFrom","line":199,"loc":{"start":{"line":199,"column":4},"end":{"line":211,"column":4}}},"13":{"name":"burnAndMint","line":226,"loc":{"start":{"line":226,"column":4},"end":{"line":229,"column":4}}},"14":{"name":"forcedBurn","line":244,"loc":{"start":{"line":240,"column":4},"end":{"line":249,"column":4}}},"15":{"name":"_mintOverride","line":256,"loc":{"start":{"line":256,"column":4},"end":{"line":259,"column":4}}},"16":{"name":"_burnOverride","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":265,"column":4}}},"17":{"name":"_minterTransferOverride","line":270,"loc":{"start":{"line":270,"column":4},"end":{"line":277,"column":4}}},"18":{"name":"_authorizeForcedBurn","line":280,"loc":{"start":{"line":280,"column":4},"end":{"line":280,"column":82}}},"19":{"name":"_authorizeMint","line":282,"loc":{"start":{"line":282,"column":4},"end":{"line":282,"column":95}}},"20":{"name":"_authorizeBurn","line":284,"loc":{"start":{"line":284,"column":4},"end":{"line":284,"column":95}}},"21":{"name":"_authorizePause","line":286,"loc":{"start":{"line":286,"column":4},"end":{"line":286,"column":92}}},"22":{"name":"_authorizeDeactivate","line":287,"loc":{"start":{"line":287,"column":4},"end":{"line":287,"column":104}}},"23":{"name":"_authorizeFreeze","line":289,"loc":{"start":{"line":289,"column":4},"end":{"line":289,"column":101}}},"24":{"name":"_authorizeTokenAttributeManagement","line":291,"loc":{"start":{"line":291,"column":4},"end":{"line":291,"column":127}}}},"statementMap":{"1":{"start":{"line":61,"column":8},"end":{"line":61,"column":29}},"2":{"start":{"line":78,"column":8},"end":{"line":78,"column":3167}},"3":{"start":{"line":94,"column":8},"end":{"line":94,"column":33}},"4":{"start":{"line":97,"column":8},"end":{"line":97,"column":32}},"5":{"start":{"line":100,"column":8},"end":{"line":100,"column":44}},"6":{"start":{"line":103,"column":8},"end":{"line":103,"column":62}},"7":{"start":{"line":111,"column":8},"end":{"line":111,"column":39}},"8":{"start":{"line":112,"column":8},"end":{"line":112,"column":34}},"9":{"start":{"line":121,"column":8},"end":{"line":121,"column":50}},"10":{"start":{"line":122,"column":8},"end":{"line":122,"column":77}},"11":{"start":{"line":123,"column":8},"end":{"line":123,"column":92}},"12":{"start":{"line":148,"column":8},"end":{"line":148,"column":41}},"13":{"start":{"line":156,"column":8},"end":{"line":156,"column":42}},"14":{"start":{"line":163,"column":8},"end":{"line":163,"column":44}},"15":{"start":{"line":175,"column":8},"end":{"line":175,"column":144}},"16":{"start":{"line":183,"column":8},"end":{"line":183,"column":35}},"17":{"start":{"line":184,"column":8},"end":{"line":184,"column":82}},"18":{"start":{"line":185,"column":8},"end":{"line":185,"column":50}},"19":{"start":{"line":186,"column":8},"end":{"line":186,"column":19}},"20":{"start":{"line":193,"column":8},"end":{"line":193,"column":76}},"21":{"start":{"line":194,"column":8},"end":{"line":194,"column":55}},"22":{"start":{"line":209,"column":8},"end":{"line":209,"column":84}},"23":{"start":{"line":210,"column":8},"end":{"line":210,"column":60}},"24":{"start":{"line":227,"column":8},"end":{"line":227,"column":53}},"25":{"start":{"line":228,"column":8},"end":{"line":228,"column":51}},"26":{"start":{"line":245,"column":8},"end":{"line":245,"column":95}},"27":{"start":{"line":247,"column":8},"end":{"line":247,"column":45}},"28":{"start":{"line":248,"column":8},"end":{"line":248,"column":75}},"29":{"start":{"line":257,"column":8},"end":{"line":257,"column":58}},"30":{"start":{"line":258,"column":8},"end":{"line":258,"column":60}},"31":{"start":{"line":263,"column":8},"end":{"line":263,"column":58}},"32":{"start":{"line":264,"column":8},"end":{"line":264,"column":60}},"33":{"start":{"line":275,"column":8},"end":{"line":275,"column":84}},"34":{"start":{"line":276,"column":8},"end":{"line":276,"column":71}}},"branchMap":{"1":{"line":77,"type":"if","locations":[{"start":{"line":77,"column":21},"end":{"line":77,"column":21}},{"start":{"line":77,"column":21},"end":{"line":77,"column":21}}]},"2":{"line":91,"type":"if","locations":[{"start":{"line":91,"column":23},"end":{"line":91,"column":23}},{"start":{"line":91,"column":23},"end":{"line":91,"column":23}}]},"3":{"line":109,"type":"if","locations":[{"start":{"line":109,"column":68},"end":{"line":109,"column":68}},{"start":{"line":109,"column":68},"end":{"line":109,"column":68}}]},"4":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":136},"end":{"line":119,"column":136}},{"start":{"line":119,"column":136},"end":{"line":119,"column":136}}]},"5":{"line":175,"type":"cond-expr","locations":[{"start":{"line":175,"column":15},"end":{"line":175,"column":39}},{"start":{"line":175,"column":44},"end":{"line":175,"column":84}}]},"6":{"line":175,"type":"cond-expr","locations":[{"start":{"line":175,"column":15},"end":{"line":175,"column":84}},{"start":{"line":175,"column":89},"end":{"line":175,"column":143}}]},"7":{"line":244,"type":"if","locations":[{"start":{"line":244,"column":48},"end":{"line":244,"column":48}},{"start":{"line":244,"column":48},"end":{"line":244,"column":48}}]},"8":{"line":245,"type":"if","locations":[{"start":{"line":245,"column":8},"end":{"line":245,"column":8}},{"start":{"line":245,"column":8},"end":{"line":245,"column":8}}]},"9":{"line":280,"type":"if","locations":[{"start":{"line":280,"column":53},"end":{"line":280,"column":53}},{"start":{"line":280,"column":53},"end":{"line":280,"column":53}}]},"10":{"line":282,"type":"if","locations":[{"start":{"line":282,"column":73},"end":{"line":282,"column":73}},{"start":{"line":282,"column":73},"end":{"line":282,"column":73}}]},"11":{"line":284,"type":"if","locations":[{"start":{"line":284,"column":73},"end":{"line":284,"column":73}},{"start":{"line":284,"column":73},"end":{"line":284,"column":73}}]},"12":{"line":286,"type":"if","locations":[{"start":{"line":286,"column":70},"end":{"line":286,"column":70}},{"start":{"line":286,"column":70},"end":{"line":286,"column":70}}]},"13":{"line":287,"type":"if","locations":[{"start":{"line":287,"column":75},"end":{"line":287,"column":75}},{"start":{"line":287,"column":75},"end":{"line":287,"column":75}}]},"14":{"line":289,"type":"if","locations":[{"start":{"line":289,"column":77},"end":{"line":289,"column":77}},{"start":{"line":289,"column":77},"end":{"line":289,"column":77}}]},"15":{"line":291,"type":"if","locations":[{"start":{"line":291,"column":98},"end":{"line":291,"column":98}},{"start":{"line":291,"column":98},"end":{"line":291,"column":98}}]}}},"contracts/modules/0_CMTATBaseGeneric.sol":{"l":{"50":72,"53":72,"56":72,"59":72,"67":72,"68":72,"76":72,"78":72},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseGeneric.sol","s":{"1":72,"2":72,"3":72,"4":72,"5":72,"6":72,"7":72,"8":72},"b":{"1":[72,0],"2":[72,0],"3":[72,0],"4":[16,2],"5":[3,3]},"f":{"1":72,"2":72,"3":72,"4":16,"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":3118,"21":3118,"22":231,"23":231,"24":231,"25":231,"26":231,"28":2887},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseSnapshot.sol","s":{"1":3118,"2":3118,"3":231,"4":231,"5":231,"6":231,"7":231,"8":2887},"b":{"1":[231,2887]},"f":{"1":3118},"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":{"36":5872,"38":5870,"39":5870,"41":5870,"57":45},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAccessControl.sol","s":{"1":5872,"2":5870,"3":5870,"4":5870,"5":45},"b":{"1":[5872,0],"2":[16,2],"3":[2,2],"4":[2,2],"5":[2,4],"6":[46,44],"7":[5827,66],"8":[691,88],"9":[355,44],"10":[83,79],"11":[1364,66],"12":[298,44]},"f":{"1":5872,"2":45,"3":46,"4":5827,"5":691,"6":355,"7":83,"8":1364,"9":298},"fnMap":{"1":{"name":"__CMTAT_commonModules_init_unchained","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":42,"column":4}}},"2":{"name":"supportsInterface","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":58,"column":4}}},"3":{"name":"_authorizeTokenAttributeManagement","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":70,"column":127}}},"4":{"name":"_authorizeMint","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":76,"column":95}}},"5":{"name":"_authorizeBurn","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":82,"column":95}}},"6":{"name":"_authorizeDocumentManagement","line":88,"loc":{"start":{"line":88,"column":4},"end":{"line":88,"column":117}}},"7":{"name":"_authorizeExtraInfoManagement","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":94,"column":129}}},"8":{"name":"_authorizeERC20Enforcer","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":100,"column":118}}},"9":{"name":"_authorizeForcedTransfer","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":106,"column":119}}}},"statementMap":{"1":{"start":{"line":36,"column":8},"end":{"line":36,"column":50}},"2":{"start":{"line":38,"column":8},"end":{"line":38,"column":77}},"3":{"start":{"line":39,"column":8},"end":{"line":39,"column":92}},"4":{"start":{"line":41,"column":8},"end":{"line":41,"column":177}},"5":{"start":{"line":57,"column":8},"end":{"line":57,"column":218}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":228},"end":{"line":34,"column":228}},{"start":{"line":34,"column":228},"end":{"line":34,"column":228}}]},"2":{"line":57,"type":"cond-expr","locations":[{"start":{"line":57,"column":15},"end":{"line":57,"column":39}},{"start":{"line":57,"column":44},"end":{"line":57,"column":68}}]},"3":{"line":57,"type":"cond-expr","locations":[{"start":{"line":57,"column":15},"end":{"line":57,"column":68}},{"start":{"line":57,"column":73},"end":{"line":57,"column":113}}]},"4":{"line":57,"type":"cond-expr","locations":[{"start":{"line":57,"column":15},"end":{"line":57,"column":113}},{"start":{"line":57,"column":118},"end":{"line":57,"column":158}}]},"5":{"line":57,"type":"cond-expr","locations":[{"start":{"line":57,"column":15},"end":{"line":57,"column":158}},{"start":{"line":57,"column":163},"end":{"line":57,"column":217}}]},"6":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":98},"end":{"line":70,"column":98}},{"start":{"line":70,"column":98},"end":{"line":70,"column":98}}]},"7":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":73},"end":{"line":76,"column":73}},{"start":{"line":76,"column":73},"end":{"line":76,"column":73}}]},"8":{"line":82,"type":"if","locations":[{"start":{"line":82,"column":73},"end":{"line":82,"column":73}},{"start":{"line":82,"column":73},"end":{"line":82,"column":73}}]},"9":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":93},"end":{"line":88,"column":93}},{"start":{"line":88,"column":93},"end":{"line":88,"column":93}}]},"10":{"line":94,"type":"if","locations":[{"start":{"line":94,"column":96},"end":{"line":94,"column":96}},{"start":{"line":94,"column":96},"end":{"line":94,"column":96}}]},"11":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":89},"end":{"line":100,"column":89}},{"start":{"line":100,"column":89},"end":{"line":100,"column":89}}]},"12":{"line":106,"type":"if","locations":[{"start":{"line":106,"column":90},"end":{"line":106,"column":90}},{"start":{"line":106,"column":90},"end":{"line":106,"column":90}}]}}},"contracts/modules/3_CMTATBaseAllowlist.sol":{"l":{"57":705,"75":705,"78":705,"81":705,"84":705,"92":705,"93":705,"95":705,"102":705,"104":705,"128":116,"129":97,"138":58,"147":39,"157":3,"167":9,"177":9,"188":316,"189":316,"190":84,"192":232,"206":31,"207":31,"208":6,"210":25,"226":200,"229":49,"239":12,"245":849,"251":128,"255":273,"259":38,"267":245,"275":118,"279":1110,"280":1095,"290":235,"307":8559,"317":8561,"330":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol","s":{"1":705,"2":705,"3":705,"4":705,"5":705,"6":705,"7":705,"8":705,"9":705,"10":705,"11":116,"12":97,"13":58,"14":39,"15":3,"16":9,"17":9,"18":316,"19":316,"20":84,"21":232,"22":31,"23":31,"24":6,"25":25,"26":200,"27":49,"28":12,"29":849,"30":128,"31":273,"32":38,"33":245,"34":118,"35":1110,"36":1095,"37":235,"38":8559,"39":8561,"40":2},"b":{"1":[705,0],"2":[705,0],"3":[705,0],"4":[705,0],"5":[84,232],"6":[6,25],"7":[84,6],"8":[33,3],"9":[96,9],"10":[1121,8]},"f":{"1":705,"2":705,"3":705,"4":705,"5":116,"6":58,"7":39,"8":3,"9":9,"10":9,"11":316,"12":31,"13":84,"14":33,"15":96,"16":1121,"17":200,"18":49,"19":12,"20":849,"21":128,"22":273,"23":38,"24":245,"25":118,"26":1110,"27":235,"28":8559,"29":8561,"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":125,"loc":{"start":{"line":125,"column":4},"end":{"line":130,"column":4}}},"6":{"name":"transfer","line":132,"loc":{"start":{"line":132,"column":4},"end":{"line":139,"column":4}}},"7":{"name":"transferFrom","line":141,"loc":{"start":{"line":141,"column":4},"end":{"line":148,"column":4}}},"8":{"name":"decimals","line":150,"loc":{"start":{"line":150,"column":4},"end":{"line":158,"column":4}}},"9":{"name":"name","line":160,"loc":{"start":{"line":160,"column":4},"end":{"line":168,"column":4}}},"10":{"name":"symbol","line":170,"loc":{"start":{"line":170,"column":4},"end":{"line":178,"column":4}}},"11":{"name":"canTransfer","line":183,"loc":{"start":{"line":183,"column":4},"end":{"line":195,"column":4}}},"12":{"name":"canTransferFrom","line":200,"loc":{"start":{"line":200,"column":3},"end":{"line":212,"column":4}}},"13":{"name":"_authorizePause","line":219,"loc":{"start":{"line":219,"column":4},"end":{"line":219,"column":92}}},"14":{"name":"_authorizeDeactivate","line":220,"loc":{"start":{"line":220,"column":4},"end":{"line":220,"column":104}}},"15":{"name":"_authorizeFreeze","line":222,"loc":{"start":{"line":222,"column":4},"end":{"line":222,"column":101}}},"16":{"name":"_authorizeAllowlistManagement","line":224,"loc":{"start":{"line":224,"column":4},"end":{"line":224,"column":114}}},"17":{"name":"_authorizeERC20Enforcer","line":225,"loc":{"start":{"line":225,"column":4},"end":{"line":227,"column":4}}},"18":{"name":"_authorizeForcedTransfer","line":228,"loc":{"start":{"line":228,"column":4},"end":{"line":230,"column":4}}},"19":{"name":"_canMintBurnByModule","line":236,"loc":{"start":{"line":236,"column":4},"end":{"line":240,"column":4}}},"20":{"name":"_canMintByModuleAndRevert","line":242,"loc":{"start":{"line":242,"column":4},"end":{"line":246,"column":4}}},"21":{"name":"_canBurnByModuleAndRevert","line":248,"loc":{"start":{"line":248,"column":4},"end":{"line":252,"column":4}}},"22":{"name":"_canSend","line":254,"loc":{"start":{"line":254,"column":4},"end":{"line":256,"column":4}}},"23":{"name":"_canReceive","line":258,"loc":{"start":{"line":258,"column":4},"end":{"line":260,"column":4}}},"24":{"name":"_canTransferStandardByModule","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":268,"column":4}}},"25":{"name":"_canTransferStandardByModuleAndRevert","line":270,"loc":{"start":{"line":270,"column":4},"end":{"line":276,"column":4}}},"26":{"name":"_checkTransferred","line":278,"loc":{"start":{"line":278,"column":4},"end":{"line":281,"column":4}}},"27":{"name":"getFrozenTokens","line":283,"loc":{"start":{"line":283,"column":4},"end":{"line":291,"column":4}}},"28":{"name":"_msgSender","line":301,"loc":{"start":{"line":301,"column":4},"end":{"line":308,"column":4}}},"29":{"name":"_contextSuffixLength","line":314,"loc":{"start":{"line":314,"column":4},"end":{"line":318,"column":4}}},"30":{"name":"_msgData","line":324,"loc":{"start":{"line":324,"column":4},"end":{"line":331,"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":128,"column":8},"end":{"line":128,"column":76}},"12":{"start":{"line":129,"column":8},"end":{"line":129,"column":55}},"13":{"start":{"line":138,"column":8},"end":{"line":138,"column":50}},"14":{"start":{"line":147,"column":8},"end":{"line":147,"column":60}},"15":{"start":{"line":157,"column":8},"end":{"line":157,"column":41}},"16":{"start":{"line":167,"column":8},"end":{"line":167,"column":37}},"17":{"start":{"line":177,"column":8},"end":{"line":177,"column":39}},"18":{"start":{"line":188,"column":8},"end":{"line":188,"column":89}},"19":{"start":{"line":189,"column":8},"end":{"line":189,"column":7550}},"20":{"start":{"line":190,"column":12},"end":{"line":190,"column":24}},"21":{"start":{"line":192,"column":12},"end":{"line":192,"column":68}},"22":{"start":{"line":206,"column":8},"end":{"line":206,"column":89}},"23":{"start":{"line":207,"column":8},"end":{"line":207,"column":8049}},"24":{"start":{"line":208,"column":12},"end":{"line":208,"column":24}},"25":{"start":{"line":210,"column":12},"end":{"line":210,"column":81}},"26":{"start":{"line":226,"column":8},"end":{"line":226,"column":55}},"27":{"start":{"line":229,"column":8},"end":{"line":229,"column":56}},"28":{"start":{"line":239,"column":8},"end":{"line":239,"column":70}},"29":{"start":{"line":245,"column":8},"end":{"line":245,"column":62}},"30":{"start":{"line":251,"column":8},"end":{"line":251,"column":64}},"31":{"start":{"line":255,"column":8},"end":{"line":255,"column":58}},"32":{"start":{"line":259,"column":8},"end":{"line":259,"column":61}},"33":{"start":{"line":267,"column":8},"end":{"line":267,"column":88}},"34":{"start":{"line":275,"column":8},"end":{"line":275,"column":89}},"35":{"start":{"line":279,"column":8},"end":{"line":279,"column":66}},"36":{"start":{"line":280,"column":8},"end":{"line":280,"column":79}},"37":{"start":{"line":290,"column":8},"end":{"line":290,"column":69}},"38":{"start":{"line":307,"column":8},"end":{"line":307,"column":53}},"39":{"start":{"line":317,"column":9},"end":{"line":317,"column":64}},"40":{"start":{"line":330,"column":8},"end":{"line":330,"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":189,"type":"if","locations":[{"start":{"line":189,"column":8},"end":{"line":189,"column":8}},{"start":{"line":189,"column":8},"end":{"line":189,"column":8}}]},"6":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":8},"end":{"line":207,"column":8}},{"start":{"line":207,"column":8},"end":{"line":207,"column":8}}]},"7":{"line":219,"type":"if","locations":[{"start":{"line":219,"column":70},"end":{"line":219,"column":70}},{"start":{"line":219,"column":70},"end":{"line":219,"column":70}}]},"8":{"line":220,"type":"if","locations":[{"start":{"line":220,"column":75},"end":{"line":220,"column":75}},{"start":{"line":220,"column":75},"end":{"line":220,"column":75}}]},"9":{"line":222,"type":"if","locations":[{"start":{"line":222,"column":77},"end":{"line":222,"column":77}},{"start":{"line":222,"column":77},"end":{"line":222,"column":77}}]},"10":{"line":224,"type":"if","locations":[{"start":{"line":224,"column":88},"end":{"line":224,"column":88}},{"start":{"line":224,"column":88},"end":{"line":224,"column":88}}]}}},"contracts/modules/3_CMTATBaseRuleEngine.sol":{"l":{"47":5167,"64":5167,"83":5167,"86":5167,"89":5167,"91":5167,"94":5167,"102":5167,"103":5167,"105":5167,"112":5167,"119":5167,"134":958,"135":863,"145":1600,"146":1600,"147":532,"149":1068,"162":215,"163":215,"164":38,"166":177,"183":7858,"184":7763},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol","s":{"1":5167,"2":5167,"3":5167,"4":5167,"5":5167,"6":5167,"7":5167,"8":5167,"9":5167,"10":5167,"11":5167,"12":5167,"13":958,"14":863,"15":1600,"16":1600,"17":532,"18":1068,"19":215,"20":215,"21":38,"22":177,"23":7858,"24":7763},"b":{"1":[5167,4],"2":[5167,0],"3":[5167,0],"4":[5167,0],"5":[5167,0],"6":[5167,0],"7":[532,1068],"8":[38,177],"9":[636,39],"10":[259,19],"11":[688,57],"12":[367,3]},"f":{"1":5167,"2":5167,"3":5167,"4":5167,"5":5167,"6":5167,"7":958,"8":1600,"9":215,"10":636,"11":259,"12":688,"13":367,"14":7858},"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":131,"loc":{"start":{"line":131,"column":4},"end":{"line":136,"column":4}}},"8":{"name":"canTransfer","line":140,"loc":{"start":{"line":140,"column":4},"end":{"line":151,"column":4}}},"9":{"name":"canTransferFrom","line":156,"loc":{"start":{"line":156,"column":3},"end":{"line":168,"column":4}}},"10":{"name":"_authorizePause","line":174,"loc":{"start":{"line":174,"column":4},"end":{"line":174,"column":92}}},"11":{"name":"_authorizeDeactivate","line":175,"loc":{"start":{"line":175,"column":4},"end":{"line":175,"column":104}}},"12":{"name":"_authorizeFreeze","line":177,"loc":{"start":{"line":177,"column":4},"end":{"line":177,"column":101}}},"13":{"name":"_authorizeRuleEngineManagement","line":179,"loc":{"start":{"line":179,"column":4},"end":{"line":179,"column":129}}},"14":{"name":"_checkTransferred","line":182,"loc":{"start":{"line":182,"column":4},"end":{"line":185,"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":134,"column":8},"end":{"line":134,"column":76}},"14":{"start":{"line":135,"column":8},"end":{"line":135,"column":55}},"15":{"start":{"line":145,"column":8},"end":{"line":145,"column":90}},"16":{"start":{"line":146,"column":8},"end":{"line":146,"column":6145}},"17":{"start":{"line":147,"column":12},"end":{"line":147,"column":24}},"18":{"start":{"line":149,"column":12},"end":{"line":149,"column":74}},"19":{"start":{"line":162,"column":8},"end":{"line":162,"column":89}},"20":{"start":{"line":163,"column":8},"end":{"line":163,"column":6653}},"21":{"start":{"line":164,"column":12},"end":{"line":164,"column":24}},"22":{"start":{"line":166,"column":12},"end":{"line":166,"column":87}},"23":{"start":{"line":183,"column":8},"end":{"line":183,"column":66}},"24":{"start":{"line":184,"column":8},"end":{"line":184,"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":146,"type":"if","locations":[{"start":{"line":146,"column":8},"end":{"line":146,"column":8}},{"start":{"line":146,"column":8},"end":{"line":146,"column":8}}]},"8":{"line":163,"type":"if","locations":[{"start":{"line":163,"column":8},"end":{"line":163,"column":8}},{"start":{"line":163,"column":8},"end":{"line":163,"column":8}}]},"9":{"line":174,"type":"if","locations":[{"start":{"line":174,"column":70},"end":{"line":174,"column":70}},{"start":{"line":174,"column":70},"end":{"line":174,"column":70}}]},"10":{"line":175,"type":"if","locations":[{"start":{"line":175,"column":75},"end":{"line":175,"column":75}},{"start":{"line":175,"column":75},"end":{"line":175,"column":75}}]},"11":{"line":177,"type":"if","locations":[{"start":{"line":177,"column":77},"end":{"line":177,"column":77}},{"start":{"line":177,"column":77},"end":{"line":177,"column":77}}]},"12":{"line":179,"type":"if","locations":[{"start":{"line":179,"column":100},"end":{"line":179,"column":100}},{"start":{"line":179,"column":100},"end":{"line":179,"column":100}}]}}},"contracts/modules/4_CMTATBaseDebt.sol":{"l":{"19":136,"25":82,"31":44,"37":4,"43":12,"49":12,"55":1326},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseDebt.sol","s":{"1":136,"2":82,"3":44,"4":4,"5":12,"6":12,"7":1326},"b":{"1":[12,12],"2":[98,3]},"f":{"1":136,"2":82,"3":44,"4":4,"5":12,"6":12,"7":1326,"8":12,"9":98},"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":139,"35":44,"37":95,"50":1272,"62":179,"78":49,"99":339,"100":339,"101":88,"103":251},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC1404.sol","s":{"1":139,"2":44,"3":95,"4":1272,"5":179,"6":49,"7":339,"8":339,"9":88,"10":251},"b":{"1":[44,95],"2":[2,2],"3":[2,26],"4":[88,251]},"f":{"1":139,"2":1272,"3":179,"4":49,"5":339},"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":"supportsInterface","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":82,"column":4}}},"5":{"name":"_detectTransferRestriction","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":104,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1453}},"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":78,"column":8},"end":{"line":78,"column":3145}},"7":{"start":{"line":99,"column":8},"end":{"line":99,"column":59}},"8":{"start":{"line":100,"column":8},"end":{"line":100,"column":4213}},"9":{"start":{"line":101,"column":12},"end":{"line":101,"column":110}},"10":{"start":{"line":103,"column":8},"end":{"line":103,"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":79,"type":"cond-expr","locations":[{"start":{"line":79,"column":12},"end":{"line":79,"column":52}},{"start":{"line":80,"column":12},"end":{"line":80,"column":77}}]},"3":{"line":79,"type":"cond-expr","locations":[{"start":{"line":79,"column":12},"end":{"line":80,"column":77}},{"start":{"line":81,"column":12},"end":{"line":81,"column":47}}]},"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}}]}}},"contracts/modules/5_CMTATBaseERC20CrossChain.sol":{"l":{"26":822,"29":302,"44":223,"59":15,"67":67,"74":49,"78":73,"91":4842,"100":863,"109":222,"130":206},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol","s":{"1":822,"2":302,"3":223,"4":15,"5":67,"6":49,"7":73,"8":4842,"9":863,"10":222,"11":206},"b":{"1":[24,30],"2":[36,12],"3":[206,48],"4":[84,12],"5":[60,24],"6":[72,12],"7":[48,24]},"f":{"1":822,"2":302,"3":223,"4":15,"5":67,"6":49,"7":73,"8":4842,"9":863,"10":222,"11":36,"12":206,"13":60,"14":48},"fnMap":{"1":{"name":"approve","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"transfer","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":30,"column":4}}},"3":{"name":"transferFrom","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":45,"column":4}}},"4":{"name":"decimals","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":60,"column":4}}},"5":{"name":"name","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":68,"column":4}}},"6":{"name":"symbol","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":75,"column":4}}},"7":{"name":"supportsInterface","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":79,"column":4}}},"8":{"name":"_mintOverride","line":89,"loc":{"start":{"line":89,"column":4},"end":{"line":92,"column":4}}},"9":{"name":"_burnOverride","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":101,"column":4}}},"10":{"name":"_minterTransferOverride","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":110,"column":4}}},"11":{"name":"_authorizeCCIPSetAdmin","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":118,"column":106}}},"12":{"name":"_checkTokenBridge","line":129,"loc":{"start":{"line":129,"column":4},"end":{"line":131,"column":4}}},"13":{"name":"_authorizeBurnFrom","line":138,"loc":{"start":{"line":138,"column":4},"end":{"line":138,"column":124}}},"14":{"name":"_authorizeSelfBurn","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":145,"column":124}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":58}},"2":{"start":{"line":29,"column":9},"end":{"line":29,"column":51}},"3":{"start":{"line":44,"column":8},"end":{"line":44,"column":60}},"4":{"start":{"line":59,"column":8},"end":{"line":59,"column":41}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":37}},"6":{"start":{"line":74,"column":8},"end":{"line":74,"column":39}},"7":{"start":{"line":78,"column":8},"end":{"line":78,"column":121}},"8":{"start":{"line":91,"column":8},"end":{"line":91,"column":52}},"9":{"start":{"line":100,"column":8},"end":{"line":100,"column":52}},"10":{"start":{"line":109,"column":8},"end":{"line":109,"column":63}},"11":{"start":{"line":130,"column":8},"end":{"line":130,"column":68}}},"branchMap":{"1":{"line":78,"type":"cond-expr","locations":[{"start":{"line":78,"column":16},"end":{"line":78,"column":68}},{"start":{"line":78,"column":72},"end":{"line":78,"column":120}}]},"2":{"line":118,"type":"if","locations":[{"start":{"line":118,"column":76},"end":{"line":118,"column":76}},{"start":{"line":118,"column":76},"end":{"line":118,"column":76}}]},"3":{"line":129,"type":"if","locations":[{"start":{"line":129,"column":96},"end":{"line":129,"column":96}},{"start":{"line":129,"column":96},"end":{"line":129,"column":96}}]},"4":{"line":138,"type":"if","locations":[{"start":{"line":138,"column":83},"end":{"line":138,"column":83}},{"start":{"line":138,"column":83},"end":{"line":138,"column":83}}]},"5":{"line":138,"type":"if","locations":[{"start":{"line":138,"column":110},"end":{"line":138,"column":110}},{"start":{"line":138,"column":110},"end":{"line":138,"column":110}}]},"6":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":83},"end":{"line":145,"column":83}},{"start":{"line":145,"column":83},"end":{"line":145,"column":83}}]},"7":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":110},"end":{"line":145,"column":110}},{"start":{"line":145,"column":110},"end":{"line":145,"column":110}}]}}},"contracts/modules/6_CMTATBaseDebtEngine.sol":{"l":{"25":978,"31":58,"37":33,"43":102,"49":3,"55":9,"61":9},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseDebtEngine.sol","s":{"1":978,"2":58,"3":33,"4":102,"5":3,"6":9,"7":9},"b":{"1":[15,3],"2":[50,2]},"f":{"1":978,"2":58,"3":33,"4":102,"5":3,"6":9,"7":9,"8":15,"9":50},"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":500,"28":500,"29":500,"30":500,"56":22,"57":16,"71":114,"81":30,"97":26,"111":2,"124":26,"137":10},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol","s":{"1":500,"2":500,"3":500,"4":500,"5":22,"6":16,"7":114,"8":30,"9":26,"10":2,"11":26,"12":10},"b":{"1":[500,0]},"f":{"1":500,"2":22,"3":114,"4":30,"5":26,"6":2,"7":26,"8":10},"fnMap":{"1":{"name":"__CMTAT_openzeppelin_init_unchained","line":26,"loc":{"start":{"line":24,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"permit","line":47,"loc":{"start":{"line":47,"column":4},"end":{"line":58,"column":4}}},"3":{"name":"approve","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":72,"column":4}}},"4":{"name":"transfer","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":82,"column":4}}},"5":{"name":"transferFrom","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":98,"column":4}}},"6":{"name":"decimals","line":104,"loc":{"start":{"line":104,"column":4},"end":{"line":112,"column":4}}},"7":{"name":"name","line":117,"loc":{"start":{"line":117,"column":4},"end":{"line":125,"column":4}}},"8":{"name":"symbol","line":130,"loc":{"start":{"line":130,"column":4},"end":{"line":138,"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":56,"column":8},"end":{"line":56,"column":69}},"6":{"start":{"line":57,"column":8},"end":{"line":57,"column":78}},"7":{"start":{"line":71,"column":8},"end":{"line":71,"column":63}},"8":{"start":{"line":81,"column":8},"end":{"line":81,"column":59}},"9":{"start":{"line":97,"column":8},"end":{"line":97,"column":79}},"10":{"start":{"line":111,"column":8},"end":{"line":111,"column":50}},"11":{"start":{"line":124,"column":8},"end":{"line":124,"column":46}},"12":{"start":{"line":137,"column":8},"end":{"line":137,"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":{"27":20226,"37":20232,"50":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2771.sol","s":{"1":20226,"2":20232,"3":6},"b":{},"f":{"1":20226,"2":20232,"3":6},"fnMap":{"1":{"name":"_msgSender","line":21,"loc":{"start":{"line":21,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"_contextSuffixLength","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":38,"column":4}}},"3":{"name":"_msgData","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":51,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":53}},"2":{"start":{"line":37,"column":9},"end":{"line":37,"column":64}},"3":{"start":{"line":50,"column":8},"end":{"line":50,"column":51}}},"branchMap":{}},"contracts/modules/7_CMTATBaseERC2771Snapshot.sol":{"l":{"24":814,"30":58,"36":26,"42":114,"48":2,"54":6,"60":6,"70":4035,"76":2,"82":4037},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC2771Snapshot.sol","s":{"1":814,"2":58,"3":26,"4":114,"5":2,"6":6,"7":6,"8":4035,"9":2,"10":4037},"b":{"1":[192,4]},"f":{"1":814,"2":58,"3":26,"4":114,"5":2,"6":6,"7":6,"8":4035,"9":2,"10":4037,"11":192},"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":424,"26":98,"37":12904,"45":4,"53":12908,"64":125,"72":114,"80":378,"88":20,"96":18,"104":6,"112":358},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC7551Enforcement.sol","s":{"1":424,"2":98,"3":12904,"4":4,"5":12908,"6":125,"7":114,"8":378,"9":20,"10":18,"11":6,"12":358},"b":{},"f":{"1":424,"2":98,"3":12904,"4":4,"5":12908,"6":125,"7":114,"8":378,"9":20,"10":18,"11":6,"12":358},"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":533,"27":533,"42":115,"49":37,"65":28,"75":23,"89":2,"97":6,"104":6,"124":3728,"133":3730,"145":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol","s":{"1":533,"2":533,"3":115,"4":37,"5":28,"6":23,"7":2,"8":6,"9":6,"10":3728,"11":3730,"12":2},"b":{"1":[533,0],"2":[6,12]},"f":{"1":533,"2":115,"3":37,"4":28,"5":23,"6":2,"7":6,"8":6,"9":3728,"10":3730,"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":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":4}}},"3":{"name":"transfer","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":50,"column":4}}},"4":{"name":"transferFrom","line":55,"loc":{"start":{"line":55,"column":4},"end":{"line":66,"column":4}}},"5":{"name":"supportsInterface","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":76,"column":4}}},"6":{"name":"decimals","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":90,"column":4}}},"7":{"name":"name","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":98,"column":4}}},"8":{"name":"symbol","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":105,"column":4}}},"9":{"name":"_msgSender","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":125,"column":4}}},"10":{"name":"_contextSuffixLength","line":130,"loc":{"start":{"line":130,"column":4},"end":{"line":134,"column":4}}},"11":{"name":"_msgData","line":139,"loc":{"start":{"line":139,"column":4},"end":{"line":146,"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":42,"column":8},"end":{"line":42,"column":66}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":62}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":82}},"6":{"start":{"line":75,"column":8},"end":{"line":75,"column":123}},"7":{"start":{"line":89,"column":8},"end":{"line":89,"column":53}},"8":{"start":{"line":97,"column":8},"end":{"line":97,"column":49}},"9":{"start":{"line":104,"column":8},"end":{"line":104,"column":51}},"10":{"start":{"line":124,"column":8},"end":{"line":124,"column":55}},"11":{"start":{"line":133,"column":9},"end":{"line":133,"column":66}},"12":{"start":{"line":145,"column":8},"end":{"line":145,"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":75,"type":"cond-expr","locations":[{"start":{"line":75,"column":15},"end":{"line":75,"column":63}},{"start":{"line":75,"column":68},"end":{"line":75,"column":122}}]}}},"contracts/modules/8_CMTATBaseERC7551.sol":{"l":{"20":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC7551.sol","s":{"1":22},"b":{},"f":{"1":22},"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/8_CMTATBaseHolderList.sol":{"l":{"38":8,"49":0,"60":0,"72":0,"83":0,"94":0,"102":0,"116":114,"130":372,"141":0,"152":372},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseHolderList.sol","s":{"1":8,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":114,"9":372,"10":0,"11":372},"b":{"1":[0,0]},"f":{"1":8,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":114,"9":372,"10":0,"11":372},"fnMap":{"1":{"name":"transfer","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"transferFrom","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":50,"column":4}}},"3":{"name":"approve","line":55,"loc":{"start":{"line":55,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"name","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":73,"column":4}}},"5":{"name":"symbol","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":84,"column":4}}},"6":{"name":"decimals","line":89,"loc":{"start":{"line":89,"column":4},"end":{"line":95,"column":4}}},"7":{"name":"supportsInterface","line":97,"loc":{"start":{"line":97,"column":4},"end":{"line":104,"column":4}}},"8":{"name":"_update","line":112,"loc":{"start":{"line":112,"column":4},"end":{"line":117,"column":4}}},"9":{"name":"_msgSender","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":131,"column":4}}},"10":{"name":"_msgData","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":142,"column":4}}},"11":{"name":"_contextSuffixLength","line":147,"loc":{"start":{"line":147,"column":4},"end":{"line":153,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":62}},"2":{"start":{"line":49,"column":8},"end":{"line":49,"column":72}},"3":{"start":{"line":60,"column":8},"end":{"line":60,"column":66}},"4":{"start":{"line":72,"column":8},"end":{"line":72,"column":49}},"5":{"start":{"line":83,"column":8},"end":{"line":83,"column":51}},"6":{"start":{"line":94,"column":8},"end":{"line":94,"column":53}},"7":{"start":{"line":102,"column":8},"end":{"line":102,"column":3606}},"8":{"start":{"line":116,"column":8},"end":{"line":116,"column":48}},"9":{"start":{"line":130,"column":8},"end":{"line":130,"column":55}},"10":{"start":{"line":141,"column":8},"end":{"line":141,"column":53}},"11":{"start":{"line":152,"column":8},"end":{"line":152,"column":65}}},"branchMap":{"1":{"line":102,"type":"cond-expr","locations":[{"start":{"line":102,"column":15},"end":{"line":102,"column":64}},{"start":{"line":103,"column":15},"end":{"line":103,"column":69}}]}}},"contracts/modules/internal/AllowlistModuleInternal.sol":{"l":{"30":705,"31":705,"40":326,"41":326,"45":2626,"49":584,"50":580,"51":580,"52":2300,"60":211,"61":211,"70":1580,"71":1580,"79":1667,"80":1667,"87":5069},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol","s":{"1":705,"2":326,"3":326,"4":584,"5":580,"6":580,"7":2300,"8":211,"9":1580,"10":1580,"11":1667,"12":1667},"b":{"1":[705,0]},"f":{"1":705,"2":326,"3":2626,"4":584,"5":211,"6":1580,"7":1667,"8":5069},"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":69,"loc":{"start":{"line":69,"column":4},"end":{"line":72,"column":4}}},"7":{"name":"_isAllowlistEnabled","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":81,"column":4}}},"8":{"name":"_getAllowlistModuleInternalStorage","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":90,"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":70,"column":8},"end":{"line":70,"column":87}},"10":{"start":{"line":71,"column":8},"end":{"line":71,"column":36}},"11":{"start":{"line":79,"column":8},"end":{"line":79,"column":87}},"12":{"start":{"line":80,"column":8},"end":{"line":80,"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":734,"19":707},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/common/EnforcementModuleLibrary.sol","s":{"1":734,"2":707},"b":{"1":[707,27],"2":[680,27]},"f":{"1":734},"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":719,"35":719,"39":919,"40":75,"42":844,"46":150,"47":100,"48":100,"49":200,"59":18213,"60":18213,"65":19032},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInternal.sol","s":{"1":719,"2":719,"3":919,"4":150,"5":100,"6":100,"7":200,"8":18213,"9":18213},"b":{"1":[75,844]},"f":{"1":719,"2":919,"3":150,"4":18213,"5":19032},"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":58,"loc":{"start":{"line":58,"column":4},"end":{"line":61,"column":4}}},"5":{"name":"_getEnforcementModuleInternalStorage","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":68,"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":59,"column":8},"end":{"line":59,"column":91}},"9":{"start":{"line":60,"column":8},"end":{"line":60,"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":{"32":330,"35":306,"36":258,"37":638,"51":1023},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol","s":{"1":330,"2":306,"3":258,"4":638,"5":1023},"b":{"1":[306,24],"2":[258,48]},"f":{"1":330,"2":1023},"fnMap":{"1":{"name":"_batchBurn","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"_burnOverride","line":47,"loc":{"start":{"line":47,"column":4},"end":{"line":52,"column":4}}}},"statementMap":{"1":{"start":{"line":32,"column":8},"end":{"line":32,"column":70}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":97}},"3":{"start":{"line":36,"column":8},"end":{"line":36,"column":1563}},"4":{"start":{"line":37,"column":13},"end":{"line":37,"column":49}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":45}}},"branchMap":{"1":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":8},"end":{"line":32,"column":8}},{"start":{"line":32,"column":8},"end":{"line":32,"column":8}}]},"2":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":8},"end":{"line":35,"column":8}},{"start":{"line":35,"column":8},"end":{"line":35,"column":8}}]}}},"contracts/modules/internal/ERC20EnforcementModuleInternal.sol":{"l":{"41":476,"42":88,"44":388,"45":388,"47":388,"48":88,"49":88,"50":88,"53":278,"54":278,"55":278,"57":22,"59":366,"63":652,"64":30,"66":622,"68":622,"69":622,"71":622,"73":600,"74":600,"78":236,"79":30,"81":206,"82":206,"84":184,"85":184,"86":184,"93":276,"94":276,"95":22,"97":254,"98":254,"100":254,"102":254,"103":232,"105":254,"106":66,"107":66,"108":66,"109":66,"122":298,"123":276,"124":254,"125":44,"129":210,"130":210,"132":44,"133":44,"134":44,"138":44,"140":210,"142":254,"146":878,"150":338,"155":8968,"156":8968,"157":8968,"158":8968,"167":11469,"168":11469,"169":1628,"171":1628,"172":132,"173":66,"175":66,"177":1496,"178":1496,"179":792,"184":10545,"188":13719,"189":13719,"193":440,"194":440,"195":440,"197":440,"198":32,"200":408,"205":15629},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol","s":{"1":476,"2":388,"3":388,"4":388,"5":88,"6":88,"7":300,"8":278,"9":278,"10":366,"11":652,"12":622,"13":622,"14":622,"15":622,"16":600,"17":236,"18":206,"19":206,"20":184,"21":184,"22":276,"23":276,"24":254,"25":254,"26":254,"27":254,"28":254,"29":66,"30":66,"31":298,"32":276,"33":254,"34":44,"35":210,"36":210,"37":44,"38":44,"39":44,"40":210,"41":254,"42":878,"43":338,"44":8968,"45":8968,"46":8968,"47":11469,"48":11469,"49":1628,"50":1628,"51":132,"52":66,"53":66,"54":1496,"55":792,"56":10545,"57":13719,"58":13719,"59":440,"60":440,"61":440,"62":440,"63":32,"64":408},"b":{"1":[88,388],"2":[88,300],"3":[278,22],"4":[30,622],"5":[600,22],"6":[30,206],"7":[184,22],"8":[22,254],"9":[232,22],"10":[66,188],"11":[276,22],"12":[44,210],"13":[44,166],"14":[22,22],"15":[8858,110],"16":[1628,9841],"17":[132,1496],"18":[66,66],"19":[792,704],"20":[32,408]},"f":{"1":476,"2":652,"3":236,"4":276,"5":298,"6":878,"7":338,"8":8968,"9":11469,"10":13719,"11":440,"12":15629},"fnMap":{"1":{"name":"_setFrozenTokens","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"_freezePartialTokens","line":62,"loc":{"start":{"line":62,"column":4},"end":{"line":75,"column":4}}},"3":{"name":"_unfreezePartialTokens","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":87,"column":4}}},"4":{"name":"_unfreezeTokens","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":111,"column":4}}},"5":{"name":"_forcedTransfer","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":143,"column":4}}},"6":{"name":"_freezeTokensEmitEvents","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":147,"column":4}}},"7":{"name":"_unfreezeTokensEmitEvents","line":149,"loc":{"start":{"line":149,"column":4},"end":{"line":151,"column":4}}},"8":{"name":"_checkActiveBalanceAndRevert","line":154,"loc":{"start":{"line":154,"column":4},"end":{"line":159,"column":4}}},"9":{"name":"_checkActiveBalance","line":166,"loc":{"start":{"line":166,"column":4},"end":{"line":185,"column":4}}},"10":{"name":"_getFrozenTokens","line":187,"loc":{"start":{"line":187,"column":4},"end":{"line":190,"column":5}}},"11":{"name":"_getActiveBalanceOf","line":192,"loc":{"start":{"line":192,"column":4},"end":{"line":201,"column":5}}},"12":{"name":"_getEnforcementModuleStorage","line":204,"loc":{"start":{"line":204,"column":4},"end":{"line":208,"column":4}}}},"statementMap":{"1":{"start":{"line":41,"column":8},"end":{"line":41,"column":2167}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":80}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":60}},"4":{"start":{"line":47,"column":8},"end":{"line":47,"column":2456}},"5":{"start":{"line":48,"column":13},"end":{"line":48,"column":59}},"6":{"start":{"line":50,"column":13},"end":{"line":50,"column":65}},"7":{"start":{"line":51,"column":15},"end":{"line":51,"column":2682}},"8":{"start":{"line":53,"column":12},"end":{"line":53,"column":58}},"9":{"start":{"line":55,"column":12},"end":{"line":55,"column":62}},"10":{"start":{"line":59,"column":8},"end":{"line":59,"column":19}},"11":{"start":{"line":63,"column":7},"end":{"line":63,"column":3204}},"12":{"start":{"line":66,"column":7},"end":{"line":66,"column":79}},"13":{"start":{"line":68,"column":8},"end":{"line":68,"column":61}},"14":{"start":{"line":69,"column":8},"end":{"line":69,"column":68}},"15":{"start":{"line":71,"column":8},"end":{"line":71,"column":105}},"16":{"start":{"line":74,"column":8},"end":{"line":74,"column":65}},"17":{"start":{"line":78,"column":8},"end":{"line":78,"column":3943}},"18":{"start":{"line":81,"column":8},"end":{"line":81,"column":80}},"19":{"start":{"line":82,"column":8},"end":{"line":82,"column":107}},"20":{"start":{"line":84,"column":8},"end":{"line":84,"column":69}},"21":{"start":{"line":86,"column":8},"end":{"line":86,"column":68}},"22":{"start":{"line":93,"column":8},"end":{"line":93,"column":61}},"23":{"start":{"line":94,"column":8},"end":{"line":94,"column":4705}},"24":{"start":{"line":97,"column":8},"end":{"line":97,"column":80}},"25":{"start":{"line":98,"column":8},"end":{"line":98,"column":60}},"26":{"start":{"line":100,"column":8},"end":{"line":100,"column":29}},"27":{"start":{"line":102,"column":8},"end":{"line":102,"column":5124}},"28":{"start":{"line":105,"column":8},"end":{"line":105,"column":5234}},"29":{"start":{"line":106,"column":12},"end":{"line":106,"column":60}},"30":{"start":{"line":109,"column":12},"end":{"line":109,"column":83}},"31":{"start":{"line":122,"column":8},"end":{"line":122,"column":81}},"32":{"start":{"line":123,"column":8},"end":{"line":123,"column":35}},"33":{"start":{"line":124,"column":8},"end":{"line":124,"column":6304}},"34":{"start":{"line":125,"column":12},"end":{"line":125,"column":46}},"35":{"start":{"line":129,"column":12},"end":{"line":129,"column":58}},"36":{"start":{"line":130,"column":12},"end":{"line":130,"column":6592}},"37":{"start":{"line":132,"column":16},"end":{"line":132,"column":92}},"38":{"start":{"line":134,"column":20},"end":{"line":134,"column":96}},"39":{"start":{"line":138,"column":16},"end":{"line":138,"column":68}},"40":{"start":{"line":140,"column":12},"end":{"line":140,"column":54}},"41":{"start":{"line":142,"column":8},"end":{"line":142,"column":44}},"42":{"start":{"line":146,"column":8},"end":{"line":146,"column":83}},"43":{"start":{"line":150,"column":8},"end":{"line":150,"column":84}},"44":{"start":{"line":155,"column":8},"end":{"line":155,"column":20}},"45":{"start":{"line":156,"column":8},"end":{"line":156,"column":29}},"46":{"start":{"line":158,"column":8},"end":{"line":158,"column":89}},"47":{"start":{"line":167,"column":8},"end":{"line":167,"column":58}},"48":{"start":{"line":168,"column":8},"end":{"line":168,"column":8612}},"49":{"start":{"line":169,"column":12},"end":{"line":169,"column":62}},"50":{"start":{"line":171,"column":12},"end":{"line":171,"column":8792}},"51":{"start":{"line":172,"column":16},"end":{"line":172,"column":8848}},"52":{"start":{"line":173,"column":20},"end":{"line":173,"column":36}},"53":{"start":{"line":175,"column":16},"end":{"line":175,"column":33}},"54":{"start":{"line":178,"column":12},"end":{"line":178,"column":9036}},"55":{"start":{"line":179,"column":19},"end":{"line":179,"column":48}},"56":{"start":{"line":184,"column":8},"end":{"line":184,"column":36}},"57":{"start":{"line":188,"column":8},"end":{"line":188,"column":80}},"58":{"start":{"line":189,"column":8},"end":{"line":189,"column":39}},"59":{"start":{"line":193,"column":8},"end":{"line":193,"column":80}},"60":{"start":{"line":194,"column":8},"end":{"line":194,"column":61}},"61":{"start":{"line":195,"column":8},"end":{"line":195,"column":55}},"62":{"start":{"line":197,"column":8},"end":{"line":197,"column":9956}},"63":{"start":{"line":198,"column":12},"end":{"line":198,"column":20}},"64":{"start":{"line":200,"column":8},"end":{"line":200,"column":37}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":8},"end":{"line":41,"column":8}},{"start":{"line":41,"column":8},"end":{"line":41,"column":8}}]},"2":{"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}}]},"3":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":15},"end":{"line":51,"column":15}},{"start":{"line":51,"column":15},"end":{"line":51,"column":15}}]},"4":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":7},"end":{"line":63,"column":7}},{"start":{"line":63,"column":7},"end":{"line":63,"column":7}}]},"5":{"line":71,"type":"if","locations":[{"start":{"line":71,"column":8},"end":{"line":71,"column":8}},{"start":{"line":71,"column":8},"end":{"line":71,"column":8}}]},"6":{"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}}]},"7":{"line":82,"type":"if","locations":[{"start":{"line":82,"column":8},"end":{"line":82,"column":8}},{"start":{"line":82,"column":8},"end":{"line":82,"column":8}}]},"8":{"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}}]},"9":{"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}}]},"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":122,"type":"if","locations":[{"start":{"line":122,"column":8},"end":{"line":122,"column":8}},{"start":{"line":122,"column":8},"end":{"line":122,"column":8}}]},"12":{"line":124,"type":"if","locations":[{"start":{"line":124,"column":8},"end":{"line":124,"column":8}},{"start":{"line":124,"column":8},"end":{"line":124,"column":8}}]},"13":{"line":130,"type":"if","locations":[{"start":{"line":130,"column":12},"end":{"line":130,"column":12}},{"start":{"line":130,"column":12},"end":{"line":130,"column":12}}]},"14":{"line":132,"type":"if","locations":[{"start":{"line":132,"column":68},"end":{"line":132,"column":83}},{"start":{"line":132,"column":87},"end":{"line":132,"column":91}}]},"15":{"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}}]},"16":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":8},"end":{"line":168,"column":8}},{"start":{"line":168,"column":8},"end":{"line":168,"column":8}}]},"17":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":12},"end":{"line":171,"column":12}},{"start":{"line":171,"column":12},"end":{"line":171,"column":12}}]},"18":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":16},"end":{"line":172,"column":16}},{"start":{"line":172,"column":16},"end":{"line":172,"column":16}}]},"19":{"line":178,"type":"if","locations":[{"start":{"line":178,"column":12},"end":{"line":178,"column":12}},{"start":{"line":178,"column":12},"end":{"line":178,"column":12}}]},"20":{"line":197,"type":"if","locations":[{"start":{"line":197,"column":8},"end":{"line":197,"column":8}},{"start":{"line":197,"column":8},"end":{"line":197,"column":8}}]}}},"contracts/modules/internal/ERC20MintModuleInternal.sol":{"l":{"34":780,"37":756,"38":708,"39":1936,"47":262,"48":238,"51":238,"52":190,"53":334,"57":43,"66":6931,"72":211},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol","s":{"1":780,"2":756,"3":708,"4":1936,"5":262,"6":238,"7":238,"8":190,"9":334,"10":43,"11":6931,"12":211},"b":{"1":[756,24],"2":[708,48],"3":[238,24],"4":[190,48]},"f":{"1":780,"2":262,"3":6931,"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":65,"loc":{"start":{"line":65,"column":4},"end":{"line":67,"column":4}}},"4":{"name":"_minterTransferOverride","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":73,"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":66,"column":8},"end":{"line":66,"column":45}},"12":{"start":{"line":72,"column":12},"end":{"line":72,"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":5167,"39":83,"53":9132,"54":9132,"68":447,"69":447,"70":447,"75":9579},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol","s":{"1":5167,"2":83,"3":9132,"4":9132,"5":447,"6":447},"b":{"1":[5167,0],"2":[83,5084]},"f":{"1":5167,"2":9132,"3":447,"4":9579},"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":456,"32":50,"52":1558,"53":34,"56":14,"59":1510,"69":8929,"70":6737,"73":1169,"76":1023,"89":42,"93":12,"95":30,"106":7131,"107":7082,"108":60,"120":1241,"121":1169,"122":84,"140":1464,"143":312,"145":1152,"154":842,"155":48,"157":24,"159":50,"168":1464,"170":460,"172":1004,"186":1013,"187":842,"199":2342,"210":28},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol","s":{"1":456,"2":50,"3":1558,"4":34,"5":1524,"6":14,"7":1510,"8":8929,"9":6737,"10":2192,"11":1169,"12":1023,"13":42,"14":12,"15":30,"16":7131,"17":7082,"18":1241,"19":1169,"20":1464,"21":312,"22":1152,"23":842,"24":794,"25":770,"26":1464,"27":460,"28":1004,"29":1013,"30":842,"31":2342,"32":28},"b":{"1":[34,1524],"2":[14,1510],"3":[6737,2192],"4":[1169,1023],"5":[12,30],"6":[0,12],"7":[60,7022],"8":[84,1085],"9":[312,1152],"10":[24,240],"11":[240,48],"12":[48,794],"13":[24,770],"14":[50,720],"15":[460,1004],"16":[312,148]},"f":{"1":456,"2":50,"3":1558,"4":8929,"5":42,"6":7131,"7":1241,"8":1464,"9":842,"10":1464,"11":1013,"12":2342,"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":46,"loc":{"start":{"line":46,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"_canTransferGenericByModuleAndRevert","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"_canMintBurnByModule","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":96,"column":4}}},"6":{"name":"_canMintByModuleAndRevert","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":110,"column":4}}},"7":{"name":"_canBurnByModuleAndRevert","line":117,"loc":{"start":{"line":117,"column":4},"end":{"line":124,"column":4}}},"8":{"name":"_canTransferisFrozen","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":147,"column":4}}},"9":{"name":"_canTransferisFrozenAndRevert","line":149,"loc":{"start":{"line":149,"column":4},"end":{"line":161,"column":4}}},"10":{"name":"_canTransferStandardByModule","line":163,"loc":{"start":{"line":163,"column":2},"end":{"line":174,"column":4}}},"11":{"name":"_canTransferStandardByModuleAndRevert","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":188,"column":4}}},"12":{"name":"_canSend","line":198,"loc":{"start":{"line":198,"column":4},"end":{"line":200,"column":4}}},"13":{"name":"_canReceive","line":209,"loc":{"start":{"line":209,"column":4},"end":{"line":211,"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":52,"column":8},"end":{"line":52,"column":2058}},"4":{"start":{"line":53,"column":12},"end":{"line":53,"column":43}},"5":{"start":{"line":55,"column":13},"end":{"line":55,"column":2158}},"6":{"start":{"line":56,"column":12},"end":{"line":56,"column":45}},"7":{"start":{"line":59,"column":12},"end":{"line":59,"column":66}},"8":{"start":{"line":69,"column":8},"end":{"line":69,"column":2529}},"9":{"start":{"line":70,"column":13},"end":{"line":70,"column":41}},"10":{"start":{"line":72,"column":13},"end":{"line":72,"column":2628}},"11":{"start":{"line":73,"column":12},"end":{"line":73,"column":42}},"12":{"start":{"line":76,"column":13},"end":{"line":76,"column":68}},"13":{"start":{"line":89,"column":8},"end":{"line":89,"column":3255}},"14":{"start":{"line":93,"column":12},"end":{"line":93,"column":24}},"15":{"start":{"line":95,"column":8},"end":{"line":95,"column":19}},"16":{"start":{"line":106,"column":8},"end":{"line":106,"column":31}},"17":{"start":{"line":107,"column":8},"end":{"line":107,"column":3913}},"18":{"start":{"line":120,"column":8},"end":{"line":120,"column":31}},"19":{"start":{"line":121,"column":8},"end":{"line":121,"column":4338}},"20":{"start":{"line":140,"column":8},"end":{"line":140,"column":5012}},"21":{"start":{"line":143,"column":12},"end":{"line":143,"column":23}},"22":{"start":{"line":145,"column":13},"end":{"line":145,"column":25}},"23":{"start":{"line":154,"column":8},"end":{"line":154,"column":5377}},"24":{"start":{"line":156,"column":15},"end":{"line":156,"column":5481}},"25":{"start":{"line":158,"column":15},"end":{"line":158,"column":5580}},"26":{"start":{"line":168,"column":8},"end":{"line":168,"column":5839}},"27":{"start":{"line":170,"column":12},"end":{"line":170,"column":24}},"28":{"start":{"line":172,"column":13},"end":{"line":172,"column":24}},"29":{"start":{"line":186,"column":8},"end":{"line":186,"column":26}},"30":{"start":{"line":187,"column":8},"end":{"line":187,"column":55}},"31":{"start":{"line":199,"column":8},"end":{"line":199,"column":51}},"32":{"start":{"line":210,"column":8},"end":{"line":210,"column":51}}},"branchMap":{"1":{"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}}]},"2":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":13},"end":{"line":55,"column":13}},{"start":{"line":55,"column":13},"end":{"line":55,"column":13}}]},"3":{"line":69,"type":"if","locations":[{"start":{"line":69,"column":8},"end":{"line":69,"column":8}},{"start":{"line":69,"column":8},"end":{"line":69,"column":8}}]},"4":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":13},"end":{"line":72,"column":13}},{"start":{"line":72,"column":13},"end":{"line":72,"column":13}}]},"5":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":8},"end":{"line":89,"column":8}},{"start":{"line":89,"column":8},"end":{"line":89,"column":8}}]},"6":{"line":89,"type":"cond-expr","locations":[{"start":{"line":89,"column":11},"end":{"line":89,"column":35}},{"start":{"line":89,"column":40},"end":{"line":89,"column":73}}]},"7":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":8},"end":{"line":107,"column":8}},{"start":{"line":107,"column":8},"end":{"line":107,"column":8}}]},"8":{"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}}]},"9":{"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}}]},"10":{"line":140,"type":"cond-expr","locations":[{"start":{"line":140,"column":12},"end":{"line":140,"column":46}},{"start":{"line":141,"column":11},"end":{"line":141,"column":42}}]},"11":{"line":140,"type":"cond-expr","locations":[{"start":{"line":140,"column":12},"end":{"line":141,"column":42}},{"start":{"line":142,"column":11},"end":{"line":142,"column":40}}]},"12":{"line":154,"type":"if","locations":[{"start":{"line":154,"column":8},"end":{"line":154,"column":8}},{"start":{"line":154,"column":8},"end":{"line":154,"column":8}}]},"13":{"line":156,"type":"if","locations":[{"start":{"line":156,"column":15},"end":{"line":156,"column":15}},{"start":{"line":156,"column":15},"end":{"line":156,"column":15}}]},"14":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":15},"end":{"line":158,"column":15}},{"start":{"line":158,"column":15},"end":{"line":158,"column":15}}]},"15":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":8},"end":{"line":168,"column":8}},{"start":{"line":168,"column":8},"end":{"line":168,"column":8}}]},"16":{"line":168,"type":"cond-expr","locations":[{"start":{"line":168,"column":12},"end":{"line":168,"column":50}},{"start":{"line":169,"column":11},"end":{"line":169,"column":30}}]}}},"contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol":{"l":{"29":12,"30":6,"32":6,"48":245,"49":184,"50":184,"51":46,"54":199,"69":245,"70":46,"72":199,"77":273,"78":30,"80":243,"86":38,"87":22,"89":16,"98":849,"99":4,"101":845,"109":128,"110":4,"112":124,"121":118,"122":108,"130":118,"131":85,"132":2,"134":2,"136":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol","s":{"1":12,"2":6,"3":6,"4":245,"5":184,"6":184,"7":46,"8":199,"9":245,"10":46,"11":199,"12":273,"13":30,"14":243,"15":38,"16":22,"17":16,"18":849,"19":845,"20":128,"21":124,"22":118,"23":108,"24":118,"25":85,"26":83,"27":81},"b":{"1":[6,6],"2":[184,61],"3":[46,138],"4":[2,24],"5":[24,20],"6":[46,199],"7":[30,243],"8":[22,16],"9":[4,845],"10":[4,124],"11":[85,33],"12":[2,83],"13":[2,81],"14":[6,75]},"f":{"1":12,"2":245,"3":245,"4":273,"5":38,"6":849,"7":128,"8":118,"9":118},"fnMap":{"1":{"name":"_canMintBurnByModule","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":34,"column":4}}},"2":{"name":"_canTransferStandardByModuleAllowlist","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":55,"column":4}}},"3":{"name":"_canTransferStandardByModule","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":73,"column":4}}},"4":{"name":"_canSend","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":82,"column":4}}},"5":{"name":"_canReceive","line":85,"loc":{"start":{"line":85,"column":4},"end":{"line":91,"column":4}}},"6":{"name":"_canMintByModuleAndRevert","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":103,"column":4}}},"7":{"name":"_canBurnByModuleAndRevert","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":114,"column":4}}},"8":{"name":"_canTransferStandardByModuleAndRevert","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":123,"column":4}}},"9":{"name":"_canTransferStandardByModuleAllowlistAndRevert","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":139,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":1088}},"2":{"start":{"line":30,"column":12},"end":{"line":30,"column":24}},"3":{"start":{"line":32,"column":12},"end":{"line":32,"column":65}},"4":{"start":{"line":48,"column":8},"end":{"line":48,"column":1766}},"5":{"start":{"line":49,"column":12},"end":{"line":49,"column":80}},"6":{"start":{"line":50,"column":12},"end":{"line":50,"column":1891}},"7":{"start":{"line":51,"column":16},"end":{"line":51,"column":27}},"8":{"start":{"line":54,"column":7},"end":{"line":54,"column":19}},"9":{"start":{"line":69,"column":8},"end":{"line":69,"column":2535}},"10":{"start":{"line":70,"column":11},"end":{"line":70,"column":23}},"11":{"start":{"line":72,"column":8},"end":{"line":72,"column":79}},"12":{"start":{"line":77,"column":8},"end":{"line":77,"column":2878}},"13":{"start":{"line":78,"column":12},"end":{"line":78,"column":24}},"14":{"start":{"line":80,"column":12},"end":{"line":80,"column":53}},"15":{"start":{"line":86,"column":8},"end":{"line":86,"column":3208}},"16":{"start":{"line":87,"column":12},"end":{"line":87,"column":24}},"17":{"start":{"line":89,"column":12},"end":{"line":89,"column":56}},"18":{"start":{"line":98,"column":8},"end":{"line":98,"column":3605}},"19":{"start":{"line":101,"column":12},"end":{"line":101,"column":57}},"20":{"start":{"line":109,"column":8},"end":{"line":109,"column":3956}},"21":{"start":{"line":112,"column":12},"end":{"line":112,"column":59}},"22":{"start":{"line":121,"column":8},"end":{"line":121,"column":72}},"23":{"start":{"line":122,"column":8},"end":{"line":122,"column":80}},"24":{"start":{"line":130,"column":8},"end":{"line":130,"column":4652}},"25":{"start":{"line":131,"column":12},"end":{"line":131,"column":4695}},"26":{"start":{"line":133,"column":19},"end":{"line":133,"column":4820}},"27":{"start":{"line":135,"column":19},"end":{"line":135,"column":4915}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":8},"end":{"line":29,"column":8}},{"start":{"line":29,"column":8},"end":{"line":29,"column":8}}]},"2":{"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}}]},"3":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":12},"end":{"line":50,"column":12}},{"start":{"line":50,"column":12},"end":{"line":50,"column":12}}]},"4":{"line":50,"type":"cond-expr","locations":[{"start":{"line":50,"column":16},"end":{"line":50,"column":27}},{"start":{"line":50,"column":32},"end":{"line":50,"column":51}}]},"5":{"line":50,"type":"cond-expr","locations":[{"start":{"line":50,"column":16},"end":{"line":50,"column":51}},{"start":{"line":50,"column":56},"end":{"line":50,"column":73}}]},"6":{"line":69,"type":"if","locations":[{"start":{"line":69,"column":8},"end":{"line":69,"column":8}},{"start":{"line":69,"column":8},"end":{"line":69,"column":8}}]},"7":{"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}}]},"8":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":8},"end":{"line":86,"column":8}},{"start":{"line":86,"column":8},"end":{"line":86,"column":8}}]},"9":{"line":98,"type":"if","locations":[{"start":{"line":98,"column":8},"end":{"line":98,"column":8}},{"start":{"line":98,"column":8},"end":{"line":98,"column":8}}]},"10":{"line":109,"type":"if","locations":[{"start":{"line":109,"column":8},"end":{"line":109,"column":8}},{"start":{"line":109,"column":8},"end":{"line":109,"column":8}}]},"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":131,"type":"if","locations":[{"start":{"line":131,"column":12},"end":{"line":131,"column":12}},{"start":{"line":131,"column":12},"end":{"line":131,"column":12}}]},"13":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":19},"end":{"line":133,"column":19}},{"start":{"line":133,"column":19},"end":{"line":133,"column":19}}]},"14":{"line":135,"type":"if","locations":[{"start":{"line":135,"column":19},"end":{"line":135,"column":19}},{"start":{"line":135,"column":19},"end":{"line":135,"column":19}}]}}},"contracts/modules/wrapper/core/EnforcementModule.sol":{"l":{"27":944,"28":869,"42":347,"60":372,"71":150,"79":18213,"87":919,"88":844},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol","s":{"1":944,"2":347,"3":372,"4":150,"5":18213,"6":919,"7":844},"b":{"1":[347,0],"2":[372,50],"3":[150,25]},"f":{"1":944,"2":347,"3":372,"4":150,"5":18213,"6":919},"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":{"38":6188,"39":6188,"59":188,"61":116,"64":116,"67":116,"77":24,"78":24,"85":48,"86":48,"87":24,"89":48,"97":6212},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol","s":{"1":6188,"2":188,"3":116,"4":116,"5":116,"6":24,"7":24,"8":48},"b":{"1":[6188,0],"2":[116,0]},"f":{"1":6188,"2":188,"3":24,"4":48,"5":6212},"fnMap":{"1":{"name":"__ERC20BaseModule_init_unchained","line":37,"loc":{"start":{"line":35,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"transferFrom","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":68,"column":4}}},"3":{"name":"decimals","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"4":{"name":"batchBalanceOf","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":90,"column":4}}},"5":{"name":"_getERC20BaseModuleStorage","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":100,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":71}},"2":{"start":{"line":59,"column":8},"end":{"line":59,"column":68}},"3":{"start":{"line":61,"column":8},"end":{"line":61,"column":2397}},"4":{"start":{"line":64,"column":12},"end":{"line":64,"column":49}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":21}},"6":{"start":{"line":77,"column":8},"end":{"line":77,"column":71}},"7":{"start":{"line":78,"column":8},"end":{"line":78,"column":26}},"8":{"start":{"line":86,"column":8},"end":{"line":86,"column":3310}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":23},"end":{"line":37,"column":23}},{"start":{"line":37,"column":23},"end":{"line":37,"column":23}}]},"2":{"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}}]}}},"contracts/modules/wrapper/core/ERC20BurnModule.sol":{"l":{"26":841,"27":745,"45":271,"57":144,"73":254,"74":91,"87":76,"88":74,"100":415,"101":298},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol","s":{"1":841,"2":271,"3":144,"4":254,"5":91,"6":76,"7":74,"8":415,"9":298},"b":{"1":[271,72],"2":[144,0],"3":[254,24],"4":[76,0]},"f":{"1":841,"2":271,"3":144,"4":254,"5":76,"6":415},"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":6197,"29":6125,"44":148,"60":4935,"76":780,"77":633,"89":262,"96":5083,"97":5008},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol","s":{"1":6197,"2":148,"3":4935,"4":780,"5":633,"6":262,"7":5083,"8":5008},"b":{"1":[148,24],"2":[4935,24],"3":[780,24],"4":[262,0]},"f":{"1":6197,"2":148,"3":4935,"4":780,"5":262,"6":5083},"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":841,"42":790,"46":344,"47":319,"60":713,"69":77,"70":77,"71":50,"86":319,"87":294,"88":294,"89":25,"91":269,"92":269,"100":5018,"107":8717,"108":8717,"119":8372,"120":121,"126":9088},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol","s":{"1":841,"2":344,"3":713,"4":77,"5":77,"6":50,"7":319,"8":294,"9":294,"10":269,"11":5018,"12":8717,"13":8717,"14":8372},"b":{"1":[713,26],"2":[77,25],"3":[50,27],"4":[319,25],"5":[25,269],"6":[121,8251]},"f":{"1":841,"2":344,"3":713,"4":77,"5":319,"6":5018,"7":8717,"8":8372,"9":9088},"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":3399}},"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":4467}}},"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/TokenAttributeModule.sol":{"l":{"39":98,"40":50,"51":6188,"52":6188,"53":6188,"65":94,"66":94,"74":76,"75":76,"92":26,"93":26,"94":26,"101":24,"102":24,"103":24,"114":6408},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/TokenAttributeModule.sol","s":{"1":98,"2":6188,"3":94,"4":94,"5":76,"6":76,"7":26,"8":26,"9":24,"10":24},"b":{"1":[6188,0],"2":[26,24],"3":[24,24]},"f":{"1":98,"2":6188,"3":94,"4":76,"5":26,"6":24,"7":6408},"fnMap":{"1":{"name":"onlyTokenAttributeManager","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"__TokenAttributeModule_init_unchained","line":50,"loc":{"start":{"line":47,"column":4},"end":{"line":54,"column":4}}},"3":{"name":"name","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":67,"column":4}}},"4":{"name":"symbol","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"setName","line":91,"loc":{"start":{"line":91,"column":4},"end":{"line":95,"column":4}}},"6":{"name":"setSymbol","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":104,"column":4}}},"7":{"name":"_getTokenAttributeModuleStorage","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":117,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":43}},"2":{"start":{"line":51,"column":8},"end":{"line":51,"column":81}},"3":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"4":{"start":{"line":66,"column":8},"end":{"line":66,"column":22}},"5":{"start":{"line":74,"column":8},"end":{"line":74,"column":81}},"6":{"start":{"line":75,"column":8},"end":{"line":75,"column":24}},"7":{"start":{"line":92,"column":8},"end":{"line":92,"column":81}},"8":{"start":{"line":94,"column":8},"end":{"line":94,"column":31}},"9":{"start":{"line":101,"column":8},"end":{"line":101,"column":81}},"10":{"start":{"line":103,"column":8},"end":{"line":103,"column":37}}},"branchMap":{"1":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":23},"end":{"line":50,"column":23}},{"start":{"line":50,"column":23},"end":{"line":50,"column":23}}]},"2":{"line":91,"type":"if","locations":[{"start":{"line":91,"column":87},"end":{"line":91,"column":87}},{"start":{"line":91,"column":87},"end":{"line":91,"column":87}}]},"3":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":91},"end":{"line":100,"column":91}},{"start":{"line":100,"column":91},"end":{"line":100,"column":91}}]}}},"contracts/modules/wrapper/core/ValidationModuleCore.sol":{"l":{"25":1346,"34":212,"54":1558},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol","s":{"1":1346,"2":212,"3":1558},"b":{},"f":{"1":1346,"2":212,"3":1558},"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":48,"loc":{"start":{"line":48,"column":4},"end":{"line":55,"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":54,"column":8},"end":{"line":54,"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":446,"25":400,"29":152,"30":152,"34":49,"38":297,"39":272,"40":272,"41":272,"42":272,"43":272,"45":272,"46":248,"47":248,"50":272,"54":103,"55":103,"56":103,"58":78,"59":78,"60":78,"62":78,"63":26,"64":26,"65":26,"68":78,"69":78,"70":78,"72":78,"78":576},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol","s":{"1":446,"2":152,"3":152,"4":49,"5":297,"6":272,"7":272,"8":272,"9":248,"10":272,"11":103,"12":103,"13":103,"14":78,"15":78,"16":78,"17":78,"18":26,"19":78,"20":78},"b":{"1":[297,23],"2":[272,25],"3":[248,24],"4":[103,23],"5":[78,25],"6":[26,52]},"f":{"1":446,"2":152,"3":49,"4":297,"5":103,"6":576},"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":31,"column":4}}},"3":{"name":"getAllDocuments","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":35,"column":4}}},"4":{"name":"setDocument","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":51,"column":4}}},"5":{"name":"removeDocument","line":53,"loc":{"start":{"line":53,"column":4},"end":{"line":73,"column":4}}},"6":{"name":"_getDocumentERC1643ModuleStorage","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":81,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":37}},"2":{"start":{"line":29,"column":8},"end":{"line":29,"column":87}},"3":{"start":{"line":30,"column":8},"end":{"line":30,"column":75}},"4":{"start":{"line":34,"column":8},"end":{"line":34,"column":64}},"5":{"start":{"line":38,"column":8},"end":{"line":38,"column":56}},"6":{"start":{"line":39,"column":8},"end":{"line":39,"column":83}},"7":{"start":{"line":40,"column":8},"end":{"line":40,"column":54}},"8":{"start":{"line":45,"column":8},"end":{"line":45,"column":1952}},"9":{"start":{"line":46,"column":12},"end":{"line":46,"column":38}},"10":{"start":{"line":50,"column":8},"end":{"line":50,"column":53}},"11":{"start":{"line":54,"column":8},"end":{"line":54,"column":83}},"12":{"start":{"line":55,"column":8},"end":{"line":55,"column":42}},"13":{"start":{"line":56,"column":8},"end":{"line":56,"column":50}},"14":{"start":{"line":58,"column":8},"end":{"line":58,"column":53}},"15":{"start":{"line":59,"column":8},"end":{"line":59,"column":31}},"16":{"start":{"line":60,"column":8},"end":{"line":60,"column":55}},"17":{"start":{"line":62,"column":8},"end":{"line":62,"column":2584}},"18":{"start":{"line":63,"column":12},"end":{"line":63,"column":59}},"19":{"start":{"line":68,"column":8},"end":{"line":68,"column":29}},"20":{"start":{"line":72,"column":8},"end":{"line":72,"column":71}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":106},"end":{"line":37,"column":106}},{"start":{"line":37,"column":106},"end":{"line":37,"column":106}}]},"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}}]},"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}}]},"4":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":66},"end":{"line":53,"column":66}},{"start":{"line":53,"column":66},"end":{"line":53,"column":66}}]},"5":{"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}}]},"6":{"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}}]}}},"contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol":{"l":{"26":1430,"27":1364,"32":342,"33":298,"44":2062,"55":200,"56":164,"66":596,"76":204,"87":476,"95":878,"96":878,"100":338,"101":338},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol","s":{"1":1430,"2":342,"3":2062,"4":200,"5":164,"6":596,"7":204,"8":476,"9":878,"10":878,"11":338,"12":338},"b":{"1":[200,44],"2":[596,22],"3":[204,22],"4":[476,22]},"f":{"1":1430,"2":342,"3":2062,"4":200,"5":596,"6":204,"7":476,"8":878,"9":338},"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":168,"33":86,"45":5942,"47":5942,"49":5942,"51":5942,"68":26,"69":26,"79":26,"92":28,"93":28,"101":130,"102":130,"109":118,"110":118,"117":108,"118":108,"125":26,"126":26,"137":4,"138":4,"139":4,"140":4,"142":4,"148":5968,"149":5968,"154":5968,"156":5968,"157":5968,"158":5968,"160":5968,"164":5970,"165":5970,"173":6382},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ExtraInformationModule.sol","s":{"1":168,"2":5942,"3":5942,"4":5942,"5":5942,"6":26,"7":26,"8":26,"9":28,"10":28,"11":130,"12":130,"13":118,"14":118,"15":108,"16":108,"17":26,"18":26,"19":4,"20":4,"21":5968,"22":5968,"23":5970},"b":{"1":[5942,0],"2":[26,26],"3":[26,26],"4":[28,26]},"f":{"1":168,"2":5942,"3":26,"4":26,"5":28,"6":130,"7":118,"8":108,"9":26,"10":4,"11":5968,"12":5968,"13":5970,"14":6382},"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":"_setTermsDocument","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":143,"column":4}}},"11":{"name":"_setTokenId","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":150,"column":4}}},"12":{"name":"_setTerms","line":152,"loc":{"start":{"line":152,"column":4},"end":{"line":161,"column":4}}},"13":{"name":"_setInformation","line":163,"loc":{"start":{"line":163,"column":4},"end":{"line":166,"column":4}}},"14":{"name":"_getExtraInformationModuleStorage","line":172,"loc":{"start":{"line":172,"column":4},"end":{"line":176,"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":137,"column":8},"end":{"line":137,"column":85}},"20":{"start":{"line":142,"column":8},"end":{"line":142,"column":28}},"21":{"start":{"line":149,"column":8},"end":{"line":149,"column":40}},"22":{"start":{"line":160,"column":8},"end":{"line":160,"column":28}},"23":{"start":{"line":165,"column":8},"end":{"line":165,"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":349,"31":340,"45":27,"46":18,"47":18,"65":340,"66":340,"67":331,"77":3476,"78":3476,"87":349,"88":349,"95":3834},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol","s":{"1":349,"2":27,"3":18,"4":18,"5":340,"6":340,"7":331,"8":3476,"9":3476,"10":349},"b":{"1":[27,0],"2":[18,9],"3":[340,9],"4":[331,9]},"f":{"1":349,"2":27,"3":340,"4":3476,"5":349,"6":3834},"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":{"42":1150,"43":128,"45":1022,"46":972,"47":28,"49":944,"50":52},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol","s":{"1":1150,"2":128,"3":1022,"4":972,"5":944},"b":{"1":[128,1022],"2":[28,944],"3":[52,892]},"f":{"1":1150},"fnMap":{"1":{"name":"_canAuthorizeAllowanceByModuleAndRevert","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":52,"column":4}}}},"statementMap":{"1":{"start":{"line":42,"column":8},"end":{"line":42,"column":1829}},"2":{"start":{"line":43,"column":12},"end":{"line":43,"column":18}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":26}},"4":{"start":{"line":46,"column":8},"end":{"line":46,"column":1914}},"5":{"start":{"line":49,"column":8},"end":{"line":49,"column":2001}}},"branchMap":{"1":{"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}}]},"2":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":8},"end":{"line":46,"column":8}},{"start":{"line":46,"column":8},"end":{"line":46,"column":8}}]},"3":{"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}}]}}},"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol":{"l":{"80":95,"81":95,"82":6,"87":22,"92":13,"97":11,"102":11,"107":11,"109":18,"111":3,"131":190,"132":190,"133":190,"134":112,"136":42,"138":36,"163":160,"164":160,"165":11,"167":149,"168":149,"169":92,"171":24,"173":33,"191":251,"192":39,"194":55,"196":11,"198":11,"201":135},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol","s":{"1":95,"2":95,"3":6,"4":89,"5":22,"6":67,"7":13,"8":54,"9":11,"10":43,"11":11,"12":32,"13":11,"14":21,"15":18,"16":3,"17":190,"18":190,"19":190,"20":112,"21":78,"22":42,"23":36,"24":160,"25":160,"26":11,"27":149,"28":149,"29":92,"30":57,"31":24,"32":33,"33":251,"34":39,"35":212,"36":55,"37":157,"38":11,"39":146,"40":11,"41":135},"b":{"1":[6,89],"2":[22,67],"3":[13,54],"4":[11,43],"5":[11,32],"6":[11,21],"7":[18,3],"8":[112,78],"9":[42,36],"10":[11,149],"11":[92,57],"12":[24,33],"13":[39,212],"14":[55,157],"15":[11,146],"16":[11,135]},"f":{"1":95,"2":190,"3":160,"4":251},"fnMap":{"1":{"name":"messageForTransferRestriction","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":113,"column":4}}},"2":{"name":"detectTransferRestriction","line":126,"loc":{"start":{"line":126,"column":4},"end":{"line":140,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":176,"column":4}}},"4":{"name":"_detectTransferRestriction","line":186,"loc":{"start":{"line":186,"column":4},"end":{"line":203,"column":4}}}},"statementMap":{"1":{"start":{"line":80,"column":10},"end":{"line":80,"column":84}},"2":{"start":{"line":81,"column":8},"end":{"line":81,"column":3926}},"3":{"start":{"line":82,"column":12},"end":{"line":82,"column":35}},"4":{"start":{"line":83,"column":15},"end":{"line":83,"column":4057}},"5":{"start":{"line":87,"column":12},"end":{"line":87,"column":48}},"6":{"start":{"line":88,"column":15},"end":{"line":88,"column":4248}},"7":{"start":{"line":92,"column":12},"end":{"line":92,"column":53}},"8":{"start":{"line":93,"column":15},"end":{"line":93,"column":4449}},"9":{"start":{"line":97,"column":12},"end":{"line":97,"column":53}},"10":{"start":{"line":98,"column":15},"end":{"line":98,"column":4650}},"11":{"start":{"line":102,"column":12},"end":{"line":102,"column":51}},"12":{"start":{"line":103,"column":16},"end":{"line":103,"column":4848}},"13":{"start":{"line":107,"column":12},"end":{"line":107,"column":56}},"14":{"start":{"line":108,"column":15},"end":{"line":108,"column":5055}},"15":{"start":{"line":109,"column":12},"end":{"line":109,"column":77}},"16":{"start":{"line":111,"column":12},"end":{"line":111,"column":36}},"17":{"start":{"line":131,"column":9},"end":{"line":131,"column":83}},"18":{"start":{"line":132,"column":9},"end":{"line":132,"column":71}},"19":{"start":{"line":133,"column":9},"end":{"line":133,"column":6213}},"20":{"start":{"line":134,"column":12},"end":{"line":134,"column":29}},"21":{"start":{"line":135,"column":16},"end":{"line":135,"column":6333}},"22":{"start":{"line":136,"column":12},"end":{"line":136,"column":73}},"23":{"start":{"line":138,"column":12},"end":{"line":138,"column":71}},"24":{"start":{"line":163,"column":8},"end":{"line":163,"column":82}},"25":{"start":{"line":164,"column":8},"end":{"line":164,"column":7854}},"26":{"start":{"line":165,"column":12},"end":{"line":165,"column":92}},"27":{"start":{"line":167,"column":12},"end":{"line":167,"column":74}},"28":{"start":{"line":168,"column":12},"end":{"line":168,"column":8082}},"29":{"start":{"line":169,"column":16},"end":{"line":169,"column":33}},"30":{"start":{"line":170,"column":19},"end":{"line":170,"column":8210}},"31":{"start":{"line":171,"column":16},"end":{"line":171,"column":90}},"32":{"start":{"line":173,"column":16},"end":{"line":173,"column":75}},"33":{"start":{"line":191,"column":8},"end":{"line":191,"column":8975}},"34":{"start":{"line":192,"column":12},"end":{"line":192,"column":89}},"35":{"start":{"line":193,"column":15},"end":{"line":193,"column":9101}},"36":{"start":{"line":194,"column":12},"end":{"line":194,"column":84}},"37":{"start":{"line":195,"column":15},"end":{"line":195,"column":9218}},"38":{"start":{"line":196,"column":12},"end":{"line":196,"column":89}},"39":{"start":{"line":197,"column":15},"end":{"line":197,"column":9346}},"40":{"start":{"line":198,"column":12},"end":{"line":198,"column":87}},"41":{"start":{"line":201,"column":12},"end":{"line":201,"column":71}}},"branchMap":{"1":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":8},"end":{"line":81,"column":8}},{"start":{"line":81,"column":8},"end":{"line":81,"column":8}}]},"2":{"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}}]},"3":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":15},"end":{"line":88,"column":15}},{"start":{"line":88,"column":15},"end":{"line":88,"column":15}}]},"4":{"line":93,"type":"if","locations":[{"start":{"line":93,"column":15},"end":{"line":93,"column":15}},{"start":{"line":93,"column":15},"end":{"line":93,"column":15}}]},"5":{"line":98,"type":"if","locations":[{"start":{"line":98,"column":15},"end":{"line":98,"column":15}},{"start":{"line":98,"column":15},"end":{"line":98,"column":15}}]},"6":{"line":103,"type":"if","locations":[{"start":{"line":103,"column":16},"end":{"line":103,"column":16}},{"start":{"line":103,"column":16},"end":{"line":103,"column":16}}]},"7":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":15},"end":{"line":108,"column":15}},{"start":{"line":108,"column":15},"end":{"line":108,"column":15}}]},"8":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":9},"end":{"line":133,"column":9}},{"start":{"line":133,"column":9},"end":{"line":133,"column":9}}]},"9":{"line":135,"type":"if","locations":[{"start":{"line":135,"column":16},"end":{"line":135,"column":16}},{"start":{"line":135,"column":16},"end":{"line":135,"column":16}}]},"10":{"line":164,"type":"if","locations":[{"start":{"line":164,"column":8},"end":{"line":164,"column":8}},{"start":{"line":164,"column":8},"end":{"line":164,"column":8}}]},"11":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":12},"end":{"line":168,"column":12}},{"start":{"line":168,"column":12},"end":{"line":168,"column":12}}]},"12":{"line":170,"type":"if","locations":[{"start":{"line":170,"column":19},"end":{"line":170,"column":19}},{"start":{"line":170,"column":19},"end":{"line":170,"column":19}}]},"13":{"line":191,"type":"if","locations":[{"start":{"line":191,"column":8},"end":{"line":191,"column":8}},{"start":{"line":191,"column":8},"end":{"line":191,"column":8}}]},"14":{"line":193,"type":"if","locations":[{"start":{"line":193,"column":15},"end":{"line":193,"column":15}},{"start":{"line":193,"column":15},"end":{"line":193,"column":15}}]},"15":{"line":195,"type":"if","locations":[{"start":{"line":195,"column":15},"end":{"line":195,"column":15}},{"start":{"line":195,"column":15},"end":{"line":195,"column":15}}]},"16":{"line":197,"type":"if","locations":[{"start":{"line":197,"column":15},"end":{"line":197,"column":15}},{"start":{"line":197,"column":15},"end":{"line":197,"column":15}}]}}},"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol":{"l":{"29":370,"30":367,"51":367,"52":364,"64":1068,"77":177,"89":1068,"90":299,"92":769,"102":177,"103":78,"105":99,"115":99,"116":99,"117":30,"119":69,"127":769,"128":769,"129":60,"131":709,"167":7763,"168":7309,"169":7309,"170":733,"189":725,"190":709,"192":16},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol","s":{"1":370,"2":367,"3":364,"4":1068,"5":177,"6":1068,"7":299,"8":769,"9":177,"10":78,"11":99,"12":99,"13":99,"14":30,"15":69,"16":769,"17":769,"18":60,"19":709,"20":7763,"21":7309,"22":7309,"23":733,"24":725,"25":709,"26":16},"b":{"1":[367,3],"2":[364,3],"3":[299,769],"4":[78,99],"5":[30,69],"6":[60,709],"7":[733,6576],"8":[709,16]},"f":{"1":370,"2":367,"3":1068,"4":177,"5":1068,"6":177,"7":99,"8":769,"9":7763,"10":725},"fnMap":{"1":{"name":"onlyRuleEngineManager","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"setRuleEngine","line":50,"loc":{"start":{"line":48,"column":4},"end":{"line":53,"column":4}}},"3":{"name":"canTransfer","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"canTransferFrom","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"_canTransfer","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":94,"column":4}}},"6":{"name":"_canTransferFrom","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":107,"column":4}}},"7":{"name":"_canTransferFromWithRuleEngine","line":109,"loc":{"start":{"line":109,"column":4},"end":{"line":121,"column":4}}},"8":{"name":"_canTransferWithRuleEngine","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":133,"column":4}}},"9":{"name":"_transferred","line":166,"loc":{"start":{"line":166,"column":4},"end":{"line":172,"column":4}}},"10":{"name":"_callRuleEngineTransferred","line":182,"loc":{"start":{"line":182,"column":4},"end":{"line":194,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":39}},"2":{"start":{"line":51,"column":9},"end":{"line":51,"column":98}},"3":{"start":{"line":52,"column":8},"end":{"line":52,"column":34}},"4":{"start":{"line":64,"column":7},"end":{"line":64,"column":43}},"5":{"start":{"line":77,"column":8},"end":{"line":77,"column":57}},"6":{"start":{"line":89,"column":7},"end":{"line":89,"column":3017}},"7":{"start":{"line":90,"column":12},"end":{"line":90,"column":24}},"8":{"start":{"line":92,"column":12},"end":{"line":92,"column":62}},"9":{"start":{"line":102,"column":8},"end":{"line":102,"column":3372}},"10":{"start":{"line":103,"column":12},"end":{"line":103,"column":24}},"11":{"start":{"line":105,"column":12},"end":{"line":105,"column":75}},"12":{"start":{"line":115,"column":8},"end":{"line":115,"column":46}},"13":{"start":{"line":116,"column":8},"end":{"line":116,"column":3815}},"14":{"start":{"line":117,"column":12},"end":{"line":117,"column":72}},"15":{"start":{"line":119,"column":12},"end":{"line":119,"column":23}},"16":{"start":{"line":127,"column":8},"end":{"line":127,"column":46}},"17":{"start":{"line":128,"column":8},"end":{"line":128,"column":4194}},"18":{"start":{"line":129,"column":12},"end":{"line":129,"column":59}},"19":{"start":{"line":131,"column":12},"end":{"line":131,"column":23}},"20":{"start":{"line":167,"column":8},"end":{"line":167,"column":62}},"21":{"start":{"line":168,"column":8},"end":{"line":168,"column":46}},"22":{"start":{"line":169,"column":8},"end":{"line":169,"column":6631}},"23":{"start":{"line":170,"column":12},"end":{"line":170,"column":76}},"24":{"start":{"line":189,"column":8},"end":{"line":189,"column":7390}},"25":{"start":{"line":190,"column":12},"end":{"line":190,"column":60}},"26":{"start":{"line":192,"column":12},"end":{"line":192,"column":51}}},"branchMap":{"1":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":21}},{"start":{"line":50,"column":21},"end":{"line":50,"column":21}}]},"2":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":9},"end":{"line":51,"column":9}},{"start":{"line":51,"column":9},"end":{"line":51,"column":9}}]},"3":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":7},"end":{"line":89,"column":7}},{"start":{"line":89,"column":7},"end":{"line":89,"column":7}}]},"4":{"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}}]},"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}}]},"6":{"line":128,"type":"if","locations":[{"start":{"line":128,"column":8},"end":{"line":128,"column":8}},{"start":{"line":128,"column":8},"end":{"line":128,"column":8}}]},"7":{"line":169,"type":"if","locations":[{"start":{"line":169,"column":8},"end":{"line":169,"column":8}},{"start":{"line":169,"column":8},"end":{"line":169,"column":8}}]},"8":{"line":189,"type":"if","locations":[{"start":{"line":189,"column":8},"end":{"line":189,"column":8}},{"start":{"line":189,"column":8},"end":{"line":189,"column":8}}]}}},"contracts/modules/wrapper/options/AllowlistModule.sol":{"l":{"25":1129,"26":1121,"37":4,"47":322,"57":584,"67":211,"68":211,"77":4,"84":1580,"91":2626,"92":2626},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/AllowlistModule.sol","s":{"1":1129,"2":4,"3":322,"4":584,"5":211,"6":211,"7":4,"8":1580,"9":2626,"10":2626},"b":{"1":[4,2],"2":[322,4],"3":[584,2],"4":[211,0]},"f":{"1":1129,"2":4,"3":322,"4":584,"5":211,"6":4,"7":1580,"8":2626},"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,"56":24,"57":24,"68":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":55,"loc":{"start":{"line":55,"column":2},"end":{"line":58,"column":2}}},"4":{"name":"_getCCIPModuleStorage","line":67,"loc":{"start":{"line":67,"column":2},"end":{"line":71,"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":56,"column":4},"end":{"line":56,"column":57}},"7":{"start":{"line":57,"column":4},"end":{"line":57,"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":55,"30":50,"43":53,"44":6,"45":6,"57":19,"58":19,"65":9,"66":9,"67":6,"69":3,"77":5,"78":5,"79":2,"84":18,"85":18,"91":15,"92":14,"96":7,"97":7,"102":7,"103":7,"104":6,"115":25,"116":25,"117":22,"127":28,"128":28,"136":89},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DocumentEngineModule.sol","s":{"1":55,"2":53,"3":6,"4":6,"5":19,"6":19,"7":9,"8":9,"9":6,"10":3,"11":5,"12":5,"13":18,"14":18,"15":15,"16":14,"17":7,"18":7,"19":7,"20":7,"21":6,"22":25,"23":25,"24":22,"25":28},"b":{"1":[53,0],"2":[6,47],"3":[6,3],"4":[2,3],"5":[18,1],"6":[15,3],"7":[7,1],"8":[7,0],"9":[25,3],"10":[22,3]},"f":{"1":55,"2":53,"3":19,"4":9,"5":5,"6":18,"7":7,"8":25,"9":28,"10":89},"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":93,"column":4}}},"7":{"name":"removeDocument","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":105,"column":4}}},"8":{"name":"setDocumentEngine","line":114,"loc":{"start":{"line":112,"column":4},"end":{"line":118,"column":4}}},"9":{"name":"_setDocumentEngine","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":129,"column":4}}},"10":{"name":"_getDocumentEngineModuleStorage","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":139,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":37}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":1726}},"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":2705}},"9":{"start":{"line":67,"column":12},"end":{"line":67,"column":54}},"10":{"start":{"line":69,"column":12},"end":{"line":69,"column":31}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":3119}},"13":{"start":{"line":84,"column":8},"end":{"line":84,"column":81}},"14":{"start":{"line":85,"column":8},"end":{"line":85,"column":103}},"15":{"start":{"line":91,"column":8},"end":{"line":91,"column":61}},"16":{"start":{"line":92,"column":8},"end":{"line":92,"column":53}},"17":{"start":{"line":96,"column":8},"end":{"line":96,"column":81}},"18":{"start":{"line":97,"column":8},"end":{"line":97,"column":103}},"19":{"start":{"line":102,"column":8},"end":{"line":102,"column":89}},"20":{"start":{"line":103,"column":8},"end":{"line":103,"column":45}},"21":{"start":{"line":104,"column":8},"end":{"line":104,"column":53}},"22":{"start":{"line":115,"column":8},"end":{"line":115,"column":81}},"23":{"start":{"line":116,"column":8},"end":{"line":116,"column":110}},"24":{"start":{"line":117,"column":8},"end":{"line":117,"column":45}},"25":{"start":{"line":128,"column":8},"end":{"line":128,"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":85,"type":"if","locations":[{"start":{"line":85,"column":8},"end":{"line":85,"column":8}},{"start":{"line":85,"column":8},"end":{"line":85,"column":8}}]},"7":{"line":95,"type":"if","locations":[{"start":{"line":95,"column":76},"end":{"line":95,"column":76}},{"start":{"line":95,"column":76},"end":{"line":95,"column":76}}]},"8":{"line":97,"type":"if","locations":[{"start":{"line":97,"column":8},"end":{"line":97,"column":8}},{"start":{"line":97,"column":8},"end":{"line":97,"column":8}}]},"9":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":53},"end":{"line":114,"column":53}},{"start":{"line":114,"column":53},"end":{"line":114,"column":53}}]},"10":{"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/options/ERC20CrossChainModule.sol":{"l":{"39":254,"40":182,"45":96,"46":60,"51":84,"52":48,"67":86,"68":62,"80":96,"81":60,"92":60,"93":60,"104":48,"105":48,"110":92,"118":60,"121":48,"122":48,"126":96,"127":48},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol","s":{"1":254,"2":96,"3":84,"4":86,"5":62,"6":96,"7":60,"8":60,"9":60,"10":48,"11":48,"12":92,"13":60,"14":48,"15":48,"16":96,"17":48},"b":{"1":[86,36],"2":[96,36],"3":[60,36],"4":[48,36],"5":[12,12]},"f":{"1":254,"2":96,"3":84,"4":86,"5":96,"6":60,"7":48,"8":92,"9":60,"10":96},"fnMap":{"1":{"name":"onlyTokenBridge","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"onlyBurnerFrom","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":47,"column":4}}},"3":{"name":"onlySelfBurn","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":53,"column":4}}},"4":{"name":"crosschainMint","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":69,"column":4}}},"5":{"name":"crosschainBurn","line":79,"loc":{"start":{"line":79,"column":4},"end":{"line":82,"column":4}}},"6":{"name":"burnFrom","line":90,"loc":{"start":{"line":89,"column":4},"end":{"line":94,"column":4}}},"7":{"name":"burn","line":103,"loc":{"start":{"line":101,"column":4},"end":{"line":106,"column":4}}},"8":{"name":"supportsInterface","line":109,"loc":{"start":{"line":109,"column":4},"end":{"line":111,"column":4}}},"9":{"name":"_burnFrom","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":123,"column":4}}},"10":{"name":"_burnFromOperator","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":128,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":36}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":27}},"3":{"start":{"line":51,"column":8},"end":{"line":51,"column":27}},"4":{"start":{"line":67,"column":8},"end":{"line":67,"column":31}},"5":{"start":{"line":68,"column":8},"end":{"line":68,"column":51}},"6":{"start":{"line":80,"column":8},"end":{"line":80,"column":33}},"7":{"start":{"line":81,"column":8},"end":{"line":81,"column":54}},"8":{"start":{"line":92,"column":8},"end":{"line":92,"column":38}},"9":{"start":{"line":93,"column":8},"end":{"line":93,"column":40}},"10":{"start":{"line":104,"column":8},"end":{"line":104,"column":37}},"11":{"start":{"line":105,"column":8},"end":{"line":105,"column":47}},"12":{"start":{"line":110,"column":8},"end":{"line":110,"column":110}},"13":{"start":{"line":118,"column":8},"end":{"line":118,"column":64}},"14":{"start":{"line":121,"column":8},"end":{"line":121,"column":58}},"15":{"start":{"line":122,"column":8},"end":{"line":122,"column":48}},"16":{"start":{"line":126,"column":8},"end":{"line":126,"column":36}},"17":{"start":{"line":127,"column":8},"end":{"line":127,"column":53}}},"branchMap":{"1":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":89},"end":{"line":66,"column":89}},{"start":{"line":66,"column":89},"end":{"line":66,"column":89}}]},"2":{"line":79,"type":"if","locations":[{"start":{"line":79,"column":91},"end":{"line":79,"column":91}},{"start":{"line":79,"column":91},"end":{"line":79,"column":91}}]},"3":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":48},"end":{"line":90,"column":48}},{"start":{"line":90,"column":48},"end":{"line":90,"column":48}}]},"4":{"line":103,"type":"if","locations":[{"start":{"line":103,"column":46},"end":{"line":103,"column":46}},{"start":{"line":103,"column":46},"end":{"line":103,"column":46}}]},"5":{"line":110,"type":"cond-expr","locations":[{"start":{"line":110,"column":15},"end":{"line":110,"column":56}},{"start":{"line":110,"column":61},"end":{"line":110,"column":109}}]}}},"contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol":{"l":{"30":593,"39":440,"49":98,"50":98,"51":90,"52":90,"53":24,"55":90,"56":90,"66":56,"67":48,"77":32,"78":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol","s":{"1":593,"2":440,"3":98,"4":98,"5":90,"6":90,"7":24,"8":90,"9":90,"10":56,"11":48,"12":32,"13":24},"b":{"1":[98,0],"2":[24,66],"3":[56,0],"4":[32,0]},"f":{"1":593,"2":440,"3":98,"4":56,"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":3687},"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":{"42":2,"43":2,"55":4,"56":4,"61":4,"62":4,"69":4,"78":2,"79":2,"84":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC7551Module.sol","s":{"1":2,"2":2,"3":4,"4":4,"5":4,"6":4,"7":4,"8":2},"b":{"1":[2,2],"2":[4,2]},"f":{"1":2,"2":4,"3":4,"4":4,"5":2,"6":6},"fnMap":{"1":{"name":"setMetaData","line":41,"loc":{"start":{"line":39,"column":4},"end":{"line":44,"column":4}}},"2":{"name":"setTerms","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":57,"column":4}}},"3":{"name":"metaData","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"termsHash","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":70,"column":4}}},"5":{"name":"_setMetaData","line":75,"loc":{"start":{"line":75,"column":3},"end":{"line":80,"column":4}}},"6":{"name":"_getERC7551ModuleStorage","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":87,"column":4}}}},"statementMap":{"1":{"start":{"line":42,"column":8},"end":{"line":42,"column":67}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":34}},"3":{"start":{"line":55,"column":8},"end":{"line":55,"column":37}},"4":{"start":{"line":56,"column":8},"end":{"line":56,"column":31}},"5":{"start":{"line":61,"column":8},"end":{"line":61,"column":67}},"6":{"start":{"line":62,"column":8},"end":{"line":62,"column":26}},"7":{"start":{"line":69,"column":8},"end":{"line":69,"column":39}},"8":{"start":{"line":79,"column":8},"end":{"line":79,"column":32}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":48},"end":{"line":41,"column":48}},{"start":{"line":41,"column":48},"end":{"line":41,"column":48}}]},"2":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":101},"end":{"line":51,"column":101}},{"start":{"line":51,"column":101},"end":{"line":51,"column":101}}]}}},"contracts/modules/wrapper/options/HolderListModule.sol":{"l":{"45":28,"46":28,"53":22,"54":22,"64":10,"65":10,"66":10,"67":8,"74":10,"75":10,"84":22,"85":18,"86":18,"87":18,"88":16,"89":16,"90":10,"103":114,"104":114,"106":114,"107":10,"108":10,"112":114,"113":106,"114":104,"121":202},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/HolderListModule.sol","s":{"1":28,"2":28,"3":22,"4":22,"5":10,"6":10,"7":10,"8":8,"9":10,"10":10,"11":22,"12":18,"13":18,"14":18,"15":16,"16":114,"17":114,"18":114,"19":10,"20":10,"21":114,"22":106,"23":104},"b":{"1":[8,2],"2":[18,4],"3":[16,2],"4":[10,104],"5":[10,0],"6":[106,8],"7":[104,2]},"f":{"1":28,"2":22,"3":10,"4":10,"5":22,"6":114,"7":202},"fnMap":{"1":{"name":"holderCount","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":47,"column":4}}},"2":{"name":"isHolder","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":55,"column":4}}},"3":{"name":"holderByIndex","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":68,"column":4}}},"4":{"name":"holders","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"holdersInRange","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":92,"column":4}}},"6":{"name":"_update","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":117,"column":4}}},"7":{"name":"_getHolderListModuleStorage","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":124,"column":4}}}},"statementMap":{"1":{"start":{"line":45,"column":8},"end":{"line":45,"column":73}},"2":{"start":{"line":46,"column":8},"end":{"line":46,"column":34}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":73}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":43}},"5":{"start":{"line":64,"column":8},"end":{"line":64,"column":73}},"6":{"start":{"line":65,"column":8},"end":{"line":65,"column":54}},"7":{"start":{"line":66,"column":8},"end":{"line":66,"column":106}},"8":{"start":{"line":67,"column":8},"end":{"line":67,"column":35}},"9":{"start":{"line":74,"column":8},"end":{"line":74,"column":73}},"10":{"start":{"line":75,"column":8},"end":{"line":75,"column":34}},"11":{"start":{"line":84,"column":8},"end":{"line":84,"column":93}},"12":{"start":{"line":85,"column":8},"end":{"line":85,"column":73}},"13":{"start":{"line":86,"column":8},"end":{"line":86,"column":54}},"14":{"start":{"line":87,"column":8},"end":{"line":87,"column":111}},"15":{"start":{"line":89,"column":8},"end":{"line":89,"column":4120}},"16":{"start":{"line":103,"column":8},"end":{"line":103,"column":37}},"17":{"start":{"line":104,"column":8},"end":{"line":104,"column":73}},"18":{"start":{"line":106,"column":8},"end":{"line":106,"column":5014}},"19":{"start":{"line":107,"column":12},"end":{"line":107,"column":5080}},"20":{"start":{"line":108,"column":16},"end":{"line":108,"column":40}},"21":{"start":{"line":112,"column":8},"end":{"line":112,"column":5257}},"22":{"start":{"line":113,"column":12},"end":{"line":113,"column":5319}},"23":{"start":{"line":114,"column":16},"end":{"line":114,"column":36}}},"branchMap":{"1":{"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}}]},"2":{"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}}]},"3":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":8},"end":{"line":87,"column":8}},{"start":{"line":87,"column":8},"end":{"line":87,"column":8}}]},"4":{"line":106,"type":"if","locations":[{"start":{"line":106,"column":8},"end":{"line":106,"column":8}},{"start":{"line":106,"column":8},"end":{"line":106,"column":8}}]},"5":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":12},"end":{"line":107,"column":12}},{"start":{"line":107,"column":12},"end":{"line":107,"column":12}}]},"6":{"line":112,"type":"if","locations":[{"start":{"line":112,"column":8},"end":{"line":112,"column":8}},{"start":{"line":112,"column":8},"end":{"line":112,"column":8}}]},"7":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":12},"end":{"line":113,"column":12}},{"start":{"line":113,"column":12},"end":{"line":113,"column":12}}]}}},"contracts/modules/wrapper/security/AccessControlModule.sol":{"l":{"25":6262,"26":2,"31":6260,"46":21844,"47":13326,"49":8518},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol","s":{"1":6262,"2":6260,"3":21844,"4":13326,"5":8518},"b":{"1":[6262,0],"2":[2,6260],"3":[13326,8518]},"f":{"1":6262,"2":21844},"fnMap":{"1":{"name":"__AccessControlModule_init_unchained","line":24,"loc":{"start":{"line":23,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"hasRole","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":51,"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":46,"column":8},"end":{"line":46,"column":1961}},"4":{"start":{"line":47,"column":12},"end":{"line":47,"column":23}},"5":{"start":{"line":49,"column":12},"end":{"line":49,"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":46,"type":"if","locations":[{"start":{"line":46,"column":8},"end":{"line":46,"column":8}},{"start":{"line":46,"column":8},"end":{"line":46,"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 4a2a2822..79b0b8e2 100644 --- a/doc/test/coverage/coverage-final.json +++ b/doc/test/coverage/coverage-final.json @@ -1,23 +1,25 @@ { -"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/deployment/allowlist/CMTATStandaloneAllowlist.sol":{"l":{"28":458},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol","s":{"1":458},"b":{},"f":{"1":458},"fnMap":{"1":{"name":"constructor","line":26,"loc":{"start":{"line":21,"column":4},"end":{"line":33,"column":4}}}},"statementMap":{"1":{"start":{"line":28,"column":8},"end":{"line":28,"column":1208}}},"branchMap":{}}, +"contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol":{"l":{"20":247},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeableAllowlist.sol","s":{"1":247},"b":{},"f":{"1":247},"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":{"34":344,"63":142},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardStandalone.sol","s":{"1":344,"2":142},"b":{"1":[142,4]},"f":{"1":344,"2":142},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":26,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":62,"loc":{"start":{"line":56,"column":4},"end":{"line":64,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1664}},"2":{"start":{"line":63,"column":8},"end":{"line":63,"column":78}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":32},"end":{"line":62,"column":32}},{"start":{"line":62,"column":32},"end":{"line":62,"column":32}}]}}}, +"contracts/deployment/CMTATStandardUpgradeable.sol":{"l":{"25":367,"49":237},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardUpgradeable.sol","s":{"1":367,"2":237},"b":{"1":[237,4]},"f":{"1":367,"2":237},"fnMap":{"1":{"name":"constructor","line":23,"loc":{"start":{"line":21,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":48,"loc":{"start":{"line":42,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":29}},"2":{"start":{"line":49,"column":8},"end":{"line":49,"column":78}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":32},"end":{"line":48,"column":32}},{"start":{"line":48,"column":32},"end":{"line":48,"column":32}}]}}}, +"contracts/deployment/CMTATUpgradeableUUPS.sol":{"l":{"22":484},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol","s":{"1":484},"b":{"1":[2,1]},"f":{"1":484,"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":482},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.sol","s":{"1":482},"b":{},"f":{"1":482},"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":1033}}},"branchMap":{}}, +"contracts/deployment/debt/CMTATUpgradeableDebt.sol":{"l":{"16":492},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt.sol","s":{"1":492},"b":{},"f":{"1":492},"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":486},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandaloneDebtEngine.sol","s":{"1":486},"b":{},"f":{"1":486},"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":1057}}},"branchMap":{}}, +"contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol":{"l":{"16":222},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol","s":{"1":222},"b":{},"f":{"1":222},"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":245},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC1363.sol","s":{"1":245},"b":{},"f":{"1":245},"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":285},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableERC1363.sol","s":{"1":285},"b":{},"f":{"1":285},"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":{"33":248,"67":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol","s":{"1":248,"2":22},"b":{"1":[22,0]},"f":{"1":248,"2":22},"fnMap":{"1":{"name":"constructor","line":31,"loc":{"start":{"line":25,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":66,"loc":{"start":{"line":60,"column":4},"end":{"line":68,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":1614}},"2":{"start":{"line":67,"column":8},"end":{"line":67,"column":78}}},"branchMap":{"1":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":32},"end":{"line":66,"column":32}},{"start":{"line":66,"column":32},"end":{"line":66,"column":32}}]}}}, +"contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol":{"l":{"24":248,"48":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol","s":{"1":248,"2":22},"b":{"1":[22,0]},"f":{"1":248,"2":22},"fnMap":{"1":{"name":"constructor","line":22,"loc":{"start":{"line":20,"column":4},"end":{"line":25,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":47,"loc":{"start":{"line":41,"column":4},"end":{"line":49,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":29}},"2":{"start":{"line":48,"column":8},"end":{"line":48,"column":78}}},"branchMap":{"1":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":32},"end":{"line":47,"column":32}},{"start":{"line":47,"column":32},"end":{"line":47,"column":32}}]}}}, +"contracts/deployment/holderList/CMTATStandaloneHolderList.sol":{"l":{"31":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATStandaloneHolderList.sol","s":{"1":24},"b":{},"f":{"1":24},"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":1345}}},"branchMap":{}}, +"contracts/deployment/holderList/CMTATUpgradeableHolderList.sol":{"l":{"22":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol","s":{"1":24},"b":{},"f":{"1":24},"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/light/CMTATStandaloneLight.sol":{"l":{"23":134},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight.sol","s":{"1":134},"b":{},"f":{"1":134},"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":131},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLight.sol","s":{"1":131},"b":{},"f":{"1":131},"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":248},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATStandalonePermit.sol","s":{"1":248},"b":{},"f":{"1":248},"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":250},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATUpgradeablePermit.sol","s":{"1":250},"b":{},"f":{"1":250},"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":{"34":344,"63":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol","s":{"1":344,"2":22},"b":{"1":[22,0]},"f":{"1":344,"2":22},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":26,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":62,"loc":{"start":{"line":56,"column":4},"end":{"line":64,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1669}},"2":{"start":{"line":63,"column":8},"end":{"line":63,"column":78}}},"branchMap":{"1":{"line":62,"type":"if","locations":[{"start":{"line":62,"column":32},"end":{"line":62,"column":32}},{"start":{"line":62,"column":32},"end":{"line":62,"column":32}}]}}}, +"contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol":{"l":{"25":369,"49":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol","s":{"1":369,"2":22},"b":{"1":[22,0]},"f":{"1":369,"2":22},"fnMap":{"1":{"name":"constructor","line":23,"loc":{"start":{"line":21,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"_callRuleEngineTransferred","line":48,"loc":{"start":{"line":42,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":29}},"2":{"start":{"line":49,"column":8},"end":{"line":49,"column":78}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":32},"end":{"line":48,"column":32}},{"start":{"line":48,"column":32},"end":{"line":48,"column":32}}]}}}, "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":{}}, @@ -26,6 +28,7 @@ "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/IHolderListModule.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IHolderListModule.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":{}}, @@ -38,58 +41,62 @@ "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/draft-IERC8343.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC8343.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/0_CMTATBaseCommon.sol":{"l":{"53":22,"61":88,"68":70,"74":442,"75":442,"76":252,"77":190,"92":306,"93":174,"110":110,"111":66,"118":8968,"129":6737,"130":6571,"140":1169,"141":957,"151":314,"152":199},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol","s":{"1":22,"2":88,"3":70,"4":442,"5":442,"6":252,"7":190,"8":306,"9":174,"10":110,"11":66,"12":8968,"13":6737,"14":6571,"15":1169,"16":957,"17":314,"18":199},"b":{},"f":{"1":22,"2":88,"3":70,"4":442,"5":306,"6":110,"7":8968,"8":6737,"9":1169,"10":314},"fnMap":{"1":{"name":"decimals","line":46,"loc":{"start":{"line":46,"column":4},"end":{"line":54,"column":4}}},"2":{"name":"name","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":62,"column":4}}},"3":{"name":"symbol","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":69,"column":4}}},"4":{"name":"transfer","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"transferFrom","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":94,"column":4}}},"6":{"name":"burnAndMint","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":112,"column":4}}},"7":{"name":"_checkTransferred","line":117,"loc":{"start":{"line":117,"column":4},"end":{"line":119,"column":4}}},"8":{"name":"_mintOverride","line":128,"loc":{"start":{"line":128,"column":4},"end":{"line":131,"column":4}}},"9":{"name":"_burnOverride","line":139,"loc":{"start":{"line":139,"column":4},"end":{"line":142,"column":4}}},"10":{"name":"_minterTransferOverride","line":150,"loc":{"start":{"line":150,"column":4},"end":{"line":153,"column":4}}}},"statementMap":{"1":{"start":{"line":53,"column":8},"end":{"line":53,"column":41}},"2":{"start":{"line":61,"column":8},"end":{"line":61,"column":42}},"3":{"start":{"line":68,"column":8},"end":{"line":68,"column":44}},"4":{"start":{"line":74,"column":9},"end":{"line":74,"column":36}},"5":{"start":{"line":75,"column":8},"end":{"line":75,"column":53}},"6":{"start":{"line":76,"column":8},"end":{"line":76,"column":50}},"7":{"start":{"line":77,"column":8},"end":{"line":77,"column":19}},"8":{"start":{"line":92,"column":8},"end":{"line":92,"column":55}},"9":{"start":{"line":93,"column":8},"end":{"line":93,"column":60}},"10":{"start":{"line":110,"column":8},"end":{"line":110,"column":53}},"11":{"start":{"line":111,"column":8},"end":{"line":111,"column":51}},"12":{"start":{"line":118,"column":8},"end":{"line":118,"column":79}},"13":{"start":{"line":129,"column":8},"end":{"line":129,"column":66}},"14":{"start":{"line":130,"column":8},"end":{"line":130,"column":60}},"15":{"start":{"line":140,"column":8},"end":{"line":140,"column":67}},"16":{"start":{"line":141,"column":8},"end":{"line":141,"column":60}},"17":{"start":{"line":151,"column":8},"end":{"line":151,"column":55}},"18":{"start":{"line":152,"column":8},"end":{"line":152,"column":71}}},"branchMap":{}}, +"contracts/modules/0_CMTATBaseCore.sol":{"l":{"61":4,"62":3,"78":265,"94":318,"97":318,"100":318,"103":318,"111":318,"112":318,"121":318,"122":318,"123":318,"148":2,"156":6,"163":6,"175":19,"183":26,"184":26,"185":16,"186":10,"193":54,"194":44,"209":18,"210":14,"227":10,"228":6,"245":3,"247":2,"248":2,"257":368,"258":360,"263":76,"264":66,"275":20,"276":12},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol","s":{"1":4,"2":265,"3":318,"4":318,"5":318,"6":318,"7":318,"8":318,"9":318,"10":318,"11":318,"12":2,"13":6,"14":6,"15":19,"16":26,"17":26,"18":16,"19":10,"20":54,"21":44,"22":18,"23":14,"24":10,"25":6,"26":3,"27":2,"28":2,"29":368,"30":360,"31":76,"32":66,"33":20,"34":12},"b":{"1":[265,0],"2":[318,0],"3":[318,0],"4":[318,0],"5":[2,2],"6":[2,5],"7":[3,1],"8":[2,1],"9":[3,1],"10":[298,6],"11":[54,8],"12":[56,4],"13":[22,2],"14":[65,6],"15":[4,4]},"f":{"1":4,"2":265,"3":318,"4":318,"5":318,"6":2,"7":6,"8":6,"9":19,"10":26,"11":54,"12":18,"13":10,"14":3,"15":368,"16":76,"17":20,"18":3,"19":298,"20":54,"21":56,"22":22,"23":65,"24":4},"fnMap":{"1":{"name":"onlyERC20ForcedBurnManager","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":63,"column":4}}},"2":{"name":"initialize","line":77,"loc":{"start":{"line":74,"column":4},"end":{"line":82,"column":4}}},"3":{"name":"__CMTAT_init","line":91,"loc":{"start":{"line":88,"column":4},"end":{"line":104,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":109,"loc":{"start":{"line":109,"column":4},"end":{"line":113,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":119,"loc":{"start":{"line":119,"column":4},"end":{"line":124,"column":4}}},"6":{"name":"decimals","line":141,"loc":{"start":{"line":141,"column":4},"end":{"line":149,"column":4}}},"7":{"name":"name","line":155,"loc":{"start":{"line":155,"column":4},"end":{"line":157,"column":4}}},"8":{"name":"symbol","line":162,"loc":{"start":{"line":162,"column":4},"end":{"line":164,"column":4}}},"9":{"name":"supportsInterface","line":174,"loc":{"start":{"line":174,"column":4},"end":{"line":176,"column":4}}},"10":{"name":"transfer","line":182,"loc":{"start":{"line":182,"column":4},"end":{"line":187,"column":4}}},"11":{"name":"approve","line":192,"loc":{"start":{"line":192,"column":4},"end":{"line":195,"column":4}}},"12":{"name":"transferFrom","line":199,"loc":{"start":{"line":199,"column":4},"end":{"line":211,"column":4}}},"13":{"name":"burnAndMint","line":226,"loc":{"start":{"line":226,"column":4},"end":{"line":229,"column":4}}},"14":{"name":"forcedBurn","line":244,"loc":{"start":{"line":240,"column":4},"end":{"line":249,"column":4}}},"15":{"name":"_mintOverride","line":256,"loc":{"start":{"line":256,"column":4},"end":{"line":259,"column":4}}},"16":{"name":"_burnOverride","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":265,"column":4}}},"17":{"name":"_minterTransferOverride","line":270,"loc":{"start":{"line":270,"column":4},"end":{"line":277,"column":4}}},"18":{"name":"_authorizeForcedBurn","line":280,"loc":{"start":{"line":280,"column":4},"end":{"line":280,"column":82}}},"19":{"name":"_authorizeMint","line":282,"loc":{"start":{"line":282,"column":4},"end":{"line":282,"column":95}}},"20":{"name":"_authorizeBurn","line":284,"loc":{"start":{"line":284,"column":4},"end":{"line":284,"column":95}}},"21":{"name":"_authorizePause","line":286,"loc":{"start":{"line":286,"column":4},"end":{"line":286,"column":92}}},"22":{"name":"_authorizeDeactivate","line":287,"loc":{"start":{"line":287,"column":4},"end":{"line":287,"column":104}}},"23":{"name":"_authorizeFreeze","line":289,"loc":{"start":{"line":289,"column":4},"end":{"line":289,"column":101}}},"24":{"name":"_authorizeTokenAttributeManagement","line":291,"loc":{"start":{"line":291,"column":4},"end":{"line":291,"column":127}}}},"statementMap":{"1":{"start":{"line":61,"column":8},"end":{"line":61,"column":29}},"2":{"start":{"line":78,"column":8},"end":{"line":78,"column":3167}},"3":{"start":{"line":94,"column":8},"end":{"line":94,"column":33}},"4":{"start":{"line":97,"column":8},"end":{"line":97,"column":32}},"5":{"start":{"line":100,"column":8},"end":{"line":100,"column":44}},"6":{"start":{"line":103,"column":8},"end":{"line":103,"column":62}},"7":{"start":{"line":111,"column":8},"end":{"line":111,"column":39}},"8":{"start":{"line":112,"column":8},"end":{"line":112,"column":34}},"9":{"start":{"line":121,"column":8},"end":{"line":121,"column":50}},"10":{"start":{"line":122,"column":8},"end":{"line":122,"column":77}},"11":{"start":{"line":123,"column":8},"end":{"line":123,"column":92}},"12":{"start":{"line":148,"column":8},"end":{"line":148,"column":41}},"13":{"start":{"line":156,"column":8},"end":{"line":156,"column":42}},"14":{"start":{"line":163,"column":8},"end":{"line":163,"column":44}},"15":{"start":{"line":175,"column":8},"end":{"line":175,"column":144}},"16":{"start":{"line":183,"column":8},"end":{"line":183,"column":35}},"17":{"start":{"line":184,"column":8},"end":{"line":184,"column":82}},"18":{"start":{"line":185,"column":8},"end":{"line":185,"column":50}},"19":{"start":{"line":186,"column":8},"end":{"line":186,"column":19}},"20":{"start":{"line":193,"column":8},"end":{"line":193,"column":76}},"21":{"start":{"line":194,"column":8},"end":{"line":194,"column":55}},"22":{"start":{"line":209,"column":8},"end":{"line":209,"column":84}},"23":{"start":{"line":210,"column":8},"end":{"line":210,"column":60}},"24":{"start":{"line":227,"column":8},"end":{"line":227,"column":53}},"25":{"start":{"line":228,"column":8},"end":{"line":228,"column":51}},"26":{"start":{"line":245,"column":8},"end":{"line":245,"column":95}},"27":{"start":{"line":247,"column":8},"end":{"line":247,"column":45}},"28":{"start":{"line":248,"column":8},"end":{"line":248,"column":75}},"29":{"start":{"line":257,"column":8},"end":{"line":257,"column":58}},"30":{"start":{"line":258,"column":8},"end":{"line":258,"column":60}},"31":{"start":{"line":263,"column":8},"end":{"line":263,"column":58}},"32":{"start":{"line":264,"column":8},"end":{"line":264,"column":60}},"33":{"start":{"line":275,"column":8},"end":{"line":275,"column":84}},"34":{"start":{"line":276,"column":8},"end":{"line":276,"column":71}}},"branchMap":{"1":{"line":77,"type":"if","locations":[{"start":{"line":77,"column":21},"end":{"line":77,"column":21}},{"start":{"line":77,"column":21},"end":{"line":77,"column":21}}]},"2":{"line":91,"type":"if","locations":[{"start":{"line":91,"column":23},"end":{"line":91,"column":23}},{"start":{"line":91,"column":23},"end":{"line":91,"column":23}}]},"3":{"line":109,"type":"if","locations":[{"start":{"line":109,"column":68},"end":{"line":109,"column":68}},{"start":{"line":109,"column":68},"end":{"line":109,"column":68}}]},"4":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":136},"end":{"line":119,"column":136}},{"start":{"line":119,"column":136},"end":{"line":119,"column":136}}]},"5":{"line":175,"type":"cond-expr","locations":[{"start":{"line":175,"column":15},"end":{"line":175,"column":39}},{"start":{"line":175,"column":44},"end":{"line":175,"column":84}}]},"6":{"line":175,"type":"cond-expr","locations":[{"start":{"line":175,"column":15},"end":{"line":175,"column":84}},{"start":{"line":175,"column":89},"end":{"line":175,"column":143}}]},"7":{"line":244,"type":"if","locations":[{"start":{"line":244,"column":48},"end":{"line":244,"column":48}},{"start":{"line":244,"column":48},"end":{"line":244,"column":48}}]},"8":{"line":245,"type":"if","locations":[{"start":{"line":245,"column":8},"end":{"line":245,"column":8}},{"start":{"line":245,"column":8},"end":{"line":245,"column":8}}]},"9":{"line":280,"type":"if","locations":[{"start":{"line":280,"column":53},"end":{"line":280,"column":53}},{"start":{"line":280,"column":53},"end":{"line":280,"column":53}}]},"10":{"line":282,"type":"if","locations":[{"start":{"line":282,"column":73},"end":{"line":282,"column":73}},{"start":{"line":282,"column":73},"end":{"line":282,"column":73}}]},"11":{"line":284,"type":"if","locations":[{"start":{"line":284,"column":73},"end":{"line":284,"column":73}},{"start":{"line":284,"column":73},"end":{"line":284,"column":73}}]},"12":{"line":286,"type":"if","locations":[{"start":{"line":286,"column":70},"end":{"line":286,"column":70}},{"start":{"line":286,"column":70},"end":{"line":286,"column":70}}]},"13":{"line":287,"type":"if","locations":[{"start":{"line":287,"column":75},"end":{"line":287,"column":75}},{"start":{"line":287,"column":75},"end":{"line":287,"column":75}}]},"14":{"line":289,"type":"if","locations":[{"start":{"line":289,"column":77},"end":{"line":289,"column":77}},{"start":{"line":289,"column":77},"end":{"line":289,"column":77}}]},"15":{"line":291,"type":"if","locations":[{"start":{"line":291,"column":98},"end":{"line":291,"column":98}},{"start":{"line":291,"column":98},"end":{"line":291,"column":98}}]}}}, +"contracts/modules/0_CMTATBaseGeneric.sol":{"l":{"50":72,"53":72,"56":72,"59":72,"67":72,"68":72,"76":72,"78":72},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseGeneric.sol","s":{"1":72,"2":72,"3":72,"4":72,"5":72,"6":72,"7":72,"8":72},"b":{"1":[72,0],"2":[72,0],"3":[72,0],"4":[16,2],"5":[3,3]},"f":{"1":72,"2":72,"3":72,"4":16,"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":3118,"21":3118,"22":231,"23":231,"24":231,"25":231,"26":231,"28":2887},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseSnapshot.sol","s":{"1":3118,"2":3118,"3":231,"4":231,"5":231,"6":231,"7":231,"8":2887},"b":{"1":[231,2887]},"f":{"1":3118},"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/2_CMTATBaseAccessControl.sol":{"l":{"36":5872,"38":5870,"39":5870,"41":5870,"57":45},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAccessControl.sol","s":{"1":5872,"2":5870,"3":5870,"4":5870,"5":45},"b":{"1":[5872,0],"2":[16,2],"3":[2,2],"4":[2,2],"5":[2,4],"6":[46,44],"7":[5827,66],"8":[691,88],"9":[355,44],"10":[83,79],"11":[1364,66],"12":[298,44]},"f":{"1":5872,"2":45,"3":46,"4":5827,"5":691,"6":355,"7":83,"8":1364,"9":298},"fnMap":{"1":{"name":"__CMTAT_commonModules_init_unchained","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":42,"column":4}}},"2":{"name":"supportsInterface","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":58,"column":4}}},"3":{"name":"_authorizeTokenAttributeManagement","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":70,"column":127}}},"4":{"name":"_authorizeMint","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":76,"column":95}}},"5":{"name":"_authorizeBurn","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":82,"column":95}}},"6":{"name":"_authorizeDocumentManagement","line":88,"loc":{"start":{"line":88,"column":4},"end":{"line":88,"column":117}}},"7":{"name":"_authorizeExtraInfoManagement","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":94,"column":129}}},"8":{"name":"_authorizeERC20Enforcer","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":100,"column":118}}},"9":{"name":"_authorizeForcedTransfer","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":106,"column":119}}}},"statementMap":{"1":{"start":{"line":36,"column":8},"end":{"line":36,"column":50}},"2":{"start":{"line":38,"column":8},"end":{"line":38,"column":77}},"3":{"start":{"line":39,"column":8},"end":{"line":39,"column":92}},"4":{"start":{"line":41,"column":8},"end":{"line":41,"column":177}},"5":{"start":{"line":57,"column":8},"end":{"line":57,"column":218}}},"branchMap":{"1":{"line":34,"type":"if","locations":[{"start":{"line":34,"column":228},"end":{"line":34,"column":228}},{"start":{"line":34,"column":228},"end":{"line":34,"column":228}}]},"2":{"line":57,"type":"cond-expr","locations":[{"start":{"line":57,"column":15},"end":{"line":57,"column":39}},{"start":{"line":57,"column":44},"end":{"line":57,"column":68}}]},"3":{"line":57,"type":"cond-expr","locations":[{"start":{"line":57,"column":15},"end":{"line":57,"column":68}},{"start":{"line":57,"column":73},"end":{"line":57,"column":113}}]},"4":{"line":57,"type":"cond-expr","locations":[{"start":{"line":57,"column":15},"end":{"line":57,"column":113}},{"start":{"line":57,"column":118},"end":{"line":57,"column":158}}]},"5":{"line":57,"type":"cond-expr","locations":[{"start":{"line":57,"column":15},"end":{"line":57,"column":158}},{"start":{"line":57,"column":163},"end":{"line":57,"column":217}}]},"6":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":98},"end":{"line":70,"column":98}},{"start":{"line":70,"column":98},"end":{"line":70,"column":98}}]},"7":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":73},"end":{"line":76,"column":73}},{"start":{"line":76,"column":73},"end":{"line":76,"column":73}}]},"8":{"line":82,"type":"if","locations":[{"start":{"line":82,"column":73},"end":{"line":82,"column":73}},{"start":{"line":82,"column":73},"end":{"line":82,"column":73}}]},"9":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":93},"end":{"line":88,"column":93}},{"start":{"line":88,"column":93},"end":{"line":88,"column":93}}]},"10":{"line":94,"type":"if","locations":[{"start":{"line":94,"column":96},"end":{"line":94,"column":96}},{"start":{"line":94,"column":96},"end":{"line":94,"column":96}}]},"11":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":89},"end":{"line":100,"column":89}},{"start":{"line":100,"column":89},"end":{"line":100,"column":89}}]},"12":{"line":106,"type":"if","locations":[{"start":{"line":106,"column":90},"end":{"line":106,"column":90}},{"start":{"line":106,"column":90},"end":{"line":106,"column":90}}]}}}, +"contracts/modules/3_CMTATBaseAllowlist.sol":{"l":{"57":705,"75":705,"78":705,"81":705,"84":705,"92":705,"93":705,"95":705,"102":705,"104":705,"128":116,"129":97,"138":58,"147":39,"157":3,"167":9,"177":9,"188":316,"189":316,"190":84,"192":232,"206":31,"207":31,"208":6,"210":25,"226":200,"229":49,"239":12,"245":849,"251":128,"255":273,"259":38,"267":245,"275":118,"279":1110,"280":1095,"290":235,"307":8559,"317":8561,"330":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol","s":{"1":705,"2":705,"3":705,"4":705,"5":705,"6":705,"7":705,"8":705,"9":705,"10":705,"11":116,"12":97,"13":58,"14":39,"15":3,"16":9,"17":9,"18":316,"19":316,"20":84,"21":232,"22":31,"23":31,"24":6,"25":25,"26":200,"27":49,"28":12,"29":849,"30":128,"31":273,"32":38,"33":245,"34":118,"35":1110,"36":1095,"37":235,"38":8559,"39":8561,"40":2},"b":{"1":[705,0],"2":[705,0],"3":[705,0],"4":[705,0],"5":[84,232],"6":[6,25],"7":[84,6],"8":[33,3],"9":[96,9],"10":[1121,8]},"f":{"1":705,"2":705,"3":705,"4":705,"5":116,"6":58,"7":39,"8":3,"9":9,"10":9,"11":316,"12":31,"13":84,"14":33,"15":96,"16":1121,"17":200,"18":49,"19":12,"20":849,"21":128,"22":273,"23":38,"24":245,"25":118,"26":1110,"27":235,"28":8559,"29":8561,"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":125,"loc":{"start":{"line":125,"column":4},"end":{"line":130,"column":4}}},"6":{"name":"transfer","line":132,"loc":{"start":{"line":132,"column":4},"end":{"line":139,"column":4}}},"7":{"name":"transferFrom","line":141,"loc":{"start":{"line":141,"column":4},"end":{"line":148,"column":4}}},"8":{"name":"decimals","line":150,"loc":{"start":{"line":150,"column":4},"end":{"line":158,"column":4}}},"9":{"name":"name","line":160,"loc":{"start":{"line":160,"column":4},"end":{"line":168,"column":4}}},"10":{"name":"symbol","line":170,"loc":{"start":{"line":170,"column":4},"end":{"line":178,"column":4}}},"11":{"name":"canTransfer","line":183,"loc":{"start":{"line":183,"column":4},"end":{"line":195,"column":4}}},"12":{"name":"canTransferFrom","line":200,"loc":{"start":{"line":200,"column":3},"end":{"line":212,"column":4}}},"13":{"name":"_authorizePause","line":219,"loc":{"start":{"line":219,"column":4},"end":{"line":219,"column":92}}},"14":{"name":"_authorizeDeactivate","line":220,"loc":{"start":{"line":220,"column":4},"end":{"line":220,"column":104}}},"15":{"name":"_authorizeFreeze","line":222,"loc":{"start":{"line":222,"column":4},"end":{"line":222,"column":101}}},"16":{"name":"_authorizeAllowlistManagement","line":224,"loc":{"start":{"line":224,"column":4},"end":{"line":224,"column":114}}},"17":{"name":"_authorizeERC20Enforcer","line":225,"loc":{"start":{"line":225,"column":4},"end":{"line":227,"column":4}}},"18":{"name":"_authorizeForcedTransfer","line":228,"loc":{"start":{"line":228,"column":4},"end":{"line":230,"column":4}}},"19":{"name":"_canMintBurnByModule","line":236,"loc":{"start":{"line":236,"column":4},"end":{"line":240,"column":4}}},"20":{"name":"_canMintByModuleAndRevert","line":242,"loc":{"start":{"line":242,"column":4},"end":{"line":246,"column":4}}},"21":{"name":"_canBurnByModuleAndRevert","line":248,"loc":{"start":{"line":248,"column":4},"end":{"line":252,"column":4}}},"22":{"name":"_canSend","line":254,"loc":{"start":{"line":254,"column":4},"end":{"line":256,"column":4}}},"23":{"name":"_canReceive","line":258,"loc":{"start":{"line":258,"column":4},"end":{"line":260,"column":4}}},"24":{"name":"_canTransferStandardByModule","line":262,"loc":{"start":{"line":262,"column":4},"end":{"line":268,"column":4}}},"25":{"name":"_canTransferStandardByModuleAndRevert","line":270,"loc":{"start":{"line":270,"column":4},"end":{"line":276,"column":4}}},"26":{"name":"_checkTransferred","line":278,"loc":{"start":{"line":278,"column":4},"end":{"line":281,"column":4}}},"27":{"name":"getFrozenTokens","line":283,"loc":{"start":{"line":283,"column":4},"end":{"line":291,"column":4}}},"28":{"name":"_msgSender","line":301,"loc":{"start":{"line":301,"column":4},"end":{"line":308,"column":4}}},"29":{"name":"_contextSuffixLength","line":314,"loc":{"start":{"line":314,"column":4},"end":{"line":318,"column":4}}},"30":{"name":"_msgData","line":324,"loc":{"start":{"line":324,"column":4},"end":{"line":331,"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":128,"column":8},"end":{"line":128,"column":76}},"12":{"start":{"line":129,"column":8},"end":{"line":129,"column":55}},"13":{"start":{"line":138,"column":8},"end":{"line":138,"column":50}},"14":{"start":{"line":147,"column":8},"end":{"line":147,"column":60}},"15":{"start":{"line":157,"column":8},"end":{"line":157,"column":41}},"16":{"start":{"line":167,"column":8},"end":{"line":167,"column":37}},"17":{"start":{"line":177,"column":8},"end":{"line":177,"column":39}},"18":{"start":{"line":188,"column":8},"end":{"line":188,"column":89}},"19":{"start":{"line":189,"column":8},"end":{"line":189,"column":7550}},"20":{"start":{"line":190,"column":12},"end":{"line":190,"column":24}},"21":{"start":{"line":192,"column":12},"end":{"line":192,"column":68}},"22":{"start":{"line":206,"column":8},"end":{"line":206,"column":89}},"23":{"start":{"line":207,"column":8},"end":{"line":207,"column":8049}},"24":{"start":{"line":208,"column":12},"end":{"line":208,"column":24}},"25":{"start":{"line":210,"column":12},"end":{"line":210,"column":81}},"26":{"start":{"line":226,"column":8},"end":{"line":226,"column":55}},"27":{"start":{"line":229,"column":8},"end":{"line":229,"column":56}},"28":{"start":{"line":239,"column":8},"end":{"line":239,"column":70}},"29":{"start":{"line":245,"column":8},"end":{"line":245,"column":62}},"30":{"start":{"line":251,"column":8},"end":{"line":251,"column":64}},"31":{"start":{"line":255,"column":8},"end":{"line":255,"column":58}},"32":{"start":{"line":259,"column":8},"end":{"line":259,"column":61}},"33":{"start":{"line":267,"column":8},"end":{"line":267,"column":88}},"34":{"start":{"line":275,"column":8},"end":{"line":275,"column":89}},"35":{"start":{"line":279,"column":8},"end":{"line":279,"column":66}},"36":{"start":{"line":280,"column":8},"end":{"line":280,"column":79}},"37":{"start":{"line":290,"column":8},"end":{"line":290,"column":69}},"38":{"start":{"line":307,"column":8},"end":{"line":307,"column":53}},"39":{"start":{"line":317,"column":9},"end":{"line":317,"column":64}},"40":{"start":{"line":330,"column":8},"end":{"line":330,"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":189,"type":"if","locations":[{"start":{"line":189,"column":8},"end":{"line":189,"column":8}},{"start":{"line":189,"column":8},"end":{"line":189,"column":8}}]},"6":{"line":207,"type":"if","locations":[{"start":{"line":207,"column":8},"end":{"line":207,"column":8}},{"start":{"line":207,"column":8},"end":{"line":207,"column":8}}]},"7":{"line":219,"type":"if","locations":[{"start":{"line":219,"column":70},"end":{"line":219,"column":70}},{"start":{"line":219,"column":70},"end":{"line":219,"column":70}}]},"8":{"line":220,"type":"if","locations":[{"start":{"line":220,"column":75},"end":{"line":220,"column":75}},{"start":{"line":220,"column":75},"end":{"line":220,"column":75}}]},"9":{"line":222,"type":"if","locations":[{"start":{"line":222,"column":77},"end":{"line":222,"column":77}},{"start":{"line":222,"column":77},"end":{"line":222,"column":77}}]},"10":{"line":224,"type":"if","locations":[{"start":{"line":224,"column":88},"end":{"line":224,"column":88}},{"start":{"line":224,"column":88},"end":{"line":224,"column":88}}]}}}, +"contracts/modules/3_CMTATBaseRuleEngine.sol":{"l":{"47":5167,"64":5167,"83":5167,"86":5167,"89":5167,"91":5167,"94":5167,"102":5167,"103":5167,"105":5167,"112":5167,"119":5167,"134":958,"135":863,"145":1600,"146":1600,"147":532,"149":1068,"162":215,"163":215,"164":38,"166":177,"183":7858,"184":7763},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol","s":{"1":5167,"2":5167,"3":5167,"4":5167,"5":5167,"6":5167,"7":5167,"8":5167,"9":5167,"10":5167,"11":5167,"12":5167,"13":958,"14":863,"15":1600,"16":1600,"17":532,"18":1068,"19":215,"20":215,"21":38,"22":177,"23":7858,"24":7763},"b":{"1":[5167,4],"2":[5167,0],"3":[5167,0],"4":[5167,0],"5":[5167,0],"6":[5167,0],"7":[532,1068],"8":[38,177],"9":[636,39],"10":[259,19],"11":[688,57],"12":[367,3]},"f":{"1":5167,"2":5167,"3":5167,"4":5167,"5":5167,"6":5167,"7":958,"8":1600,"9":215,"10":636,"11":259,"12":688,"13":367,"14":7858},"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":131,"loc":{"start":{"line":131,"column":4},"end":{"line":136,"column":4}}},"8":{"name":"canTransfer","line":140,"loc":{"start":{"line":140,"column":4},"end":{"line":151,"column":4}}},"9":{"name":"canTransferFrom","line":156,"loc":{"start":{"line":156,"column":3},"end":{"line":168,"column":4}}},"10":{"name":"_authorizePause","line":174,"loc":{"start":{"line":174,"column":4},"end":{"line":174,"column":92}}},"11":{"name":"_authorizeDeactivate","line":175,"loc":{"start":{"line":175,"column":4},"end":{"line":175,"column":104}}},"12":{"name":"_authorizeFreeze","line":177,"loc":{"start":{"line":177,"column":4},"end":{"line":177,"column":101}}},"13":{"name":"_authorizeRuleEngineManagement","line":179,"loc":{"start":{"line":179,"column":4},"end":{"line":179,"column":129}}},"14":{"name":"_checkTransferred","line":182,"loc":{"start":{"line":182,"column":4},"end":{"line":185,"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":134,"column":8},"end":{"line":134,"column":76}},"14":{"start":{"line":135,"column":8},"end":{"line":135,"column":55}},"15":{"start":{"line":145,"column":8},"end":{"line":145,"column":90}},"16":{"start":{"line":146,"column":8},"end":{"line":146,"column":6145}},"17":{"start":{"line":147,"column":12},"end":{"line":147,"column":24}},"18":{"start":{"line":149,"column":12},"end":{"line":149,"column":74}},"19":{"start":{"line":162,"column":8},"end":{"line":162,"column":89}},"20":{"start":{"line":163,"column":8},"end":{"line":163,"column":6653}},"21":{"start":{"line":164,"column":12},"end":{"line":164,"column":24}},"22":{"start":{"line":166,"column":12},"end":{"line":166,"column":87}},"23":{"start":{"line":183,"column":8},"end":{"line":183,"column":66}},"24":{"start":{"line":184,"column":8},"end":{"line":184,"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":146,"type":"if","locations":[{"start":{"line":146,"column":8},"end":{"line":146,"column":8}},{"start":{"line":146,"column":8},"end":{"line":146,"column":8}}]},"8":{"line":163,"type":"if","locations":[{"start":{"line":163,"column":8},"end":{"line":163,"column":8}},{"start":{"line":163,"column":8},"end":{"line":163,"column":8}}]},"9":{"line":174,"type":"if","locations":[{"start":{"line":174,"column":70},"end":{"line":174,"column":70}},{"start":{"line":174,"column":70},"end":{"line":174,"column":70}}]},"10":{"line":175,"type":"if","locations":[{"start":{"line":175,"column":75},"end":{"line":175,"column":75}},{"start":{"line":175,"column":75},"end":{"line":175,"column":75}}]},"11":{"line":177,"type":"if","locations":[{"start":{"line":177,"column":77},"end":{"line":177,"column":77}},{"start":{"line":177,"column":77},"end":{"line":177,"column":77}}]},"12":{"line":179,"type":"if","locations":[{"start":{"line":179,"column":100},"end":{"line":179,"column":100}},{"start":{"line":179,"column":100},"end":{"line":179,"column":100}}]}}}, +"contracts/modules/4_CMTATBaseDebt.sol":{"l":{"19":136,"25":82,"31":44,"37":4,"43":12,"49":12,"55":1326},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseDebt.sol","s":{"1":136,"2":82,"3":44,"4":4,"5":12,"6":12,"7":1326},"b":{"1":[12,12],"2":[98,3]},"f":{"1":136,"2":82,"3":44,"4":4,"5":12,"6":12,"7":1326,"8":12,"9":98},"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":139,"35":44,"37":95,"50":1272,"62":179,"78":49,"99":339,"100":339,"101":88,"103":251},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC1404.sol","s":{"1":139,"2":44,"3":95,"4":1272,"5":179,"6":49,"7":339,"8":339,"9":88,"10":251},"b":{"1":[44,95],"2":[2,2],"3":[2,26],"4":[88,251]},"f":{"1":139,"2":1272,"3":179,"4":49,"5":339},"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":"supportsInterface","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":82,"column":4}}},"5":{"name":"_detectTransferRestriction","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":104,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1453}},"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":78,"column":8},"end":{"line":78,"column":3145}},"7":{"start":{"line":99,"column":8},"end":{"line":99,"column":59}},"8":{"start":{"line":100,"column":8},"end":{"line":100,"column":4213}},"9":{"start":{"line":101,"column":12},"end":{"line":101,"column":110}},"10":{"start":{"line":103,"column":8},"end":{"line":103,"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":79,"type":"cond-expr","locations":[{"start":{"line":79,"column":12},"end":{"line":79,"column":52}},{"start":{"line":80,"column":12},"end":{"line":80,"column":77}}]},"3":{"line":79,"type":"cond-expr","locations":[{"start":{"line":79,"column":12},"end":{"line":80,"column":77}},{"start":{"line":81,"column":12},"end":{"line":81,"column":47}}]},"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}}]}}}, +"contracts/modules/5_CMTATBaseERC20CrossChain.sol":{"l":{"26":822,"29":302,"44":223,"59":15,"67":67,"74":49,"78":73,"91":4842,"100":863,"109":222,"130":206},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol","s":{"1":822,"2":302,"3":223,"4":15,"5":67,"6":49,"7":73,"8":4842,"9":863,"10":222,"11":206},"b":{"1":[24,30],"2":[36,12],"3":[206,48],"4":[84,12],"5":[60,24],"6":[72,12],"7":[48,24]},"f":{"1":822,"2":302,"3":223,"4":15,"5":67,"6":49,"7":73,"8":4842,"9":863,"10":222,"11":36,"12":206,"13":60,"14":48},"fnMap":{"1":{"name":"approve","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":27,"column":4}}},"2":{"name":"transfer","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":30,"column":4}}},"3":{"name":"transferFrom","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":45,"column":4}}},"4":{"name":"decimals","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":60,"column":4}}},"5":{"name":"name","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":68,"column":4}}},"6":{"name":"symbol","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":75,"column":4}}},"7":{"name":"supportsInterface","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":79,"column":4}}},"8":{"name":"_mintOverride","line":89,"loc":{"start":{"line":89,"column":4},"end":{"line":92,"column":4}}},"9":{"name":"_burnOverride","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":101,"column":4}}},"10":{"name":"_minterTransferOverride","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":110,"column":4}}},"11":{"name":"_authorizeCCIPSetAdmin","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":118,"column":106}}},"12":{"name":"_checkTokenBridge","line":129,"loc":{"start":{"line":129,"column":4},"end":{"line":131,"column":4}}},"13":{"name":"_authorizeBurnFrom","line":138,"loc":{"start":{"line":138,"column":4},"end":{"line":138,"column":124}}},"14":{"name":"_authorizeSelfBurn","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":145,"column":124}}}},"statementMap":{"1":{"start":{"line":26,"column":8},"end":{"line":26,"column":58}},"2":{"start":{"line":29,"column":9},"end":{"line":29,"column":51}},"3":{"start":{"line":44,"column":8},"end":{"line":44,"column":60}},"4":{"start":{"line":59,"column":8},"end":{"line":59,"column":41}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":37}},"6":{"start":{"line":74,"column":8},"end":{"line":74,"column":39}},"7":{"start":{"line":78,"column":8},"end":{"line":78,"column":121}},"8":{"start":{"line":91,"column":8},"end":{"line":91,"column":52}},"9":{"start":{"line":100,"column":8},"end":{"line":100,"column":52}},"10":{"start":{"line":109,"column":8},"end":{"line":109,"column":63}},"11":{"start":{"line":130,"column":8},"end":{"line":130,"column":68}}},"branchMap":{"1":{"line":78,"type":"cond-expr","locations":[{"start":{"line":78,"column":16},"end":{"line":78,"column":68}},{"start":{"line":78,"column":72},"end":{"line":78,"column":120}}]},"2":{"line":118,"type":"if","locations":[{"start":{"line":118,"column":76},"end":{"line":118,"column":76}},{"start":{"line":118,"column":76},"end":{"line":118,"column":76}}]},"3":{"line":129,"type":"if","locations":[{"start":{"line":129,"column":96},"end":{"line":129,"column":96}},{"start":{"line":129,"column":96},"end":{"line":129,"column":96}}]},"4":{"line":138,"type":"if","locations":[{"start":{"line":138,"column":83},"end":{"line":138,"column":83}},{"start":{"line":138,"column":83},"end":{"line":138,"column":83}}]},"5":{"line":138,"type":"if","locations":[{"start":{"line":138,"column":110},"end":{"line":138,"column":110}},{"start":{"line":138,"column":110},"end":{"line":138,"column":110}}]},"6":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":83},"end":{"line":145,"column":83}},{"start":{"line":145,"column":83},"end":{"line":145,"column":83}}]},"7":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":110},"end":{"line":145,"column":110}},{"start":{"line":145,"column":110},"end":{"line":145,"column":110}}]}}}, +"contracts/modules/6_CMTATBaseDebtEngine.sol":{"l":{"25":978,"31":58,"37":33,"43":102,"49":3,"55":9,"61":9},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseDebtEngine.sol","s":{"1":978,"2":58,"3":33,"4":102,"5":3,"6":9,"7":9},"b":{"1":[15,3],"2":[50,2]},"f":{"1":978,"2":58,"3":33,"4":102,"5":3,"6":9,"7":9,"8":15,"9":50},"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":500,"28":500,"29":500,"30":500,"56":22,"57":16,"71":114,"81":30,"97":26,"111":2,"124":26,"137":10},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol","s":{"1":500,"2":500,"3":500,"4":500,"5":22,"6":16,"7":114,"8":30,"9":26,"10":2,"11":26,"12":10},"b":{"1":[500,0]},"f":{"1":500,"2":22,"3":114,"4":30,"5":26,"6":2,"7":26,"8":10},"fnMap":{"1":{"name":"__CMTAT_openzeppelin_init_unchained","line":26,"loc":{"start":{"line":24,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"permit","line":47,"loc":{"start":{"line":47,"column":4},"end":{"line":58,"column":4}}},"3":{"name":"approve","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":72,"column":4}}},"4":{"name":"transfer","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":82,"column":4}}},"5":{"name":"transferFrom","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":98,"column":4}}},"6":{"name":"decimals","line":104,"loc":{"start":{"line":104,"column":4},"end":{"line":112,"column":4}}},"7":{"name":"name","line":117,"loc":{"start":{"line":117,"column":4},"end":{"line":125,"column":4}}},"8":{"name":"symbol","line":130,"loc":{"start":{"line":130,"column":4},"end":{"line":138,"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":56,"column":8},"end":{"line":56,"column":69}},"6":{"start":{"line":57,"column":8},"end":{"line":57,"column":78}},"7":{"start":{"line":71,"column":8},"end":{"line":71,"column":63}},"8":{"start":{"line":81,"column":8},"end":{"line":81,"column":59}},"9":{"start":{"line":97,"column":8},"end":{"line":97,"column":79}},"10":{"start":{"line":111,"column":8},"end":{"line":111,"column":50}},"11":{"start":{"line":124,"column":8},"end":{"line":124,"column":46}},"12":{"start":{"line":137,"column":8},"end":{"line":137,"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":{"27":20226,"37":20232,"50":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2771.sol","s":{"1":20226,"2":20232,"3":6},"b":{},"f":{"1":20226,"2":20232,"3":6},"fnMap":{"1":{"name":"_msgSender","line":21,"loc":{"start":{"line":21,"column":4},"end":{"line":28,"column":4}}},"2":{"name":"_contextSuffixLength","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":38,"column":4}}},"3":{"name":"_msgData","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":51,"column":4}}}},"statementMap":{"1":{"start":{"line":27,"column":8},"end":{"line":27,"column":53}},"2":{"start":{"line":37,"column":9},"end":{"line":37,"column":64}},"3":{"start":{"line":50,"column":8},"end":{"line":50,"column":51}}},"branchMap":{}}, +"contracts/modules/7_CMTATBaseERC2771Snapshot.sol":{"l":{"24":814,"30":58,"36":26,"42":114,"48":2,"54":6,"60":6,"70":4035,"76":2,"82":4037},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC2771Snapshot.sol","s":{"1":814,"2":58,"3":26,"4":114,"5":2,"6":6,"7":6,"8":4035,"9":2,"10":4037},"b":{"1":[192,4]},"f":{"1":814,"2":58,"3":26,"4":114,"5":2,"6":6,"7":6,"8":4035,"9":2,"10":4037,"11":192},"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":424,"26":98,"37":12904,"45":4,"53":12908,"64":125,"72":114,"80":378,"88":20,"96":18,"104":6,"112":358},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/7_CMTATBaseERC7551Enforcement.sol","s":{"1":424,"2":98,"3":12904,"4":4,"5":12908,"6":125,"7":114,"8":378,"9":20,"10":18,"11":6,"12":358},"b":{},"f":{"1":424,"2":98,"3":12904,"4":4,"5":12908,"6":125,"7":114,"8":378,"9":20,"10":18,"11":6,"12":358},"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":533,"27":533,"42":115,"49":37,"65":28,"75":23,"89":2,"97":6,"104":6,"124":3728,"133":3730,"145":2},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol","s":{"1":533,"2":533,"3":115,"4":37,"5":28,"6":23,"7":2,"8":6,"9":6,"10":3728,"11":3730,"12":2},"b":{"1":[533,0],"2":[6,12]},"f":{"1":533,"2":115,"3":37,"4":28,"5":23,"6":2,"7":6,"8":6,"9":3728,"10":3730,"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":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":4}}},"3":{"name":"transfer","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":50,"column":4}}},"4":{"name":"transferFrom","line":55,"loc":{"start":{"line":55,"column":4},"end":{"line":66,"column":4}}},"5":{"name":"supportsInterface","line":74,"loc":{"start":{"line":74,"column":4},"end":{"line":76,"column":4}}},"6":{"name":"decimals","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":90,"column":4}}},"7":{"name":"name","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":98,"column":4}}},"8":{"name":"symbol","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":105,"column":4}}},"9":{"name":"_msgSender","line":118,"loc":{"start":{"line":118,"column":4},"end":{"line":125,"column":4}}},"10":{"name":"_contextSuffixLength","line":130,"loc":{"start":{"line":130,"column":4},"end":{"line":134,"column":4}}},"11":{"name":"_msgData","line":139,"loc":{"start":{"line":139,"column":4},"end":{"line":146,"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":42,"column":8},"end":{"line":42,"column":66}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":62}},"5":{"start":{"line":65,"column":8},"end":{"line":65,"column":82}},"6":{"start":{"line":75,"column":8},"end":{"line":75,"column":123}},"7":{"start":{"line":89,"column":8},"end":{"line":89,"column":53}},"8":{"start":{"line":97,"column":8},"end":{"line":97,"column":49}},"9":{"start":{"line":104,"column":8},"end":{"line":104,"column":51}},"10":{"start":{"line":124,"column":8},"end":{"line":124,"column":55}},"11":{"start":{"line":133,"column":9},"end":{"line":133,"column":66}},"12":{"start":{"line":145,"column":8},"end":{"line":145,"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":75,"type":"cond-expr","locations":[{"start":{"line":75,"column":15},"end":{"line":75,"column":63}},{"start":{"line":75,"column":68},"end":{"line":75,"column":122}}]}}}, +"contracts/modules/8_CMTATBaseERC7551.sol":{"l":{"20":22},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC7551.sol","s":{"1":22},"b":{},"f":{"1":22},"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/8_CMTATBaseHolderList.sol":{"l":{"38":8,"49":0,"60":0,"72":0,"83":0,"94":0,"102":0,"116":114,"130":372,"141":0,"152":372},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseHolderList.sol","s":{"1":8,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":114,"9":372,"10":0,"11":372},"b":{"1":[0,0]},"f":{"1":8,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":114,"9":372,"10":0,"11":372},"fnMap":{"1":{"name":"transfer","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"transferFrom","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":50,"column":4}}},"3":{"name":"approve","line":55,"loc":{"start":{"line":55,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"name","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":73,"column":4}}},"5":{"name":"symbol","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":84,"column":4}}},"6":{"name":"decimals","line":89,"loc":{"start":{"line":89,"column":4},"end":{"line":95,"column":4}}},"7":{"name":"supportsInterface","line":97,"loc":{"start":{"line":97,"column":4},"end":{"line":104,"column":4}}},"8":{"name":"_update","line":112,"loc":{"start":{"line":112,"column":4},"end":{"line":117,"column":4}}},"9":{"name":"_msgSender","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":131,"column":4}}},"10":{"name":"_msgData","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":142,"column":4}}},"11":{"name":"_contextSuffixLength","line":147,"loc":{"start":{"line":147,"column":4},"end":{"line":153,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":62}},"2":{"start":{"line":49,"column":8},"end":{"line":49,"column":72}},"3":{"start":{"line":60,"column":8},"end":{"line":60,"column":66}},"4":{"start":{"line":72,"column":8},"end":{"line":72,"column":49}},"5":{"start":{"line":83,"column":8},"end":{"line":83,"column":51}},"6":{"start":{"line":94,"column":8},"end":{"line":94,"column":53}},"7":{"start":{"line":102,"column":8},"end":{"line":102,"column":3606}},"8":{"start":{"line":116,"column":8},"end":{"line":116,"column":48}},"9":{"start":{"line":130,"column":8},"end":{"line":130,"column":55}},"10":{"start":{"line":141,"column":8},"end":{"line":141,"column":53}},"11":{"start":{"line":152,"column":8},"end":{"line":152,"column":65}}},"branchMap":{"1":{"line":102,"type":"cond-expr","locations":[{"start":{"line":102,"column":15},"end":{"line":102,"column":64}},{"start":{"line":103,"column":15},"end":{"line":103,"column":69}}]}}}, +"contracts/modules/internal/AllowlistModuleInternal.sol":{"l":{"30":705,"31":705,"40":326,"41":326,"45":2626,"49":584,"50":580,"51":580,"52":2300,"60":211,"61":211,"70":1580,"71":1580,"79":1667,"80":1667,"87":5069},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol","s":{"1":705,"2":326,"3":326,"4":584,"5":580,"6":580,"7":2300,"8":211,"9":1580,"10":1580,"11":1667,"12":1667},"b":{"1":[705,0]},"f":{"1":705,"2":326,"3":2626,"4":584,"5":211,"6":1580,"7":1667,"8":5069},"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":69,"loc":{"start":{"line":69,"column":4},"end":{"line":72,"column":4}}},"7":{"name":"_isAllowlistEnabled","line":78,"loc":{"start":{"line":78,"column":4},"end":{"line":81,"column":4}}},"8":{"name":"_getAllowlistModuleInternalStorage","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":90,"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":70,"column":8},"end":{"line":70,"column":87}},"10":{"start":{"line":71,"column":8},"end":{"line":71,"column":36}},"11":{"start":{"line":79,"column":8},"end":{"line":79,"column":87}},"12":{"start":{"line":80,"column":8},"end":{"line":80,"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":734,"19":707},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/common/EnforcementModuleLibrary.sol","s":{"1":734,"2":707},"b":{"1":[707,27],"2":[680,27]},"f":{"1":734},"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":719,"35":719,"39":919,"40":75,"42":844,"46":150,"47":100,"48":100,"49":200,"59":18213,"60":18213,"65":19032},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInternal.sol","s":{"1":719,"2":719,"3":919,"4":150,"5":100,"6":100,"7":200,"8":18213,"9":18213},"b":{"1":[75,844]},"f":{"1":719,"2":919,"3":150,"4":18213,"5":19032},"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":58,"loc":{"start":{"line":58,"column":4},"end":{"line":61,"column":4}}},"5":{"name":"_getEnforcementModuleInternalStorage","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":68,"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":59,"column":8},"end":{"line":59,"column":91}},"9":{"start":{"line":60,"column":8},"end":{"line":60,"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":{"32":330,"35":306,"36":258,"37":638,"51":1023},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol","s":{"1":330,"2":306,"3":258,"4":638,"5":1023},"b":{"1":[306,24],"2":[258,48]},"f":{"1":330,"2":1023},"fnMap":{"1":{"name":"_batchBurn","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"_burnOverride","line":47,"loc":{"start":{"line":47,"column":4},"end":{"line":52,"column":4}}}},"statementMap":{"1":{"start":{"line":32,"column":8},"end":{"line":32,"column":70}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":97}},"3":{"start":{"line":36,"column":8},"end":{"line":36,"column":1563}},"4":{"start":{"line":37,"column":13},"end":{"line":37,"column":49}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":45}}},"branchMap":{"1":{"line":32,"type":"if","locations":[{"start":{"line":32,"column":8},"end":{"line":32,"column":8}},{"start":{"line":32,"column":8},"end":{"line":32,"column":8}}]},"2":{"line":35,"type":"if","locations":[{"start":{"line":35,"column":8},"end":{"line":35,"column":8}},{"start":{"line":35,"column":8},"end":{"line":35,"column":8}}]}}}, +"contracts/modules/internal/ERC20EnforcementModuleInternal.sol":{"l":{"41":476,"42":88,"44":388,"45":388,"47":388,"48":88,"49":88,"50":88,"53":278,"54":278,"55":278,"57":22,"59":366,"63":652,"64":30,"66":622,"68":622,"69":622,"71":622,"73":600,"74":600,"78":236,"79":30,"81":206,"82":206,"84":184,"85":184,"86":184,"93":276,"94":276,"95":22,"97":254,"98":254,"100":254,"102":254,"103":232,"105":254,"106":66,"107":66,"108":66,"109":66,"122":298,"123":276,"124":254,"125":44,"129":210,"130":210,"132":44,"133":44,"134":44,"138":44,"140":210,"142":254,"146":878,"150":338,"155":8968,"156":8968,"157":8968,"158":8968,"167":11469,"168":11469,"169":1628,"171":1628,"172":132,"173":66,"175":66,"177":1496,"178":1496,"179":792,"184":10545,"188":13719,"189":13719,"193":440,"194":440,"195":440,"197":440,"198":32,"200":408,"205":15629},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol","s":{"1":476,"2":388,"3":388,"4":388,"5":88,"6":88,"7":300,"8":278,"9":278,"10":366,"11":652,"12":622,"13":622,"14":622,"15":622,"16":600,"17":236,"18":206,"19":206,"20":184,"21":184,"22":276,"23":276,"24":254,"25":254,"26":254,"27":254,"28":254,"29":66,"30":66,"31":298,"32":276,"33":254,"34":44,"35":210,"36":210,"37":44,"38":44,"39":44,"40":210,"41":254,"42":878,"43":338,"44":8968,"45":8968,"46":8968,"47":11469,"48":11469,"49":1628,"50":1628,"51":132,"52":66,"53":66,"54":1496,"55":792,"56":10545,"57":13719,"58":13719,"59":440,"60":440,"61":440,"62":440,"63":32,"64":408},"b":{"1":[88,388],"2":[88,300],"3":[278,22],"4":[30,622],"5":[600,22],"6":[30,206],"7":[184,22],"8":[22,254],"9":[232,22],"10":[66,188],"11":[276,22],"12":[44,210],"13":[44,166],"14":[22,22],"15":[8858,110],"16":[1628,9841],"17":[132,1496],"18":[66,66],"19":[792,704],"20":[32,408]},"f":{"1":476,"2":652,"3":236,"4":276,"5":298,"6":878,"7":338,"8":8968,"9":11469,"10":13719,"11":440,"12":15629},"fnMap":{"1":{"name":"_setFrozenTokens","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"_freezePartialTokens","line":62,"loc":{"start":{"line":62,"column":4},"end":{"line":75,"column":4}}},"3":{"name":"_unfreezePartialTokens","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":87,"column":4}}},"4":{"name":"_unfreezeTokens","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":111,"column":4}}},"5":{"name":"_forcedTransfer","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":143,"column":4}}},"6":{"name":"_freezeTokensEmitEvents","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":147,"column":4}}},"7":{"name":"_unfreezeTokensEmitEvents","line":149,"loc":{"start":{"line":149,"column":4},"end":{"line":151,"column":4}}},"8":{"name":"_checkActiveBalanceAndRevert","line":154,"loc":{"start":{"line":154,"column":4},"end":{"line":159,"column":4}}},"9":{"name":"_checkActiveBalance","line":166,"loc":{"start":{"line":166,"column":4},"end":{"line":185,"column":4}}},"10":{"name":"_getFrozenTokens","line":187,"loc":{"start":{"line":187,"column":4},"end":{"line":190,"column":5}}},"11":{"name":"_getActiveBalanceOf","line":192,"loc":{"start":{"line":192,"column":4},"end":{"line":201,"column":5}}},"12":{"name":"_getEnforcementModuleStorage","line":204,"loc":{"start":{"line":204,"column":4},"end":{"line":208,"column":4}}}},"statementMap":{"1":{"start":{"line":41,"column":8},"end":{"line":41,"column":2167}},"2":{"start":{"line":44,"column":8},"end":{"line":44,"column":80}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":60}},"4":{"start":{"line":47,"column":8},"end":{"line":47,"column":2456}},"5":{"start":{"line":48,"column":13},"end":{"line":48,"column":59}},"6":{"start":{"line":50,"column":13},"end":{"line":50,"column":65}},"7":{"start":{"line":51,"column":15},"end":{"line":51,"column":2682}},"8":{"start":{"line":53,"column":12},"end":{"line":53,"column":58}},"9":{"start":{"line":55,"column":12},"end":{"line":55,"column":62}},"10":{"start":{"line":59,"column":8},"end":{"line":59,"column":19}},"11":{"start":{"line":63,"column":7},"end":{"line":63,"column":3204}},"12":{"start":{"line":66,"column":7},"end":{"line":66,"column":79}},"13":{"start":{"line":68,"column":8},"end":{"line":68,"column":61}},"14":{"start":{"line":69,"column":8},"end":{"line":69,"column":68}},"15":{"start":{"line":71,"column":8},"end":{"line":71,"column":105}},"16":{"start":{"line":74,"column":8},"end":{"line":74,"column":65}},"17":{"start":{"line":78,"column":8},"end":{"line":78,"column":3943}},"18":{"start":{"line":81,"column":8},"end":{"line":81,"column":80}},"19":{"start":{"line":82,"column":8},"end":{"line":82,"column":107}},"20":{"start":{"line":84,"column":8},"end":{"line":84,"column":69}},"21":{"start":{"line":86,"column":8},"end":{"line":86,"column":68}},"22":{"start":{"line":93,"column":8},"end":{"line":93,"column":61}},"23":{"start":{"line":94,"column":8},"end":{"line":94,"column":4705}},"24":{"start":{"line":97,"column":8},"end":{"line":97,"column":80}},"25":{"start":{"line":98,"column":8},"end":{"line":98,"column":60}},"26":{"start":{"line":100,"column":8},"end":{"line":100,"column":29}},"27":{"start":{"line":102,"column":8},"end":{"line":102,"column":5124}},"28":{"start":{"line":105,"column":8},"end":{"line":105,"column":5234}},"29":{"start":{"line":106,"column":12},"end":{"line":106,"column":60}},"30":{"start":{"line":109,"column":12},"end":{"line":109,"column":83}},"31":{"start":{"line":122,"column":8},"end":{"line":122,"column":81}},"32":{"start":{"line":123,"column":8},"end":{"line":123,"column":35}},"33":{"start":{"line":124,"column":8},"end":{"line":124,"column":6304}},"34":{"start":{"line":125,"column":12},"end":{"line":125,"column":46}},"35":{"start":{"line":129,"column":12},"end":{"line":129,"column":58}},"36":{"start":{"line":130,"column":12},"end":{"line":130,"column":6592}},"37":{"start":{"line":132,"column":16},"end":{"line":132,"column":92}},"38":{"start":{"line":134,"column":20},"end":{"line":134,"column":96}},"39":{"start":{"line":138,"column":16},"end":{"line":138,"column":68}},"40":{"start":{"line":140,"column":12},"end":{"line":140,"column":54}},"41":{"start":{"line":142,"column":8},"end":{"line":142,"column":44}},"42":{"start":{"line":146,"column":8},"end":{"line":146,"column":83}},"43":{"start":{"line":150,"column":8},"end":{"line":150,"column":84}},"44":{"start":{"line":155,"column":8},"end":{"line":155,"column":20}},"45":{"start":{"line":156,"column":8},"end":{"line":156,"column":29}},"46":{"start":{"line":158,"column":8},"end":{"line":158,"column":89}},"47":{"start":{"line":167,"column":8},"end":{"line":167,"column":58}},"48":{"start":{"line":168,"column":8},"end":{"line":168,"column":8612}},"49":{"start":{"line":169,"column":12},"end":{"line":169,"column":62}},"50":{"start":{"line":171,"column":12},"end":{"line":171,"column":8792}},"51":{"start":{"line":172,"column":16},"end":{"line":172,"column":8848}},"52":{"start":{"line":173,"column":20},"end":{"line":173,"column":36}},"53":{"start":{"line":175,"column":16},"end":{"line":175,"column":33}},"54":{"start":{"line":178,"column":12},"end":{"line":178,"column":9036}},"55":{"start":{"line":179,"column":19},"end":{"line":179,"column":48}},"56":{"start":{"line":184,"column":8},"end":{"line":184,"column":36}},"57":{"start":{"line":188,"column":8},"end":{"line":188,"column":80}},"58":{"start":{"line":189,"column":8},"end":{"line":189,"column":39}},"59":{"start":{"line":193,"column":8},"end":{"line":193,"column":80}},"60":{"start":{"line":194,"column":8},"end":{"line":194,"column":61}},"61":{"start":{"line":195,"column":8},"end":{"line":195,"column":55}},"62":{"start":{"line":197,"column":8},"end":{"line":197,"column":9956}},"63":{"start":{"line":198,"column":12},"end":{"line":198,"column":20}},"64":{"start":{"line":200,"column":8},"end":{"line":200,"column":37}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":8},"end":{"line":41,"column":8}},{"start":{"line":41,"column":8},"end":{"line":41,"column":8}}]},"2":{"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}}]},"3":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":15},"end":{"line":51,"column":15}},{"start":{"line":51,"column":15},"end":{"line":51,"column":15}}]},"4":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":7},"end":{"line":63,"column":7}},{"start":{"line":63,"column":7},"end":{"line":63,"column":7}}]},"5":{"line":71,"type":"if","locations":[{"start":{"line":71,"column":8},"end":{"line":71,"column":8}},{"start":{"line":71,"column":8},"end":{"line":71,"column":8}}]},"6":{"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}}]},"7":{"line":82,"type":"if","locations":[{"start":{"line":82,"column":8},"end":{"line":82,"column":8}},{"start":{"line":82,"column":8},"end":{"line":82,"column":8}}]},"8":{"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}}]},"9":{"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}}]},"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":122,"type":"if","locations":[{"start":{"line":122,"column":8},"end":{"line":122,"column":8}},{"start":{"line":122,"column":8},"end":{"line":122,"column":8}}]},"12":{"line":124,"type":"if","locations":[{"start":{"line":124,"column":8},"end":{"line":124,"column":8}},{"start":{"line":124,"column":8},"end":{"line":124,"column":8}}]},"13":{"line":130,"type":"if","locations":[{"start":{"line":130,"column":12},"end":{"line":130,"column":12}},{"start":{"line":130,"column":12},"end":{"line":130,"column":12}}]},"14":{"line":132,"type":"if","locations":[{"start":{"line":132,"column":68},"end":{"line":132,"column":83}},{"start":{"line":132,"column":87},"end":{"line":132,"column":91}}]},"15":{"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}}]},"16":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":8},"end":{"line":168,"column":8}},{"start":{"line":168,"column":8},"end":{"line":168,"column":8}}]},"17":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":12},"end":{"line":171,"column":12}},{"start":{"line":171,"column":12},"end":{"line":171,"column":12}}]},"18":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":16},"end":{"line":172,"column":16}},{"start":{"line":172,"column":16},"end":{"line":172,"column":16}}]},"19":{"line":178,"type":"if","locations":[{"start":{"line":178,"column":12},"end":{"line":178,"column":12}},{"start":{"line":178,"column":12},"end":{"line":178,"column":12}}]},"20":{"line":197,"type":"if","locations":[{"start":{"line":197,"column":8},"end":{"line":197,"column":8}},{"start":{"line":197,"column":8},"end":{"line":197,"column":8}}]}}}, +"contracts/modules/internal/ERC20MintModuleInternal.sol":{"l":{"34":780,"37":756,"38":708,"39":1936,"47":262,"48":238,"51":238,"52":190,"53":334,"57":43,"66":6931,"72":211},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol","s":{"1":780,"2":756,"3":708,"4":1936,"5":262,"6":238,"7":238,"8":190,"9":334,"10":43,"11":6931,"12":211},"b":{"1":[756,24],"2":[708,48],"3":[238,24],"4":[190,48]},"f":{"1":780,"2":262,"3":6931,"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":65,"loc":{"start":{"line":65,"column":4},"end":{"line":67,"column":4}}},"4":{"name":"_minterTransferOverride","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":73,"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":66,"column":8},"end":{"line":66,"column":45}},"12":{"start":{"line":72,"column":12},"end":{"line":72,"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":5167,"39":83,"53":9132,"54":9132,"68":447,"69":447,"70":447,"75":9579},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ValidationModuleRuleEngineInternal.sol","s":{"1":5167,"2":83,"3":9132,"4":9132,"5":447,"6":447},"b":{"1":[5167,0],"2":[83,5084]},"f":{"1":5167,"2":9132,"3":447,"4":9579},"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":456,"32":50,"52":1558,"53":34,"56":14,"59":1510,"69":8929,"70":6737,"73":1169,"76":1023,"89":42,"93":12,"95":30,"106":7131,"107":7082,"108":60,"120":1241,"121":1169,"122":84,"140":1464,"143":312,"145":1152,"154":842,"155":48,"157":24,"159":50,"168":1464,"170":460,"172":1004,"186":1013,"187":842,"199":2342,"210":28},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol","s":{"1":456,"2":50,"3":1558,"4":34,"5":1524,"6":14,"7":1510,"8":8929,"9":6737,"10":2192,"11":1169,"12":1023,"13":42,"14":12,"15":30,"16":7131,"17":7082,"18":1241,"19":1169,"20":1464,"21":312,"22":1152,"23":842,"24":794,"25":770,"26":1464,"27":460,"28":1004,"29":1013,"30":842,"31":2342,"32":28},"b":{"1":[34,1524],"2":[14,1510],"3":[6737,2192],"4":[1169,1023],"5":[12,30],"6":[0,12],"7":[60,7022],"8":[84,1085],"9":[312,1152],"10":[24,240],"11":[240,48],"12":[48,794],"13":[24,770],"14":[50,720],"15":[460,1004],"16":[312,148]},"f":{"1":456,"2":50,"3":1558,"4":8929,"5":42,"6":7131,"7":1241,"8":1464,"9":842,"10":1464,"11":1013,"12":2342,"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":46,"loc":{"start":{"line":46,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"_canTransferGenericByModuleAndRevert","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"_canMintBurnByModule","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":96,"column":4}}},"6":{"name":"_canMintByModuleAndRevert","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":110,"column":4}}},"7":{"name":"_canBurnByModuleAndRevert","line":117,"loc":{"start":{"line":117,"column":4},"end":{"line":124,"column":4}}},"8":{"name":"_canTransferisFrozen","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":147,"column":4}}},"9":{"name":"_canTransferisFrozenAndRevert","line":149,"loc":{"start":{"line":149,"column":4},"end":{"line":161,"column":4}}},"10":{"name":"_canTransferStandardByModule","line":163,"loc":{"start":{"line":163,"column":2},"end":{"line":174,"column":4}}},"11":{"name":"_canTransferStandardByModuleAndRevert","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":188,"column":4}}},"12":{"name":"_canSend","line":198,"loc":{"start":{"line":198,"column":4},"end":{"line":200,"column":4}}},"13":{"name":"_canReceive","line":209,"loc":{"start":{"line":209,"column":4},"end":{"line":211,"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":52,"column":8},"end":{"line":52,"column":2058}},"4":{"start":{"line":53,"column":12},"end":{"line":53,"column":43}},"5":{"start":{"line":55,"column":13},"end":{"line":55,"column":2158}},"6":{"start":{"line":56,"column":12},"end":{"line":56,"column":45}},"7":{"start":{"line":59,"column":12},"end":{"line":59,"column":66}},"8":{"start":{"line":69,"column":8},"end":{"line":69,"column":2529}},"9":{"start":{"line":70,"column":13},"end":{"line":70,"column":41}},"10":{"start":{"line":72,"column":13},"end":{"line":72,"column":2628}},"11":{"start":{"line":73,"column":12},"end":{"line":73,"column":42}},"12":{"start":{"line":76,"column":13},"end":{"line":76,"column":68}},"13":{"start":{"line":89,"column":8},"end":{"line":89,"column":3255}},"14":{"start":{"line":93,"column":12},"end":{"line":93,"column":24}},"15":{"start":{"line":95,"column":8},"end":{"line":95,"column":19}},"16":{"start":{"line":106,"column":8},"end":{"line":106,"column":31}},"17":{"start":{"line":107,"column":8},"end":{"line":107,"column":3913}},"18":{"start":{"line":120,"column":8},"end":{"line":120,"column":31}},"19":{"start":{"line":121,"column":8},"end":{"line":121,"column":4338}},"20":{"start":{"line":140,"column":8},"end":{"line":140,"column":5012}},"21":{"start":{"line":143,"column":12},"end":{"line":143,"column":23}},"22":{"start":{"line":145,"column":13},"end":{"line":145,"column":25}},"23":{"start":{"line":154,"column":8},"end":{"line":154,"column":5377}},"24":{"start":{"line":156,"column":15},"end":{"line":156,"column":5481}},"25":{"start":{"line":158,"column":15},"end":{"line":158,"column":5580}},"26":{"start":{"line":168,"column":8},"end":{"line":168,"column":5839}},"27":{"start":{"line":170,"column":12},"end":{"line":170,"column":24}},"28":{"start":{"line":172,"column":13},"end":{"line":172,"column":24}},"29":{"start":{"line":186,"column":8},"end":{"line":186,"column":26}},"30":{"start":{"line":187,"column":8},"end":{"line":187,"column":55}},"31":{"start":{"line":199,"column":8},"end":{"line":199,"column":51}},"32":{"start":{"line":210,"column":8},"end":{"line":210,"column":51}}},"branchMap":{"1":{"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}}]},"2":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":13},"end":{"line":55,"column":13}},{"start":{"line":55,"column":13},"end":{"line":55,"column":13}}]},"3":{"line":69,"type":"if","locations":[{"start":{"line":69,"column":8},"end":{"line":69,"column":8}},{"start":{"line":69,"column":8},"end":{"line":69,"column":8}}]},"4":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":13},"end":{"line":72,"column":13}},{"start":{"line":72,"column":13},"end":{"line":72,"column":13}}]},"5":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":8},"end":{"line":89,"column":8}},{"start":{"line":89,"column":8},"end":{"line":89,"column":8}}]},"6":{"line":89,"type":"cond-expr","locations":[{"start":{"line":89,"column":11},"end":{"line":89,"column":35}},{"start":{"line":89,"column":40},"end":{"line":89,"column":73}}]},"7":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":8},"end":{"line":107,"column":8}},{"start":{"line":107,"column":8},"end":{"line":107,"column":8}}]},"8":{"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}}]},"9":{"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}}]},"10":{"line":140,"type":"cond-expr","locations":[{"start":{"line":140,"column":12},"end":{"line":140,"column":46}},{"start":{"line":141,"column":11},"end":{"line":141,"column":42}}]},"11":{"line":140,"type":"cond-expr","locations":[{"start":{"line":140,"column":12},"end":{"line":141,"column":42}},{"start":{"line":142,"column":11},"end":{"line":142,"column":40}}]},"12":{"line":154,"type":"if","locations":[{"start":{"line":154,"column":8},"end":{"line":154,"column":8}},{"start":{"line":154,"column":8},"end":{"line":154,"column":8}}]},"13":{"line":156,"type":"if","locations":[{"start":{"line":156,"column":15},"end":{"line":156,"column":15}},{"start":{"line":156,"column":15},"end":{"line":156,"column":15}}]},"14":{"line":158,"type":"if","locations":[{"start":{"line":158,"column":15},"end":{"line":158,"column":15}},{"start":{"line":158,"column":15},"end":{"line":158,"column":15}}]},"15":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":8},"end":{"line":168,"column":8}},{"start":{"line":168,"column":8},"end":{"line":168,"column":8}}]},"16":{"line":168,"type":"cond-expr","locations":[{"start":{"line":168,"column":12},"end":{"line":168,"column":50}},{"start":{"line":169,"column":11},"end":{"line":169,"column":30}}]}}}, +"contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol":{"l":{"29":12,"30":6,"32":6,"48":245,"49":184,"50":184,"51":46,"54":199,"69":245,"70":46,"72":199,"77":273,"78":30,"80":243,"86":38,"87":22,"89":16,"98":849,"99":4,"101":845,"109":128,"110":4,"112":124,"121":118,"122":108,"130":118,"131":85,"132":2,"134":2,"136":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol","s":{"1":12,"2":6,"3":6,"4":245,"5":184,"6":184,"7":46,"8":199,"9":245,"10":46,"11":199,"12":273,"13":30,"14":243,"15":38,"16":22,"17":16,"18":849,"19":845,"20":128,"21":124,"22":118,"23":108,"24":118,"25":85,"26":83,"27":81},"b":{"1":[6,6],"2":[184,61],"3":[46,138],"4":[2,24],"5":[24,20],"6":[46,199],"7":[30,243],"8":[22,16],"9":[4,845],"10":[4,124],"11":[85,33],"12":[2,83],"13":[2,81],"14":[6,75]},"f":{"1":12,"2":245,"3":245,"4":273,"5":38,"6":849,"7":128,"8":118,"9":118},"fnMap":{"1":{"name":"_canMintBurnByModule","line":26,"loc":{"start":{"line":26,"column":4},"end":{"line":34,"column":4}}},"2":{"name":"_canTransferStandardByModuleAllowlist","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":55,"column":4}}},"3":{"name":"_canTransferStandardByModule","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":73,"column":4}}},"4":{"name":"_canSend","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":82,"column":4}}},"5":{"name":"_canReceive","line":85,"loc":{"start":{"line":85,"column":4},"end":{"line":91,"column":4}}},"6":{"name":"_canMintByModuleAndRevert","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":103,"column":4}}},"7":{"name":"_canBurnByModuleAndRevert","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":114,"column":4}}},"8":{"name":"_canTransferStandardByModuleAndRevert","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":123,"column":4}}},"9":{"name":"_canTransferStandardByModuleAllowlistAndRevert","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":139,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":1088}},"2":{"start":{"line":30,"column":12},"end":{"line":30,"column":24}},"3":{"start":{"line":32,"column":12},"end":{"line":32,"column":65}},"4":{"start":{"line":48,"column":8},"end":{"line":48,"column":1766}},"5":{"start":{"line":49,"column":12},"end":{"line":49,"column":80}},"6":{"start":{"line":50,"column":12},"end":{"line":50,"column":1891}},"7":{"start":{"line":51,"column":16},"end":{"line":51,"column":27}},"8":{"start":{"line":54,"column":7},"end":{"line":54,"column":19}},"9":{"start":{"line":69,"column":8},"end":{"line":69,"column":2535}},"10":{"start":{"line":70,"column":11},"end":{"line":70,"column":23}},"11":{"start":{"line":72,"column":8},"end":{"line":72,"column":79}},"12":{"start":{"line":77,"column":8},"end":{"line":77,"column":2878}},"13":{"start":{"line":78,"column":12},"end":{"line":78,"column":24}},"14":{"start":{"line":80,"column":12},"end":{"line":80,"column":53}},"15":{"start":{"line":86,"column":8},"end":{"line":86,"column":3208}},"16":{"start":{"line":87,"column":12},"end":{"line":87,"column":24}},"17":{"start":{"line":89,"column":12},"end":{"line":89,"column":56}},"18":{"start":{"line":98,"column":8},"end":{"line":98,"column":3605}},"19":{"start":{"line":101,"column":12},"end":{"line":101,"column":57}},"20":{"start":{"line":109,"column":8},"end":{"line":109,"column":3956}},"21":{"start":{"line":112,"column":12},"end":{"line":112,"column":59}},"22":{"start":{"line":121,"column":8},"end":{"line":121,"column":72}},"23":{"start":{"line":122,"column":8},"end":{"line":122,"column":80}},"24":{"start":{"line":130,"column":8},"end":{"line":130,"column":4652}},"25":{"start":{"line":131,"column":12},"end":{"line":131,"column":4695}},"26":{"start":{"line":133,"column":19},"end":{"line":133,"column":4820}},"27":{"start":{"line":135,"column":19},"end":{"line":135,"column":4915}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":8},"end":{"line":29,"column":8}},{"start":{"line":29,"column":8},"end":{"line":29,"column":8}}]},"2":{"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}}]},"3":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":12},"end":{"line":50,"column":12}},{"start":{"line":50,"column":12},"end":{"line":50,"column":12}}]},"4":{"line":50,"type":"cond-expr","locations":[{"start":{"line":50,"column":16},"end":{"line":50,"column":27}},{"start":{"line":50,"column":32},"end":{"line":50,"column":51}}]},"5":{"line":50,"type":"cond-expr","locations":[{"start":{"line":50,"column":16},"end":{"line":50,"column":51}},{"start":{"line":50,"column":56},"end":{"line":50,"column":73}}]},"6":{"line":69,"type":"if","locations":[{"start":{"line":69,"column":8},"end":{"line":69,"column":8}},{"start":{"line":69,"column":8},"end":{"line":69,"column":8}}]},"7":{"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}}]},"8":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":8},"end":{"line":86,"column":8}},{"start":{"line":86,"column":8},"end":{"line":86,"column":8}}]},"9":{"line":98,"type":"if","locations":[{"start":{"line":98,"column":8},"end":{"line":98,"column":8}},{"start":{"line":98,"column":8},"end":{"line":98,"column":8}}]},"10":{"line":109,"type":"if","locations":[{"start":{"line":109,"column":8},"end":{"line":109,"column":8}},{"start":{"line":109,"column":8},"end":{"line":109,"column":8}}]},"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":131,"type":"if","locations":[{"start":{"line":131,"column":12},"end":{"line":131,"column":12}},{"start":{"line":131,"column":12},"end":{"line":131,"column":12}}]},"13":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":19},"end":{"line":133,"column":19}},{"start":{"line":133,"column":19},"end":{"line":133,"column":19}}]},"14":{"line":135,"type":"if","locations":[{"start":{"line":135,"column":19},"end":{"line":135,"column":19}},{"start":{"line":135,"column":19},"end":{"line":135,"column":19}}]}}}, +"contracts/modules/wrapper/core/EnforcementModule.sol":{"l":{"27":944,"28":869,"42":347,"60":372,"71":150,"79":18213,"87":919,"88":844},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/EnforcementModule.sol","s":{"1":944,"2":347,"3":372,"4":150,"5":18213,"6":919,"7":844},"b":{"1":[347,0],"2":[372,50],"3":[150,25]},"f":{"1":944,"2":347,"3":372,"4":150,"5":18213,"6":919},"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":{"38":6188,"39":6188,"59":188,"61":116,"64":116,"67":116,"77":24,"78":24,"85":48,"86":48,"87":24,"89":48,"97":6212},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol","s":{"1":6188,"2":188,"3":116,"4":116,"5":116,"6":24,"7":24,"8":48},"b":{"1":[6188,0],"2":[116,0]},"f":{"1":6188,"2":188,"3":24,"4":48,"5":6212},"fnMap":{"1":{"name":"__ERC20BaseModule_init_unchained","line":37,"loc":{"start":{"line":35,"column":4},"end":{"line":40,"column":4}}},"2":{"name":"transferFrom","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":68,"column":4}}},"3":{"name":"decimals","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":79,"column":4}}},"4":{"name":"batchBalanceOf","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":90,"column":4}}},"5":{"name":"_getERC20BaseModuleStorage","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":100,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":71}},"2":{"start":{"line":59,"column":8},"end":{"line":59,"column":68}},"3":{"start":{"line":61,"column":8},"end":{"line":61,"column":2397}},"4":{"start":{"line":64,"column":12},"end":{"line":64,"column":49}},"5":{"start":{"line":67,"column":8},"end":{"line":67,"column":21}},"6":{"start":{"line":77,"column":8},"end":{"line":77,"column":71}},"7":{"start":{"line":78,"column":8},"end":{"line":78,"column":26}},"8":{"start":{"line":86,"column":8},"end":{"line":86,"column":3310}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":23},"end":{"line":37,"column":23}},{"start":{"line":37,"column":23},"end":{"line":37,"column":23}}]},"2":{"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}}]}}}, +"contracts/modules/wrapper/core/ERC20BurnModule.sol":{"l":{"26":841,"27":745,"45":271,"57":144,"73":254,"74":91,"87":76,"88":74,"100":415,"101":298},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol","s":{"1":841,"2":271,"3":144,"4":254,"5":91,"6":76,"7":74,"8":415,"9":298},"b":{"1":[271,72],"2":[144,0],"3":[254,24],"4":[76,0]},"f":{"1":841,"2":271,"3":144,"4":254,"5":76,"6":415},"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":6197,"29":6125,"44":148,"60":4935,"76":780,"77":633,"89":262,"96":5083,"97":5008},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20MintModule.sol","s":{"1":6197,"2":148,"3":4935,"4":780,"5":633,"6":262,"7":5083,"8":5008},"b":{"1":[148,24],"2":[4935,24],"3":[780,24],"4":[262,0]},"f":{"1":6197,"2":148,"3":4935,"4":780,"5":262,"6":5083},"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":841,"42":790,"46":344,"47":319,"60":713,"69":77,"70":77,"71":50,"86":319,"87":294,"88":294,"89":25,"91":269,"92":269,"100":5018,"107":8717,"108":8717,"119":8372,"120":121,"126":9088},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/PauseModule.sol","s":{"1":841,"2":344,"3":713,"4":77,"5":77,"6":50,"7":319,"8":294,"9":294,"10":269,"11":5018,"12":8717,"13":8717,"14":8372},"b":{"1":[713,26],"2":[77,25],"3":[50,27],"4":[319,25],"5":[25,269],"6":[121,8251]},"f":{"1":841,"2":344,"3":713,"4":77,"5":319,"6":5018,"7":8717,"8":8372,"9":9088},"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":3399}},"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":4467}}},"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/TokenAttributeModule.sol":{"l":{"39":98,"40":50,"51":6188,"52":6188,"53":6188,"65":94,"66":94,"74":76,"75":76,"92":26,"93":26,"94":26,"101":24,"102":24,"103":24,"114":6408},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/TokenAttributeModule.sol","s":{"1":98,"2":6188,"3":94,"4":94,"5":76,"6":76,"7":26,"8":26,"9":24,"10":24},"b":{"1":[6188,0],"2":[26,24],"3":[24,24]},"f":{"1":98,"2":6188,"3":94,"4":76,"5":26,"6":24,"7":6408},"fnMap":{"1":{"name":"onlyTokenAttributeManager","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"__TokenAttributeModule_init_unchained","line":50,"loc":{"start":{"line":47,"column":4},"end":{"line":54,"column":4}}},"3":{"name":"name","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":67,"column":4}}},"4":{"name":"symbol","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"setName","line":91,"loc":{"start":{"line":91,"column":4},"end":{"line":95,"column":4}}},"6":{"name":"setSymbol","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":104,"column":4}}},"7":{"name":"_getTokenAttributeModuleStorage","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":117,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":43}},"2":{"start":{"line":51,"column":8},"end":{"line":51,"column":81}},"3":{"start":{"line":65,"column":8},"end":{"line":65,"column":81}},"4":{"start":{"line":66,"column":8},"end":{"line":66,"column":22}},"5":{"start":{"line":74,"column":8},"end":{"line":74,"column":81}},"6":{"start":{"line":75,"column":8},"end":{"line":75,"column":24}},"7":{"start":{"line":92,"column":8},"end":{"line":92,"column":81}},"8":{"start":{"line":94,"column":8},"end":{"line":94,"column":31}},"9":{"start":{"line":101,"column":8},"end":{"line":101,"column":81}},"10":{"start":{"line":103,"column":8},"end":{"line":103,"column":37}}},"branchMap":{"1":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":23},"end":{"line":50,"column":23}},{"start":{"line":50,"column":23},"end":{"line":50,"column":23}}]},"2":{"line":91,"type":"if","locations":[{"start":{"line":91,"column":87},"end":{"line":91,"column":87}},{"start":{"line":91,"column":87},"end":{"line":91,"column":87}}]},"3":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":91},"end":{"line":100,"column":91}},{"start":{"line":100,"column":91},"end":{"line":100,"column":91}}]}}}, +"contracts/modules/wrapper/core/ValidationModuleCore.sol":{"l":{"25":1346,"34":212,"54":1558},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol","s":{"1":1346,"2":212,"3":1558},"b":{},"f":{"1":1346,"2":212,"3":1558},"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":48,"loc":{"start":{"line":48,"column":4},"end":{"line":55,"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":54,"column":8},"end":{"line":54,"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/extensions/DocumentERC1643Module.sol":{"l":{"24":446,"25":400,"29":152,"30":152,"34":49,"38":297,"39":272,"40":272,"41":272,"42":272,"43":272,"45":272,"46":248,"47":248,"50":272,"54":103,"55":103,"56":103,"58":78,"59":78,"60":78,"62":78,"63":26,"64":26,"65":26,"68":78,"69":78,"70":78,"72":78,"78":576},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol","s":{"1":446,"2":152,"3":152,"4":49,"5":297,"6":272,"7":272,"8":272,"9":248,"10":272,"11":103,"12":103,"13":103,"14":78,"15":78,"16":78,"17":78,"18":26,"19":78,"20":78},"b":{"1":[297,23],"2":[272,25],"3":[248,24],"4":[103,23],"5":[78,25],"6":[26,52]},"f":{"1":446,"2":152,"3":49,"4":297,"5":103,"6":576},"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":31,"column":4}}},"3":{"name":"getAllDocuments","line":33,"loc":{"start":{"line":33,"column":4},"end":{"line":35,"column":4}}},"4":{"name":"setDocument","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":51,"column":4}}},"5":{"name":"removeDocument","line":53,"loc":{"start":{"line":53,"column":4},"end":{"line":73,"column":4}}},"6":{"name":"_getDocumentERC1643ModuleStorage","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":81,"column":4}}}},"statementMap":{"1":{"start":{"line":24,"column":8},"end":{"line":24,"column":37}},"2":{"start":{"line":29,"column":8},"end":{"line":29,"column":87}},"3":{"start":{"line":30,"column":8},"end":{"line":30,"column":75}},"4":{"start":{"line":34,"column":8},"end":{"line":34,"column":64}},"5":{"start":{"line":38,"column":8},"end":{"line":38,"column":56}},"6":{"start":{"line":39,"column":8},"end":{"line":39,"column":83}},"7":{"start":{"line":40,"column":8},"end":{"line":40,"column":54}},"8":{"start":{"line":45,"column":8},"end":{"line":45,"column":1952}},"9":{"start":{"line":46,"column":12},"end":{"line":46,"column":38}},"10":{"start":{"line":50,"column":8},"end":{"line":50,"column":53}},"11":{"start":{"line":54,"column":8},"end":{"line":54,"column":83}},"12":{"start":{"line":55,"column":8},"end":{"line":55,"column":42}},"13":{"start":{"line":56,"column":8},"end":{"line":56,"column":50}},"14":{"start":{"line":58,"column":8},"end":{"line":58,"column":53}},"15":{"start":{"line":59,"column":8},"end":{"line":59,"column":31}},"16":{"start":{"line":60,"column":8},"end":{"line":60,"column":55}},"17":{"start":{"line":62,"column":8},"end":{"line":62,"column":2584}},"18":{"start":{"line":63,"column":12},"end":{"line":63,"column":59}},"19":{"start":{"line":68,"column":8},"end":{"line":68,"column":29}},"20":{"start":{"line":72,"column":8},"end":{"line":72,"column":71}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":106},"end":{"line":37,"column":106}},{"start":{"line":37,"column":106},"end":{"line":37,"column":106}}]},"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}}]},"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}}]},"4":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":66},"end":{"line":53,"column":66}},{"start":{"line":53,"column":66},"end":{"line":53,"column":66}}]},"5":{"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}}]},"6":{"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}}]}}}, +"contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol":{"l":{"26":1430,"27":1364,"32":342,"33":298,"44":2062,"55":200,"56":164,"66":596,"76":204,"87":476,"95":878,"96":878,"100":338,"101":338},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol","s":{"1":1430,"2":342,"3":2062,"4":200,"5":164,"6":596,"7":204,"8":476,"9":878,"10":878,"11":338,"12":338},"b":{"1":[200,44],"2":[596,22],"3":[204,22],"4":[476,22]},"f":{"1":1430,"2":342,"3":2062,"4":200,"5":596,"6":204,"7":476,"8":878,"9":338},"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":168,"33":86,"45":5942,"47":5942,"49":5942,"51":5942,"68":26,"69":26,"79":26,"92":28,"93":28,"101":130,"102":130,"109":118,"110":118,"117":108,"118":108,"125":26,"126":26,"137":4,"138":4,"139":4,"140":4,"142":4,"148":5968,"149":5968,"154":5968,"156":5968,"157":5968,"158":5968,"160":5968,"164":5970,"165":5970,"173":6382},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ExtraInformationModule.sol","s":{"1":168,"2":5942,"3":5942,"4":5942,"5":5942,"6":26,"7":26,"8":26,"9":28,"10":28,"11":130,"12":130,"13":118,"14":118,"15":108,"16":108,"17":26,"18":26,"19":4,"20":4,"21":5968,"22":5968,"23":5970},"b":{"1":[5942,0],"2":[26,26],"3":[26,26],"4":[28,26]},"f":{"1":168,"2":5942,"3":26,"4":26,"5":28,"6":130,"7":118,"8":108,"9":26,"10":4,"11":5968,"12":5968,"13":5970,"14":6382},"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":"_setTermsDocument","line":136,"loc":{"start":{"line":136,"column":4},"end":{"line":143,"column":4}}},"11":{"name":"_setTokenId","line":145,"loc":{"start":{"line":145,"column":4},"end":{"line":150,"column":4}}},"12":{"name":"_setTerms","line":152,"loc":{"start":{"line":152,"column":4},"end":{"line":161,"column":4}}},"13":{"name":"_setInformation","line":163,"loc":{"start":{"line":163,"column":4},"end":{"line":166,"column":4}}},"14":{"name":"_getExtraInformationModuleStorage","line":172,"loc":{"start":{"line":172,"column":4},"end":{"line":176,"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":137,"column":8},"end":{"line":137,"column":85}},"20":{"start":{"line":142,"column":8},"end":{"line":142,"column":28}},"21":{"start":{"line":149,"column":8},"end":{"line":149,"column":40}},"22":{"start":{"line":160,"column":8},"end":{"line":160,"column":28}},"23":{"start":{"line":165,"column":8},"end":{"line":165,"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":349,"31":340,"45":27,"46":18,"47":18,"65":340,"66":340,"67":331,"77":3476,"78":3476,"87":349,"88":349,"95":3834},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/SnapshotEngineModule.sol","s":{"1":349,"2":27,"3":18,"4":18,"5":340,"6":340,"7":331,"8":3476,"9":3476,"10":349},"b":{"1":[27,0],"2":[18,9],"3":[340,9],"4":[331,9]},"f":{"1":349,"2":27,"3":340,"4":3476,"5":349,"6":3834},"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":{"42":1150,"43":128,"45":1022,"46":972,"47":28,"49":944,"50":52},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol","s":{"1":1150,"2":128,"3":1022,"4":972,"5":944},"b":{"1":[128,1022],"2":[28,944],"3":[52,892]},"f":{"1":1150},"fnMap":{"1":{"name":"_canAuthorizeAllowanceByModuleAndRevert","line":36,"loc":{"start":{"line":36,"column":4},"end":{"line":52,"column":4}}}},"statementMap":{"1":{"start":{"line":42,"column":8},"end":{"line":42,"column":1829}},"2":{"start":{"line":43,"column":12},"end":{"line":43,"column":18}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":26}},"4":{"start":{"line":46,"column":8},"end":{"line":46,"column":1914}},"5":{"start":{"line":49,"column":8},"end":{"line":49,"column":2001}}},"branchMap":{"1":{"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}}]},"2":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":8},"end":{"line":46,"column":8}},{"start":{"line":46,"column":8},"end":{"line":46,"column":8}}]},"3":{"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}}]}}}, +"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol":{"l":{"80":95,"81":95,"82":6,"87":22,"92":13,"97":11,"102":11,"107":11,"109":18,"111":3,"131":190,"132":190,"133":190,"134":112,"136":42,"138":36,"163":160,"164":160,"165":11,"167":149,"168":149,"169":92,"171":24,"173":33,"191":251,"192":39,"194":55,"196":11,"198":11,"201":135},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol","s":{"1":95,"2":95,"3":6,"4":89,"5":22,"6":67,"7":13,"8":54,"9":11,"10":43,"11":11,"12":32,"13":11,"14":21,"15":18,"16":3,"17":190,"18":190,"19":190,"20":112,"21":78,"22":42,"23":36,"24":160,"25":160,"26":11,"27":149,"28":149,"29":92,"30":57,"31":24,"32":33,"33":251,"34":39,"35":212,"36":55,"37":157,"38":11,"39":146,"40":11,"41":135},"b":{"1":[6,89],"2":[22,67],"3":[13,54],"4":[11,43],"5":[11,32],"6":[11,21],"7":[18,3],"8":[112,78],"9":[42,36],"10":[11,149],"11":[92,57],"12":[24,33],"13":[39,212],"14":[55,157],"15":[11,146],"16":[11,135]},"f":{"1":95,"2":190,"3":160,"4":251},"fnMap":{"1":{"name":"messageForTransferRestriction","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":113,"column":4}}},"2":{"name":"detectTransferRestriction","line":126,"loc":{"start":{"line":126,"column":4},"end":{"line":140,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":176,"column":4}}},"4":{"name":"_detectTransferRestriction","line":186,"loc":{"start":{"line":186,"column":4},"end":{"line":203,"column":4}}}},"statementMap":{"1":{"start":{"line":80,"column":10},"end":{"line":80,"column":84}},"2":{"start":{"line":81,"column":8},"end":{"line":81,"column":3926}},"3":{"start":{"line":82,"column":12},"end":{"line":82,"column":35}},"4":{"start":{"line":83,"column":15},"end":{"line":83,"column":4057}},"5":{"start":{"line":87,"column":12},"end":{"line":87,"column":48}},"6":{"start":{"line":88,"column":15},"end":{"line":88,"column":4248}},"7":{"start":{"line":92,"column":12},"end":{"line":92,"column":53}},"8":{"start":{"line":93,"column":15},"end":{"line":93,"column":4449}},"9":{"start":{"line":97,"column":12},"end":{"line":97,"column":53}},"10":{"start":{"line":98,"column":15},"end":{"line":98,"column":4650}},"11":{"start":{"line":102,"column":12},"end":{"line":102,"column":51}},"12":{"start":{"line":103,"column":16},"end":{"line":103,"column":4848}},"13":{"start":{"line":107,"column":12},"end":{"line":107,"column":56}},"14":{"start":{"line":108,"column":15},"end":{"line":108,"column":5055}},"15":{"start":{"line":109,"column":12},"end":{"line":109,"column":77}},"16":{"start":{"line":111,"column":12},"end":{"line":111,"column":36}},"17":{"start":{"line":131,"column":9},"end":{"line":131,"column":83}},"18":{"start":{"line":132,"column":9},"end":{"line":132,"column":71}},"19":{"start":{"line":133,"column":9},"end":{"line":133,"column":6213}},"20":{"start":{"line":134,"column":12},"end":{"line":134,"column":29}},"21":{"start":{"line":135,"column":16},"end":{"line":135,"column":6333}},"22":{"start":{"line":136,"column":12},"end":{"line":136,"column":73}},"23":{"start":{"line":138,"column":12},"end":{"line":138,"column":71}},"24":{"start":{"line":163,"column":8},"end":{"line":163,"column":82}},"25":{"start":{"line":164,"column":8},"end":{"line":164,"column":7854}},"26":{"start":{"line":165,"column":12},"end":{"line":165,"column":92}},"27":{"start":{"line":167,"column":12},"end":{"line":167,"column":74}},"28":{"start":{"line":168,"column":12},"end":{"line":168,"column":8082}},"29":{"start":{"line":169,"column":16},"end":{"line":169,"column":33}},"30":{"start":{"line":170,"column":19},"end":{"line":170,"column":8210}},"31":{"start":{"line":171,"column":16},"end":{"line":171,"column":90}},"32":{"start":{"line":173,"column":16},"end":{"line":173,"column":75}},"33":{"start":{"line":191,"column":8},"end":{"line":191,"column":8975}},"34":{"start":{"line":192,"column":12},"end":{"line":192,"column":89}},"35":{"start":{"line":193,"column":15},"end":{"line":193,"column":9101}},"36":{"start":{"line":194,"column":12},"end":{"line":194,"column":84}},"37":{"start":{"line":195,"column":15},"end":{"line":195,"column":9218}},"38":{"start":{"line":196,"column":12},"end":{"line":196,"column":89}},"39":{"start":{"line":197,"column":15},"end":{"line":197,"column":9346}},"40":{"start":{"line":198,"column":12},"end":{"line":198,"column":87}},"41":{"start":{"line":201,"column":12},"end":{"line":201,"column":71}}},"branchMap":{"1":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":8},"end":{"line":81,"column":8}},{"start":{"line":81,"column":8},"end":{"line":81,"column":8}}]},"2":{"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}}]},"3":{"line":88,"type":"if","locations":[{"start":{"line":88,"column":15},"end":{"line":88,"column":15}},{"start":{"line":88,"column":15},"end":{"line":88,"column":15}}]},"4":{"line":93,"type":"if","locations":[{"start":{"line":93,"column":15},"end":{"line":93,"column":15}},{"start":{"line":93,"column":15},"end":{"line":93,"column":15}}]},"5":{"line":98,"type":"if","locations":[{"start":{"line":98,"column":15},"end":{"line":98,"column":15}},{"start":{"line":98,"column":15},"end":{"line":98,"column":15}}]},"6":{"line":103,"type":"if","locations":[{"start":{"line":103,"column":16},"end":{"line":103,"column":16}},{"start":{"line":103,"column":16},"end":{"line":103,"column":16}}]},"7":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":15},"end":{"line":108,"column":15}},{"start":{"line":108,"column":15},"end":{"line":108,"column":15}}]},"8":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":9},"end":{"line":133,"column":9}},{"start":{"line":133,"column":9},"end":{"line":133,"column":9}}]},"9":{"line":135,"type":"if","locations":[{"start":{"line":135,"column":16},"end":{"line":135,"column":16}},{"start":{"line":135,"column":16},"end":{"line":135,"column":16}}]},"10":{"line":164,"type":"if","locations":[{"start":{"line":164,"column":8},"end":{"line":164,"column":8}},{"start":{"line":164,"column":8},"end":{"line":164,"column":8}}]},"11":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":12},"end":{"line":168,"column":12}},{"start":{"line":168,"column":12},"end":{"line":168,"column":12}}]},"12":{"line":170,"type":"if","locations":[{"start":{"line":170,"column":19},"end":{"line":170,"column":19}},{"start":{"line":170,"column":19},"end":{"line":170,"column":19}}]},"13":{"line":191,"type":"if","locations":[{"start":{"line":191,"column":8},"end":{"line":191,"column":8}},{"start":{"line":191,"column":8},"end":{"line":191,"column":8}}]},"14":{"line":193,"type":"if","locations":[{"start":{"line":193,"column":15},"end":{"line":193,"column":15}},{"start":{"line":193,"column":15},"end":{"line":193,"column":15}}]},"15":{"line":195,"type":"if","locations":[{"start":{"line":195,"column":15},"end":{"line":195,"column":15}},{"start":{"line":195,"column":15},"end":{"line":195,"column":15}}]},"16":{"line":197,"type":"if","locations":[{"start":{"line":197,"column":15},"end":{"line":197,"column":15}},{"start":{"line":197,"column":15},"end":{"line":197,"column":15}}]}}}, +"contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol":{"l":{"29":370,"30":367,"51":367,"52":364,"64":1068,"77":177,"89":1068,"90":299,"92":769,"102":177,"103":78,"105":99,"115":99,"116":99,"117":30,"119":69,"127":769,"128":769,"129":60,"131":709,"167":7763,"168":7309,"169":7309,"170":733,"189":725,"190":709,"192":16},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol","s":{"1":370,"2":367,"3":364,"4":1068,"5":177,"6":1068,"7":299,"8":769,"9":177,"10":78,"11":99,"12":99,"13":99,"14":30,"15":69,"16":769,"17":769,"18":60,"19":709,"20":7763,"21":7309,"22":7309,"23":733,"24":725,"25":709,"26":16},"b":{"1":[367,3],"2":[364,3],"3":[299,769],"4":[78,99],"5":[30,69],"6":[60,709],"7":[733,6576],"8":[709,16]},"f":{"1":370,"2":367,"3":1068,"4":177,"5":1068,"6":177,"7":99,"8":769,"9":7763,"10":725},"fnMap":{"1":{"name":"onlyRuleEngineManager","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":31,"column":4}}},"2":{"name":"setRuleEngine","line":50,"loc":{"start":{"line":48,"column":4},"end":{"line":53,"column":4}}},"3":{"name":"canTransfer","line":59,"loc":{"start":{"line":59,"column":4},"end":{"line":65,"column":4}}},"4":{"name":"canTransferFrom","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":78,"column":4}}},"5":{"name":"_canTransfer","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":94,"column":4}}},"6":{"name":"_canTransferFrom","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":107,"column":4}}},"7":{"name":"_canTransferFromWithRuleEngine","line":109,"loc":{"start":{"line":109,"column":4},"end":{"line":121,"column":4}}},"8":{"name":"_canTransferWithRuleEngine","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":133,"column":4}}},"9":{"name":"_transferred","line":166,"loc":{"start":{"line":166,"column":4},"end":{"line":172,"column":4}}},"10":{"name":"_callRuleEngineTransferred","line":182,"loc":{"start":{"line":182,"column":4},"end":{"line":194,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":39}},"2":{"start":{"line":51,"column":9},"end":{"line":51,"column":98}},"3":{"start":{"line":52,"column":8},"end":{"line":52,"column":34}},"4":{"start":{"line":64,"column":7},"end":{"line":64,"column":43}},"5":{"start":{"line":77,"column":8},"end":{"line":77,"column":57}},"6":{"start":{"line":89,"column":7},"end":{"line":89,"column":3017}},"7":{"start":{"line":90,"column":12},"end":{"line":90,"column":24}},"8":{"start":{"line":92,"column":12},"end":{"line":92,"column":62}},"9":{"start":{"line":102,"column":8},"end":{"line":102,"column":3372}},"10":{"start":{"line":103,"column":12},"end":{"line":103,"column":24}},"11":{"start":{"line":105,"column":12},"end":{"line":105,"column":75}},"12":{"start":{"line":115,"column":8},"end":{"line":115,"column":46}},"13":{"start":{"line":116,"column":8},"end":{"line":116,"column":3815}},"14":{"start":{"line":117,"column":12},"end":{"line":117,"column":72}},"15":{"start":{"line":119,"column":12},"end":{"line":119,"column":23}},"16":{"start":{"line":127,"column":8},"end":{"line":127,"column":46}},"17":{"start":{"line":128,"column":8},"end":{"line":128,"column":4194}},"18":{"start":{"line":129,"column":12},"end":{"line":129,"column":59}},"19":{"start":{"line":131,"column":12},"end":{"line":131,"column":23}},"20":{"start":{"line":167,"column":8},"end":{"line":167,"column":62}},"21":{"start":{"line":168,"column":8},"end":{"line":168,"column":46}},"22":{"start":{"line":169,"column":8},"end":{"line":169,"column":6631}},"23":{"start":{"line":170,"column":12},"end":{"line":170,"column":76}},"24":{"start":{"line":189,"column":8},"end":{"line":189,"column":7390}},"25":{"start":{"line":190,"column":12},"end":{"line":190,"column":60}},"26":{"start":{"line":192,"column":12},"end":{"line":192,"column":51}}},"branchMap":{"1":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":21}},{"start":{"line":50,"column":21},"end":{"line":50,"column":21}}]},"2":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":9},"end":{"line":51,"column":9}},{"start":{"line":51,"column":9},"end":{"line":51,"column":9}}]},"3":{"line":89,"type":"if","locations":[{"start":{"line":89,"column":7},"end":{"line":89,"column":7}},{"start":{"line":89,"column":7},"end":{"line":89,"column":7}}]},"4":{"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}}]},"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}}]},"6":{"line":128,"type":"if","locations":[{"start":{"line":128,"column":8},"end":{"line":128,"column":8}},{"start":{"line":128,"column":8},"end":{"line":128,"column":8}}]},"7":{"line":169,"type":"if","locations":[{"start":{"line":169,"column":8},"end":{"line":169,"column":8}},{"start":{"line":169,"column":8},"end":{"line":169,"column":8}}]},"8":{"line":189,"type":"if","locations":[{"start":{"line":189,"column":8},"end":{"line":189,"column":8}},{"start":{"line":189,"column":8},"end":{"line":189,"column":8}}]}}}, +"contracts/modules/wrapper/options/AllowlistModule.sol":{"l":{"25":1129,"26":1121,"37":4,"47":322,"57":584,"67":211,"68":211,"77":4,"84":1580,"91":2626,"92":2626},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/AllowlistModule.sol","s":{"1":1129,"2":4,"3":322,"4":584,"5":211,"6":211,"7":4,"8":1580,"9":2626,"10":2626},"b":{"1":[4,2],"2":[322,4],"3":[584,2],"4":[211,0]},"f":{"1":1129,"2":4,"3":322,"4":584,"5":211,"6":4,"7":1580,"8":2626},"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,"56":24,"57":24,"68":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":55,"loc":{"start":{"line":55,"column":2},"end":{"line":58,"column":2}}},"4":{"name":"_getCCIPModuleStorage","line":67,"loc":{"start":{"line":67,"column":2},"end":{"line":71,"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":56,"column":4},"end":{"line":56,"column":57}},"7":{"start":{"line":57,"column":4},"end":{"line":57,"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}}]}}}} +"contracts/modules/wrapper/options/DocumentEngineModule.sol":{"l":{"29":55,"30":50,"43":53,"44":6,"45":6,"57":19,"58":19,"65":9,"66":9,"67":6,"69":3,"77":5,"78":5,"79":2,"84":18,"85":18,"91":15,"92":14,"96":7,"97":7,"102":7,"103":7,"104":6,"115":25,"116":25,"117":22,"127":28,"128":28,"136":89},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/DocumentEngineModule.sol","s":{"1":55,"2":53,"3":6,"4":6,"5":19,"6":19,"7":9,"8":9,"9":6,"10":3,"11":5,"12":5,"13":18,"14":18,"15":15,"16":14,"17":7,"18":7,"19":7,"20":7,"21":6,"22":25,"23":25,"24":22,"25":28},"b":{"1":[53,0],"2":[6,47],"3":[6,3],"4":[2,3],"5":[18,1],"6":[15,3],"7":[7,1],"8":[7,0],"9":[25,3],"10":[22,3]},"f":{"1":55,"2":53,"3":19,"4":9,"5":5,"6":18,"7":7,"8":25,"9":28,"10":89},"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":93,"column":4}}},"7":{"name":"removeDocument","line":95,"loc":{"start":{"line":95,"column":4},"end":{"line":105,"column":4}}},"8":{"name":"setDocumentEngine","line":114,"loc":{"start":{"line":112,"column":4},"end":{"line":118,"column":4}}},"9":{"name":"_setDocumentEngine","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":129,"column":4}}},"10":{"name":"_getDocumentEngineModuleStorage","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":139,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":37}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":1726}},"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":2705}},"9":{"start":{"line":67,"column":12},"end":{"line":67,"column":54}},"10":{"start":{"line":69,"column":12},"end":{"line":69,"column":31}},"11":{"start":{"line":77,"column":8},"end":{"line":77,"column":81}},"12":{"start":{"line":78,"column":8},"end":{"line":78,"column":3119}},"13":{"start":{"line":84,"column":8},"end":{"line":84,"column":81}},"14":{"start":{"line":85,"column":8},"end":{"line":85,"column":103}},"15":{"start":{"line":91,"column":8},"end":{"line":91,"column":61}},"16":{"start":{"line":92,"column":8},"end":{"line":92,"column":53}},"17":{"start":{"line":96,"column":8},"end":{"line":96,"column":81}},"18":{"start":{"line":97,"column":8},"end":{"line":97,"column":103}},"19":{"start":{"line":102,"column":8},"end":{"line":102,"column":89}},"20":{"start":{"line":103,"column":8},"end":{"line":103,"column":45}},"21":{"start":{"line":104,"column":8},"end":{"line":104,"column":53}},"22":{"start":{"line":115,"column":8},"end":{"line":115,"column":81}},"23":{"start":{"line":116,"column":8},"end":{"line":116,"column":110}},"24":{"start":{"line":117,"column":8},"end":{"line":117,"column":45}},"25":{"start":{"line":128,"column":8},"end":{"line":128,"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":85,"type":"if","locations":[{"start":{"line":85,"column":8},"end":{"line":85,"column":8}},{"start":{"line":85,"column":8},"end":{"line":85,"column":8}}]},"7":{"line":95,"type":"if","locations":[{"start":{"line":95,"column":76},"end":{"line":95,"column":76}},{"start":{"line":95,"column":76},"end":{"line":95,"column":76}}]},"8":{"line":97,"type":"if","locations":[{"start":{"line":97,"column":8},"end":{"line":97,"column":8}},{"start":{"line":97,"column":8},"end":{"line":97,"column":8}}]},"9":{"line":114,"type":"if","locations":[{"start":{"line":114,"column":53},"end":{"line":114,"column":53}},{"start":{"line":114,"column":53},"end":{"line":114,"column":53}}]},"10":{"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/options/ERC20CrossChainModule.sol":{"l":{"39":254,"40":182,"45":96,"46":60,"51":84,"52":48,"67":86,"68":62,"80":96,"81":60,"92":60,"93":60,"104":48,"105":48,"110":92,"118":60,"121":48,"122":48,"126":96,"127":48},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol","s":{"1":254,"2":96,"3":84,"4":86,"5":62,"6":96,"7":60,"8":60,"9":60,"10":48,"11":48,"12":92,"13":60,"14":48,"15":48,"16":96,"17":48},"b":{"1":[86,36],"2":[96,36],"3":[60,36],"4":[48,36],"5":[12,12]},"f":{"1":254,"2":96,"3":84,"4":86,"5":96,"6":60,"7":48,"8":92,"9":60,"10":96},"fnMap":{"1":{"name":"onlyTokenBridge","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"onlyBurnerFrom","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":47,"column":4}}},"3":{"name":"onlySelfBurn","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":53,"column":4}}},"4":{"name":"crosschainMint","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":69,"column":4}}},"5":{"name":"crosschainBurn","line":79,"loc":{"start":{"line":79,"column":4},"end":{"line":82,"column":4}}},"6":{"name":"burnFrom","line":90,"loc":{"start":{"line":89,"column":4},"end":{"line":94,"column":4}}},"7":{"name":"burn","line":103,"loc":{"start":{"line":101,"column":4},"end":{"line":106,"column":4}}},"8":{"name":"supportsInterface","line":109,"loc":{"start":{"line":109,"column":4},"end":{"line":111,"column":4}}},"9":{"name":"_burnFrom","line":116,"loc":{"start":{"line":116,"column":4},"end":{"line":123,"column":4}}},"10":{"name":"_burnFromOperator","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":128,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":36}},"2":{"start":{"line":45,"column":8},"end":{"line":45,"column":27}},"3":{"start":{"line":51,"column":8},"end":{"line":51,"column":27}},"4":{"start":{"line":67,"column":8},"end":{"line":67,"column":31}},"5":{"start":{"line":68,"column":8},"end":{"line":68,"column":51}},"6":{"start":{"line":80,"column":8},"end":{"line":80,"column":33}},"7":{"start":{"line":81,"column":8},"end":{"line":81,"column":54}},"8":{"start":{"line":92,"column":8},"end":{"line":92,"column":38}},"9":{"start":{"line":93,"column":8},"end":{"line":93,"column":40}},"10":{"start":{"line":104,"column":8},"end":{"line":104,"column":37}},"11":{"start":{"line":105,"column":8},"end":{"line":105,"column":47}},"12":{"start":{"line":110,"column":8},"end":{"line":110,"column":110}},"13":{"start":{"line":118,"column":8},"end":{"line":118,"column":64}},"14":{"start":{"line":121,"column":8},"end":{"line":121,"column":58}},"15":{"start":{"line":122,"column":8},"end":{"line":122,"column":48}},"16":{"start":{"line":126,"column":8},"end":{"line":126,"column":36}},"17":{"start":{"line":127,"column":8},"end":{"line":127,"column":53}}},"branchMap":{"1":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":89},"end":{"line":66,"column":89}},{"start":{"line":66,"column":89},"end":{"line":66,"column":89}}]},"2":{"line":79,"type":"if","locations":[{"start":{"line":79,"column":91},"end":{"line":79,"column":91}},{"start":{"line":79,"column":91},"end":{"line":79,"column":91}}]},"3":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":48},"end":{"line":90,"column":48}},{"start":{"line":90,"column":48},"end":{"line":90,"column":48}}]},"4":{"line":103,"type":"if","locations":[{"start":{"line":103,"column":46},"end":{"line":103,"column":46}},{"start":{"line":103,"column":46},"end":{"line":103,"column":46}}]},"5":{"line":110,"type":"cond-expr","locations":[{"start":{"line":110,"column":15},"end":{"line":110,"column":56}},{"start":{"line":110,"column":61},"end":{"line":110,"column":109}}]}}}, +"contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol":{"l":{"30":593,"39":440,"49":98,"50":98,"51":90,"52":90,"53":24,"55":90,"56":90,"66":56,"67":48,"77":32,"78":24},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20EnforcementERC7551Module.sol","s":{"1":593,"2":440,"3":98,"4":98,"5":90,"6":90,"7":24,"8":90,"9":90,"10":56,"11":48,"12":32,"13":24},"b":{"1":[98,0],"2":[24,66],"3":[56,0],"4":[32,0]},"f":{"1":593,"2":440,"3":98,"4":56,"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":3687},"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":{"42":2,"43":2,"55":4,"56":4,"61":4,"62":4,"69":4,"78":2,"79":2,"84":6},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC7551Module.sol","s":{"1":2,"2":2,"3":4,"4":4,"5":4,"6":4,"7":4,"8":2},"b":{"1":[2,2],"2":[4,2]},"f":{"1":2,"2":4,"3":4,"4":4,"5":2,"6":6},"fnMap":{"1":{"name":"setMetaData","line":41,"loc":{"start":{"line":39,"column":4},"end":{"line":44,"column":4}}},"2":{"name":"setTerms","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":57,"column":4}}},"3":{"name":"metaData","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":63,"column":4}}},"4":{"name":"termsHash","line":68,"loc":{"start":{"line":68,"column":4},"end":{"line":70,"column":4}}},"5":{"name":"_setMetaData","line":75,"loc":{"start":{"line":75,"column":3},"end":{"line":80,"column":4}}},"6":{"name":"_getERC7551ModuleStorage","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":87,"column":4}}}},"statementMap":{"1":{"start":{"line":42,"column":8},"end":{"line":42,"column":67}},"2":{"start":{"line":43,"column":8},"end":{"line":43,"column":34}},"3":{"start":{"line":55,"column":8},"end":{"line":55,"column":37}},"4":{"start":{"line":56,"column":8},"end":{"line":56,"column":31}},"5":{"start":{"line":61,"column":8},"end":{"line":61,"column":67}},"6":{"start":{"line":62,"column":8},"end":{"line":62,"column":26}},"7":{"start":{"line":69,"column":8},"end":{"line":69,"column":39}},"8":{"start":{"line":79,"column":8},"end":{"line":79,"column":32}}},"branchMap":{"1":{"line":41,"type":"if","locations":[{"start":{"line":41,"column":48},"end":{"line":41,"column":48}},{"start":{"line":41,"column":48},"end":{"line":41,"column":48}}]},"2":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":101},"end":{"line":51,"column":101}},{"start":{"line":51,"column":101},"end":{"line":51,"column":101}}]}}}, +"contracts/modules/wrapper/options/HolderListModule.sol":{"l":{"45":28,"46":28,"53":22,"54":22,"64":10,"65":10,"66":10,"67":8,"74":10,"75":10,"84":22,"85":18,"86":18,"87":18,"88":16,"89":16,"90":10,"103":114,"104":114,"106":114,"107":10,"108":10,"112":114,"113":106,"114":104,"121":202},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/HolderListModule.sol","s":{"1":28,"2":28,"3":22,"4":22,"5":10,"6":10,"7":10,"8":8,"9":10,"10":10,"11":22,"12":18,"13":18,"14":18,"15":16,"16":114,"17":114,"18":114,"19":10,"20":10,"21":114,"22":106,"23":104},"b":{"1":[8,2],"2":[18,4],"3":[16,2],"4":[10,104],"5":[10,0],"6":[106,8],"7":[104,2]},"f":{"1":28,"2":22,"3":10,"4":10,"5":22,"6":114,"7":202},"fnMap":{"1":{"name":"holderCount","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":47,"column":4}}},"2":{"name":"isHolder","line":52,"loc":{"start":{"line":52,"column":4},"end":{"line":55,"column":4}}},"3":{"name":"holderByIndex","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":68,"column":4}}},"4":{"name":"holders","line":73,"loc":{"start":{"line":73,"column":4},"end":{"line":76,"column":4}}},"5":{"name":"holdersInRange","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":92,"column":4}}},"6":{"name":"_update","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":117,"column":4}}},"7":{"name":"_getHolderListModuleStorage","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":124,"column":4}}}},"statementMap":{"1":{"start":{"line":45,"column":8},"end":{"line":45,"column":73}},"2":{"start":{"line":46,"column":8},"end":{"line":46,"column":34}},"3":{"start":{"line":53,"column":8},"end":{"line":53,"column":73}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":43}},"5":{"start":{"line":64,"column":8},"end":{"line":64,"column":73}},"6":{"start":{"line":65,"column":8},"end":{"line":65,"column":54}},"7":{"start":{"line":66,"column":8},"end":{"line":66,"column":106}},"8":{"start":{"line":67,"column":8},"end":{"line":67,"column":35}},"9":{"start":{"line":74,"column":8},"end":{"line":74,"column":73}},"10":{"start":{"line":75,"column":8},"end":{"line":75,"column":34}},"11":{"start":{"line":84,"column":8},"end":{"line":84,"column":93}},"12":{"start":{"line":85,"column":8},"end":{"line":85,"column":73}},"13":{"start":{"line":86,"column":8},"end":{"line":86,"column":54}},"14":{"start":{"line":87,"column":8},"end":{"line":87,"column":111}},"15":{"start":{"line":89,"column":8},"end":{"line":89,"column":4120}},"16":{"start":{"line":103,"column":8},"end":{"line":103,"column":37}},"17":{"start":{"line":104,"column":8},"end":{"line":104,"column":73}},"18":{"start":{"line":106,"column":8},"end":{"line":106,"column":5014}},"19":{"start":{"line":107,"column":12},"end":{"line":107,"column":5080}},"20":{"start":{"line":108,"column":16},"end":{"line":108,"column":40}},"21":{"start":{"line":112,"column":8},"end":{"line":112,"column":5257}},"22":{"start":{"line":113,"column":12},"end":{"line":113,"column":5319}},"23":{"start":{"line":114,"column":16},"end":{"line":114,"column":36}}},"branchMap":{"1":{"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}}]},"2":{"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}}]},"3":{"line":87,"type":"if","locations":[{"start":{"line":87,"column":8},"end":{"line":87,"column":8}},{"start":{"line":87,"column":8},"end":{"line":87,"column":8}}]},"4":{"line":106,"type":"if","locations":[{"start":{"line":106,"column":8},"end":{"line":106,"column":8}},{"start":{"line":106,"column":8},"end":{"line":106,"column":8}}]},"5":{"line":107,"type":"if","locations":[{"start":{"line":107,"column":12},"end":{"line":107,"column":12}},{"start":{"line":107,"column":12},"end":{"line":107,"column":12}}]},"6":{"line":112,"type":"if","locations":[{"start":{"line":112,"column":8},"end":{"line":112,"column":8}},{"start":{"line":112,"column":8},"end":{"line":112,"column":8}}]},"7":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":12},"end":{"line":113,"column":12}},{"start":{"line":113,"column":12},"end":{"line":113,"column":12}}]}}}, +"contracts/modules/wrapper/security/AccessControlModule.sol":{"l":{"25":6262,"26":2,"31":6260,"46":21844,"47":13326,"49":8518},"path":"/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol","s":{"1":6262,"2":6260,"3":21844,"4":13326,"5":8518},"b":{"1":[6262,0],"2":[2,6260],"3":[13326,8518]},"f":{"1":6262,"2":21844},"fnMap":{"1":{"name":"__AccessControlModule_init_unchained","line":24,"loc":{"start":{"line":23,"column":4},"end":{"line":32,"column":4}}},"2":{"name":"hasRole","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":51,"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":46,"column":8},"end":{"line":46,"column":1961}},"4":{"start":{"line":47,"column":12},"end":{"line":47,"column":23}},"5":{"start":{"line":49,"column":12},"end":{"line":49,"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":46,"type":"if","locations":[{"start":{"line":46,"column":8},"end":{"line":46,"column":8}},{"start":{"line":46,"column":8},"end":{"line":46,"column":8}}]}}}} diff --git a/doc/test/coverage/deployment/CMTATStandardStandalone.sol.html b/doc/test/coverage/deployment/CMTATStandardStandalone.sol.html index b8576a0c..60b2e170 100644 --- a/doc/test/coverage/deployment/CMTATStandardStandalone.sol.html +++ b/doc/test/coverage/deployment/CMTATStandardStandalone.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
100% Branches - 0/0 + 2/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -81,7 +81,34 @@

36 37 38 -39  +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66        @@ -111,19 +138,49 @@

      -308×       +344×         +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +142× +  +   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../interfaces/engine/IRuleEngine.sol";
 import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
 import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
  
@@ -131,7 +188,7 @@ 

/** * @title CMTAT standard version for a standalone deployment (without proxy) — no snapshot engine */ -contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement { +contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement, ReentrancyGuardTransient { /** * @notice Contract version for standalone deployment * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -156,6 +213,30 @@

engines_ ); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -163,7 +244,7 @@

diff --git a/doc/test/coverage/deployment/CMTATStandardUpgradeable.sol.html b/doc/test/coverage/deployment/CMTATStandardUpgradeable.sol.html index eb0eff88..322a675b 100644 --- a/doc/test/coverage/deployment/CMTATStandardUpgradeable.sol.html +++ b/doc/test/coverage/deployment/CMTATStandardUpgradeable.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
100% Branches - 0/0 + 2/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -67,7 +67,34 @@

22 23 24 -25  +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52        @@ -88,21 +115,51 @@

      -336× +  +  +  +367× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +237×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../interfaces/engine/IRuleEngine.sol";
 import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
  
  
 /**
 * @title CMTAT standard version for a proxy deployment (Transparent or Beacon proxy) — no snapshot engine
 */
-contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement {
+contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement, ReentrancyGuardTransient {
     /**
      * @notice Contract version for the deployment with a proxy
      * @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -114,6 +171,30 @@ 

// Disable the possibility to initialize the implementation _disableInitializers(); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -121,7 +202,7 @@

diff --git a/doc/test/coverage/deployment/CMTATUpgradeableUUPS.sol.html b/doc/test/coverage/deployment/CMTATUpgradeableUUPS.sol.html index 1527c608..3c5f0496 100644 --- a/doc/test/coverage/deployment/CMTATUpgradeableUUPS.sol.html +++ b/doc/test/coverage/deployment/CMTATUpgradeableUUPS.sol.html @@ -97,7 +97,7 @@

      -450× +484×       @@ -111,7 +111,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
 import {CMTATBaseERC2771} from "../modules/6_CMTATBaseERC2771.sol";
 import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
@@ -148,7 +148,7 @@ 

diff --git a/doc/test/coverage/deployment/ERC1363/CMTATStandaloneERC1363.sol.html b/doc/test/coverage/deployment/ERC1363/CMTATStandaloneERC1363.sol.html index 838d3967..677c9b52 100644 --- a/doc/test/coverage/deployment/ERC1363/CMTATStandaloneERC1363.sol.html +++ b/doc/test/coverage/deployment/ERC1363/CMTATStandaloneERC1363.sol.html @@ -111,7 +111,7 @@

      -228× +245×       @@ -121,7 +121,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC1363} from "../../modules/8_CMTATBaseERC1363.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
@@ -163,7 +163,7 @@ 

diff --git a/doc/test/coverage/deployment/ERC1363/CMTATUpgradeableERC1363.sol.html b/doc/test/coverage/deployment/ERC1363/CMTATUpgradeableERC1363.sol.html index 6cfc3bc8..965838e8 100644 --- a/doc/test/coverage/deployment/ERC1363/CMTATUpgradeableERC1363.sol.html +++ b/doc/test/coverage/deployment/ERC1363/CMTATUpgradeableERC1363.sol.html @@ -89,13 +89,13 @@

      -268× +285×        
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC1363} from "../../modules/8_CMTATBaseERC1363.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
@@ -124,7 +124,7 @@ 

diff --git a/doc/test/coverage/deployment/ERC1363/index.html b/doc/test/coverage/deployment/ERC1363/index.html index 14e52d57..fc430369 100644 --- a/doc/test/coverage/deployment/ERC1363/index.html +++ b/doc/test/coverage/deployment/ERC1363/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/deployment/ERC7551/CMTATStandaloneERC7551.sol.html b/doc/test/coverage/deployment/ERC7551/CMTATStandaloneERC7551.sol.html index 937d3fb0..6e2010d9 100644 --- a/doc/test/coverage/deployment/ERC7551/CMTATStandaloneERC7551.sol.html +++ b/doc/test/coverage/deployment/ERC7551/CMTATStandaloneERC7551.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
- 100% + 50% Branches - 0/0 + 1/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -85,7 +85,48 @@

40 41 42 -43  +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -103,6 +144,7 @@

      +248×       @@ -114,7 +156,6 @@

      -230×       @@ -127,18 +168,34 @@

      +  +  +  +  +  +  +  +  +  +  +22× +  +   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.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)
 */
-contract CMTATStandaloneERC7551 is CMTATBaseERC7551 {
+contract CMTATStandaloneERC7551 is CMTATBaseERC7551, ReentrancyGuardTransient {
     /**
      * @notice Contract version for standalone deployment
      * @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -168,6 +225,30 @@ 

      +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override EnonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -175,7 +256,7 @@

diff --git a/doc/test/coverage/deployment/ERC7551/CMTATUpgradeableERC7551.sol.html b/doc/test/coverage/deployment/ERC7551/CMTATUpgradeableERC7551.sol.html index 5371cd32..d14c3763 100644 --- a/doc/test/coverage/deployment/ERC7551/CMTATUpgradeableERC7551.sol.html +++ b/doc/test/coverage/deployment/ERC7551/CMTATUpgradeableERC7551.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
- 100% + 50% Branches - 0/0 + 1/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -66,7 +66,48 @@

21 22 23 -24  +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -75,6 +116,7 @@

      +248×       @@ -86,20 +128,35 @@

      -230× +  +  +  +  +  +  +  +  +  +  +  +  +22×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
 import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol";
  
 /**
 * @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
 */
-contract CMTATUpgradeableERC7551 is CMTATBaseERC7551 {
+contract CMTATUpgradeableERC7551 is CMTATBaseERC7551, ReentrancyGuardTransient {
     /**
      * @notice Contract version for the deployment with a proxy
      * @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -111,6 +168,30 @@ 

// Disable the possibility to initialize the implementation _disableInitializers(); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override EnonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -118,7 +199,7 @@

diff --git a/doc/test/coverage/deployment/ERC7551/index.html b/doc/test/coverage/deployment/ERC7551/index.html index aae6158e..9945511e 100644 --- a/doc/test/coverage/deployment/ERC7551/index.html +++ b/doc/test/coverage/deployment/ERC7551/index.html @@ -22,22 +22,22 @@

100% Statements - 2/2 + 4/4
- 100% + 50% Branches - 0/0 + 2/4
100% Functions - 2/2 + 4/4
100% Lines - 2/2 + 4/4
@@ -62,26 +62,26 @@

CMTATStandaloneERC7551.sol
100% - 1/1 - 100% - 0/0 + 2/2 + 50% + 1/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 CMTATUpgradeableERC7551.sol
100% - 1/1 - 100% - 0/0 + 2/2 + 50% + 1/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/deployment/allowlist/CMTATStandaloneAllowlist.sol.html b/doc/test/coverage/deployment/allowlist/CMTATStandaloneAllowlist.sol.html index 7e6321a2..d9a9f8e0 100644 --- a/doc/test/coverage/deployment/allowlist/CMTATStandaloneAllowlist.sol.html +++ b/doc/test/coverage/deployment/allowlist/CMTATStandaloneAllowlist.sol.html @@ -77,8 +77,7 @@

32 33 34 -35 -36  +35        @@ -105,8 +104,7 @@

      -  -368× +458×       @@ -115,7 +113,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseAllowlist} from "../../modules/3_CMTATBaseAllowlist.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
@@ -131,7 +129,6 @@ 

* @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( @@ -154,7 +151,7 @@

diff --git a/doc/test/coverage/deployment/allowlist/CMTATUpgradeableAllowlist.sol.html b/doc/test/coverage/deployment/allowlist/CMTATUpgradeableAllowlist.sol.html index 1eecb4a5..8ab8c11d 100644 --- a/doc/test/coverage/deployment/allowlist/CMTATUpgradeableAllowlist.sol.html +++ b/doc/test/coverage/deployment/allowlist/CMTATUpgradeableAllowlist.sol.html @@ -84,12 +84,12 @@

      -226× +247×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseAllowlist} from "../../modules/3_CMTATBaseAllowlist.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
@@ -115,7 +115,7 @@ 

diff --git a/doc/test/coverage/deployment/allowlist/index.html b/doc/test/coverage/deployment/allowlist/index.html index e2e5f8a4..cc7e00ef 100644 --- a/doc/test/coverage/deployment/allowlist/index.html +++ b/doc/test/coverage/deployment/allowlist/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/deployment/debt/CMTATStandaloneDebt.sol.html b/doc/test/coverage/deployment/debt/CMTATStandaloneDebt.sol.html index 4a5dff77..f17ee82f 100644 --- a/doc/test/coverage/deployment/debt/CMTATStandaloneDebt.sol.html +++ b/doc/test/coverage/deployment/debt/CMTATStandaloneDebt.sol.html @@ -101,7 +101,7 @@

      -446× +482×       @@ -111,7 +111,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
@@ -123,7 +123,7 @@ 

* @notice Contract version for standalone deployment * @param admin address of the admin of contract (Access Control) * @param ERC20Attributes_ ERC20 name, symbol and decimals - * @param baseModuleAttributes_ tokenId, terms, information + * @param extraInformationAttributes_ tokenId, terms, information * @param engines_ external contract */ /// @custom:oz-upgrades-unsafe-allow constructor @@ -148,7 +148,7 @@

diff --git a/doc/test/coverage/deployment/debt/CMTATUpgradeableDebt.sol.html b/doc/test/coverage/deployment/debt/CMTATUpgradeableDebt.sol.html index e0cc58c3..f0f7d2d9 100644 --- a/doc/test/coverage/deployment/debt/CMTATUpgradeableDebt.sol.html +++ b/doc/test/coverage/deployment/debt/CMTATUpgradeableDebt.sol.html @@ -76,12 +76,12 @@

      -456× +492×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol";
 /**
@@ -103,7 +103,7 @@ 

diff --git a/doc/test/coverage/deployment/debt/index.html b/doc/test/coverage/deployment/debt/index.html index 6ea81d37..5f8c0932 100644 --- a/doc/test/coverage/deployment/debt/index.html +++ b/doc/test/coverage/deployment/debt/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/deployment/debtEngine/CMTATStandaloneDebtEngine.sol.html b/doc/test/coverage/deployment/debtEngine/CMTATStandaloneDebtEngine.sol.html index 9f8b6028..dfeb6383 100644 --- a/doc/test/coverage/deployment/debtEngine/CMTATStandaloneDebtEngine.sol.html +++ b/doc/test/coverage/deployment/debtEngine/CMTATStandaloneDebtEngine.sol.html @@ -101,7 +101,7 @@

      -450× +486×       @@ -111,7 +111,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
@@ -123,7 +123,7 @@ 

* @notice Contract version for standalone deployment * @param admin address of the admin of contract (Access Control) * @param ERC20Attributes_ ERC20 name, symbol and decimals - * @param baseModuleAttributes_ tokenId, terms, information + * @param extraInformationAttributes_ tokenId, terms, information * @param engines_ external contract */ /// @custom:oz-upgrades-unsafe-allow constructor @@ -148,7 +148,7 @@

diff --git a/doc/test/coverage/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol.html b/doc/test/coverage/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol.html index 4c56bd21..d8125fd4 100644 --- a/doc/test/coverage/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol.html +++ b/doc/test/coverage/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol.html @@ -76,12 +76,12 @@

      -204× +222×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol";
 /**
@@ -103,7 +103,7 @@ 

diff --git a/doc/test/coverage/deployment/debtEngine/index.html b/doc/test/coverage/deployment/debtEngine/index.html index 8b49f219..af0784e9 100644 --- a/doc/test/coverage/deployment/debtEngine/index.html +++ b/doc/test/coverage/deployment/debtEngine/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/deployment/holderList/CMTATStandaloneHolderList.sol.html b/doc/test/coverage/deployment/holderList/CMTATStandaloneHolderList.sol.html new file mode 100644 index 00000000..6650c373 --- /dev/null +++ b/doc/test/coverage/deployment/holderList/CMTATStandaloneHolderList.sol.html @@ -0,0 +1,179 @@ + + + + Code coverage report for deployment/holderList/CMTATStandaloneHolderList.sol + + + + + + + +
+
+

+ all files / deployment/holderList/ CMTATStandaloneHolderList.sol +

+
+
+ 100% + Statements + 1/1 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 1/1 +
+
+ 100% + Lines + 1/1 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +24× +  +  +  +  +  +  +  + 
//SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+import {CMTATBaseHolderList} from "../../modules/8_CMTATBaseHolderList.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
+import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
+ 
+ 
+/**
+* @title CMTAT standard version for a standalone deployment (without proxy), with the on-chain holder list
+*/
+contract CMTATStandaloneHolderList is CMTATBaseHolderList {
+    /**
+     * @notice Contract version for standalone deployment
+     * @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/doc/test/coverage/deployment/holderList/CMTATUpgradeableHolderList.sol.html b/doc/test/coverage/deployment/holderList/CMTATUpgradeableHolderList.sol.html new file mode 100644 index 00000000..beaf624e --- /dev/null +++ b/doc/test/coverage/deployment/holderList/CMTATUpgradeableHolderList.sol.html @@ -0,0 +1,137 @@ + + + + Code coverage report for deployment/holderList/CMTATUpgradeableHolderList.sol + + + + + + + +
+
+

+ all files / deployment/holderList/ CMTATUpgradeableHolderList.sol +

+
+
+ 100% + Statements + 1/1 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 1/1 +
+
+ 100% + Lines + 1/1 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +24× +  +  + 
//SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+import {CMTATBaseHolderList} from "../../modules/8_CMTATBaseHolderList.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
+ 
+ 
+/**
+* @title CMTAT standard version for a proxy deployment (Transparent or Beacon proxy), with the on-chain holder list
+*/
+contract CMTATUpgradeableHolderList is CMTATBaseHolderList {
+    /**
+     * @notice Contract version for the deployment with a proxy
+     * @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/doc/test/coverage/deployment/holderList/index.html b/doc/test/coverage/deployment/holderList/index.html new file mode 100644 index 00000000..1b1405c9 --- /dev/null +++ b/doc/test/coverage/deployment/holderList/index.html @@ -0,0 +1,106 @@ + + + + Code coverage report for deployment/holderList/ + + + + + + + +
+
+

+ all files deployment/holderList/ +

+
+
+ 100% + Statements + 2/2 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 2/2 +
+
+ 100% + Lines + 2/2 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
CMTATStandaloneHolderList.sol
100%1/1100%0/0100%1/1100%1/1
CMTATUpgradeableHolderList.sol
100%1/1100%0/0100%1/1100%1/1
+
+
+ + + + + + + diff --git a/doc/test/coverage/deployment/index.html b/doc/test/coverage/deployment/index.html index 704e9948..ae7e83c2 100644 --- a/doc/test/coverage/deployment/index.html +++ b/doc/test/coverage/deployment/index.html @@ -22,22 +22,22 @@

100% Statements - 3/3 + 5/5
100% Branches - 2/2 + 6/6
100% Functions - 4/4 + 6/6
100% Lines - 3/3 + 5/5
@@ -62,26 +62,26 @@

CMTATStandardStandalone.sol
100% - 1/1 + 2/2 100% - 0/0 + 2/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 CMTATStandardUpgradeable.sol
100% - 1/1 + 2/2 100% - 0/0 + 2/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 @@ -103,7 +103,7 @@

diff --git a/doc/test/coverage/deployment/light/CMTATStandaloneLight.sol.html b/doc/test/coverage/deployment/light/CMTATStandaloneLight.sol.html index 57416bd3..cd6096d1 100644 --- a/doc/test/coverage/deployment/light/CMTATStandaloneLight.sol.html +++ b/doc/test/coverage/deployment/light/CMTATStandaloneLight.sol.html @@ -93,7 +93,7 @@

      -125× +134×       @@ -101,7 +101,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseCore} from "../../modules/0_CMTATBaseCore.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
@@ -133,7 +133,7 @@ 

diff --git a/doc/test/coverage/deployment/light/CMTATUpgradeableLight.sol.html b/doc/test/coverage/deployment/light/CMTATUpgradeableLight.sol.html index 84a0ba4f..eeef827b 100644 --- a/doc/test/coverage/deployment/light/CMTATUpgradeableLight.sol.html +++ b/doc/test/coverage/deployment/light/CMTATUpgradeableLight.sol.html @@ -80,12 +80,12 @@

      -122× +131×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseCore} from "../../modules/0_CMTATBaseCore.sol";
  
@@ -109,7 +109,7 @@ 

diff --git a/doc/test/coverage/deployment/light/index.html b/doc/test/coverage/deployment/light/index.html index 2f3b85fe..623369fd 100644 --- a/doc/test/coverage/deployment/light/index.html +++ b/doc/test/coverage/deployment/light/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/deployment/permit/CMTATStandalonePermit.sol.html b/doc/test/coverage/deployment/permit/CMTATStandalonePermit.sol.html index c23ecc9c..b1a34171 100644 --- a/doc/test/coverage/deployment/permit/CMTATStandalonePermit.sol.html +++ b/doc/test/coverage/deployment/permit/CMTATStandalonePermit.sol.html @@ -103,7 +103,7 @@

      -228× +248×       @@ -113,7 +113,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
@@ -151,7 +151,7 @@ 

diff --git a/doc/test/coverage/deployment/permit/CMTATUpgradeablePermit.sol.html b/doc/test/coverage/deployment/permit/CMTATUpgradeablePermit.sol.html index 70154cfa..86bc940f 100644 --- a/doc/test/coverage/deployment/permit/CMTATUpgradeablePermit.sol.html +++ b/doc/test/coverage/deployment/permit/CMTATUpgradeablePermit.sol.html @@ -78,12 +78,12 @@

      -230× +250×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol";
  
@@ -106,7 +106,7 @@ 

diff --git a/doc/test/coverage/deployment/permit/index.html b/doc/test/coverage/deployment/permit/index.html index 41c6110b..63987ee8 100644 --- a/doc/test/coverage/deployment/permit/index.html +++ b/doc/test/coverage/deployment/permit/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/deployment/snapshot/CMTATStandaloneSnapshot.sol.html b/doc/test/coverage/deployment/snapshot/CMTATStandaloneSnapshot.sol.html index db7938f0..5dea1eb6 100644 --- a/doc/test/coverage/deployment/snapshot/CMTATStandaloneSnapshot.sol.html +++ b/doc/test/coverage/deployment/snapshot/CMTATStandaloneSnapshot.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
- 100% + 50% Branches - 0/0 + 1/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -81,7 +81,48 @@

36 37 38 -39  +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -100,6 +141,7 @@

      +344×       @@ -111,7 +153,6 @@

      -327×       @@ -119,11 +160,27 @@

      +  +  +  +  +  +  +  +  +  +  +22× +  +   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC2771Snapshot} from "../../modules/7_CMTATBaseERC2771Snapshot.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
  
@@ -131,7 +188,7 @@ 

/** * @title CMTAT with snapshot engine — standalone deployment (without proxy) */ -contract CMTATStandaloneSnapshot is CMTATBaseERC2771Snapshot { +contract CMTATStandaloneSnapshot is CMTATBaseERC2771Snapshot, ReentrancyGuardTransient { /** * @notice Contract version for standalone deployment with snapshot engine * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -156,6 +213,30 @@

engines_ ); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override EnonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -163,7 +244,7 @@

diff --git a/doc/test/coverage/deployment/snapshot/CMTATUpgradeableSnapshot.sol.html b/doc/test/coverage/deployment/snapshot/CMTATUpgradeableSnapshot.sol.html index 557d19f9..7af75baf 100644 --- a/doc/test/coverage/deployment/snapshot/CMTATUpgradeableSnapshot.sol.html +++ b/doc/test/coverage/deployment/snapshot/CMTATUpgradeableSnapshot.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
- 100% + 50% Branches - 0/0 + 1/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -67,7 +67,48 @@

22 23 24 -25  +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -77,6 +118,7 @@

      +369×       @@ -88,21 +130,36 @@

      -352× +  +  +  +  +  +  +  +  +  +  +  +  +22×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC2771Snapshot} from "../../modules/7_CMTATBaseERC2771Snapshot.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
  
  
 /**
 * @title CMTAT with snapshot engine — proxy deployment (Transparent or Beacon proxy)
 */
-contract CMTATUpgradeableSnapshot is CMTATBaseERC2771Snapshot {
+contract CMTATUpgradeableSnapshot is CMTATBaseERC2771Snapshot, ReentrancyGuardTransient {
     /**
      * @notice Contract version for the deployment with a proxy, with snapshot engine
      * @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -114,6 +171,30 @@ 

// Disable the possibility to initialize the implementation _disableInitializers(); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override EnonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -121,7 +202,7 @@

diff --git a/doc/test/coverage/deployment/snapshot/index.html b/doc/test/coverage/deployment/snapshot/index.html index 06e7485e..aa9989fc 100644 --- a/doc/test/coverage/deployment/snapshot/index.html +++ b/doc/test/coverage/deployment/snapshot/index.html @@ -22,22 +22,22 @@

100% Statements - 2/2 + 4/4
- 100% + 50% Branches - 0/0 + 2/4
100% Functions - 2/2 + 4/4
100% Lines - 2/2 + 4/4
@@ -62,26 +62,26 @@

CMTATStandaloneSnapshot.sol
100% - 1/1 - 100% - 0/0 + 2/2 + 50% + 1/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 CMTATUpgradeableSnapshot.sol
100% - 1/1 - 100% - 0/0 + 2/2 + 50% + 1/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/index.html b/doc/test/coverage/index.html index fd998231..13d3d723 100644 --- a/doc/test/coverage/index.html +++ b/doc/test/coverage/index.html @@ -20,24 +20,24 @@

- 100% + 99.07% Statements - 700/700 + 747/754
- 92.13% + 91.18% Branches - 433/470 + 465/510
- 100% + 98.38% Functions - 402/402 + 426/433
- 100% + 99.18% Lines - 789/789 + 843/850
@@ -62,13 +62,13 @@

deployment/
100% - 3/3 + 5/5 100% - 2/2 + 6/6 100% - 4/4 + 6/6 100% - 3/3 + 5/5 @@ -88,13 +88,13 @@

deployment/ERC7551/
100% - 2/2 - 100% - 0/0 + 4/4 + 50% + 2/4 100% - 2/2 + 4/4 100% - 2/2 + 4/4 @@ -137,7 +137,7 @@

- deployment/light/ + deployment/holderList/
100% 2/2 @@ -150,7 +150,7 @@

- deployment/permit/ + deployment/light/
100% 2/2 @@ -163,7 +163,7 @@

- deployment/snapshot/ + deployment/permit/
100% 2/2 @@ -175,6 +175,19 @@

2/2 + + deployment/snapshot/ +
+ 100% + 4/4 + 50% + 2/4 + 100% + 4/4 + 100% + 4/4 + + interfaces/engine/
@@ -242,28 +255,28 @@

modules/ -
- 100% - 224/224 - 87.33% - 131/150 - 100% - 175/175 - 100% - 225/225 +
+ 97% + 226/233 + 86% + 129/150 + 96.26% + 180/187 + 97.01% + 227/234 modules/internal/
100% - 106/106 - 96.43% - 54/56 + 108/108 + 96.67% + 58/60 100% 35/35 100% - 130/130 + 132/132 @@ -296,52 +309,52 @@

modules/wrapper/core/
100% - 59/59 - 85.71% - 36/42 + 60/60 + 84.09% + 37/44 100% - 41/41 + 43/43 100% - 78/78 + 80/80 modules/wrapper/extensions/
100% - 61/61 - 91.18% - 31/34 + 65/65 + 94.44% + 34/36 100% - 34/34 + 35/35 100% - 84/84 + 91/91 modules/wrapper/extensions/ValidationModule/
100% - 69/69 + 72/72 100% - 52/52 + 54/54 100% - 14/14 + 15/15 100% - 61/61 + 64/64 modules/wrapper/options/
100% - 96/96 - 92.19% - 59/64 + 123/123 + 91.46% + 75/82 100% - 58/58 + 65/65 100% - 121/121 + 151/151 @@ -363,7 +376,7 @@

diff --git a/doc/test/coverage/interfaces/engine/IDebtEngine.sol.html b/doc/test/coverage/interfaces/engine/IDebtEngine.sol.html index 151dd833..76659e8a 100644 --- a/doc/test/coverage/interfaces/engine/IDebtEngine.sol.html +++ b/doc/test/coverage/interfaces/engine/IDebtEngine.sol.html @@ -67,7 +67,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol";
  
 /*
@@ -82,7 +82,7 @@ 

diff --git a/doc/test/coverage/interfaces/engine/IDocumentEngine.sol.html b/doc/test/coverage/interfaces/engine/IDocumentEngine.sol.html index 73df3d4f..713c9034 100644 --- a/doc/test/coverage/interfaces/engine/IDocumentEngine.sol.html +++ b/doc/test/coverage/interfaces/engine/IDocumentEngine.sol.html @@ -67,7 +67,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IERC1643} from "../tokenization/draft-IERC1643.sol";
 /*
@@ -82,7 +82,7 @@ 

diff --git a/doc/test/coverage/interfaces/engine/IRuleEngine.sol.html b/doc/test/coverage/interfaces/engine/IRuleEngine.sol.html index fc76d0de..95498756 100644 --- a/doc/test/coverage/interfaces/engine/IRuleEngine.sol.html +++ b/doc/test/coverage/interfaces/engine/IRuleEngine.sol.html @@ -79,7 +79,37 @@

34 35 36 -37  +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -117,7 +147,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IERC1404Extend} from "../tokenization/draft-IERC1404.sol";
 import {IERC3643IComplianceContract} from "../tokenization/IERC3643Partial.sol";
@@ -131,15 +161,30 @@ 

/** * @notice * Function called whenever tokens are transferred from one wallet to another - * @dev + * @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 + * + * WARNING - zero-value calls are permissionless. ERC-20 requires transfers of `0` to be + * treated as normal transfers, and OpenZeppelin's `_spendAllowance` consumes no allowance + * when `value == 0`. Any address can therefore call `transferFrom(victim, anyone, 0)` on the + * token and reach this callback for an arbitrary `from`, with itself as `spender`, without + * ever having been approved. The token deliberately does not suppress the notification, + * because doing so would make its compliance notifications inconsistent with its own + * ERC-20 transfer semantics. + * + * Implementations MUST therefore treat `value == 0` as carrying no economic meaning: any + * stateful rule (cooldown, holding period, quota, tax bucket, counter, holder tracking, ...) + * MUST be a no-op for a zero value, otherwise an attacker can desynchronize policy state + * from balances, or keep a holder permanently restricted, at no cost. The same applies to + * the 3-argument ERC-3643 overload, which a zero-value `transfer(to, 0)` reaches the same way. + * * @param spender spender address (sender) * @param from token holder address * @param to receiver address - * @param value value of tokens involved in the transfer + * @param value value of tokens involved in the transfer; MAY be `0` — see the warning above */ function transferred(address spender, address from, address to, uint256 value) external; } @@ -157,7 +202,7 @@

diff --git a/doc/test/coverage/interfaces/engine/ISnapshotEngine.sol.html b/doc/test/coverage/interfaces/engine/ISnapshotEngine.sol.html index 90d9d51e..ab6b285f 100644 --- a/doc/test/coverage/interfaces/engine/ISnapshotEngine.sol.html +++ b/doc/test/coverage/interfaces/engine/ISnapshotEngine.sol.html @@ -127,7 +127,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /*
 * @dev minimum interface to define a SnapshotEngine
@@ -172,7 +172,7 @@ 

diff --git a/doc/test/coverage/interfaces/engine/index.html b/doc/test/coverage/interfaces/engine/index.html index 90f31aac..943d91c2 100644 --- a/doc/test/coverage/interfaces/engine/index.html +++ b/doc/test/coverage/interfaces/engine/index.html @@ -116,7 +116,7 @@

diff --git a/doc/test/coverage/interfaces/modules/IAllowlistModule.sol.html b/doc/test/coverage/interfaces/modules/IAllowlistModule.sol.html index f29bd428..e6d8e43b 100644 --- a/doc/test/coverage/interfaces/modules/IAllowlistModule.sol.html +++ b/doc/test/coverage/interfaces/modules/IAllowlistModule.sol.html @@ -180,7 +180,7 @@

 
 
 //SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /*
 * @title Allowlist Module Interface
@@ -250,7 +250,7 @@ 

diff --git a/doc/test/coverage/interfaces/modules/IDebtEngineModule.sol.html b/doc/test/coverage/interfaces/modules/IDebtEngineModule.sol.html index 87669859..74dc09b8 100644 --- a/doc/test/coverage/interfaces/modules/IDebtEngineModule.sol.html +++ b/doc/test/coverage/interfaces/modules/IDebtEngineModule.sol.html @@ -102,7 +102,7 @@

 
//SPDX-License-Identifier: MPL-2.0
 import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol";
 import {IDebtEngine} from "../engine/IDebtEngine.sol";
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /**
 * @notice interface to represent DebtEngineModule (debt information and credit events.)
 */
@@ -133,7 +133,7 @@ 

diff --git a/doc/test/coverage/interfaces/modules/IDebtModule.sol.html b/doc/test/coverage/interfaces/modules/IDebtModule.sol.html index 1c1599fd..8b337925 100644 --- a/doc/test/coverage/interfaces/modules/IDebtModule.sol.html +++ b/doc/test/coverage/interfaces/modules/IDebtModule.sol.html @@ -150,7 +150,7 @@

 
//SPDX-License-Identifier: MPL-2.0
 import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol";
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /**
 * @notice interface to represent DebtModule (debt information and credit events.)
 */
@@ -205,7 +205,7 @@ 

diff --git a/doc/test/coverage/interfaces/modules/IDocumentEngineModule.sol.html b/doc/test/coverage/interfaces/modules/IDocumentEngineModule.sol.html index 28769424..2d3a1f27 100644 --- a/doc/test/coverage/interfaces/modules/IDocumentEngineModule.sol.html +++ b/doc/test/coverage/interfaces/modules/IDocumentEngineModule.sol.html @@ -84,7 +84,15 @@

39 40 41 -42  +42 +43 +44 +45 +46  +  +  +  +        @@ -127,7 +135,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IERC1643} from "../tokenization/draft-IERC1643.sol";
  
@@ -149,6 +157,10 @@ 

* @notice Thrown when attempting to set the same document engine as the current one. */ error CMTAT_DocumentEngineModule_SameValue(); + /** + * @notice Thrown when a document mutation is attempted while no document engine is set. + */ + error CMTAT_DocumentEngineModule_NoDocumentEngine(); /* ============ Functions ============ */ /** * @notice Sets a new document engine contract. @@ -172,7 +184,7 @@

diff --git a/doc/test/coverage/interfaces/modules/IHolderListModule.sol.html b/doc/test/coverage/interfaces/modules/IHolderListModule.sol.html new file mode 100644 index 00000000..7083a951 --- /dev/null +++ b/doc/test/coverage/interfaces/modules/IHolderListModule.sol.html @@ -0,0 +1,365 @@ + + + + Code coverage report for interfaces/modules/IHolderListModule.sol + + + + + + + +
+
+

+ all files / interfaces/modules/ IHolderListModule.sol +

+
+
+ 100% + Statements + 0/0 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 0/0 +
+
+ 100% + Lines + 0/0 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
//SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+/*
+* @title Holder List Module Interface
+* @notice Maintain on-chain the list of the addresses holding a non-zero balance
+* @dev The holder set is a view over `balanceOf`: an address belongs to it if and only if
+* its balance is non-zero. {holderCount}, {holderByIndex}, {isHolder}, {holders} and
+* {holdersInRange} follow the naming of the fungible holder-enumeration specification.
+*/
+interface IHolderListModule {
+    /* ============ Errors ============ */
+    /**
+     * @notice A requested index is past the end of the holder set
+     * @dev Raised by {holderByIndex} when `index >= holderCount()`, and by {holdersInRange}
+     * when `toIndex > holderCount()`. The second parameter is always the current holder count,
+     * so a caller that raced a concurrent removal learns the new bound from the revert data.
+     * @param index The index that was requested
+     * @param holderCount The current number of holders, i.e. the exclusive upper bound
+     */
+    error CMTAT_HolderListModule_IndexOutOfBounds(uint256 index, uint256 holderCount);
+    /**
+     * @notice A range is malformed because its lower bound exceeds its upper bound
+     * @dev Distinct from {CMTAT_HolderListModule_IndexOutOfBounds}: the range is not past the
+     * end of the set, it is internally inconsistent, so neither argument is a holder count.
+     * @param fromIndex The requested lower bound, inclusive
+     * @param toIndex The requested upper bound, exclusive
+     */
+    error CMTAT_HolderListModule_InvalidRange(uint256 fromIndex, uint256 toIndex);
+ 
+    /* ============ Events ============ */
+    /**
+     * @notice Emitted when an address becomes a holder, its balance moving from zero to non-zero
+     * @param holder The address added to the holder list
+     */
+    event HolderAdded(address indexed holder);
+    /**
+     * @notice Emitted when an address stops being a holder, its balance moving from non-zero to zero
+     * @param holder The address removed from the holder list
+     */
+    event HolderRemoved(address indexed holder);
+ 
+    /* ============ Functions ============ */
+    /**
+     * @notice Returns the number of addresses currently holding a non-zero balance
+     * @return The holder count
+     */
+    function holderCount() external view returns (uint256);
+ 
+    /**
+     * @notice Returns whether an account currently holds a non-zero balance
+     * @param account The address to check
+     * @return True if the address is a holder, false otherwise
+     */
+    function isHolder(address account) external view returns (bool);
+ 
+    /**
+     * @notice Returns the holder stored at a given index
+     * @dev Reverts with {CMTAT_HolderListModule_IndexOutOfBounds} if `index >= holderCount()`.
+     * Holders are stored in an unordered set: the index of a given holder is not stable across
+     * state changes. See {holdersInRange} for the implications on pagination.
+     * @param index The position in the holder set, in `[0, holderCount())`
+     * @return The holder address at `index`
+     */
+    function holderByIndex(uint256 index) external view returns (address);
+ 
+    /**
+     * @notice Returns the whole holder list in a single call
+     * @dev Unbounded: the cost grows with {holderCount} and this call will run out of gas once
+     * the holder list is large enough. It is intended for off-chain `eth_call`. On-chain callers,
+     * and any caller that cannot bound the holder count, MUST use {holdersInRange} instead.
+     * The returned array is ordered as {holderByIndex}: `holders()[i] == holderByIndex(i)` within
+     * a single block, and `holders()` is exactly `holdersInRange(0, holderCount())`.
+     * @return The full list of holder addresses
+     */
+    function holders() external view returns (address[] memory);
+ 
+    /**
+     * @notice Returns the contiguous window of holders at indices `[fromIndex, toIndex)`
+     * @dev Half-open: `fromIndex` inclusive, `toIndex` exclusive, so the returned length is
+     * exactly `toIndex - fromIndex`. The window is a slice of the sequence {holderByIndex}
+     * enumerates: `holdersInRange(f, t)[i] == holderByIndex(f + i)` within a single block.
+     *
+     * Reverts with {CMTAT_HolderListModule_InvalidRange} if `fromIndex > toIndex`, and with
+     * {CMTAT_HolderListModule_IndexOutOfBounds} if `toIndex > holderCount()`. The malformed-range
+     * check is evaluated first, so an inverted range always yields {CMTAT_HolderListModule_InvalidRange}
+     * regardless of where the bounds fall. `fromIndex == toIndex` returns an empty array without
+     * reverting, including when both equal `holderCount()` — the natural terminating condition of
+     * a paging loop.
+     *
+     * The underlying set is unordered and a removal moves the last holder into the freed slot, so
+     * windows read across several blocks may miss a holder or return one twice. Read the whole set
+     * at a fixed block (`eth_call` at a block number) if a consistent snapshot is required.
+     * @param fromIndex The index of the first holder to return, inclusive
+     * @param toIndex The index one past the last holder to return, exclusive
+     * @return window The holders at indices `fromIndex` through `toIndex - 1`, in enumeration order
+     */
+    function holdersInRange(uint256 fromIndex, uint256 toIndex) external view returns (address[] memory window);
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/interfaces/modules/ISnapshotEngineModule.sol.html b/doc/test/coverage/interfaces/modules/ISnapshotEngineModule.sol.html index 1bfbd988..7d99c5e7 100644 --- a/doc/test/coverage/interfaces/modules/ISnapshotEngineModule.sol.html +++ b/doc/test/coverage/interfaces/modules/ISnapshotEngineModule.sol.html @@ -129,7 +129,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Engine === */
 import {ISnapshotEngine} from "../engine/ISnapshotEngine.sol";
@@ -175,7 +175,7 @@ 

diff --git a/doc/test/coverage/interfaces/modules/index.html b/doc/test/coverage/interfaces/modules/index.html index 01bcfd8e..57b3b4f5 100644 --- a/doc/test/coverage/interfaces/modules/index.html +++ b/doc/test/coverage/interfaces/modules/index.html @@ -110,6 +110,19 @@

0/0 + + IHolderListModule.sol +
+ 100% + 0/0 + 100% + 0/0 + 100% + 0/0 + 100% + 0/0 + + ISnapshotEngineModule.sol
@@ -129,7 +142,7 @@

diff --git a/doc/test/coverage/interfaces/technical/ICMTATConstructor.sol.html b/doc/test/coverage/interfaces/technical/ICMTATConstructor.sol.html index c31cc696..4edc80b5 100644 --- a/doc/test/coverage/interfaces/technical/ICMTATConstructor.sol.html +++ b/doc/test/coverage/interfaces/technical/ICMTATConstructor.sol.html @@ -106,7 +106,7 @@

     
//SPDX-License-Identifier: MPL-2.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IRuleEngine} from "../engine/IRuleEngine.sol";
 import {IERC1643CMTAT} from "../tokenization/draft-IERC1643CMTAT.sol";
@@ -142,7 +142,7 @@ 

diff --git a/doc/test/coverage/interfaces/technical/IERC20Allowance.sol.html b/doc/test/coverage/interfaces/technical/IERC20Allowance.sol.html index 64597636..4131b793 100644 --- a/doc/test/coverage/interfaces/technical/IERC20Allowance.sol.html +++ b/doc/test/coverage/interfaces/technical/IERC20Allowance.sol.html @@ -71,7 +71,25 @@

26 27 28 -29  +29 +30 +31 +32 +33 +34 +35 +36 +37 +38  +  +  +  +  +  +  +  +  +        @@ -101,7 +119,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /**
  * @title IERC20Allowance
@@ -110,19 +128,28 @@ 

interface IERC20Allowance { /* ============ Events ============ */ /** - * @notice Emitted when a `spender` spends a `value` amount of tokens on behalf of an `account`. + * @notice Emitted when a `spender` uses a `value` amount of an `account`'s allowance. * @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. + * - Similar in intent to the ERC-20 `Approval` event, but signals *consumption* of an + * allowance rather than its granting. + * - Emitted by the allowance-consuming entry points: `transferFrom` (ERC20BaseModule), + * `burnFrom` (ERC20CrossChainModule), and `forcedTransfer` (ERC20EnforcementModule) when the + * latter reduces a finite owner→recipient allowance. + * - WARNING - this event does NOT, by itself, imply that the on-chain allowance decreased. + * It is emitted on *every* successful allowance-consuming `transferFrom` / `burnFrom`, + * including when the allowance is infinite (`type(uint256).max`), in which case OpenZeppelin + * leaves the allowance unchanged. `value` is the amount used, not the size of any reduction. + * - For `forcedTransfer`, `Spend` is emitted only when the allowance is finite and non-zero + * (the case where it is actually reduced), and `value` is the amount taken from it (capped by + * the allowance). `forcedTransfer` does not emit `Approval` for that reduction. + * - To reconstruct the current allowance, read `allowance(owner, spender)` — never accumulate + * `Spend` (or `Approval`) events. + * - Event ordering differs between the emit sites: `transferFrom` emits `Transfer` then + * `Spend`; `burnFrom` emits `Spend` then `Transfer` then `BurnFrom`. See + * [doc/technical/allowance-spend-event.md](../../../doc/technical/allowance-spend-event.md). * @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. + * @param value The amount of allowance used (not necessarily the amount by which it decreased). */ event Spend(address indexed account, address indexed spender, uint256 value); } @@ -133,7 +160,7 @@

diff --git a/doc/test/coverage/interfaces/technical/IERC5679.sol.html b/doc/test/coverage/interfaces/technical/IERC5679.sol.html index ab7186ea..571b6a6d 100644 --- a/doc/test/coverage/interfaces/technical/IERC5679.sol.html +++ b/doc/test/coverage/interfaces/technical/IERC5679.sol.html @@ -132,7 +132,7 @@

     
// SPDX-License-Identifier: MPL-2.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
  
@@ -181,7 +181,7 @@ 

diff --git a/doc/test/coverage/interfaces/technical/IERC7802.sol.html b/doc/test/coverage/interfaces/technical/IERC7802.sol.html index 67e7cf26..456f6d22 100644 --- a/doc/test/coverage/interfaces/technical/IERC7802.sol.html +++ b/doc/test/coverage/interfaces/technical/IERC7802.sol.html @@ -115,7 +115,7 @@

   
// SPDX-License-Identifier: MIT
 // From https://github.com/ethereum-optimism/optimism/blob/op-node/v1.13.2/packages/contracts-bedrock/interfaces/L2/IERC7802.sol
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
  
@@ -154,7 +154,7 @@ 

diff --git a/doc/test/coverage/interfaces/technical/IGetCCIPAdmin.sol.html b/doc/test/coverage/interfaces/technical/IGetCCIPAdmin.sol.html index f3482c00..481ad67e 100644 --- a/doc/test/coverage/interfaces/technical/IGetCCIPAdmin.sol.html +++ b/doc/test/coverage/interfaces/technical/IGetCCIPAdmin.sol.html @@ -54,7 +54,9 @@

9 10 11 -12  +12 +13  +        @@ -66,7 +68,7 @@

     
// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 interface IGetCCIPAdmin {
   event CCIPAdminTransferred(address indexed previousAdmin, address indexed newAdmin);
@@ -74,6 +76,7 @@ 

/** * @notice Returns the admin of the token. * @dev This method is named to never conflict with existing methods. + * @return The address of the token's CCIP admin. */ function getCCIPAdmin() external view returns (address); }

@@ -82,7 +85,7 @@

diff --git a/doc/test/coverage/interfaces/technical/IMintBurnToken.sol.html b/doc/test/coverage/interfaces/technical/IMintBurnToken.sol.html index 5167bcb9..469851fc 100644 --- a/doc/test/coverage/interfaces/technical/IMintBurnToken.sol.html +++ b/doc/test/coverage/interfaces/technical/IMintBurnToken.sol.html @@ -173,7 +173,9 @@

128 129 130 -131  +131 +132  +        @@ -305,7 +307,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
  
 /**
@@ -338,6 +340,7 @@ 

* @param to receiver to send the new minted tokens * @param amountToBurn number of tokens to burn * @param amountToMint number of tokens to mint +* @param data Optional data forwarded to the burn and mint hooks. */ function burnAndMint(address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes calldata data) external; } @@ -439,7 +442,7 @@

diff --git a/doc/test/coverage/interfaces/technical/index.html b/doc/test/coverage/interfaces/technical/index.html index 684f4223..65aa3721 100644 --- a/doc/test/coverage/interfaces/technical/index.html +++ b/doc/test/coverage/interfaces/technical/index.html @@ -142,7 +142,7 @@

diff --git a/doc/test/coverage/interfaces/tokenization/ICMTAT.sol.html b/doc/test/coverage/interfaces/tokenization/ICMTAT.sol.html index 00290a8b..efffc54e 100644 --- a/doc/test/coverage/interfaces/tokenization/ICMTAT.sol.html +++ b/doc/test/coverage/interfaces/tokenization/ICMTAT.sol.html @@ -194,107 +194,7 @@

149 150 151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  +152        @@ -447,64 +347,12 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 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
-* the distributed ledger.
-* Contrary to the “burn” function, the “deactivateContract” function
-* affects all tokens in issuance, and not only some of them. 
-* 
-* a) This function is necessary to allow the issuer to carry out certain corporate actions 
-* (e.g. share splits, reverse splits or mergers), which 
-* require that all existing tokens are either canceled or immobilized and decoupled from the shares
-* (i.e. the tokens no longer represent shares).
-* 
-* b) The “deactivateContract” function can also be used if the issuer decides that it no longer wishes
-* to have its shares issued in the form of ledger-based securities
-* 
-* The “deactivateContract” function does not delete the smart contract’s 
-* storage and code, i.e. tokens are not burned by the function, however it permanently and
-* irreversibly deactivates the smart contract (unless a proxy is used). 
-* 
-*/
-interface ICMTATDeactivate {
-     /**
-     * @notice Emitted when the contract is permanently deactivated.
-     * @param account The address that performed the 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.
-     * @dev 
-     * This action is irreversible — once executed, the contract cannot be reactivated.
-     * Requirements:
-     * - The contract MUST be paused before deactivation is allowed.
-     * Emits a {Deactivated} event.
-     * WARNING: Use with caution. This action permanently disables core contract functionality.
-     */
-    function deactivateContract() external;
- 
-     /**
-     * @notice Returns whether the contract has been permanently deactivated.
-     * @return isDeactivated A boolean indicating the deactivation status.
-     * @dev Returns `true` if `deactivateContract()` has been successfully called.
-     */
-    function deactivated() external view returns (bool isDeactivated) ;
-}
- 
- 
- 
-/** 
 * @title ICMTATBase - Core Tokenization Metadata Interface as part of CMTAT specification
 * @notice Defines base properties and metadata structure for a tokenized asset.
 * @dev Includes token ID, terms (using IERC1643-compliant document), and a general information field.
@@ -583,6 +431,7 @@ 

interface ICMTATCreditEvents { /** * @notice Returns credit events + * @return creditEvents_ The current credit-event flags for the token. */ function creditEvents() external view returns(CreditEvents memory creditEvents_);   @@ -643,6 +492,7 @@

} /** * @notice Returns debt information + * @return debtInformation_ The current debt information for the token. */ function debt() external view returns(DebtInformation memory debtInformation_); } @@ -652,7 +502,7 @@

diff --git a/doc/test/coverage/interfaces/tokenization/IERC3643Partial.sol.html b/doc/test/coverage/interfaces/tokenization/IERC3643Partial.sol.html index 3a62f046..f434e4f1 100644 --- a/doc/test/coverage/interfaces/tokenization/IERC3643Partial.sol.html +++ b/doc/test/coverage/interfaces/tokenization/IERC3643Partial.sol.html @@ -343,7 +343,15 @@

298 299 300 -301  +301 +302 +303 +304 +305  +  +  +  +        @@ -652,7 +660,7 @@

* (e.g., `amount` → `value`). */   -pragma solidity ^0.8.20; +pragma solidity ^0.8.24;   import {IERC7943FungibleEnforcement} from "./draft-IERC7943.sol";   @@ -921,6 +929,10 @@

/** * @notice Returns true if the transfer is valid, and false otherwise. * @dev Don't check the balance and the user's right (access control) + * @param from The address sending tokens. + * @param to The address receiving tokens. + * @param value The amount of tokens to transfer. + * @return isValid True if the transfer is valid, false otherwise. */ function canTransfer( address from, @@ -949,7 +961,7 @@

diff --git a/doc/test/coverage/interfaces/tokenization/draft-IERC1404.sol.html b/doc/test/coverage/interfaces/tokenization/draft-IERC1404.sol.html index b4558f42..9e5abfda 100644 --- a/doc/test/coverage/interfaces/tokenization/draft-IERC1404.sol.html +++ b/doc/test/coverage/interfaces/tokenization/draft-IERC1404.sol.html @@ -121,7 +121,17 @@

76 77 78 -79  +79 +80 +81 +82 +83 +84  +  +  +  +  +        @@ -201,7 +211,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /*
 * @dev Contrary to the ERC-1404,
@@ -231,9 +241,10 @@ 

  /** * @dev See {ERC-1404} - * This function is effectively an accessor for the "message", - * a human-readable explanation as to why a transaction is restricted. - * + * This function is effectively an accessor for the "message", + * a human-readable explanation as to why a transaction is restricted. + * @param restrictionCode The restriction code to translate into a message. + * @return The human-readable message corresponding to `restrictionCode`. */ function messageForTransferRestriction( uint8 restrictionCode @@ -266,6 +277,10 @@

* 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. + * @param spender The address initiating the delegated transfer. + * @param from The address sending tokens. + * @param to The address receiving tokens. + * @param value amount of tokens to transfer * @return uint8 restricted code, 0 means the transfer is authorized * */ @@ -283,7 +298,7 @@

diff --git a/doc/test/coverage/interfaces/tokenization/draft-IERC1643.sol.html b/doc/test/coverage/interfaces/tokenization/draft-IERC1643.sol.html index c9b6825d..1838f8bf 100644 --- a/doc/test/coverage/interfaces/tokenization/draft-IERC1643.sol.html +++ b/doc/test/coverage/interfaces/tokenization/draft-IERC1643.sol.html @@ -84,7 +84,25 @@

39 40 41 -42  +42 +43 +44 +45 +46 +47 +48 +49 +50 +51  +  +  +  +  +  +  +  +  +        @@ -127,7 +145,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /**
 * @title IERC1643 Document Management 
@@ -135,6 +153,11 @@ 

* Contrary to the original specification, use a struct Document to represent a Document */ interface IERC1643 { + /// @dev Reverted when removing a document whose name is not registered. + error ERC1643MissingDocument(); + /// @dev Reverted when setting a document with the zero name. + error ERC1643InvalidName(); +  /// @dev Struct used to represent a document and its metadata. struct Document { // URI of the off-chain document (e.g., IPFS, HTTPS) @@ -148,10 +171,14 @@

// Document Management /** * @notice Retrieves a document by its registered name. + * @dev Returns the three fields as flat values, matching the ERC-1643 ABI. A missing + * document yields empty values and does not revert. * @param name The unique name used to identify the document. - * @return document The associated document's metadata (URI, hash, timestamp). + * @return uri The URI of the off-chain document. + * @return documentHash The hash of the document content. + * @return lastModified The timestamp of the last on-chain modification. */ - function getDocument(bytes32 name) external view returns (Document memory document); + function getDocument(bytes32 name) external view returns (string memory uri, bytes32 documentHash, uint256 lastModified); /** * @notice Returns the list of all document names registered in the contract. * @return documentNames_ An array of strings representing all document identifiers. @@ -172,7 +199,7 @@

diff --git a/doc/test/coverage/interfaces/tokenization/draft-IERC1643CMTAT.sol.html b/doc/test/coverage/interfaces/tokenization/draft-IERC1643CMTAT.sol.html index 766961e7..1e7370a1 100644 --- a/doc/test/coverage/interfaces/tokenization/draft-IERC1643CMTAT.sol.html +++ b/doc/test/coverage/interfaces/tokenization/draft-IERC1643CMTAT.sol.html @@ -67,7 +67,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 interface IERC1643CMTAT {
     struct DocumentInfo {
         string name;
@@ -82,7 +82,7 @@ 

diff --git a/doc/test/coverage/interfaces/tokenization/draft-IERC7551.sol.html b/doc/test/coverage/interfaces/tokenization/draft-IERC7551.sol.html index 2d1fd287..0859c3ec 100644 --- a/doc/test/coverage/interfaces/tokenization/draft-IERC7551.sol.html +++ b/doc/test/coverage/interfaces/tokenization/draft-IERC7551.sol.html @@ -449,7 +449,7 @@

import {IERC3643ComplianceRead} from "./IERC3643Partial.sol"; import {IERC5679Mint, IERC5679Burn} from "../technical/IERC5679.sol";   -pragma solidity ^0.8.20; +pragma solidity ^0.8.24;     /** @@ -652,7 +652,7 @@

diff --git a/doc/test/coverage/interfaces/tokenization/draft-IERC7943.sol.html b/doc/test/coverage/interfaces/tokenization/draft-IERC7943.sol.html index 5a1d8e52..b6b1434a 100644 --- a/doc/test/coverage/interfaces/tokenization/draft-IERC7943.sol.html +++ b/doc/test/coverage/interfaces/tokenization/draft-IERC7943.sol.html @@ -313,7 +313,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /**
 * @notice Enforcement Interface for ERC-20 based implementations common with ERC-3643 interface.
@@ -451,7 +451,7 @@ 

diff --git a/doc/test/coverage/interfaces/tokenization/draft-IERC8343.sol.html b/doc/test/coverage/interfaces/tokenization/draft-IERC8343.sol.html new file mode 100644 index 00000000..41948016 --- /dev/null +++ b/doc/test/coverage/interfaces/tokenization/draft-IERC8343.sol.html @@ -0,0 +1,251 @@ + + + + Code coverage report for interfaces/tokenization/draft-IERC8343.sol + + + + + + + +
+
+

+ all files / interfaces/tokenization/ draft-IERC8343.sol +

+
+
+ 100% + Statements + 0/0 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 0/0 +
+
+ 100% + Lines + 0/0 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+/**
+* @title IERC8343 - Contract Deactivation
+* @notice Interface for permanently deactivating a token contract and exposing its
+* deactivation status on-chain. Follows the proposed ERC-8343 (draft, not yet merged).
+*
+* @dev The issuer must be able to "deactivate" the smart contract, to prevent execution of
+* transactions on the distributed ledger.
+* Contrary to the "burn" function, the "deactivateContract" function
+* affects all tokens in issuance, and not only some of them.
+*
+* a) This function is necessary to allow the issuer to carry out certain corporate actions
+* (e.g. share splits, reverse splits or mergers), which
+* require that all existing tokens are either canceled or immobilized and decoupled from the shares
+* (i.e. the tokens no longer represent shares).
+*
+* b) The "deactivateContract" function can also be used if the issuer decides that it no longer wishes
+* to have its shares issued in the form of ledger-based securities.
+*
+* The "deactivateContract" function does not delete the smart contract's
+* storage and code, i.e. tokens are not burned by the function, however it permanently and
+* irreversibly deactivates the smart contract (unless a proxy is used).
+*
+* @dev The ERC-8343 interface identifier is `0xe9cd80b0`, the exclusive-or of the selectors of
+* `deactivateContract()` and `deactivated()`. This interface deliberately does NOT inherit
+* `IERC165`, so that `type(IERC8343).interfaceId` equals `0xe9cd80b0`; adding `is IERC165` would
+* fold `supportsInterface`'s selector into the id and change it. ERC-165 support is advertised
+* separately by the implementing contract.
+*/
+interface IERC8343 {
+     /**
+     * @notice Emitted when the contract is permanently deactivated.
+     * @param account The address that performed the 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.
+     * @dev
+     * This action is irreversible — once executed, the contract cannot be reactivated.
+     * Requirements:
+     * - The contract MUST be paused before deactivation is allowed.
+     * Emits a {Deactivated} event.
+     * WARNING: Use with caution. This action permanently disables core contract functionality.
+     */
+    function deactivateContract() external;
+ 
+     /**
+     * @notice Returns whether the contract has been permanently deactivated.
+     * @return isDeactivated A boolean indicating the deactivation status.
+     * @dev Returns `true` if `deactivateContract()` has been successfully called.
+     */
+    function deactivated() external view returns (bool isDeactivated);
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/interfaces/tokenization/index.html b/doc/test/coverage/interfaces/tokenization/index.html index 07943a32..b9516d88 100644 --- a/doc/test/coverage/interfaces/tokenization/index.html +++ b/doc/test/coverage/interfaces/tokenization/index.html @@ -149,13 +149,26 @@

0/0 + + draft-IERC8343.sol +
+ 100% + 0/0 + 100% + 0/0 + 100% + 0/0 + 100% + 0/0 + +
diff --git a/doc/test/coverage/lcov-report/deployment/CMTATStandardStandalone.sol.html b/doc/test/coverage/lcov-report/deployment/CMTATStandardStandalone.sol.html index b8576a0c..60b2e170 100644 --- a/doc/test/coverage/lcov-report/deployment/CMTATStandardStandalone.sol.html +++ b/doc/test/coverage/lcov-report/deployment/CMTATStandardStandalone.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
100% Branches - 0/0 + 2/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -81,7 +81,34 @@

36 37 38 -39  +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66        @@ -111,19 +138,49 @@

      -308×       +344×         +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +142× +  +   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../interfaces/engine/IRuleEngine.sol";
 import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
 import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol";
  
@@ -131,7 +188,7 @@ 

/** * @title CMTAT standard version for a standalone deployment (without proxy) — no snapshot engine */ -contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement { +contract CMTATStandardStandalone is CMTATBaseERC7551Enforcement, ReentrancyGuardTransient { /** * @notice Contract version for standalone deployment * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -156,6 +213,30 @@

engines_ ); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -163,7 +244,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/CMTATStandardUpgradeable.sol.html b/doc/test/coverage/lcov-report/deployment/CMTATStandardUpgradeable.sol.html index eb0eff88..322a675b 100644 --- a/doc/test/coverage/lcov-report/deployment/CMTATStandardUpgradeable.sol.html +++ b/doc/test/coverage/lcov-report/deployment/CMTATStandardUpgradeable.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
100% Branches - 0/0 + 2/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -67,7 +67,34 @@

22 23 24 -25  +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52        @@ -88,21 +115,51 @@

      -336× +  +  +  +367× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +237×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC7551Enforcement} from "../modules/7_CMTATBaseERC7551Enforcement.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../interfaces/engine/IRuleEngine.sol";
 import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
  
  
 /**
 * @title CMTAT standard version for a proxy deployment (Transparent or Beacon proxy) — no snapshot engine
 */
-contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement {
+contract CMTATStandardUpgradeable is CMTATBaseERC7551Enforcement, ReentrancyGuardTransient {
     /**
      * @notice Contract version for the deployment with a proxy
      * @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -114,6 +171,30 @@ 

// Disable the possibility to initialize the implementation _disableInitializers(); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override nonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -121,7 +202,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/CMTATUpgradeableUUPS.sol.html b/doc/test/coverage/lcov-report/deployment/CMTATUpgradeableUUPS.sol.html index 1527c608..3c5f0496 100644 --- a/doc/test/coverage/lcov-report/deployment/CMTATUpgradeableUUPS.sol.html +++ b/doc/test/coverage/lcov-report/deployment/CMTATUpgradeableUUPS.sol.html @@ -97,7 +97,7 @@

      -450× +484×       @@ -111,7 +111,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
 import {CMTATBaseERC2771} from "../modules/6_CMTATBaseERC2771.sol";
 import {ERC2771Module} from "../modules/wrapper/options/ERC2771Module.sol";
@@ -148,7 +148,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/ERC1363/CMTATStandaloneERC1363.sol.html b/doc/test/coverage/lcov-report/deployment/ERC1363/CMTATStandaloneERC1363.sol.html index 838d3967..677c9b52 100644 --- a/doc/test/coverage/lcov-report/deployment/ERC1363/CMTATStandaloneERC1363.sol.html +++ b/doc/test/coverage/lcov-report/deployment/ERC1363/CMTATStandaloneERC1363.sol.html @@ -111,7 +111,7 @@

      -228× +245×       @@ -121,7 +121,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC1363} from "../../modules/8_CMTATBaseERC1363.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
@@ -163,7 +163,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/ERC1363/CMTATUpgradeableERC1363.sol.html b/doc/test/coverage/lcov-report/deployment/ERC1363/CMTATUpgradeableERC1363.sol.html index 6cfc3bc8..965838e8 100644 --- a/doc/test/coverage/lcov-report/deployment/ERC1363/CMTATUpgradeableERC1363.sol.html +++ b/doc/test/coverage/lcov-report/deployment/ERC1363/CMTATUpgradeableERC1363.sol.html @@ -89,13 +89,13 @@

      -268× +285×        
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC1363} from "../../modules/8_CMTATBaseERC1363.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
@@ -124,7 +124,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/ERC1363/index.html b/doc/test/coverage/lcov-report/deployment/ERC1363/index.html index 14e52d57..fc430369 100644 --- a/doc/test/coverage/lcov-report/deployment/ERC1363/index.html +++ b/doc/test/coverage/lcov-report/deployment/ERC1363/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/ERC7551/CMTATStandaloneERC7551.sol.html b/doc/test/coverage/lcov-report/deployment/ERC7551/CMTATStandaloneERC7551.sol.html index 937d3fb0..6e2010d9 100644 --- a/doc/test/coverage/lcov-report/deployment/ERC7551/CMTATStandaloneERC7551.sol.html +++ b/doc/test/coverage/lcov-report/deployment/ERC7551/CMTATStandaloneERC7551.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
- 100% + 50% Branches - 0/0 + 1/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -85,7 +85,48 @@

40 41 42 -43  +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -103,6 +144,7 @@

      +248×       @@ -114,7 +156,6 @@

      -230×       @@ -127,18 +168,34 @@

      +  +  +  +  +  +  +  +  +  +  +22× +  +   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.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)
 */
-contract CMTATStandaloneERC7551 is CMTATBaseERC7551 {
+contract CMTATStandaloneERC7551 is CMTATBaseERC7551, ReentrancyGuardTransient {
     /**
      * @notice Contract version for standalone deployment
      * @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -168,6 +225,30 @@ 

      +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override EnonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -175,7 +256,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/ERC7551/CMTATUpgradeableERC7551.sol.html b/doc/test/coverage/lcov-report/deployment/ERC7551/CMTATUpgradeableERC7551.sol.html index 5371cd32..d14c3763 100644 --- a/doc/test/coverage/lcov-report/deployment/ERC7551/CMTATUpgradeableERC7551.sol.html +++ b/doc/test/coverage/lcov-report/deployment/ERC7551/CMTATUpgradeableERC7551.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
- 100% + 50% Branches - 0/0 + 1/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -66,7 +66,48 @@

21 22 23 -24  +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -75,6 +116,7 @@

      +248×       @@ -86,20 +128,35 @@

      -230× +  +  +  +  +  +  +  +  +  +  +  +  +22×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
 import {CMTATBaseERC7551} from "../../modules/8_CMTATBaseERC7551.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol";
  
 /**
 * @title CMTAT version for a proxy deployment (Transparent or Beacon proxy)
 */
-contract CMTATUpgradeableERC7551 is CMTATBaseERC7551 {
+contract CMTATUpgradeableERC7551 is CMTATBaseERC7551, ReentrancyGuardTransient {
     /**
      * @notice Contract version for the deployment with a proxy
      * @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -111,6 +168,30 @@ 

// Disable the possibility to initialize the implementation _disableInitializers(); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override EnonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -118,7 +199,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/ERC7551/index.html b/doc/test/coverage/lcov-report/deployment/ERC7551/index.html index aae6158e..9945511e 100644 --- a/doc/test/coverage/lcov-report/deployment/ERC7551/index.html +++ b/doc/test/coverage/lcov-report/deployment/ERC7551/index.html @@ -22,22 +22,22 @@

100% Statements - 2/2 + 4/4
- 100% + 50% Branches - 0/0 + 2/4
100% Functions - 2/2 + 4/4
100% Lines - 2/2 + 4/4
@@ -62,26 +62,26 @@

CMTATStandaloneERC7551.sol
100% - 1/1 - 100% - 0/0 + 2/2 + 50% + 1/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 CMTATUpgradeableERC7551.sol
100% - 1/1 - 100% - 0/0 + 2/2 + 50% + 1/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/allowlist/CMTATStandaloneAllowlist.sol.html b/doc/test/coverage/lcov-report/deployment/allowlist/CMTATStandaloneAllowlist.sol.html index 7e6321a2..d9a9f8e0 100644 --- a/doc/test/coverage/lcov-report/deployment/allowlist/CMTATStandaloneAllowlist.sol.html +++ b/doc/test/coverage/lcov-report/deployment/allowlist/CMTATStandaloneAllowlist.sol.html @@ -77,8 +77,7 @@

32 33 34 -35 -36  +35        @@ -105,8 +104,7 @@

      -  -368× +458×       @@ -115,7 +113,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseAllowlist} from "../../modules/3_CMTATBaseAllowlist.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
@@ -131,7 +129,6 @@ 

* @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( @@ -154,7 +151,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/allowlist/CMTATUpgradeableAllowlist.sol.html b/doc/test/coverage/lcov-report/deployment/allowlist/CMTATUpgradeableAllowlist.sol.html index 1eecb4a5..8ab8c11d 100644 --- a/doc/test/coverage/lcov-report/deployment/allowlist/CMTATUpgradeableAllowlist.sol.html +++ b/doc/test/coverage/lcov-report/deployment/allowlist/CMTATUpgradeableAllowlist.sol.html @@ -84,12 +84,12 @@

      -226× +247×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseAllowlist} from "../../modules/3_CMTATBaseAllowlist.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
@@ -115,7 +115,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/allowlist/index.html b/doc/test/coverage/lcov-report/deployment/allowlist/index.html index e2e5f8a4..cc7e00ef 100644 --- a/doc/test/coverage/lcov-report/deployment/allowlist/index.html +++ b/doc/test/coverage/lcov-report/deployment/allowlist/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/debt/CMTATStandaloneDebt.sol.html b/doc/test/coverage/lcov-report/deployment/debt/CMTATStandaloneDebt.sol.html index 4a5dff77..f17ee82f 100644 --- a/doc/test/coverage/lcov-report/deployment/debt/CMTATStandaloneDebt.sol.html +++ b/doc/test/coverage/lcov-report/deployment/debt/CMTATStandaloneDebt.sol.html @@ -101,7 +101,7 @@

      -446× +482×       @@ -111,7 +111,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
@@ -123,7 +123,7 @@ 

* @notice Contract version for standalone deployment * @param admin address of the admin of contract (Access Control) * @param ERC20Attributes_ ERC20 name, symbol and decimals - * @param baseModuleAttributes_ tokenId, terms, information + * @param extraInformationAttributes_ tokenId, terms, information * @param engines_ external contract */ /// @custom:oz-upgrades-unsafe-allow constructor @@ -148,7 +148,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/debt/CMTATUpgradeableDebt.sol.html b/doc/test/coverage/lcov-report/deployment/debt/CMTATUpgradeableDebt.sol.html index e0cc58c3..f0f7d2d9 100644 --- a/doc/test/coverage/lcov-report/deployment/debt/CMTATUpgradeableDebt.sol.html +++ b/doc/test/coverage/lcov-report/deployment/debt/CMTATUpgradeableDebt.sol.html @@ -76,12 +76,12 @@

      -456× +492×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseDebt} from "../../modules/4_CMTATBaseDebt.sol";
 /**
@@ -103,7 +103,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/debt/index.html b/doc/test/coverage/lcov-report/deployment/debt/index.html index 6ea81d37..5f8c0932 100644 --- a/doc/test/coverage/lcov-report/deployment/debt/index.html +++ b/doc/test/coverage/lcov-report/deployment/debt/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/debtEngine/CMTATStandaloneDebtEngine.sol.html b/doc/test/coverage/lcov-report/deployment/debtEngine/CMTATStandaloneDebtEngine.sol.html index 9f8b6028..dfeb6383 100644 --- a/doc/test/coverage/lcov-report/deployment/debtEngine/CMTATStandaloneDebtEngine.sol.html +++ b/doc/test/coverage/lcov-report/deployment/debtEngine/CMTATStandaloneDebtEngine.sol.html @@ -101,7 +101,7 @@

      -450× +486×       @@ -111,7 +111,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
@@ -123,7 +123,7 @@ 

* @notice Contract version for standalone deployment * @param admin address of the admin of contract (Access Control) * @param ERC20Attributes_ ERC20 name, symbol and decimals - * @param baseModuleAttributes_ tokenId, terms, information + * @param extraInformationAttributes_ tokenId, terms, information * @param engines_ external contract */ /// @custom:oz-upgrades-unsafe-allow constructor @@ -148,7 +148,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol.html b/doc/test/coverage/lcov-report/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol.html index 4c56bd21..d8125fd4 100644 --- a/doc/test/coverage/lcov-report/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol.html +++ b/doc/test/coverage/lcov-report/deployment/debtEngine/CMTATUpgradeableDebtEngine.sol.html @@ -76,12 +76,12 @@

      -204× +222×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseDebtEngine} from "../../modules/6_CMTATBaseDebtEngine.sol";
 /**
@@ -103,7 +103,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/debtEngine/index.html b/doc/test/coverage/lcov-report/deployment/debtEngine/index.html index 8b49f219..af0784e9 100644 --- a/doc/test/coverage/lcov-report/deployment/debtEngine/index.html +++ b/doc/test/coverage/lcov-report/deployment/debtEngine/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/holderList/CMTATStandaloneHolderList.sol.html b/doc/test/coverage/lcov-report/deployment/holderList/CMTATStandaloneHolderList.sol.html new file mode 100644 index 00000000..6650c373 --- /dev/null +++ b/doc/test/coverage/lcov-report/deployment/holderList/CMTATStandaloneHolderList.sol.html @@ -0,0 +1,179 @@ + + + + Code coverage report for deployment/holderList/CMTATStandaloneHolderList.sol + + + + + + + +
+
+

+ all files / deployment/holderList/ CMTATStandaloneHolderList.sol +

+
+
+ 100% + Statements + 1/1 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 1/1 +
+
+ 100% + Lines + 1/1 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +24× +  +  +  +  +  +  +  + 
//SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+import {CMTATBaseHolderList} from "../../modules/8_CMTATBaseHolderList.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
+import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
+ 
+ 
+/**
+* @title CMTAT standard version for a standalone deployment (without proxy), with the on-chain holder list
+*/
+contract CMTATStandaloneHolderList is CMTATBaseHolderList {
+    /**
+     * @notice Contract version for standalone deployment
+     * @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/doc/test/coverage/lcov-report/deployment/holderList/CMTATUpgradeableHolderList.sol.html b/doc/test/coverage/lcov-report/deployment/holderList/CMTATUpgradeableHolderList.sol.html new file mode 100644 index 00000000..beaf624e --- /dev/null +++ b/doc/test/coverage/lcov-report/deployment/holderList/CMTATUpgradeableHolderList.sol.html @@ -0,0 +1,137 @@ + + + + Code coverage report for deployment/holderList/CMTATUpgradeableHolderList.sol + + + + + + + +
+
+

+ all files / deployment/holderList/ CMTATUpgradeableHolderList.sol +

+
+
+ 100% + Statements + 1/1 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 1/1 +
+
+ 100% + Lines + 1/1 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +24× +  +  + 
//SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+import {CMTATBaseHolderList} from "../../modules/8_CMTATBaseHolderList.sol";
+import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
+ 
+ 
+/**
+* @title CMTAT standard version for a proxy deployment (Transparent or Beacon proxy), with the on-chain holder list
+*/
+contract CMTATUpgradeableHolderList is CMTATBaseHolderList {
+    /**
+     * @notice Contract version for the deployment with a proxy
+     * @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/doc/test/coverage/lcov-report/deployment/holderList/index.html b/doc/test/coverage/lcov-report/deployment/holderList/index.html new file mode 100644 index 00000000..1b1405c9 --- /dev/null +++ b/doc/test/coverage/lcov-report/deployment/holderList/index.html @@ -0,0 +1,106 @@ + + + + Code coverage report for deployment/holderList/ + + + + + + + +
+
+

+ all files deployment/holderList/ +

+
+
+ 100% + Statements + 2/2 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 2/2 +
+
+ 100% + Lines + 2/2 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
CMTATStandaloneHolderList.sol
100%1/1100%0/0100%1/1100%1/1
CMTATUpgradeableHolderList.sol
100%1/1100%0/0100%1/1100%1/1
+
+
+ + + + + + + diff --git a/doc/test/coverage/lcov-report/deployment/index.html b/doc/test/coverage/lcov-report/deployment/index.html index 704e9948..ae7e83c2 100644 --- a/doc/test/coverage/lcov-report/deployment/index.html +++ b/doc/test/coverage/lcov-report/deployment/index.html @@ -22,22 +22,22 @@

100% Statements - 3/3 + 5/5
100% Branches - 2/2 + 6/6
100% Functions - 4/4 + 6/6
100% Lines - 3/3 + 5/5
@@ -62,26 +62,26 @@

CMTATStandardStandalone.sol
100% - 1/1 + 2/2 100% - 0/0 + 2/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 CMTATStandardUpgradeable.sol
100% - 1/1 + 2/2 100% - 0/0 + 2/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 @@ -103,7 +103,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/light/CMTATStandaloneLight.sol.html b/doc/test/coverage/lcov-report/deployment/light/CMTATStandaloneLight.sol.html index 57416bd3..cd6096d1 100644 --- a/doc/test/coverage/lcov-report/deployment/light/CMTATStandaloneLight.sol.html +++ b/doc/test/coverage/lcov-report/deployment/light/CMTATStandaloneLight.sol.html @@ -93,7 +93,7 @@

      -125× +134×       @@ -101,7 +101,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseCore} from "../../modules/0_CMTATBaseCore.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
@@ -133,7 +133,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/light/CMTATUpgradeableLight.sol.html b/doc/test/coverage/lcov-report/deployment/light/CMTATUpgradeableLight.sol.html index 84a0ba4f..eeef827b 100644 --- a/doc/test/coverage/lcov-report/deployment/light/CMTATUpgradeableLight.sol.html +++ b/doc/test/coverage/lcov-report/deployment/light/CMTATUpgradeableLight.sol.html @@ -80,12 +80,12 @@

      -122× +131×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseCore} from "../../modules/0_CMTATBaseCore.sol";
  
@@ -109,7 +109,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/light/index.html b/doc/test/coverage/lcov-report/deployment/light/index.html index 2f3b85fe..623369fd 100644 --- a/doc/test/coverage/lcov-report/deployment/light/index.html +++ b/doc/test/coverage/lcov-report/deployment/light/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/permit/CMTATStandalonePermit.sol.html b/doc/test/coverage/lcov-report/deployment/permit/CMTATStandalonePermit.sol.html index c23ecc9c..b1a34171 100644 --- a/doc/test/coverage/lcov-report/deployment/permit/CMTATStandalonePermit.sol.html +++ b/doc/test/coverage/lcov-report/deployment/permit/CMTATStandalonePermit.sol.html @@ -103,7 +103,7 @@

      -228× +248×       @@ -113,7 +113,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
@@ -151,7 +151,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/permit/CMTATUpgradeablePermit.sol.html b/doc/test/coverage/lcov-report/deployment/permit/CMTATUpgradeablePermit.sol.html index 70154cfa..86bc940f 100644 --- a/doc/test/coverage/lcov-report/deployment/permit/CMTATUpgradeablePermit.sol.html +++ b/doc/test/coverage/lcov-report/deployment/permit/CMTATUpgradeablePermit.sol.html @@ -78,12 +78,12 @@

      -230× +250×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC2612} from "../../modules/6_CMTATBaseERC2612.sol";
  
@@ -106,7 +106,7 @@ 

diff --git a/doc/test/coverage/lcov-report/deployment/permit/index.html b/doc/test/coverage/lcov-report/deployment/permit/index.html index 41c6110b..63987ee8 100644 --- a/doc/test/coverage/lcov-report/deployment/permit/index.html +++ b/doc/test/coverage/lcov-report/deployment/permit/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/snapshot/CMTATStandaloneSnapshot.sol.html b/doc/test/coverage/lcov-report/deployment/snapshot/CMTATStandaloneSnapshot.sol.html index db7938f0..5dea1eb6 100644 --- a/doc/test/coverage/lcov-report/deployment/snapshot/CMTATStandaloneSnapshot.sol.html +++ b/doc/test/coverage/lcov-report/deployment/snapshot/CMTATStandaloneSnapshot.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
- 100% + 50% Branches - 0/0 + 1/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -81,7 +81,48 @@

36 37 38 -39  +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -100,6 +141,7 @@

      +344×       @@ -111,7 +153,6 @@

      -327×       @@ -119,11 +160,27 @@

      +  +  +  +  +  +  +  +  +  +  +22× +  +   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC2771Snapshot} from "../../modules/7_CMTATBaseERC2771Snapshot.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
 import {ICMTATConstructor} from "../../interfaces/technical/ICMTATConstructor.sol";
  
@@ -131,7 +188,7 @@ 

/** * @title CMTAT with snapshot engine — standalone deployment (without proxy) */ -contract CMTATStandaloneSnapshot is CMTATBaseERC2771Snapshot { +contract CMTATStandaloneSnapshot is CMTATBaseERC2771Snapshot, ReentrancyGuardTransient { /** * @notice Contract version for standalone deployment with snapshot engine * @param forwarderIrrevocable address of the forwarder, required for the gasless support @@ -156,6 +213,30 @@

engines_ ); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override EnonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -163,7 +244,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/snapshot/CMTATUpgradeableSnapshot.sol.html b/doc/test/coverage/lcov-report/deployment/snapshot/CMTATUpgradeableSnapshot.sol.html index 557d19f9..7af75baf 100644 --- a/doc/test/coverage/lcov-report/deployment/snapshot/CMTATUpgradeableSnapshot.sol.html +++ b/doc/test/coverage/lcov-report/deployment/snapshot/CMTATUpgradeableSnapshot.sol.html @@ -22,22 +22,22 @@

100% Statements - 1/1 + 2/2
- 100% + 50% Branches - 0/0 + 1/2
100% Functions - 1/1 + 2/2
100% Lines - 1/1 + 2/2
@@ -67,7 +67,48 @@

22 23 24 -25  +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -77,6 +118,7 @@

      +369×       @@ -88,21 +130,36 @@

      -352× +  +  +  +  +  +  +  +  +  +  +  +  +22×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseERC2771Snapshot} from "../../modules/7_CMTATBaseERC2771Snapshot.sol";
+import {ReentrancyGuardTransient} from "@openzeppelin/contracts/utils/ReentrancyGuardTransient.sol";
+import {ValidationModuleRuleEngine} from "../../modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {IRuleEngine} from "../../interfaces/engine/IRuleEngine.sol";
 import {ERC2771Module} from "../../modules/wrapper/options/ERC2771Module.sol";
  
  
 /**
 * @title CMTAT with snapshot engine — proxy deployment (Transparent or Beacon proxy)
 */
-contract CMTATUpgradeableSnapshot is CMTATBaseERC2771Snapshot {
+contract CMTATUpgradeableSnapshot is CMTATBaseERC2771Snapshot, ReentrancyGuardTransient {
     /**
      * @notice Contract version for the deployment with a proxy, with snapshot engine
      * @param forwarderIrrevocable address of the forwarder, required for the gasless support
@@ -114,6 +171,30 @@ 

// Disable the possibility to initialize the implementation _disableInitializers(); } +  + /** + * @inheritdoc ValidationModuleRuleEngine + * @dev + * @custom:security Wraps the external `ruleEngine.transferred(...)` call — the only point at + * which a transfer hands control to an external contract — in a transient (EIP-1153) reentrancy + * guard, so a rule engine that reenters the token during the callback reverts with + * `ReentrancyGuardReentrantCall` instead of being re-validated against a stale pre-transfer + * balance snapshot. Without it, a compromised engine can pass the active-balance check twice + * against the same state and move more than a holder's unfrozen balance. + * + * This override is applied per deployment variant rather than in the shared base because it + * costs ~195 bytes of deployed bytecode and several variants are within a few hundred bytes of + * the EIP-170 24 KiB limit. See the module documentation for the per-variant table. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual override EnonReentrant { + super._callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } }  

@@ -121,7 +202,7 @@

diff --git a/doc/test/coverage/lcov-report/deployment/snapshot/index.html b/doc/test/coverage/lcov-report/deployment/snapshot/index.html index 06e7485e..aa9989fc 100644 --- a/doc/test/coverage/lcov-report/deployment/snapshot/index.html +++ b/doc/test/coverage/lcov-report/deployment/snapshot/index.html @@ -22,22 +22,22 @@

100% Statements - 2/2 + 4/4
- 100% + 50% Branches - 0/0 + 2/4
100% Functions - 2/2 + 4/4
100% Lines - 2/2 + 4/4
@@ -62,26 +62,26 @@

CMTATStandaloneSnapshot.sol
100% - 1/1 - 100% - 0/0 + 2/2 + 50% + 1/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 CMTATUpgradeableSnapshot.sol
100% - 1/1 - 100% - 0/0 + 2/2 + 50% + 1/2 100% - 1/1 + 2/2 100% - 1/1 + 2/2 @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/index.html b/doc/test/coverage/lcov-report/index.html index fd998231..13d3d723 100644 --- a/doc/test/coverage/lcov-report/index.html +++ b/doc/test/coverage/lcov-report/index.html @@ -20,24 +20,24 @@

- 100% + 99.07% Statements - 700/700 + 747/754
- 92.13% + 91.18% Branches - 433/470 + 465/510
- 100% + 98.38% Functions - 402/402 + 426/433
- 100% + 99.18% Lines - 789/789 + 843/850
@@ -62,13 +62,13 @@

deployment/
100% - 3/3 + 5/5 100% - 2/2 + 6/6 100% - 4/4 + 6/6 100% - 3/3 + 5/5 @@ -88,13 +88,13 @@

deployment/ERC7551/
100% - 2/2 - 100% - 0/0 + 4/4 + 50% + 2/4 100% - 2/2 + 4/4 100% - 2/2 + 4/4 @@ -137,7 +137,7 @@

- deployment/light/ + deployment/holderList/
100% 2/2 @@ -150,7 +150,7 @@

- deployment/permit/ + deployment/light/
100% 2/2 @@ -163,7 +163,7 @@

- deployment/snapshot/ + deployment/permit/
100% 2/2 @@ -175,6 +175,19 @@

2/2 + + deployment/snapshot/ +
+ 100% + 4/4 + 50% + 2/4 + 100% + 4/4 + 100% + 4/4 + + interfaces/engine/
@@ -242,28 +255,28 @@

modules/ -
- 100% - 224/224 - 87.33% - 131/150 - 100% - 175/175 - 100% - 225/225 +
+ 97% + 226/233 + 86% + 129/150 + 96.26% + 180/187 + 97.01% + 227/234 modules/internal/
100% - 106/106 - 96.43% - 54/56 + 108/108 + 96.67% + 58/60 100% 35/35 100% - 130/130 + 132/132 @@ -296,52 +309,52 @@

modules/wrapper/core/
100% - 59/59 - 85.71% - 36/42 + 60/60 + 84.09% + 37/44 100% - 41/41 + 43/43 100% - 78/78 + 80/80 modules/wrapper/extensions/
100% - 61/61 - 91.18% - 31/34 + 65/65 + 94.44% + 34/36 100% - 34/34 + 35/35 100% - 84/84 + 91/91 modules/wrapper/extensions/ValidationModule/
100% - 69/69 + 72/72 100% - 52/52 + 54/54 100% - 14/14 + 15/15 100% - 61/61 + 64/64 modules/wrapper/options/
100% - 96/96 - 92.19% - 59/64 + 123/123 + 91.46% + 75/82 100% - 58/58 + 65/65 100% - 121/121 + 151/151 @@ -363,7 +376,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/engine/IDebtEngine.sol.html b/doc/test/coverage/lcov-report/interfaces/engine/IDebtEngine.sol.html index 151dd833..76659e8a 100644 --- a/doc/test/coverage/lcov-report/interfaces/engine/IDebtEngine.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/engine/IDebtEngine.sol.html @@ -67,7 +67,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol";
  
 /*
@@ -82,7 +82,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/engine/IDocumentEngine.sol.html b/doc/test/coverage/lcov-report/interfaces/engine/IDocumentEngine.sol.html index 73df3d4f..713c9034 100644 --- a/doc/test/coverage/lcov-report/interfaces/engine/IDocumentEngine.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/engine/IDocumentEngine.sol.html @@ -67,7 +67,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IERC1643} from "../tokenization/draft-IERC1643.sol";
 /*
@@ -82,7 +82,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/engine/IRuleEngine.sol.html b/doc/test/coverage/lcov-report/interfaces/engine/IRuleEngine.sol.html index fc76d0de..95498756 100644 --- a/doc/test/coverage/lcov-report/interfaces/engine/IRuleEngine.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/engine/IRuleEngine.sol.html @@ -79,7 +79,37 @@

34 35 36 -37  +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +        @@ -117,7 +147,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IERC1404Extend} from "../tokenization/draft-IERC1404.sol";
 import {IERC3643IComplianceContract} from "../tokenization/IERC3643Partial.sol";
@@ -131,15 +161,30 @@ 

/** * @notice * Function called whenever tokens are transferred from one wallet to another - * @dev + * @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 + * + * WARNING - zero-value calls are permissionless. ERC-20 requires transfers of `0` to be + * treated as normal transfers, and OpenZeppelin's `_spendAllowance` consumes no allowance + * when `value == 0`. Any address can therefore call `transferFrom(victim, anyone, 0)` on the + * token and reach this callback for an arbitrary `from`, with itself as `spender`, without + * ever having been approved. The token deliberately does not suppress the notification, + * because doing so would make its compliance notifications inconsistent with its own + * ERC-20 transfer semantics. + * + * Implementations MUST therefore treat `value == 0` as carrying no economic meaning: any + * stateful rule (cooldown, holding period, quota, tax bucket, counter, holder tracking, ...) + * MUST be a no-op for a zero value, otherwise an attacker can desynchronize policy state + * from balances, or keep a holder permanently restricted, at no cost. The same applies to + * the 3-argument ERC-3643 overload, which a zero-value `transfer(to, 0)` reaches the same way. + * * @param spender spender address (sender) * @param from token holder address * @param to receiver address - * @param value value of tokens involved in the transfer + * @param value value of tokens involved in the transfer; MAY be `0` — see the warning above */ function transferred(address spender, address from, address to, uint256 value) external; } @@ -157,7 +202,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/engine/ISnapshotEngine.sol.html b/doc/test/coverage/lcov-report/interfaces/engine/ISnapshotEngine.sol.html index 90d9d51e..ab6b285f 100644 --- a/doc/test/coverage/lcov-report/interfaces/engine/ISnapshotEngine.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/engine/ISnapshotEngine.sol.html @@ -127,7 +127,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /*
 * @dev minimum interface to define a SnapshotEngine
@@ -172,7 +172,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/engine/index.html b/doc/test/coverage/lcov-report/interfaces/engine/index.html index 90f31aac..943d91c2 100644 --- a/doc/test/coverage/lcov-report/interfaces/engine/index.html +++ b/doc/test/coverage/lcov-report/interfaces/engine/index.html @@ -116,7 +116,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/modules/IAllowlistModule.sol.html b/doc/test/coverage/lcov-report/interfaces/modules/IAllowlistModule.sol.html index f29bd428..e6d8e43b 100644 --- a/doc/test/coverage/lcov-report/interfaces/modules/IAllowlistModule.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/modules/IAllowlistModule.sol.html @@ -180,7 +180,7 @@

 
 
 //SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /*
 * @title Allowlist Module Interface
@@ -250,7 +250,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/modules/IDebtEngineModule.sol.html b/doc/test/coverage/lcov-report/interfaces/modules/IDebtEngineModule.sol.html index 87669859..74dc09b8 100644 --- a/doc/test/coverage/lcov-report/interfaces/modules/IDebtEngineModule.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/modules/IDebtEngineModule.sol.html @@ -102,7 +102,7 @@

 
//SPDX-License-Identifier: MPL-2.0
 import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol";
 import {IDebtEngine} from "../engine/IDebtEngine.sol";
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /**
 * @notice interface to represent DebtEngineModule (debt information and credit events.)
 */
@@ -133,7 +133,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/modules/IDebtModule.sol.html b/doc/test/coverage/lcov-report/interfaces/modules/IDebtModule.sol.html index 1c1599fd..8b337925 100644 --- a/doc/test/coverage/lcov-report/interfaces/modules/IDebtModule.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/modules/IDebtModule.sol.html @@ -150,7 +150,7 @@

 
//SPDX-License-Identifier: MPL-2.0
 import {ICMTATDebt, ICMTATCreditEvents} from "../tokenization/ICMTAT.sol";
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /**
 * @notice interface to represent DebtModule (debt information and credit events.)
 */
@@ -205,7 +205,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/modules/IDocumentEngineModule.sol.html b/doc/test/coverage/lcov-report/interfaces/modules/IDocumentEngineModule.sol.html index 28769424..2d3a1f27 100644 --- a/doc/test/coverage/lcov-report/interfaces/modules/IDocumentEngineModule.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/modules/IDocumentEngineModule.sol.html @@ -84,7 +84,15 @@

39 40 41 -42  +42 +43 +44 +45 +46  +  +  +  +        @@ -127,7 +135,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IERC1643} from "../tokenization/draft-IERC1643.sol";
  
@@ -149,6 +157,10 @@ 

* @notice Thrown when attempting to set the same document engine as the current one. */ error CMTAT_DocumentEngineModule_SameValue(); + /** + * @notice Thrown when a document mutation is attempted while no document engine is set. + */ + error CMTAT_DocumentEngineModule_NoDocumentEngine(); /* ============ Functions ============ */ /** * @notice Sets a new document engine contract. @@ -172,7 +184,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/modules/IHolderListModule.sol.html b/doc/test/coverage/lcov-report/interfaces/modules/IHolderListModule.sol.html new file mode 100644 index 00000000..7083a951 --- /dev/null +++ b/doc/test/coverage/lcov-report/interfaces/modules/IHolderListModule.sol.html @@ -0,0 +1,365 @@ + + + + Code coverage report for interfaces/modules/IHolderListModule.sol + + + + + + + +
+
+

+ all files / interfaces/modules/ IHolderListModule.sol +

+
+
+ 100% + Statements + 0/0 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 0/0 +
+
+ 100% + Lines + 0/0 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
//SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+/*
+* @title Holder List Module Interface
+* @notice Maintain on-chain the list of the addresses holding a non-zero balance
+* @dev The holder set is a view over `balanceOf`: an address belongs to it if and only if
+* its balance is non-zero. {holderCount}, {holderByIndex}, {isHolder}, {holders} and
+* {holdersInRange} follow the naming of the fungible holder-enumeration specification.
+*/
+interface IHolderListModule {
+    /* ============ Errors ============ */
+    /**
+     * @notice A requested index is past the end of the holder set
+     * @dev Raised by {holderByIndex} when `index >= holderCount()`, and by {holdersInRange}
+     * when `toIndex > holderCount()`. The second parameter is always the current holder count,
+     * so a caller that raced a concurrent removal learns the new bound from the revert data.
+     * @param index The index that was requested
+     * @param holderCount The current number of holders, i.e. the exclusive upper bound
+     */
+    error CMTAT_HolderListModule_IndexOutOfBounds(uint256 index, uint256 holderCount);
+    /**
+     * @notice A range is malformed because its lower bound exceeds its upper bound
+     * @dev Distinct from {CMTAT_HolderListModule_IndexOutOfBounds}: the range is not past the
+     * end of the set, it is internally inconsistent, so neither argument is a holder count.
+     * @param fromIndex The requested lower bound, inclusive
+     * @param toIndex The requested upper bound, exclusive
+     */
+    error CMTAT_HolderListModule_InvalidRange(uint256 fromIndex, uint256 toIndex);
+ 
+    /* ============ Events ============ */
+    /**
+     * @notice Emitted when an address becomes a holder, its balance moving from zero to non-zero
+     * @param holder The address added to the holder list
+     */
+    event HolderAdded(address indexed holder);
+    /**
+     * @notice Emitted when an address stops being a holder, its balance moving from non-zero to zero
+     * @param holder The address removed from the holder list
+     */
+    event HolderRemoved(address indexed holder);
+ 
+    /* ============ Functions ============ */
+    /**
+     * @notice Returns the number of addresses currently holding a non-zero balance
+     * @return The holder count
+     */
+    function holderCount() external view returns (uint256);
+ 
+    /**
+     * @notice Returns whether an account currently holds a non-zero balance
+     * @param account The address to check
+     * @return True if the address is a holder, false otherwise
+     */
+    function isHolder(address account) external view returns (bool);
+ 
+    /**
+     * @notice Returns the holder stored at a given index
+     * @dev Reverts with {CMTAT_HolderListModule_IndexOutOfBounds} if `index >= holderCount()`.
+     * Holders are stored in an unordered set: the index of a given holder is not stable across
+     * state changes. See {holdersInRange} for the implications on pagination.
+     * @param index The position in the holder set, in `[0, holderCount())`
+     * @return The holder address at `index`
+     */
+    function holderByIndex(uint256 index) external view returns (address);
+ 
+    /**
+     * @notice Returns the whole holder list in a single call
+     * @dev Unbounded: the cost grows with {holderCount} and this call will run out of gas once
+     * the holder list is large enough. It is intended for off-chain `eth_call`. On-chain callers,
+     * and any caller that cannot bound the holder count, MUST use {holdersInRange} instead.
+     * The returned array is ordered as {holderByIndex}: `holders()[i] == holderByIndex(i)` within
+     * a single block, and `holders()` is exactly `holdersInRange(0, holderCount())`.
+     * @return The full list of holder addresses
+     */
+    function holders() external view returns (address[] memory);
+ 
+    /**
+     * @notice Returns the contiguous window of holders at indices `[fromIndex, toIndex)`
+     * @dev Half-open: `fromIndex` inclusive, `toIndex` exclusive, so the returned length is
+     * exactly `toIndex - fromIndex`. The window is a slice of the sequence {holderByIndex}
+     * enumerates: `holdersInRange(f, t)[i] == holderByIndex(f + i)` within a single block.
+     *
+     * Reverts with {CMTAT_HolderListModule_InvalidRange} if `fromIndex > toIndex`, and with
+     * {CMTAT_HolderListModule_IndexOutOfBounds} if `toIndex > holderCount()`. The malformed-range
+     * check is evaluated first, so an inverted range always yields {CMTAT_HolderListModule_InvalidRange}
+     * regardless of where the bounds fall. `fromIndex == toIndex` returns an empty array without
+     * reverting, including when both equal `holderCount()` — the natural terminating condition of
+     * a paging loop.
+     *
+     * The underlying set is unordered and a removal moves the last holder into the freed slot, so
+     * windows read across several blocks may miss a holder or return one twice. Read the whole set
+     * at a fixed block (`eth_call` at a block number) if a consistent snapshot is required.
+     * @param fromIndex The index of the first holder to return, inclusive
+     * @param toIndex The index one past the last holder to return, exclusive
+     * @return window The holders at indices `fromIndex` through `toIndex - 1`, in enumeration order
+     */
+    function holdersInRange(uint256 fromIndex, uint256 toIndex) external view returns (address[] memory window);
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/lcov-report/interfaces/modules/ISnapshotEngineModule.sol.html b/doc/test/coverage/lcov-report/interfaces/modules/ISnapshotEngineModule.sol.html index 1bfbd988..7d99c5e7 100644 --- a/doc/test/coverage/lcov-report/interfaces/modules/ISnapshotEngineModule.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/modules/ISnapshotEngineModule.sol.html @@ -129,7 +129,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Engine === */
 import {ISnapshotEngine} from "../engine/ISnapshotEngine.sol";
@@ -175,7 +175,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/modules/index.html b/doc/test/coverage/lcov-report/interfaces/modules/index.html index 01bcfd8e..57b3b4f5 100644 --- a/doc/test/coverage/lcov-report/interfaces/modules/index.html +++ b/doc/test/coverage/lcov-report/interfaces/modules/index.html @@ -110,6 +110,19 @@

0/0 + + IHolderListModule.sol +
+ 100% + 0/0 + 100% + 0/0 + 100% + 0/0 + 100% + 0/0 + + ISnapshotEngineModule.sol
@@ -129,7 +142,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/technical/ICMTATConstructor.sol.html b/doc/test/coverage/lcov-report/interfaces/technical/ICMTATConstructor.sol.html index c31cc696..4edc80b5 100644 --- a/doc/test/coverage/lcov-report/interfaces/technical/ICMTATConstructor.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/technical/ICMTATConstructor.sol.html @@ -106,7 +106,7 @@

     
//SPDX-License-Identifier: MPL-2.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IRuleEngine} from "../engine/IRuleEngine.sol";
 import {IERC1643CMTAT} from "../tokenization/draft-IERC1643CMTAT.sol";
@@ -142,7 +142,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/technical/IERC20Allowance.sol.html b/doc/test/coverage/lcov-report/interfaces/technical/IERC20Allowance.sol.html index 64597636..4131b793 100644 --- a/doc/test/coverage/lcov-report/interfaces/technical/IERC20Allowance.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/technical/IERC20Allowance.sol.html @@ -71,7 +71,25 @@

26 27 28 -29  +29 +30 +31 +32 +33 +34 +35 +36 +37 +38  +  +  +  +  +  +  +  +  +        @@ -101,7 +119,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /**
  * @title IERC20Allowance
@@ -110,19 +128,28 @@ 

interface IERC20Allowance { /* ============ Events ============ */ /** - * @notice Emitted when a `spender` spends a `value` amount of tokens on behalf of an `account`. + * @notice Emitted when a `spender` uses a `value` amount of an `account`'s allowance. * @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. + * - Similar in intent to the ERC-20 `Approval` event, but signals *consumption* of an + * allowance rather than its granting. + * - Emitted by the allowance-consuming entry points: `transferFrom` (ERC20BaseModule), + * `burnFrom` (ERC20CrossChainModule), and `forcedTransfer` (ERC20EnforcementModule) when the + * latter reduces a finite owner→recipient allowance. + * - WARNING - this event does NOT, by itself, imply that the on-chain allowance decreased. + * It is emitted on *every* successful allowance-consuming `transferFrom` / `burnFrom`, + * including when the allowance is infinite (`type(uint256).max`), in which case OpenZeppelin + * leaves the allowance unchanged. `value` is the amount used, not the size of any reduction. + * - For `forcedTransfer`, `Spend` is emitted only when the allowance is finite and non-zero + * (the case where it is actually reduced), and `value` is the amount taken from it (capped by + * the allowance). `forcedTransfer` does not emit `Approval` for that reduction. + * - To reconstruct the current allowance, read `allowance(owner, spender)` — never accumulate + * `Spend` (or `Approval`) events. + * - Event ordering differs between the emit sites: `transferFrom` emits `Transfer` then + * `Spend`; `burnFrom` emits `Spend` then `Transfer` then `BurnFrom`. See + * [doc/technical/allowance-spend-event.md](../../../doc/technical/allowance-spend-event.md). * @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. + * @param value The amount of allowance used (not necessarily the amount by which it decreased). */ event Spend(address indexed account, address indexed spender, uint256 value); } @@ -133,7 +160,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/technical/IERC5679.sol.html b/doc/test/coverage/lcov-report/interfaces/technical/IERC5679.sol.html index ab7186ea..571b6a6d 100644 --- a/doc/test/coverage/lcov-report/interfaces/technical/IERC5679.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/technical/IERC5679.sol.html @@ -132,7 +132,7 @@

     
// SPDX-License-Identifier: MPL-2.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
  
@@ -181,7 +181,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/technical/IERC7802.sol.html b/doc/test/coverage/lcov-report/interfaces/technical/IERC7802.sol.html index 67e7cf26..456f6d22 100644 --- a/doc/test/coverage/lcov-report/interfaces/technical/IERC7802.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/technical/IERC7802.sol.html @@ -115,7 +115,7 @@

   
// SPDX-License-Identifier: MIT
 // From https://github.com/ethereum-optimism/optimism/blob/op-node/v1.13.2/packages/contracts-bedrock/interfaces/L2/IERC7802.sol
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
  
@@ -154,7 +154,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/technical/IGetCCIPAdmin.sol.html b/doc/test/coverage/lcov-report/interfaces/technical/IGetCCIPAdmin.sol.html index f3482c00..481ad67e 100644 --- a/doc/test/coverage/lcov-report/interfaces/technical/IGetCCIPAdmin.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/technical/IGetCCIPAdmin.sol.html @@ -54,7 +54,9 @@

9 10 11 -12  +12 +13  +        @@ -66,7 +68,7 @@

     
// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 interface IGetCCIPAdmin {
   event CCIPAdminTransferred(address indexed previousAdmin, address indexed newAdmin);
@@ -74,6 +76,7 @@ 

/** * @notice Returns the admin of the token. * @dev This method is named to never conflict with existing methods. + * @return The address of the token's CCIP admin. */ function getCCIPAdmin() external view returns (address); }

@@ -82,7 +85,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/technical/IMintBurnToken.sol.html b/doc/test/coverage/lcov-report/interfaces/technical/IMintBurnToken.sol.html index 5167bcb9..469851fc 100644 --- a/doc/test/coverage/lcov-report/interfaces/technical/IMintBurnToken.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/technical/IMintBurnToken.sol.html @@ -173,7 +173,9 @@

128 129 130 -131  +131 +132  +        @@ -305,7 +307,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
  
 /**
@@ -338,6 +340,7 @@ 

* @param to receiver to send the new minted tokens * @param amountToBurn number of tokens to burn * @param amountToMint number of tokens to mint +* @param data Optional data forwarded to the burn and mint hooks. */ function burnAndMint(address from, address to, uint256 amountToBurn, uint256 amountToMint, bytes calldata data) external; } @@ -439,7 +442,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/technical/index.html b/doc/test/coverage/lcov-report/interfaces/technical/index.html index 684f4223..65aa3721 100644 --- a/doc/test/coverage/lcov-report/interfaces/technical/index.html +++ b/doc/test/coverage/lcov-report/interfaces/technical/index.html @@ -142,7 +142,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/ICMTAT.sol.html b/doc/test/coverage/lcov-report/interfaces/tokenization/ICMTAT.sol.html index 00290a8b..efffc54e 100644 --- a/doc/test/coverage/lcov-report/interfaces/tokenization/ICMTAT.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/ICMTAT.sol.html @@ -194,107 +194,7 @@

149 150 151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  +152        @@ -447,64 +347,12 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 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
-* the distributed ledger.
-* Contrary to the “burn” function, the “deactivateContract” function
-* affects all tokens in issuance, and not only some of them. 
-* 
-* a) This function is necessary to allow the issuer to carry out certain corporate actions 
-* (e.g. share splits, reverse splits or mergers), which 
-* require that all existing tokens are either canceled or immobilized and decoupled from the shares
-* (i.e. the tokens no longer represent shares).
-* 
-* b) The “deactivateContract” function can also be used if the issuer decides that it no longer wishes
-* to have its shares issued in the form of ledger-based securities
-* 
-* The “deactivateContract” function does not delete the smart contract’s 
-* storage and code, i.e. tokens are not burned by the function, however it permanently and
-* irreversibly deactivates the smart contract (unless a proxy is used). 
-* 
-*/
-interface ICMTATDeactivate {
-     /**
-     * @notice Emitted when the contract is permanently deactivated.
-     * @param account The address that performed the 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.
-     * @dev 
-     * This action is irreversible — once executed, the contract cannot be reactivated.
-     * Requirements:
-     * - The contract MUST be paused before deactivation is allowed.
-     * Emits a {Deactivated} event.
-     * WARNING: Use with caution. This action permanently disables core contract functionality.
-     */
-    function deactivateContract() external;
- 
-     /**
-     * @notice Returns whether the contract has been permanently deactivated.
-     * @return isDeactivated A boolean indicating the deactivation status.
-     * @dev Returns `true` if `deactivateContract()` has been successfully called.
-     */
-    function deactivated() external view returns (bool isDeactivated) ;
-}
- 
- 
- 
-/** 
 * @title ICMTATBase - Core Tokenization Metadata Interface as part of CMTAT specification
 * @notice Defines base properties and metadata structure for a tokenized asset.
 * @dev Includes token ID, terms (using IERC1643-compliant document), and a general information field.
@@ -583,6 +431,7 @@ 

interface ICMTATCreditEvents { /** * @notice Returns credit events + * @return creditEvents_ The current credit-event flags for the token. */ function creditEvents() external view returns(CreditEvents memory creditEvents_);   @@ -643,6 +492,7 @@

} /** * @notice Returns debt information + * @return debtInformation_ The current debt information for the token. */ function debt() external view returns(DebtInformation memory debtInformation_); } @@ -652,7 +502,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/IERC3643Partial.sol.html b/doc/test/coverage/lcov-report/interfaces/tokenization/IERC3643Partial.sol.html index 3a62f046..f434e4f1 100644 --- a/doc/test/coverage/lcov-report/interfaces/tokenization/IERC3643Partial.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/IERC3643Partial.sol.html @@ -343,7 +343,15 @@

298 299 300 -301  +301 +302 +303 +304 +305  +  +  +  +        @@ -652,7 +660,7 @@

* (e.g., `amount` → `value`). */   -pragma solidity ^0.8.20; +pragma solidity ^0.8.24;   import {IERC7943FungibleEnforcement} from "./draft-IERC7943.sol";   @@ -921,6 +929,10 @@

/** * @notice Returns true if the transfer is valid, and false otherwise. * @dev Don't check the balance and the user's right (access control) + * @param from The address sending tokens. + * @param to The address receiving tokens. + * @param value The amount of tokens to transfer. + * @return isValid True if the transfer is valid, false otherwise. */ function canTransfer( address from, @@ -949,7 +961,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1404.sol.html b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1404.sol.html index b4558f42..9e5abfda 100644 --- a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1404.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1404.sol.html @@ -121,7 +121,17 @@

76 77 78 -79  +79 +80 +81 +82 +83 +84  +  +  +  +  +        @@ -201,7 +211,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /*
 * @dev Contrary to the ERC-1404,
@@ -231,9 +241,10 @@ 

  /** * @dev See {ERC-1404} - * This function is effectively an accessor for the "message", - * a human-readable explanation as to why a transaction is restricted. - * + * This function is effectively an accessor for the "message", + * a human-readable explanation as to why a transaction is restricted. + * @param restrictionCode The restriction code to translate into a message. + * @return The human-readable message corresponding to `restrictionCode`. */ function messageForTransferRestriction( uint8 restrictionCode @@ -266,6 +277,10 @@

* 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. + * @param spender The address initiating the delegated transfer. + * @param from The address sending tokens. + * @param to The address receiving tokens. + * @param value amount of tokens to transfer * @return uint8 restricted code, 0 means the transfer is authorized * */ @@ -283,7 +298,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1643.sol.html b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1643.sol.html index c9b6825d..1838f8bf 100644 --- a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1643.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1643.sol.html @@ -84,7 +84,25 @@

39 40 41 -42  +42 +43 +44 +45 +46 +47 +48 +49 +50 +51  +  +  +  +  +  +  +  +  +        @@ -127,7 +145,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /**
 * @title IERC1643 Document Management 
@@ -135,6 +153,11 @@ 

* Contrary to the original specification, use a struct Document to represent a Document */ interface IERC1643 { + /// @dev Reverted when removing a document whose name is not registered. + error ERC1643MissingDocument(); + /// @dev Reverted when setting a document with the zero name. + error ERC1643InvalidName(); +  /// @dev Struct used to represent a document and its metadata. struct Document { // URI of the off-chain document (e.g., IPFS, HTTPS) @@ -148,10 +171,14 @@

// Document Management /** * @notice Retrieves a document by its registered name. + * @dev Returns the three fields as flat values, matching the ERC-1643 ABI. A missing + * document yields empty values and does not revert. * @param name The unique name used to identify the document. - * @return document The associated document's metadata (URI, hash, timestamp). + * @return uri The URI of the off-chain document. + * @return documentHash The hash of the document content. + * @return lastModified The timestamp of the last on-chain modification. */ - function getDocument(bytes32 name) external view returns (Document memory document); + function getDocument(bytes32 name) external view returns (string memory uri, bytes32 documentHash, uint256 lastModified); /** * @notice Returns the list of all document names registered in the contract. * @return documentNames_ An array of strings representing all document identifiers. @@ -172,7 +199,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1643CMTAT.sol.html b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1643CMTAT.sol.html index 766961e7..1e7370a1 100644 --- a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1643CMTAT.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC1643CMTAT.sol.html @@ -67,7 +67,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 interface IERC1643CMTAT {
     struct DocumentInfo {
         string name;
@@ -82,7 +82,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC7551.sol.html b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC7551.sol.html index 2d1fd287..0859c3ec 100644 --- a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC7551.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC7551.sol.html @@ -449,7 +449,7 @@

import {IERC3643ComplianceRead} from "./IERC3643Partial.sol"; import {IERC5679Mint, IERC5679Burn} from "../technical/IERC5679.sol";   -pragma solidity ^0.8.20; +pragma solidity ^0.8.24;     /** @@ -652,7 +652,7 @@

diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC7943.sol.html b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC7943.sol.html index 5a1d8e52..b6b1434a 100644 --- a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC7943.sol.html +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC7943.sol.html @@ -313,7 +313,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /**
 * @notice Enforcement Interface for ERC-20 based implementations common with ERC-3643 interface.
@@ -451,7 +451,7 @@ 

diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC8343.sol.html b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC8343.sol.html new file mode 100644 index 00000000..41948016 --- /dev/null +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/draft-IERC8343.sol.html @@ -0,0 +1,251 @@ + + + + Code coverage report for interfaces/tokenization/draft-IERC8343.sol + + + + + + + +
+
+

+ all files / interfaces/tokenization/ draft-IERC8343.sol +

+
+
+ 100% + Statements + 0/0 +
+
+ 100% + Branches + 0/0 +
+
+ 100% + Functions + 0/0 +
+
+ 100% + Lines + 0/0 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+/**
+* @title IERC8343 - Contract Deactivation
+* @notice Interface for permanently deactivating a token contract and exposing its
+* deactivation status on-chain. Follows the proposed ERC-8343 (draft, not yet merged).
+*
+* @dev The issuer must be able to "deactivate" the smart contract, to prevent execution of
+* transactions on the distributed ledger.
+* Contrary to the "burn" function, the "deactivateContract" function
+* affects all tokens in issuance, and not only some of them.
+*
+* a) This function is necessary to allow the issuer to carry out certain corporate actions
+* (e.g. share splits, reverse splits or mergers), which
+* require that all existing tokens are either canceled or immobilized and decoupled from the shares
+* (i.e. the tokens no longer represent shares).
+*
+* b) The "deactivateContract" function can also be used if the issuer decides that it no longer wishes
+* to have its shares issued in the form of ledger-based securities.
+*
+* The "deactivateContract" function does not delete the smart contract's
+* storage and code, i.e. tokens are not burned by the function, however it permanently and
+* irreversibly deactivates the smart contract (unless a proxy is used).
+*
+* @dev The ERC-8343 interface identifier is `0xe9cd80b0`, the exclusive-or of the selectors of
+* `deactivateContract()` and `deactivated()`. This interface deliberately does NOT inherit
+* `IERC165`, so that `type(IERC8343).interfaceId` equals `0xe9cd80b0`; adding `is IERC165` would
+* fold `supportsInterface`'s selector into the id and change it. ERC-165 support is advertised
+* separately by the implementing contract.
+*/
+interface IERC8343 {
+     /**
+     * @notice Emitted when the contract is permanently deactivated.
+     * @param account The address that performed the 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.
+     * @dev
+     * This action is irreversible — once executed, the contract cannot be reactivated.
+     * Requirements:
+     * - The contract MUST be paused before deactivation is allowed.
+     * Emits a {Deactivated} event.
+     * WARNING: Use with caution. This action permanently disables core contract functionality.
+     */
+    function deactivateContract() external;
+ 
+     /**
+     * @notice Returns whether the contract has been permanently deactivated.
+     * @return isDeactivated A boolean indicating the deactivation status.
+     * @dev Returns `true` if `deactivateContract()` has been successfully called.
+     */
+    function deactivated() external view returns (bool isDeactivated);
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/lcov-report/interfaces/tokenization/index.html b/doc/test/coverage/lcov-report/interfaces/tokenization/index.html index 07943a32..b9516d88 100644 --- a/doc/test/coverage/lcov-report/interfaces/tokenization/index.html +++ b/doc/test/coverage/lcov-report/interfaces/tokenization/index.html @@ -149,13 +149,26 @@

0/0 + + draft-IERC8343.sol +
+ 100% + 0/0 + 100% + 0/0 + 100% + 0/0 + 100% + 0/0 + +
diff --git a/doc/test/coverage/lcov-report/library/ERC1404ExtendInterfaceId.sol.html b/doc/test/coverage/lcov-report/library/ERC1404ExtendInterfaceId.sol.html index 6546f4fa..2c1db3b7 100644 --- a/doc/test/coverage/lcov-report/library/ERC1404ExtendInterfaceId.sol.html +++ b/doc/test/coverage/lcov-report/library/ERC1404ExtendInterfaceId.sol.html @@ -76,7 +76,7 @@

     
// SPDX-License-Identifier: MPL-2.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 library ERC1404ExtendInterfaceId {
       /**
@@ -97,7 +97,7 @@ 

diff --git a/doc/test/coverage/lcov-report/library/RuleEngineInterfaceId.sol.html b/doc/test/coverage/lcov-report/library/RuleEngineInterfaceId.sol.html index 55f6edc8..87587139 100644 --- a/doc/test/coverage/lcov-report/library/RuleEngineInterfaceId.sol.html +++ b/doc/test/coverage/lcov-report/library/RuleEngineInterfaceId.sol.html @@ -54,7 +54,7 @@

     
// SPDX-License-Identifier: MPL-2.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 library RuleEngineInterfaceId {
       bytes4 public constant RULE_ENGINE_INTERFACE_ID = 0x20c49ce7;
@@ -64,7 +64,7 @@ 

diff --git a/doc/test/coverage/lcov-report/library/index.html b/doc/test/coverage/lcov-report/library/index.html index ed18ad45..186a578a 100644 --- a/doc/test/coverage/lcov-report/library/index.html +++ b/doc/test/coverage/lcov-report/library/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/0_CMTATBaseCommon.sol.html b/doc/test/coverage/lcov-report/modules/0_CMTATBaseCommon.sol.html index 8b130eac..f8894b6d 100644 --- a/doc/test/coverage/lcov-report/modules/0_CMTATBaseCommon.sol.html +++ b/doc/test/coverage/lcov-report/modules/0_CMTATBaseCommon.sol.html @@ -192,7 +192,14 @@

147 148 149 -150  +150 +151 +152 +153 +154 +155  +  +        @@ -250,23 +257,23 @@

      -80× +88×             -68× +70×           -431× -431× -248× -197× +442× +442× +252× +190×       @@ -281,8 +288,8 @@

      -278× -118× +306× +174×       @@ -307,7 +314,10 @@

      -8426× +8968× +  +  +        @@ -315,10 +325,10 @@

      +6737× +6571×     -6250× -6063×       @@ -326,9 +336,9 @@

      +1169× +957×   -1175× -951×       @@ -337,13 +347,13 @@

      -292× +314× 199×      
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
  
 /* ==== Wrapper === */
@@ -356,6 +366,7 @@ 

import {ERC20EnforcementModule, ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol"; // options import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol"; +import {TokenAttributeModule} from "./wrapper/core/TokenAttributeModule.sol"; /* ==== Interface and other library === */ import {IBurnMintERC20} from "../interfaces/technical/IMintBurnToken.sol"; import {IERC5679} from "../interfaces/technical/IERC5679.sol"; @@ -366,6 +377,7 @@

ERC20MintModule, ERC20BurnModule, ERC20BaseModule, + TokenAttributeModule, // Extension ERC20EnforcementModule, ExtraInformationModule, @@ -396,17 +408,17 @@

    /** - * @inheritdoc ERC20BaseModule + * @inheritdoc TokenAttributeModule */ - function name() public view virtual override(ERC20Upgradeable, ERC20BaseModule) returns (string memory) { - return ERC20BaseModule.name(); + function name() public view virtual override(ERC20Upgradeable, TokenAttributeModule) returns (string memory) { + return TokenAttributeModule.name(); }   /** - * @inheritdoc ERC20BaseModule + * @inheritdoc TokenAttributeModule */ - function symbol() public view virtual override(ERC20Upgradeable, ERC20BaseModule) returns (string memory) { - return ERC20BaseModule.symbol(); + function symbol() public view virtual override(ERC20Upgradeable, TokenAttributeModule) returns (string memory) { + return TokenAttributeModule.symbol(); }     @@ -461,9 +473,10 @@

/* ==== Mint and Burn Operations ==== */ /** - * @dev + * @dev * Mint path * Check if the mint is valid + * @inheritdoc ERC20MintModuleInternal */ function _mintOverride(address account, uint256 value) internal virtual override(ERC20MintModuleInternal) { _checkTransferred(_msgSender(), address(0), account, value); @@ -471,9 +484,10 @@

}   /** - * @dev + * @dev * Burn path * Check if the burn is valid + * @inheritdoc ERC20BurnModuleInternal */ function _burnOverride(address account, uint256 value) internal virtual override(ERC20BurnModuleInternal) { _checkTransferred(_msgSender(), account, address(0), value); @@ -481,9 +495,10 @@

}   /** - * @dev + * @dev * Minter-initiated transfer path * Check if a minter transfer is valid + * @inheritdoc ERC20MintModuleInternal */ function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(ERC20MintModuleInternal) { _checkTransferred(_msgSender(), from, to, value); @@ -496,7 +511,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/0_CMTATBaseCore.sol.html b/doc/test/coverage/lcov-report/modules/0_CMTATBaseCore.sol.html index 591c88a0..510c62dd 100644 --- a/doc/test/coverage/lcov-report/modules/0_CMTATBaseCore.sol.html +++ b/doc/test/coverage/lcov-report/modules/0_CMTATBaseCore.sol.html @@ -22,7 +22,7 @@

100% Statements - 33/33 + 34/34
86.67% @@ -37,7 +37,7 @@

100% Lines - 34/34 + 35/35

@@ -323,7 +323,22 @@

278 279 280 -281  +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293  +  +  +        @@ -397,7 +412,7 @@

      -247× +265×       @@ -413,16 +428,16 @@

      -284× +318×     -284× +318×     -284× +318×     -284× +318×       @@ -430,8 +445,8 @@

      -284× -284× +318× +318×       @@ -440,8 +455,9 @@

      -284× -284× +318× +318× +318×       @@ -493,7 +509,7 @@

      -12× +19×       @@ -501,18 +517,18 @@

      -28× -28× -18× -12× +26× +26× +16× +10×             -30× -24× +54× +44×       @@ -527,8 +543,8 @@

      +18× 14× -10×       @@ -559,6 +575,10 @@

      +  +  +  +    @@ -571,8 +591,8 @@

      -354× -346× +368× +360×       @@ -585,7 +605,11 @@

      -18× +  +  +  +  +20× 12×     @@ -605,7 +629,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -616,6 +640,7 @@ 

import {ERC20BurnModule, ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol"; import {ERC20MintModule, ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol"; import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol"; +import {TokenAttributeModule} from "./wrapper/core/TokenAttributeModule.sol";   // Other import {VersionModule} from "./wrapper/core/VersionModule.sol"; @@ -634,6 +659,7 @@

import {IERC7551ERC20EnforcementEvent} from "../interfaces/tokenization/draft-IERC7551.sol"; import {IERC7943FungibleTransferError} from "../interfaces/tokenization/draft-IERC7943.sol"; import {IERC5679} from "../interfaces/technical/IERC5679.sol"; +import {IERC8343} from "../interfaces/tokenization/draft-IERC8343.sol";   /** * @dev CMTAT with core modules @@ -648,6 +674,7 @@

ERC20BurnModule, ValidationModuleAllowance, ERC20BaseModule, + TokenAttributeModule, AccessControlModule, IForcedBurnERC20, IBurnMintERC20, @@ -721,7 +748,8 @@

function __CMTAT_modules_init_unchained(address admin, ICMTATConstructor.ERC20Attributes memory ERC20Attributes_ ) internal virtual EonlyInitializing { // AccessControlModule_init_unchained is called firstly due to inheritance __AccessControlModule_init_unchained(admin); - __ERC20BaseModule_init_unchained(ERC20Attributes_.decimalsIrrevocable, ERC20Attributes_.name, ERC20Attributes_.symbol); + __ERC20BaseModule_init_unchained(ERC20Attributes_.decimalsIrrevocable); + __TokenAttributeModule_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol); }     @@ -751,17 +779,17 @@

    /** - * @inheritdoc ERC20BaseModule + * @inheritdoc TokenAttributeModule */ - function name() public virtual override(ERC20Upgradeable, ERC20BaseModule) view returns (string memory) { - return ERC20BaseModule.name(); + function name() public virtual override(ERC20Upgradeable, TokenAttributeModule) view returns (string memory) { + return TokenAttributeModule.name(); }   /** - * @inheritdoc ERC20BaseModule + * @inheritdoc TokenAttributeModule */ - function symbol() public virtual override(ERC20Upgradeable, ERC20BaseModule) view returns (string memory) { - return ERC20BaseModule.symbol(); + function symbol() public virtual override(ERC20Upgradeable, TokenAttributeModule) view returns (string memory) { + return TokenAttributeModule.symbol(); }   /** @@ -770,10 +798,10 @@

* 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 (0x3edbb4c4) - * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate + * type(IERC8343).interfaceId (0xe9cd80b0) is the proposed ERC-8343 (draft) contract deactivation interface */ function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) { - return interfaceId == 0xd0017968 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId); + return interfaceId == 0xd0017968 || interfaceId == type(IERC8343).interfaceId || AccessControlUpgradeable.supportsInterface(interfaceId); }   /* ============ State Functions ============ */ @@ -791,7 +819,7 @@

* @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); } /* @@ -831,6 +859,10 @@

  /** * @inheritdoc IForcedBurnERC20 + * @dev Burns directly via `ERC20Upgradeable._burn`, so it bypasses the pause/deactivation + * validation used by the standard burn path. This is intentional — the Light variant's + * enforcement burn remains available **after deactivation** (per ERC-8343), so the enforcer + * can still cancel a frozen or migrated position on a terminated token. * @custom:access-control * - The caller must have the `DEFAULT_ADMIN_ROLE`. */ @@ -865,7 +897,11 @@

* @dev Check if a minter transfer is valid */ function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(ERC20MintModuleInternal) { - ValidationModule._canTransferGenericByModuleAndRevert(address(0), from, to); + // Pass the operator (_msgSender()) as spender, consistent with CMTATBaseCommon and the + // transferFrom path, instead of hardcoding address(0). A minter transfer moves the + // minter's own tokens, so `from == _msgSender()`; threading the spender keeps the + // spender-aware validation surface uniform across the Light and full bases (NM-5). + ValidationModule._canTransferGenericByModuleAndRevert(_msgSender(), from, to); ERC20MintModuleInternal._minterTransferOverride(from, to, value); }   @@ -881,7 +917,7 @@

  function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}   - function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) onlyRole(DEFAULT_ADMIN_ROLE){} + function _authorizeTokenAttributeManagement() internal virtual override(TokenAttributeModule) onlyRole(DEFAULT_ADMIN_ROLE){} }  

@@ -889,7 +925,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/0_CMTATBaseGeneric.sol.html b/doc/test/coverage/lcov-report/modules/0_CMTATBaseGeneric.sol.html index 7caea995..378b2657 100644 --- a/doc/test/coverage/lcov-report/modules/0_CMTATBaseGeneric.sol.html +++ b/doc/test/coverage/lcov-report/modules/0_CMTATBaseGeneric.sol.html @@ -180,16 +180,16 @@

      -62× +72×     -62× +72×     -62× +72×     -62× +72×       @@ -197,8 +197,8 @@

      -62× -62× +72× +72×       @@ -206,9 +206,9 @@

      -62× +72×   -62× +72×       @@ -221,7 +221,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -313,7 +313,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/0_CMTATBaseSnapshot.sol.html b/doc/test/coverage/lcov-report/modules/0_CMTATBaseSnapshot.sol.html index a91f20d9..045ffb5d 100644 --- a/doc/test/coverage/lcov-report/modules/0_CMTATBaseSnapshot.sol.html +++ b/doc/test/coverage/lcov-report/modules/0_CMTATBaseSnapshot.sol.html @@ -93,21 +93,21 @@

      -2951× -2951× -176× -176× -176× -176× -176× +3118× +3118× +231× +231× +231× +231× +231×   -2775× +2887×        
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -142,7 +142,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/1_CMTATBaseDocument.sol.html b/doc/test/coverage/lcov-report/modules/1_CMTATBaseDocument.sol.html index c1b1fbec..5434259d 100644 --- a/doc/test/coverage/lcov-report/modules/1_CMTATBaseDocument.sol.html +++ b/doc/test/coverage/lcov-report/modules/1_CMTATBaseDocument.sol.html @@ -65,7 +65,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol";
  
@@ -79,7 +79,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/2_CMTATBaseAccessControl.sol.html b/doc/test/coverage/lcov-report/modules/2_CMTATBaseAccessControl.sol.html index 34f84ab1..6496bf71 100644 --- a/doc/test/coverage/lcov-report/modules/2_CMTATBaseAccessControl.sol.html +++ b/doc/test/coverage/lcov-report/modules/2_CMTATBaseAccessControl.sol.html @@ -22,12 +22,12 @@

100% Statements - 4/4 + 5/5
- 95.45% + 95.83% Branches - 21/22 + 23/24
100% @@ -37,7 +37,7 @@

100% Lines - 4/4 + 5/5

@@ -147,7 +147,11 @@

102 103 104 -105  +105 +106 +107 +108 +109        @@ -180,13 +184,14 @@

      -5342×   -5340×   -5340× +5872×   +5870× +5870×   +5870×       @@ -199,7 +204,10 @@

      -42× +  +  +  +45×       @@ -253,7 +261,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
@@ -267,8 +275,10 @@ 

import {ExtraInformationModule} from "./wrapper/extensions/ExtraInformationModule.sol"; import {ERC20EnforcementModule} from "./wrapper/extensions/ERC20EnforcementModule.sol"; import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol"; +import {IERC1643} from "../interfaces/tokenization/draft-IERC1643.sol"; +import {IERC8343} from "../interfaces/tokenization/draft-IERC8343.sol"; // options -import {ERC20BaseModule} from "./wrapper/core/ERC20BaseModule.sol"; +import {TokenAttributeModule} from "./wrapper/core/TokenAttributeModule.sol"; /* ==== Interface and other library === */ import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol"; import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol"; @@ -286,7 +296,8 @@

// AccessControlModule_init_unchained is called firstly due to inheritance __AccessControlModule_init_unchained(admin); // Core - __ERC20BaseModule_init_unchained(ERC20Attributes_.decimalsIrrevocable, ERC20Attributes_.name, ERC20Attributes_.symbol); + __ERC20BaseModule_init_unchained(ERC20Attributes_.decimalsIrrevocable); + __TokenAttributeModule_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol); /* Extensions */ __ExtraInformationModule_init_unchained(ExtraInformationModuleAttributes_.tokenId, ExtraInformationModuleAttributes_.terms, ExtraInformationModuleAttributes_.information); } @@ -300,10 +311,11 @@

* We can not use type(IERC5679).interfaceId instead of 0xd0017968 * because IERC5679 inherits from two interfaces (IERC5679Burn and Mint) * 0x3edbb4c4 is the interfaceId of ERC-7943 - * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate + * type(IERC8343).interfaceId (0xe9cd80b0) is the proposed ERC-8343 (draft) contract deactivation interface + * type(IERC1643).interfaceId (0xecfecec8) is the ERC-1643 document management interface */ function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) { - return interfaceId == 0xd0017968 || interfaceId == 0x3edbb4c4 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId); + return interfaceId == 0xd0017968 || interfaceId == 0x3edbb4c4 || interfaceId == type(IERC8343).interfaceId || interfaceId == type(IERC1643).interfaceId || AccessControlUpgradeable.supportsInterface(interfaceId); }     @@ -316,7 +328,7 @@

* @custom:access-control * - the caller must have the `DEFAULT_ADMIN_ROLE`. */ - function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) onlyRole(DEFAULT_ADMIN_ROLE){} + function _authorizeTokenAttributeManagement() internal virtual override(TokenAttributeModule) onlyRole(DEFAULT_ADMIN_ROLE){}   /** * @custom:access-control @@ -361,7 +373,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/3_CMTATBaseAllowlist.sol.html b/doc/test/coverage/lcov-report/modules/3_CMTATBaseAllowlist.sol.html index 440d207a..903615c3 100644 --- a/doc/test/coverage/lcov-report/modules/3_CMTATBaseAllowlist.sol.html +++ b/doc/test/coverage/lcov-report/modules/3_CMTATBaseAllowlist.sol.html @@ -25,9 +25,9 @@

40/40
- 81.82% + 80% Branches - 18/22 + 16/20
100% @@ -367,7 +367,15 @@

322 323 324 -325  +325 +326 +327 +328 +329 +330 +331 +332 +333        @@ -423,7 +431,7 @@

      -594× +705×       @@ -441,16 +449,16 @@

      -594× +705×     -594× +705×     -594× +705×     -594× +705×       @@ -458,19 +466,19 @@

      -594× -594× +705× +705×   -594× +705×             -594× +705×   -594× +705×       @@ -489,8 +497,13 @@

      -68× -58× +  +  +  +  +  +116× +97×       @@ -499,7 +512,7 @@

      -54× +58×       @@ -508,7 +521,7 @@

      -35× +39×       @@ -549,11 +562,11 @@

      -240× -240× -60× +316× +316× +84×   -180× +232×       @@ -569,9 +582,9 @@

  31× 31× - +   -23× +25×       @@ -587,10 +600,10 @@

      -132× +200×     -28× +49×       @@ -606,7 +619,7 @@

      -740× +849×       @@ -616,11 +629,11 @@

      -207× +273×       -34× +38×       @@ -628,7 +641,7 @@

      -191× +245×       @@ -636,12 +649,12 @@

      -108× +118×       -992× -976× +1110× +1095×       @@ -651,7 +664,10 @@

      -116× +235× +  +  +        @@ -665,9 +681,9 @@

      +8559×     -7381×       @@ -675,8 +691,8 @@

      +8561×   -7383×       @@ -693,7 +709,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -805,15 +821,20 @@ 

Functions requiring several modules //////////////////////////////////////////////////////////////*/ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. * @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. + * @inheritdoc ERC20Upgradeable */ - function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) returns (bool) { + // The pause check lives in _canAuthorizeAllowanceByModuleAndRevert, which lets a + // revocation (value == 0) through. A `whenNotPaused` modifier here would block it. + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); }   @@ -984,6 +1005,7 @@

//////////////////////////////////////////////////////////////*/ /** * @dev This surcharge is not necessary if you do not use the ERC2771Module + * @inheritdoc ERC2771ContextUpgradeable */ function _msgSender() internal virtual @@ -996,8 +1018,9 @@

  /** * @dev This surcharge is not necessary if you do not use the ERC2771Module + * @inheritdoc ERC2771ContextUpgradeable */ - function _contextSuffixLength() internal virtual view + function _contextSuffixLength() internal virtual view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (uint256) { return ERC2771ContextUpgradeable._contextSuffixLength(); @@ -1005,6 +1028,7 @@

  /** * @dev This surcharge is not necessary if you do not use the ERC2771Module + * @inheritdoc ERC2771ContextUpgradeable */ function _msgData() internal virtual @@ -1021,7 +1045,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/3_CMTATBaseRuleEngine.sol.html b/doc/test/coverage/lcov-report/modules/3_CMTATBaseRuleEngine.sol.html index 1779ad0b..41395bc7 100644 --- a/doc/test/coverage/lcov-report/modules/3_CMTATBaseRuleEngine.sol.html +++ b/doc/test/coverage/lcov-report/modules/3_CMTATBaseRuleEngine.sol.html @@ -25,9 +25,9 @@

24/24
- 80.77% + 79.17% Branches - 21/26 + 19/24
100% @@ -224,7 +224,12 @@

179 180 181 -182  +182 +183 +184 +185 +186 +187        @@ -270,7 +275,7 @@

      -4748× +5167×       @@ -287,7 +292,7 @@

      -4748× +5167×       @@ -306,18 +311,18 @@

      -4748× +5167×     -4748× +5167×     -4748× +5167×   -4748× +5167×     -4748× +5167×       @@ -325,24 +330,24 @@

      -4748× -4748× +5167× +5167×   -4748× +5167×             -4748× +5167×             -4748× +5167×       @@ -352,27 +357,27 @@

      -700× -662×           +958× +863×         -1579× -1579× -570×   -1009×         +1600× +1600× +532×   +1068×       @@ -380,16 +385,16 @@

      -251× -251× -76×   -175×         +215× +215× +38×   +177×       @@ -401,13 +406,18 @@

      -7434× -7282× +  +  +  +  +  +7858× +7763×      
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
 /* ==== OpenZeppelin === */
@@ -530,10 +540,15 @@ 

PUBLIC/EXTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. + * @inheritdoc ERC20Upgradeable */ - function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) returns (bool) { + // The pause check lives in _canAuthorizeAllowanceByModuleAndRevert, which lets a + // revocation (value == 0) through. A `whenNotPaused` modifier here would block it. + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); } /** @@ -592,7 +607,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/4_CMTATBaseDebt.sol.html b/doc/test/coverage/lcov-report/modules/4_CMTATBaseDebt.sol.html index ffa1d3f6..8cc237a5 100644 --- a/doc/test/coverage/lcov-report/modules/4_CMTATBaseDebt.sol.html +++ b/doc/test/coverage/lcov-report/modules/4_CMTATBaseDebt.sol.html @@ -122,7 +122,7 @@

      -92× +136×       @@ -158,7 +158,7 @@

      -1250× +1326×       @@ -167,7 +167,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
 /* ==== Module === */
@@ -232,7 +232,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/4_CMTATBaseERC1404.sol.html b/doc/test/coverage/lcov-report/modules/4_CMTATBaseERC1404.sol.html index 219fa36b..ae07497d 100644 --- a/doc/test/coverage/lcov-report/modules/4_CMTATBaseERC1404.sol.html +++ b/doc/test/coverage/lcov-report/modules/4_CMTATBaseERC1404.sol.html @@ -22,7 +22,7 @@

100% Statements - 14/14 + 10/10
100% @@ -32,12 +32,12 @@

100% Functions - 4/4 + 5/5
100% Lines - 14/14 + 10/10

@@ -129,7 +129,26 @@

84 85 86 -87  +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106        @@ -162,10 +181,10 @@

      -159× -66× +139× +44×   -93× +95×       @@ -178,7 +197,7 @@

      -1255× +1272×       @@ -190,7 +209,7 @@

      -207× +179×       @@ -201,33 +220,52 @@

      -377× -377× -198× -198× -22×   -176× -176× -132×     -223× +  +  +49× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +339× +339× +88× +  +251×      
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseRuleEngine} from "./3_CMTATBaseRuleEngine.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
 /* ==== Wrapper === */
-// Use by detectTransferRestriction
+// re-exported to keep {CMTATBaseERC20CrossChain} importing ERC20Upgradeable through this file
 import {ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol";
-// Extensions
-import {ERC20EnforcementModule} from "./wrapper/extensions/ERC20EnforcementModule.sol";
 // Controllers
-import {ValidationModuleERC1404, IERC1404Extend} from "./wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol";
+import {ValidationModuleERC1404, IERC1404, IERC1404Extend} from "./wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol";
 import {ValidationModuleRuleEngine} from "./wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {ERC1404ExtendInterfaceId} from "../library/ERC1404ExtendInterfaceId.sol";
  
 abstract contract CMTATBaseERC1404 is
     CMTATBaseRuleEngine,
@@ -278,26 +316,45 @@ 

) public virtual override (CMTATBaseRuleEngine, ValidationModuleRuleEngine) view returns (bool) { return CMTATBaseRuleEngine.canTransferFrom(spender, from, to, value); } +  + /** + * @notice ERC-165 interface detection + * @dev advertises support for both the canonical ERC-1404 interface + * (`IERC1404`, id `0xab84a5c8`) and its CMTAT extension + * (`IERC1404Extend`, id `0x78a8de7d`). + * @dev The extension id is taken from {ERC1404ExtendInterfaceId} because + * Solidity's `type(IERC1404Extend).interfaceId` excludes inherited + * functions and would therefore only cover `detectTransferRestrictionFrom`. + * @inheritdoc CMTATBaseAccessControl + */ + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(CMTATBaseAccessControl) returns (bool) { + return + interfaceId == type(IERC1404).interfaceId || + interfaceId == ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID || + super.supportsInterface(interfaceId); + }   /*////////////////////////////////////////////////////////////// INTERNAL/PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////*/ + /** + * @dev Delegates the frozen-balance check to {ERC20EnforcementModuleInternal-_checkActiveBalance}, + * the same predicate the transfer path enforces, so the predicted restriction and the actual + * transfer outcome cannot drift. In particular a zero-value transfer, which `_checkActiveBalance` + * treats as always valid, is reported as unrestricted here as well. + * @return code The restriction code (0 = no restriction). + */ function _detectTransferRestriction( address from, address to, uint256 value ) internal virtual override( ValidationModuleERC1404) view returns (uint8 code) { - uint256 frozenTokensLocal = ERC20EnforcementModule.getFrozenTokens(from); - if(frozenTokensLocal > 0 ){ - 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); - } - } + (bool isValid, ) = _checkActiveBalance(from, value); + if (!isValid) { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE); + } return ValidationModuleERC1404._detectTransferRestriction(from, to, value); } } @@ -307,7 +364,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/5_CMTATBaseERC20CrossChain.sol.html b/doc/test/coverage/lcov-report/modules/5_CMTATBaseERC20CrossChain.sol.html index 3c8da20c..0f4bf2d7 100644 --- a/doc/test/coverage/lcov-report/modules/5_CMTATBaseERC20CrossChain.sol.html +++ b/doc/test/coverage/lcov-report/modules/5_CMTATBaseERC20CrossChain.sol.html @@ -185,7 +185,12 @@

140 141 142 -143  +143 +144 +145 +146 +147 +148        @@ -208,12 +213,12 @@

      -627×     -295× +822×     +302×       @@ -226,7 +231,9 @@

      -199× +  +  +223×       @@ -249,18 +256,21 @@

      -59× +67× +  +  +        +49×       -47× +73×       -66×       @@ -270,17 +280,17 @@

      +4842×     -4518×             +863×   -869×       @@ -288,7 +298,7 @@

      -207× +222×       @@ -309,7 +319,7 @@

      -218× +206×       @@ -329,12 +339,11 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
 /* ==== Module === */
 import {CMTATBaseERC1404, CMTATBaseRuleEngine, ERC20Upgradeable} from "./4_CMTATBaseERC1404.sol";
-import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
 import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
 import {ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol";
 import {ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol";
@@ -347,7 +356,10 @@ 

abstract contract CMTATBaseERC20CrossChain is ERC20CrossChainModule, CCIPModule, CMTATBaseERC1404 { /* ============ State Functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. + * @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseRuleEngine) returns (bool) { return CMTATBaseRuleEngine.approve(spender, value); @@ -401,8 +413,8 @@

return CMTATBaseCommon.symbol(); }   - function supportsInterface(bytes4 _interfaceId) public view virtual override(CMTATBaseAccessControl, ERC20CrossChainModule) returns (bool) { - return ERC20CrossChainModule.supportsInterface(_interfaceId)|| CMTATBaseAccessControl.supportsInterface( _interfaceId); + function supportsInterface(bytes4 _interfaceId) public view virtual override(CMTATBaseERC1404, ERC20CrossChainModule) returns (bool) { + return ERC20CrossChainModule.supportsInterface(_interfaceId)|| CMTATBaseERC1404.supportsInterface( _interfaceId); }   /*////////////////////////////////////////////////////////////// @@ -411,6 +423,7 @@

/* ==== Mint and Burn Operations ==== */ /** * @dev Check if the mint is valid + * @inheritdoc ERC20MintModuleInternal */ function _mintOverride(address account, uint256 value) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) { // _checkTransferred is called by _mintOverride @@ -419,6 +432,7 @@

  /** * @dev Check if the burn is valid + * @inheritdoc ERC20BurnModuleInternal */ function _burnOverride(address account, uint256 value) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) { // _checkTransferred is called by _burnOverride @@ -427,6 +441,7 @@

  /** * @dev Check if a minter transfer is valid + * @inheritdoc ERC20MintModuleInternal */ function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) { // _checkTransferred is called by _minterTransferOverride @@ -475,7 +490,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/6_CMTATBaseDebtEngine.sol.html b/doc/test/coverage/lcov-report/modules/6_CMTATBaseDebtEngine.sol.html index 46e263ea..8e9e0239 100644 --- a/doc/test/coverage/lcov-report/modules/6_CMTATBaseDebtEngine.sol.html +++ b/doc/test/coverage/lcov-report/modules/6_CMTATBaseDebtEngine.sol.html @@ -138,13 +138,13 @@

      -923× +978×           -60× +58×       @@ -156,7 +156,7 @@

      -69× +102×       @@ -187,7 +187,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -262,7 +262,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/6_CMTATBaseERC2612.sol.html b/doc/test/coverage/lcov-report/modules/6_CMTATBaseERC2612.sol.html index 1befb769..a77b5fde 100644 --- a/doc/test/coverage/lcov-report/modules/6_CMTATBaseERC2612.sol.html +++ b/doc/test/coverage/lcov-report/modules/6_CMTATBaseERC2612.sol.html @@ -173,7 +173,17 @@

128 129 130 -131  +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141        @@ -199,10 +209,16 @@

      -460× -460× -460× -460× +500× +500× +500× +500× +  +  +  +  +  +        @@ -221,9 +237,9 @@

      -10× -   +22× +16×       @@ -233,17 +249,21 @@

      -92×         +114×           -31× +  +  +  +  +30×       @@ -286,7 +306,7 @@

      -18× +26×       @@ -299,13 +319,13 @@

      - +10×        
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
@@ -340,7 +360,14 @@ 

//////////////////////////////////////////////////////////////*/ /** * @inheritdoc ERC20PermitUpgradeable - * @dev Reverts if the contract is paused or if owner/spender is frozen. + * @dev Reverts if the contract is paused or if owner/spender is frozen, unless `value` + * is zero: a zero-value permit is a gasless revocation and stays available so an owner + * can always sever ties with a spender, even while restricted. + * + * The EIP-712 domain name is fixed at initialization and is **not** updated by + * {TokenAttributeModule-setName}. Signers must build the domain from the ERC-5267 + * {eip712Domain} function (or `DOMAIN_SEPARATOR()`), not from {name}, which may have + * been changed since deployment. */ function permit( address owner, @@ -351,13 +378,16 @@

bytes32 r, bytes32 s ) public virtual override(ERC20PermitUpgradeable) { - _canAuthorizeAllowanceByModuleAndRevert(owner, spender); + _canAuthorizeAllowanceByModuleAndRevert(owner, spender, value); ERC20PermitUpgradeable.permit(owner, spender, value, deadline, v, r, s); }   /* ============ State functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. + * @inheritdoc ERC20Upgradeable */ function approve( address spender, @@ -439,7 +469,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/6_CMTATBaseERC2771.sol.html b/doc/test/coverage/lcov-report/modules/6_CMTATBaseERC2771.sol.html index 831cfd13..82475122 100644 --- a/doc/test/coverage/lcov-report/modules/6_CMTATBaseERC2771.sol.html +++ b/doc/test/coverage/lcov-report/modules/6_CMTATBaseERC2771.sol.html @@ -92,7 +92,10 @@

47 48 49 -50  +50 +51 +52 +53        @@ -117,8 +120,8 @@

      -18475×   +20226×       @@ -126,7 +129,10 @@

      -18481× +  +  +20232× +        @@ -143,7 +149,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
 /* ==== Module === */
@@ -159,6 +165,7 @@ 

//////////////////////////////////////////////////////////////*/ /** * @dev This surcharge is not necessary if you do not use the 2771Module + * @inheritdoc ERC2771ContextUpgradeable */ function _msgSender() internal virtual @@ -171,8 +178,9 @@

  /** * @dev This surcharge is not necessary if you do not use the 2771Module + * @inheritdoc ERC2771ContextUpgradeable */ - function _contextSuffixLength() internal virtual view + function _contextSuffixLength() internal virtual view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (uint256) { return ERC2771ContextUpgradeable._contextSuffixLength(); @@ -180,6 +188,7 @@

  /** * @dev This surcharge is not necessary if you do not use the 2771Module + * @inheritdoc ERC2771ContextUpgradeable */ function _msgData() internal virtual @@ -196,7 +205,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/7_CMTATBaseERC2771Snapshot.sol.html b/doc/test/coverage/lcov-report/modules/7_CMTATBaseERC2771Snapshot.sol.html index fb1beb80..366cb80c 100644 --- a/doc/test/coverage/lcov-report/modules/7_CMTATBaseERC2771Snapshot.sol.html +++ b/doc/test/coverage/lcov-report/modules/7_CMTATBaseERC2771Snapshot.sol.html @@ -156,7 +156,7 @@

      -778× +814×       @@ -174,7 +174,7 @@

      -92× +114×       @@ -202,7 +202,7 @@

      -3814× +4035×       @@ -214,7 +214,7 @@

      -3816× +4037×       @@ -225,7 +225,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -319,7 +319,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/7_CMTATBaseERC7551Enforcement.sol.html b/doc/test/coverage/lcov-report/modules/7_CMTATBaseERC7551Enforcement.sol.html index ac520563..9ac03d32 100644 --- a/doc/test/coverage/lcov-report/modules/7_CMTATBaseERC7551Enforcement.sol.html +++ b/doc/test/coverage/lcov-report/modules/7_CMTATBaseERC7551Enforcement.sol.html @@ -179,11 +179,11 @@

      -390× +424×       -78× +98×       @@ -194,7 +194,7 @@

      -11591× +12904×       @@ -210,7 +210,7 @@

      -11595× +12908×       @@ -221,7 +221,7 @@

      -114× +125×       @@ -229,7 +229,7 @@

      -90× +114×       @@ -237,7 +237,7 @@

      -282× +378×       @@ -269,13 +269,13 @@

      -336× +358×        
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
@@ -394,7 +394,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/8_CMTATBaseERC1363.sol.html b/doc/test/coverage/lcov-report/modules/8_CMTATBaseERC1363.sol.html index fe878b19..28336bb2 100644 --- a/doc/test/coverage/lcov-report/modules/8_CMTATBaseERC1363.sol.html +++ b/doc/test/coverage/lcov-report/modules/8_CMTATBaseERC1363.sol.html @@ -185,7 +185,12 @@

140 141 142 -143  +143 +144 +145 +146 +147 +148        @@ -210,8 +215,8 @@

      -499× -499× +533× +533×       @@ -223,14 +228,17 @@

      -93×       +115×       -39× +  +  +  +37×       @@ -254,7 +262,9 @@

      -18× +  +  +23×       @@ -303,7 +313,7 @@

      -3508× +3728×       @@ -312,7 +322,7 @@

      -3510× +3730×       @@ -329,7 +339,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
 import {ERC1363Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC1363Upgradeable.sol";
@@ -362,7 +372,10 @@ 

/* ============ State functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. + * @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) { return CMTATBaseERC7551Enforcement.approve(spender, value); @@ -393,7 +406,9 @@

  /* ============ View functions ============ */ /** - * + * @notice Returns true if this contract implements the interface defined by `interfaceId`. + * @param interfaceId The ERC-165 interface identifier to query. + * @return True if `interfaceId` is supported by ERC-1363 or any inherited module. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1363Upgradeable, CMTATBaseERC20CrossChain) returns (bool) { return ERC1363Upgradeable.supportsInterface(interfaceId) || CMTATBaseERC20CrossChain.supportsInterface(interfaceId); @@ -475,7 +490,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/8_CMTATBaseERC7551.sol.html b/doc/test/coverage/lcov-report/modules/8_CMTATBaseERC7551.sol.html index 14414f8c..7ae991e7 100644 --- a/doc/test/coverage/lcov-report/modules/8_CMTATBaseERC7551.sol.html +++ b/doc/test/coverage/lcov-report/modules/8_CMTATBaseERC7551.sol.html @@ -84,12 +84,12 @@

      -20× +22×      
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 /* ==== Module === */
@@ -115,7 +115,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/8_CMTATBaseHolderList.sol.html b/doc/test/coverage/lcov-report/modules/8_CMTATBaseHolderList.sol.html new file mode 100644 index 00000000..cc5d18e8 --- /dev/null +++ b/doc/test/coverage/lcov-report/modules/8_CMTATBaseHolderList.sol.html @@ -0,0 +1,527 @@ + + + + Code coverage report for modules/8_CMTATBaseHolderList.sol + + + + + + + +
+
+

+ all files / modules/ 8_CMTATBaseHolderList.sol +

+
+
+ 36.36% + Statements + 4/11 +
+
+ 0% + Branches + 0/2 +
+
+ 36.36% + Functions + 4/11 +
+
+ 36.36% + Lines + 4/11 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +114× +  +  +  +  +  +  +  +  +  +  +  +  +  +372× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +372× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+/* ==== OpenZeppelin === */
+import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+/* ==== Module === */
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseERC7551Enforcement} from "./7_CMTATBaseERC7551Enforcement.sol";
+import {HolderListModule} from "./wrapper/options/HolderListModule.sol";
+/* ==== Interface and other library === */
+import {IHolderListModule} from "../interfaces/modules/IHolderListModule.sol";
+ 
+/**
+ * @title Extend the CMTAT standard path with the on-chain holder list
+ * @dev Same modules as the CMTAT standard version, plus {HolderListModule}.
+ *
+ * {HolderListModule} inherits {ERC20Upgradeable}, so the ERC-20 entry points are reachable
+ * through two branches of the inheritance graph and have to be disambiguated here. They all
+ * resolve to {CMTATBaseERC7551Enforcement}, which keeps the validation performed by the
+ * standard path. Only {_update} resolves to {HolderListModule}, which calls `super._update`
+ * and therefore still reaches {ERC20Upgradeable-_update}.
+ */
+abstract contract CMTATBaseHolderList is CMTATBaseERC7551Enforcement, HolderListModule {
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============ State functions ============ */
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function transfer(address to, uint256 value)
+        public virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (bool)
+    {
+        return CMTATBaseERC7551Enforcement.transfer(to, value);
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function transferFrom(address from, address to, uint256 value)
+        public virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (bool)
+    {
+        return CMTATBaseERC7551Enforcement.transferFrom(from, to, value);
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function approve(address spender, uint256 value)
+        public virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (bool)
+    {
+        return CMTATBaseERC7551Enforcement.approve(spender, value);
+    }
+ 
+    /* ============ View functions ============ */
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function name()
+        public view virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (string memory)
+    {
+        return CMTATBaseERC7551Enforcement.name();
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function symbol()
+        public view virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (string memory)
+    {
+        return CMTATBaseERC7551Enforcement.symbol();
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function decimals()
+        public view virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (uint8)
+    {
+        return CMTATBaseERC7551Enforcement.decimals();
+    }
+ 
+    function supportsInterface(bytes4 interfaceId)
+        public view virtual
+        override(CMTATBaseERC20CrossChain)
+        returns (bool)
+    {
+        return interfaceId == type(IHolderListModule).interfaceId
+            || CMTATBaseERC20CrossChain.supportsInterface(interfaceId);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /**
+    * @inheritdoc HolderListModule
+    */
+    function _update(address from, address to, uint256 value)
+        internal virtual
+        override(ERC20Upgradeable, HolderListModule)
+    {
+        HolderListModule._update(from, to, value);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            ERC2771 MODULE
+    //////////////////////////////////////////////////////////////*/
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function _msgSender()
+        internal view virtual
+        override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
+        returns (address sender)
+    {
+        return CMTATBaseERC7551Enforcement._msgSender();
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function _msgData()
+        internal view virtual
+        override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
+        returns (bytes calldata)
+    {
+        return CMTATBaseERC7551Enforcement._msgData();
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function _contextSuffixLength()
+        internal view virtual
+        override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
+        returns (uint256)
+    {
+        return CMTATBaseERC7551Enforcement._contextSuffixLength();
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/lcov-report/modules/index.html b/doc/test/coverage/lcov-report/modules/index.html index fb6be627..5d5f71fb 100644 --- a/doc/test/coverage/lcov-report/modules/index.html +++ b/doc/test/coverage/lcov-report/modules/index.html @@ -20,24 +20,24 @@

- 100% + 97% Statements - 224/224 + 226/233
- 87.33% + 86% Branches - 131/150 + 129/150
- 100% + 96.26% Functions - 175/175 + 180/187
- 100% + 97.01% Lines - 225/225 + 227/234
@@ -75,13 +75,13 @@

0_CMTATBaseCore.sol
100% - 33/33 + 34/34 86.67% 26/30 100% 24/24 100% - 34/34 + 35/35 @@ -127,13 +127,13 @@

2_CMTATBaseAccessControl.sol
100% - 4/4 - 95.45% - 21/22 + 5/5 + 95.83% + 23/24 100% 9/9 100% - 4/4 + 5/5 @@ -141,8 +141,8 @@

100% 40/40 - 81.82% - 18/22 + 80% + 16/20 100% 30/30 100% @@ -154,8 +154,8 @@

100% 24/24 - 80.77% - 21/26 + 79.17% + 19/24 100% 14/14 100% @@ -179,13 +179,13 @@

4_CMTATBaseERC1404.sol
100% - 14/14 + 10/10 100% 8/8 100% - 4/4 + 5/5 100% - 14/14 + 10/10 @@ -292,13 +292,26 @@

1/1 + + 8_CMTATBaseHolderList.sol +
+ 36.36% + 4/11 + 0% + 0/2 + 36.36% + 4/11 + 36.36% + 4/11 + +
diff --git a/doc/test/coverage/lcov-report/modules/internal/AllowlistModuleInternal.sol.html b/doc/test/coverage/lcov-report/modules/internal/AllowlistModuleInternal.sol.html index bfeea6f5..cfd846bf 100644 --- a/doc/test/coverage/lcov-report/modules/internal/AllowlistModuleInternal.sol.html +++ b/doc/test/coverage/lcov-report/modules/internal/AllowlistModuleInternal.sol.html @@ -132,7 +132,9 @@

87 88 89 -90  +90 +91 +92        @@ -161,8 +163,8 @@

      -594× -594× +705× +705×       @@ -171,19 +173,19 @@

      -296× -296× +326× +326×       -2396× +2626×       -532× -528× -528× -2100× +584× +580× +580× +2300×       @@ -191,8 +193,8 @@

      -142× -142× +211× +211×       @@ -200,30 +202,32 @@

      -1438× -1438×   +1580× +1580×           -1424× -1424×     +1667× +1667×         -4422× +  +  +5069×          
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -287,6 +291,7 @@ 

/* ============ View functions ============ */ /** * @dev Returns true if the account is listed, and false otherwise. + * @return True if the account is allowlisted, false otherwise. */ function _isAllowlisted(address account) internal view virtual returns (bool) { AllowlistModuleInternalStorage storage $ = _getAllowlistModuleInternalStorage(); @@ -295,6 +300,7 @@

  /** * @dev Returns true if the list is enabled, false otherwise + * @return True if the allowlist is enabled, false otherwise. */ function _isAllowlistEnabled() internal view virtual returns (bool) { AllowlistModuleInternalStorage storage $ = _getAllowlistModuleInternalStorage(); @@ -316,7 +322,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/internal/ERC20BurnModuleInternal.sol.html b/doc/test/coverage/lcov-report/modules/internal/ERC20BurnModuleInternal.sol.html index e1c36e99..be719894 100644 --- a/doc/test/coverage/lcov-report/modules/internal/ERC20BurnModuleInternal.sol.html +++ b/doc/test/coverage/lcov-report/modules/internal/ERC20BurnModuleInternal.sol.html @@ -94,7 +94,13 @@

49 50 51 -52  +52 +53 +54 +55 +56  +  +        @@ -140,14 +146,16 @@

      -1017× +  +  +1023×          
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -169,6 +177,8 @@ 

//////////////////////////////////////////////////////////////*/ /** * @dev internal function to burn in batch + * @param accounts The accounts to burn tokens from. + * @param values The amounts of tokens to burn, aligned with `accounts`. */ function _batchBurn( address[] calldata accounts, @@ -186,6 +196,8 @@

/** * @dev Internal function to burn * Can be override to perform supplementary check on burn action + * @param account The account to burn tokens from. + * @param value The amount of tokens to burn. */ function _burnOverride( address account, @@ -202,7 +214,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/internal/ERC20EnforcementModuleInternal.sol.html b/doc/test/coverage/lcov-report/modules/internal/ERC20EnforcementModuleInternal.sol.html index ea8399c1..ede80c7e 100644 --- a/doc/test/coverage/lcov-report/modules/internal/ERC20EnforcementModuleInternal.sol.html +++ b/doc/test/coverage/lcov-report/modules/internal/ERC20EnforcementModuleInternal.sol.html @@ -22,12 +22,12 @@

100% Statements - 62/62 + 64/64
100% Branches - 36/36 + 40/40
100% @@ -37,7 +37,7 @@

100% Lines - 77/77 + 79/79

@@ -233,7 +233,26 @@

188 189 190 -191  +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210        @@ -266,169 +285,190 @@

      -378× -378×   -378× -84× -84× -84×     -273× -273× -273×   -21×   -357×     +476× +88×   +388× +388× +  +388× +88× +88× +88× +  +  +278× +278× +278× +  +22× +  +366× +  +  +  +652× +30× +  +622× +  +622× 622× -29×   -593× +622×   -593× -593× +600× +600×   -593×   -572× -572×   +236× +30×   +206× +206×   -226× -29× +184× +184× +184×   -197× -197×   -176× -176× -176×         +276× +276× +22×   +254× +254×   -220× -220× -21× +254×   -199× -199× +254× +232×   -199× +254× +66× +66× +66× +66×   -199× -178×   -199× -63× -63× -63× -63×         -220× -199× -42×       -157× -157× -42× -21× -21×     -21× -21×   +298× +276× +254× +44×       -157× +210× +210×   -199× +44× +44× +44×       -845× +44×   +210×   +254×   -323×     +878×     -8426× -8426× -8426× -8426×   +338×         +8968× +8968× +8968× +8968×   -10527× -10527× -1533×   -1533× -105× -42×   -63×   -1428× -1428× -819×         -9603× +11469× +11469× +1628×   +1628× +132× +66×   +66×   -12921× -12921× +1496× +1496× +792×       -432× -432× -432×   -432× +10545× +  +  +  +13719× +13719× +  +  +  +440× +440× +440× +  +440× 32×   -400× +408×         -14720× +15629×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+/* ==== Technical === */
+import {IERC20Allowance} from "../../interfaces/technical/IERC20Allowance.sol";
 /* ==== Tokenization === */
 import {IERC7943FungibleEnforcementEventAndError} from "../../interfaces/tokenization/draft-IERC7943.sol";
  
@@ -443,7 +483,8 @@ 

error CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed(); error CMTAT_ERC20EnforcementModule_ValueExceedsAvailableBalance(); error CMTAT_ERC20EnforcementModule_ValueExceedsFrozenBalance(); - error CMTAT_ERC20EnforcementModule_ValueEqualCurrentFrozenTokens(); + error CMTAT_ERC20EnforcementModule_ValueEqualCurrentFrozenTokens(); + error CMTAT_ERC20EnforcementModule_SelfTransferNotAllowed(); /* ============ ERC-7201 ============ */ // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.ERC20EnforcementModule")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant ERC20EnforcementModuleStorageLocation = 0x9d8059a24cb596f1948a937c2c163cf14465c2a24abfd3cd009eec4ac4c39800; @@ -456,6 +497,13 @@

INTERNAL/PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////*/ function _setFrozenTokens(address account, uint256 value) internal virtual returns(bool) { + // The zero address holds no balance, so a non-zero frozen amount on it would make + // _checkActiveBalance(address(0), value) fail for every value > 0 and revert the common + // mint path (mint, batchMint, crosschainMint, the mint leg of burnAndMint). + // Same guard as _freezePartialTokens / _unfreezePartialTokens. + if (account == address(0)) { + revert CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed(); + } ERC20EnforcementModuleStorage storage $ = _getEnforcementModuleStorage(); uint256 frozenTokensLocal = $._frozenTokens[account]; // Unfreeze path @@ -525,7 +573,16 @@

} }   + /** + * @dev + * Moves tokens through the ERC-20 `_update` primitive directly, without the pause/deactivation + * validation applied to holder transfers and standard issuance. This is intentional: forced + * transfer/burn is the enforcer's regulatory tool and, per ERC-8343, a named privileged operation + * that remains available **after deactivation** (e.g. to sweep a frozen or migrated position). + */ function _forcedTransfer(address from, address to, uint256 value) internal virtual { + // A self forced transfer moves no token, but _unfreezeTokens would still release the frozen ones + require(from != to, CMTAT_ERC20EnforcementModule_SelfTransferNotAllowed()); _unfreezeTokens(from, value); if(to == address(0)){ ERC20Upgradeable._burn(from, value); @@ -534,16 +591,14 @@

// See https://ethereum-magicians.org/t/erc-3643-the-t-rex-token-standard/6844/11 uint256 currentAllowance = allowance(from, to); if (currentAllowance > 0 && currentAllowance < type(uint256).max) { - if (currentAllowance < value) { - unchecked { - ERC20Upgradeable._approve(from, to, 0, false); - } - } else{ - unchecked { - ERC20Upgradeable._approve(from, to, currentAllowance - value, false); - } + // Amount actually taken from the from->to allowance (capped by the allowance) + uint256 spentAllowance = currentAllowance < value ? currentAllowance : value; + unchecked { + ERC20Upgradeable._approve(from, to, currentAllowance - spentAllowance, false); } - + // Emit Spend so the allowance consumption is observable, consistent with + // transferFrom / burnFrom. `_approve(..., false)` above still suppresses Approval. + emit IERC20Allowance.Spend(from, to, spentAllowance); } ERC20Upgradeable._transfer(from, to, value); } @@ -568,6 +623,8 @@

  /** * @dev we only check the balance if frozenTokens > 0 + * @return isValid True if `from` has enough unfrozen balance to move `value`. + * @return activeBalance The unfrozen (active) balance available for `from`. */ function _checkActiveBalance(address from, uint256 value) internal virtual view returns(bool isValid, uint256 activeBalance){ uint256 frozenTokensLocal = _getFrozenTokens(from); @@ -619,7 +676,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/internal/ERC20MintModuleInternal.sol.html b/doc/test/coverage/lcov-report/modules/internal/ERC20MintModuleInternal.sol.html index 35de0daf..2c1e2342 100644 --- a/doc/test/coverage/lcov-report/modules/internal/ERC20MintModuleInternal.sol.html +++ b/doc/test/coverage/lcov-report/modules/internal/ERC20MintModuleInternal.sol.html @@ -115,7 +115,9 @@

70 71 72 -73  +73 +74 +75        @@ -148,12 +150,12 @@

      -730× +780×     -706× -658× -1836× +756× +708× +1936×       @@ -161,13 +163,13 @@

      +262× 238× -214×     -214× -166× -310× +238× +190× +334×       @@ -178,7 +180,9 @@

      -6409× +  +  +6931×       @@ -189,7 +193,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -248,6 +252,8 @@ 

  /** * @dev Can be override to emit event + * @param account The account to mint tokens to. + * @param value The amount of tokens to mint. */ function _mintOverride(address account, uint256 value) internal virtual { ERC20Upgradeable._mint(account, value); @@ -265,7 +271,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/internal/EnforcementModuleInternal.sol.html b/doc/test/coverage/lcov-report/modules/internal/EnforcementModuleInternal.sol.html index a006b29b..d2f79fe4 100644 --- a/doc/test/coverage/lcov-report/modules/internal/EnforcementModuleInternal.sol.html +++ b/doc/test/coverage/lcov-report/modules/internal/EnforcementModuleInternal.sol.html @@ -111,7 +111,8 @@

66 67 68 -69  +69 +70        @@ -144,22 +145,23 @@

      -571× -571× +719× +719×       -721× +919× 75×   -646× +844×       -125× -75× -75× 150× +100× +100× +200× +        @@ -168,20 +170,20 @@

      -16612× -16612× +18213× +18213×         -17258× +19032×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
@@ -234,6 +236,7 @@ 

/* ============ View functions ============ */ /** * @dev Returns true if the account is frozen, and false otherwise. + * @return _isListed True if the account is listed (frozen), false otherwise. */ function _addressIsListed(address account) internal view virtual returns (bool _isListed) { EnforcementModuleInternalStorage storage $ = _getEnforcementModuleInternalStorage(); @@ -253,7 +256,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/internal/ValidationModuleRuleEngineInternal.sol.html b/doc/test/coverage/lcov-report/modules/internal/ValidationModuleRuleEngineInternal.sol.html index 5d92c517..386c6e03 100644 --- a/doc/test/coverage/lcov-report/modules/internal/ValidationModuleRuleEngineInternal.sol.html +++ b/doc/test/coverage/lcov-report/modules/internal/ValidationModuleRuleEngineInternal.sol.html @@ -159,7 +159,7 @@

      -4748× +5167× 83×     @@ -174,8 +174,8 @@

      -8704× -8704× +9132× +9132×       @@ -189,21 +189,21 @@

      -441× -441× -441× +447× +447× +447×         -9145× +9579×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
@@ -286,7 +286,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/internal/common/EnforcementModuleLibrary.sol.html b/doc/test/coverage/lcov-report/modules/internal/common/EnforcementModuleLibrary.sol.html index eb8df070..d4ceef49 100644 --- a/doc/test/coverage/lcov-report/modules/internal/common/EnforcementModuleLibrary.sol.html +++ b/doc/test/coverage/lcov-report/modules/internal/common/EnforcementModuleLibrary.sol.html @@ -79,15 +79,15 @@

      -657× +734×     -630× +707×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /**
  * @dev Enforcement module library
@@ -112,7 +112,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/internal/common/index.html b/doc/test/coverage/lcov-report/modules/internal/common/index.html index cb751d5a..a54c07bd 100644 --- a/doc/test/coverage/lcov-report/modules/internal/common/index.html +++ b/doc/test/coverage/lcov-report/modules/internal/common/index.html @@ -77,7 +77,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/internal/index.html b/doc/test/coverage/lcov-report/modules/internal/index.html index 1e741c0a..79dbc152 100644 --- a/doc/test/coverage/lcov-report/modules/internal/index.html +++ b/doc/test/coverage/lcov-report/modules/internal/index.html @@ -22,12 +22,12 @@

100% Statements - 106/106 + 108/108
- 96.43% + 96.67% Branches - 54/56 + 58/60
100% @@ -37,7 +37,7 @@

100% Lines - 130/130 + 132/132

@@ -88,13 +88,13 @@

ERC20EnforcementModuleInternal.sol
100% - 62/62 + 64/64 100% - 36/36 + 40/40 100% 12/12 100% - 77/77 + 79/79 @@ -142,7 +142,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/controllers/ValidationModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/controllers/ValidationModule.sol.html index c0263de6..d30ea6c1 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/controllers/ValidationModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/controllers/ValidationModule.sol.html @@ -240,7 +240,22 @@

195 196 197 -198  +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213        @@ -266,12 +281,16 @@

      -352× +456× +  +  +  +  +50×         -46×       @@ -287,14 +306,14 @@

      -1437× +1558× 34×     14×     -1389× +1510×       @@ -304,14 +323,15 @@

      -8325× -6229× +8929× +6737×     -1175× +1169×     -921× +1023× +        @@ -339,8 +359,9 @@

      -6606× -6557× +  +7131× +7082× 60×     @@ -352,8 +373,9 @@

      -1247× -1175× +  +1241× +1169× 84×     @@ -368,22 +390,26 @@

      -1353×     -240×   -1113×   +1464×     +312×   +1152×         -744× -24× +  +  +  +  +842× +48×   24×   @@ -396,11 +422,12 @@

      -1353× +1464× +  +460×   -384× +1004×   -969×       @@ -413,9 +440,9 @@

      +1013× +842×   -911× -744×       @@ -425,7 +452,10 @@

      -1906× +  +2342× +  +        @@ -439,7 +469,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {PauseModule}  from "../core/PauseModule.sol";
@@ -475,8 +505,12 @@ 

//////////////////////////////////////////////////////////////*/ /* ============ View functions ============ */ /** - * @dev + * @dev * Entrypoint to check mint/burn/standard transfer + * @param spender The address initiating the transfer (address(0) for a direct transfer). + * @param from The address tokens move from (address(0) for a mint). + * @param to The address tokens move to (address(0) for a burn). + * @return True if the mint/burn/transfer is allowed by the pause and enforcement modules. */ function _canTransferGenericByModule( address spender, @@ -516,7 +550,8 @@

* @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 - */ + * @return True if the mint/burn is allowed (contract not deactivated and `target` not frozen). + */ function _canMintBurnByModule( address target ) internal view virtual returns (bool) { @@ -532,6 +567,7 @@

/** * @dev Reverts if mint is not allowed for `to`. * Checks deactivation and frozen status of the recipient. + * @param to The recipient whose mint is being validated. */ function _canMintByModuleAndRevert( address to @@ -545,6 +581,7 @@

/** * @dev Reverts if burn is not allowed for `from`. * Checks deactivation and frozen status of the token holder. + * @param from The holder whose burn is being validated. */ function _canBurnByModuleAndRevert( address from @@ -559,6 +596,10 @@

* @dev calls Pause and Enforcement module * check relevant for standard transfer * We don't check deactivated() because the contract must be in the pause state to be deactivated + * @param spender The address initiating the transfer. + * @param from The address tokens move from. + * @param to The address tokens move to. + * @return True if any of `spender`, `from` or `to` is frozen. */ function _canTransferisFrozen( address spender, @@ -620,6 +661,8 @@

* @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. + * @param account The account being checked. + * @return allowed True if `account` is allowed to send tokens. */ function _canSend(address account) internal view virtual returns (bool allowed) { return !EnforcementModule.isFrozen(account); @@ -629,6 +672,8 @@

* @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. + * @param account The account being checked. + * @return allowed True if `account` is allowed to receive tokens. */ function _canReceive(address account) internal view virtual returns (bool allowed) { return !EnforcementModule.isFrozen(account); @@ -640,7 +685,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/controllers/ValidationModuleAllowlist.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/controllers/ValidationModuleAllowlist.sol.html index 2b0e18d3..749835aa 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/controllers/ValidationModuleAllowlist.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/controllers/ValidationModuleAllowlist.sol.html @@ -173,7 +173,19 @@

128 129 130 -131  +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141  +  +        @@ -214,13 +226,17 @@

      -191× -166× -166× -36×     -155× +  +  +245× +184× +184× +46× +  +  +199×       @@ -231,25 +247,29 @@

      -191× -36×   -155×       +245× +46×   -207× -26× +199×   -181×       +273× +30×   +243×   -34× -18× +  +  +  +  +38× +22×   16×   @@ -260,10 +280,10 @@

      -740× +849×   -736× +845×       @@ -283,8 +303,8 @@

      +118× 108× -98×       @@ -292,8 +312,8 @@

      -108× -79× +118× +85×   @@ -305,7 +325,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ValidationModule} from "./ValidationModule.sol";
@@ -325,6 +345,8 @@ 

/* ============ View functions ============ */ /** * @dev Use forcedTransfer (or forcedBurn) to burn tokens from an non-allowlist address + * @param account The account whose mint/burn is being validated. + * @return True if the mint/burn is allowed (allowlist check plus the base checks). */ function _canMintBurnByModule( address account @@ -338,6 +360,10 @@

  /** * @dev Add allowlist check for standard transfer + * @param spender The address initiating the transfer. + * @param from The address tokens move from. + * @param to The address tokens move to. + * @return True if the allowlist blocks the transfer (allowlist enabled and a party is not allowlisted). */ function _canTransferStandardByModuleAllowlist( address spender, @@ -355,6 +381,10 @@

  /** * @dev Add allowlist check for standard transfer + * @param spender The address initiating the transfer. + * @param from The address tokens move from. + * @param to The address tokens move to. + * @return True if the standard transfer is allowed (passes the allowlist and base checks). */ function _canTransferStandardByModule( address spender, @@ -439,7 +469,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/controllers/index.html b/doc/test/coverage/lcov-report/modules/wrapper/controllers/index.html index b080ccc7..5ae0b4e2 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/controllers/index.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/controllers/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20BaseModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20BaseModule.sol.html index 44bcf571..df75e93b 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20BaseModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20BaseModule.sol.html @@ -22,22 +22,22 @@

100% Statements - 17/17 + 8/8
- 75% + 50% Branches - 6/8 + 2/4
100% Functions - 10/10 + 5/5
100% Lines - 27/27 + 13/13
@@ -144,68 +144,7 @@

99 100 101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163  +102        @@ -242,9 +181,9 @@

      +6188× +6188×   -98× -50×       @@ -259,38 +198,19 @@

      -5624× -5624× -5624× -5624×         +188×   +116×     +116×     -  -  -  -  -  -  -  -  -  -  -128× -  -80× -  -  -80× -  -  -80× +116×       @@ -308,45 +228,6 @@

      -86× -86× -  -  -  -  -  -  -  -74× -74× -  -  -  -  -  -  -  -  -  -  -26× -26× -26× -  -  -  -  -  -  -24× -24× -24× -  -  -  -  -  -  48× 48× 24× @@ -359,72 +240,50 @@

      -  -  -  -5858× +6212×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
 /* ==== Technical === */
 import {IERC20Allowance} from "../../../interfaces/technical/IERC20Allowance.sol";
 import {IERC20BatchBalance} from "../../../interfaces/engine/ISnapshotEngine.sol";
-/* ==== Tokenization === */
-import {IERC3643ERC20Base} from "../../../interfaces/tokenization/IERC3643Partial.sol";
  
 /**
  * @title ERC20Base module
- * @dev 
+ * @dev
  *
  * Contains ERC-20 base functions and extension
  * Inherits from ERC-20
- * 
+ * The mutable name/symbol attributes are managed by {TokenAttributeModule}
  */
-abstract contract ERC20BaseModule is ERC20Upgradeable, IERC20Allowance, IERC3643ERC20Base, IERC20BatchBalance{
-    /* ============ Events ============ */
-    event Name(string indexed newNameIndexed, string newName);
-    event Symbol(string indexed newSymbolIndexed, string newSymbol);
- 
+abstract contract ERC20BaseModule is ERC20Upgradeable, IERC20Allowance, IERC20BatchBalance{
     /* ============ ERC-7201 ============ */
     // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.ERC20BaseModule")) - 1)) & ~bytes32(uint256(0xff))
     bytes32 private constant ERC20BaseModuleStorageLocation = 0x9bd8d607565c0370ae5f91651ca67fd26d4438022bf72037316600e29e6a3a00;
     /* ==== ERC-7201 State Variables === */
     struct ERC20BaseModuleStorage {
         uint8 _decimals;
-        // We don't use ERC20Upgradeable name and private because we can not modify them
-        string _name;
-        string _symbol;
-    }
- 
-    /* ============ Modifier ============ */
-    modifier onlyERC20AttributeManager() {
-        _authorizeERC20AttributeManagement();
-        _;
     }
  
     /* ============  Initializer Function ============ */
     /**
-     * @dev Initializers: Sets the values for decimals.
+     * @dev Initializers: Sets the value for decimals.
      *
      * this value is immutable: it can only be set once during
      * construction/initialization.
      */
     function __ERC20BaseModule_init_unchained(
-        uint8 decimals_,
-        string memory name_,
-        string memory symbol_
+        uint8 decimals_
     ) internal virtual EonlyInitializing {
         ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage();
         $._decimals = decimals_;
-        $._symbol = symbol_;
-        $._name = name_;
     }
     /*//////////////////////////////////////////////////////////////
                             PUBLIC/EXTERNAL FUNCTIONS
@@ -466,45 +325,6 @@ 

return $._decimals; }   - /** - * @notice Returns the name of the token. - */ - function name() public virtual override(ERC20Upgradeable) view returns (string memory) { - ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage(); - return $._name; - } -  - /** - * @notice Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() public virtual override(ERC20Upgradeable) view returns (string memory) { - ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage(); - return $._symbol; - } -  -  - /* ============ Custom functions ============ */ - /* ======== State Functions ======= */ - /** - * @inheritdoc IERC3643ERC20Base - * @dev - */ - function setName(string calldata name_) public virtual override(IERC3643ERC20Base) onlyERC20AttributeManager { - ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage(); - $._name = name_; - emit Name(name_, name_); - } -  - /** - * @inheritdoc IERC3643ERC20Base - */ - function setSymbol(string calldata symbol_) public virtual override(IERC3643ERC20Base) onlyERC20AttributeManager { - ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage(); - $._symbol = symbol_; - emit Symbol(symbol_, symbol_); - } - /* ======== View functions ======= */ /** * @inheritdoc IERC20BatchBalance */ @@ -519,9 +339,6 @@

/*////////////////////////////////////////////////////////////// INTERNAL/PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////*/ - /* ============ Access Control ============ */ - function _authorizeERC20AttributeManagement() internal virtual; -  /* ============ ERC-7201 ============ */ function _getERC20BaseModuleStorage() private pure returns (ERC20BaseModuleStorage storage $) { assembly { @@ -535,7 +352,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20BurnModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20BurnModule.sol.html index 0a81e47d..db65c0d4 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20BurnModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20BurnModule.sol.html @@ -174,8 +174,8 @@

      -835× -739× +841× +745×       @@ -205,7 +205,7 @@

      -138× +144×       @@ -248,8 +248,8 @@

      -409× -292× +415× +298×       @@ -257,7 +257,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ERC20BurnModuleInternal} from "../../internal/ERC20BurnModuleInternal.sol";
@@ -367,7 +367,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20MintModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20MintModule.sol.html index 5ab1eed4..bf04cb12 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20MintModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/ERC20MintModule.sol.html @@ -171,8 +171,8 @@

      -5722× -5650× +6197× +6125×       @@ -203,7 +203,7 @@

      -4534× +4935×       @@ -219,8 +219,8 @@

      -730× -583× +780× +633×       @@ -232,22 +232,22 @@

      -238× +262×             -4682× -4586× +5083× +5008×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ERC20MintModuleInternal} from "../../internal/ERC20MintModuleInternal.sol";
@@ -352,7 +352,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/EnforcementModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/core/EnforcementModule.sol.html index 078f4f11..61cd7cb4 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/core/EnforcementModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/EnforcementModule.sol.html @@ -162,8 +162,8 @@

      -771× -696× +944× +869×       @@ -177,7 +177,7 @@

      -271× +347×       @@ -195,7 +195,7 @@

      -300× +372×       @@ -206,7 +206,7 @@

      -125× +150×       @@ -214,7 +214,7 @@

      -16612× +18213×       @@ -222,8 +222,8 @@

      -721× -646× +919× +844×       @@ -231,7 +231,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {EnforcementModuleInternal} from "../../internal/EnforcementModuleInternal.sol";
@@ -253,7 +253,7 @@ 

    /* ============ Modifier ============ */ - /// @dev Modifier to restrict access to the burner functions + /// @dev Modifier to restrict access to the address-freeze functions (via `_authorizeFreeze`, ENFORCER_ROLE) modifier onlyEnforcer() { _authorizeFreeze(); _; @@ -328,7 +328,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/PauseModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/core/PauseModule.sol.html index 53a469c1..ea81eb34 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/core/PauseModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/PauseModule.sol.html @@ -213,13 +213,13 @@

      -763× -712× +841× +790×       -318× -293× +344× +319×       @@ -232,7 +232,7 @@

      -637× +713×       @@ -241,8 +241,8 @@

      -75× -75× +77× +77× 50×     @@ -258,13 +258,13 @@

      -293× -268× -268× +319× +294× +294× 25×   -243× -243× +269× +269×       @@ -272,15 +272,15 @@

      -5339× +5018×             -8168× -8168× +8717× +8717×       @@ -291,28 +291,28 @@

      -7853× +8372× 121×           -8511× +9088×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
 /* ==== Tokenization === */
 import {IERC3643Pause} from "../../../interfaces/tokenization/IERC3643Partial.sol";
 import {IERC7551Pause} from "../../../interfaces/tokenization/draft-IERC7551.sol";
-import {ICMTATDeactivate} from "../../../interfaces/tokenization/ICMTAT.sol";
+import {IERC8343} from "../../../interfaces/tokenization/draft-IERC8343.sol";
  
  
 /**
@@ -326,7 +326,7 @@ 

* period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ -abstract contract PauseModule is PausableUpgradeable, IERC3643Pause, IERC7551Pause, ICMTATDeactivate { +abstract contract PauseModule is PausableUpgradeable, IERC3643Pause, IERC7551Pause, IERC8343 { error CMTAT_PauseModule_ContractIsDeactivated(); error EnforcedDeactivation(); /* ============ State Variables ============ */ @@ -377,14 +377,14 @@

}   /** - * @inheritdoc ICMTATDeactivate + * @inheritdoc IERC8343 * @custom:access-control * - the caller must have the `DEFAULT_ADMIN_ROLE`. * @custom:devimpl * With a proxy architecture, it is still possible to rollback by deploying a new implementation which sets the variable to false. */ function deactivateContract() - public virtual override(ICMTATDeactivate) + public virtual override(IERC8343) onlyDeactivateContractManager { // Contract must be in pause state @@ -406,9 +406,9 @@

}   /** - * @inheritdoc ICMTATDeactivate + * @inheritdoc IERC8343 */ - function deactivated() public view virtual override(ICMTATDeactivate) returns (bool){ + function deactivated() public view virtual override(IERC8343) returns (bool){ PauseModuleStorage storage $ = _getPauseModuleStorage(); return $._isDeactivated; } @@ -439,7 +439,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/TokenAttributeModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/core/TokenAttributeModule.sol.html new file mode 100644 index 00000000..54805629 --- /dev/null +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/TokenAttributeModule.sol.html @@ -0,0 +1,419 @@ + + + + Code coverage report for modules/wrapper/core/TokenAttributeModule.sol + + + + + + + +
+
+

+ all files / modules/wrapper/core/ TokenAttributeModule.sol +

+
+
+ 100% + Statements + 10/10 +
+
+ 83.33% + Branches + 5/6 +
+
+ 100% + Functions + 7/7 +
+
+ 100% + Lines + 16/16 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +98× +50× +  +  +  +  +  +  +  +  +  +  +6188× +6188× +6188× +  +  +  +  +  +  +  +  +  +  +  +94× +94× +  +  +  +  +  +  +  +76× +76× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +26× +26× +26× +  +  +  +  +  +  +24× +24× +24× +  +  +  +  +  +  +  +  +  +  +6408× +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+/* ==== OpenZeppelin === */
+import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+/* ==== Tokenization === */
+import {IERC3643ERC20Base} from "../../../interfaces/tokenization/IERC3643Partial.sol";
+ 
+/**
+ * @title TokenAttribute module
+ * @dev
+ *
+ * Manages the mutable token attributes (name and symbol) independently of the
+ * underlying token standard (ERC-20, ERC-7984, ...).
+ *
+ * The attributes are stored in this module's own ERC-7201 namespaced storage, so
+ * a contract that also inherits a token standard (e.g. `ERC20Upgradeable`) only
+ * has to override that standard's `name()` / `symbol()` to delegate here. This
+ * keeps the metadata management reusable by non ERC-20 (e.g. confidential) tokens.
+ */
+abstract contract TokenAttributeModule is Initializable, IERC3643ERC20Base {
+    /* ============ Events ============ */
+    event Name(string indexed newNameIndexed, string newName);
+    event Symbol(string indexed newSymbolIndexed, string newSymbol);
+ 
+    /* ============ ERC-7201 ============ */
+    // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.TokenAttributeModule")) - 1)) & ~bytes32(uint256(0xff))
+    bytes32 private constant TokenAttributeModuleStorageLocation = 0xc541cfc06cfa9bb7e38e614bc9457bd7310b58a2a620e4f19164873143c76d00;
+    /* ==== ERC-7201 State Variables === */
+    struct TokenAttributeModuleStorage {
+        // We don't use the underlying token standard's name/symbol because we can not modify them
+        string _name;
+        string _symbol;
+    }
+ 
+    /* ============ Modifier ============ */
+    modifier onlyTokenAttributeManager() {
+        _authorizeTokenAttributeManagement();
+        _;
+    }
+ 
+    /* ============  Initializer Function ============ */
+    /**
+     * @dev Initializers: sets the token name and symbol.
+     */
+    function __TokenAttributeModule_init_unchained(
+        string memory name_,
+        string memory symbol_
+    ) internal virtual EonlyInitializing {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        $._name = name_;
+        $._symbol = symbol_;
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ======== View functions ======= */
+    /**
+     * @notice Returns the name of the token.
+     * @return The token name.
+     */
+    function name() public view virtual returns (string memory) {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        return $._name;
+    }
+ 
+    /**
+     * @notice Returns the symbol of the token, usually a shorter version of the name.
+     * @return The token symbol.
+     */
+    function symbol() public view virtual returns (string memory) {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        return $._symbol;
+    }
+ 
+    /* ======== State functions ======= */
+    /**
+     *  @inheritdoc IERC3643ERC20Base
+     *  @dev
+     *  WARNING - on deployment variants that also support ERC-2612 (`permit`), renaming the token does **not**
+     *  change the EIP-712 domain separator. The domain name is captured at initialization by OpenZeppelin's
+     *  `EIP712Upgradeable` and, per its own documentation, "cannot be changed except through a smart contract
+     *  upgrade"; `DOMAIN_SEPARATOR()` therefore keeps using the original name after {setName}.
+     *
+     *  Existing and future permits remain valid: signers must simply build the EIP-712 domain from the ERC-5267
+     *  {eip712Domain} function (or from `DOMAIN_SEPARATOR()`), which reports the name actually in use — never
+     *  from {name}. A signature produced with the post-rename {name} is rejected with `ERC2612InvalidSigner`.
+     */
+    function setName(string calldata name_) public virtual override(IERC3643ERC20Base) onlyTokenAttributeManager {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        $._name = name_;
+        emit Name(name_, name_);
+    }
+ 
+    /**
+     * @inheritdoc IERC3643ERC20Base
+     */
+    function setSymbol(string calldata symbol_) public virtual override(IERC3643ERC20Base) onlyTokenAttributeManager {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        $._symbol = symbol_;
+        emit Symbol(symbol_, symbol_);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============ Access Control ============ */
+    function _authorizeTokenAttributeManagement() internal virtual;
+ 
+    /* ============ ERC-7201 ============ */
+    function _getTokenAttributeModuleStorage() private pure returns (TokenAttributeModuleStorage storage $) {
+        assembly {
+            $.slot := TokenAttributeModuleStorageLocation
+        }
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/ValidationModuleCore.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/core/ValidationModuleCore.sol.html index 106e8ff7..10cb4641 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/core/ValidationModuleCore.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/ValidationModuleCore.sol.html @@ -95,7 +95,11 @@

50 51 52 -53  +53 +54 +55 +56 +57        @@ -119,7 +123,7 @@

      -1229× +1346×       @@ -128,7 +132,7 @@

      -208× +212×       @@ -144,12 +148,16 @@

      -1437× +  +  +  +  +1558×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ValidationModule} from "../controllers/ValidationModule.sol";
@@ -189,6 +197,10 @@ 

  /** * @dev function used by canTransfer and operateOnTransfer + * @param spender The address initiating the transfer. + * @param from The address tokens move from. + * @param to The address tokens move to. + * @return True if the transfer is allowed by the validation module. */ function _canTransferByModule( address spender, @@ -205,7 +217,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/VersionModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/core/VersionModule.sol.html index 3397cb84..128e368e 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/core/VersionModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/VersionModule.sol.html @@ -105,7 +105,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Tokenization === */
 import {IERC3643Version} from "../../../interfaces/tokenization/IERC3643Partial.sol";
@@ -122,7 +122,7 @@ 

* @dev * Get the current version of the smart contract */ - string private constant VERSION = "3.2.0"; + string private constant VERSION = "3.3.0"; /*////////////////////////////////////////////////////////////// PUBLIC/EXTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ @@ -139,7 +139,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/core/index.html b/doc/test/coverage/lcov-report/modules/wrapper/core/index.html index 343c477a..f6f683b2 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/core/index.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/core/index.html @@ -22,22 +22,22 @@

100% Statements - 59/59 + 60/60
- 85.71% + 84.09% Branches - 36/42 + 37/44
100% Functions - 41/41 + 43/43
100% Lines - 78/78 + 80/80
@@ -62,13 +62,13 @@

ERC20BaseModule.sol
100% - 17/17 - 75% - 6/8 + 8/8 + 50% + 2/4 100% - 10/10 + 5/5 100% - 27/27 + 13/13 @@ -123,6 +123,19 @@

20/20 + + TokenAttributeModule.sol +
+ 100% + 10/10 + 83.33% + 5/6 + 100% + 7/7 + 100% + 16/16 + + ValidationModuleCore.sol
@@ -155,7 +168,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/DocumentERC1643Module.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/DocumentERC1643Module.sol.html index 893e4865..532ebf3e 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/DocumentERC1643Module.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/DocumentERC1643Module.sol.html @@ -22,12 +22,12 @@

100% Statements - 18/18 + 20/20
- 90% + 100% Branches - 9/10 + 12/12
100% @@ -37,7 +37,7 @@

100% Lines - 28/28 + 30/30

@@ -123,7 +123,9 @@

78 79 80 -81  +81 +82 +83        @@ -146,66 +148,68 @@

      -299× -253× +446× +400×       -138× +152× +152×       -46× +49×       -207× -207× -207× -207× -207× +297× +272× +272× +272× +272× +272×   -207× -184× -184× +272× +248× +248×     -207× +272×       -46× -46× -46× +103× +103× +103×   -46× -46× -46× +78× +78× +78×   -46× -23× -23× -23× +78× +26× +26× +26×     -46× -46× -46× +78× +78× +78×   -46× +78×           -437× +576×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
 import {IERC1643} from "../../../interfaces/tokenization/draft-IERC1643.sol";
@@ -230,8 +234,9 @@ 

_; }   - function getDocument(bytes32 name) public view virtual override returns (Document memory document) { - return _getDocumentERC1643ModuleStorage()._documents[name]; + function getDocument(bytes32 name) public view virtual override returns (string memory uri, bytes32 documentHash, uint256 lastModified) { + Document storage document = _getDocumentERC1643ModuleStorage()._documents[name]; + return (document.uri, document.documentHash, document.lastModified); }   function getAllDocuments() public view virtual override returns (bytes32[] memory documentNames_) { @@ -239,6 +244,7 @@

}   function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) public virtual override onlyDocumentManager { + require(name != bytes32(0), ERC1643InvalidName()); DocumentERC1643ModuleStorage storage $ = _getDocumentERC1643ModuleStorage(); Document storage document = $._documents[name]; document.uri = uri; @@ -256,7 +262,7 @@

function removeDocument(bytes32 name) public virtual override onlyDocumentManager { DocumentERC1643ModuleStorage storage $ = _getDocumentERC1643ModuleStorage(); uint256 key = $._documentKey[name]; - Erequire(key != 0, "CMTAT: document does not exist"); + require(key != 0, ERC1643MissingDocument());   Document memory document = $._documents[name]; uint256 index = key - 1; @@ -289,7 +295,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ERC20EnforcementModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ERC20EnforcementModule.sol.html index 321edcda..527e70fa 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ERC20EnforcementModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ERC20EnforcementModule.sol.html @@ -175,14 +175,14 @@

      -1289× -1226× +1430× +1364×         -262× -220× +342× +298×       @@ -193,7 +193,7 @@

      -2246× +2062×       @@ -204,8 +204,8 @@

      -146× -125× +200× +164×       @@ -215,7 +215,7 @@

      -574× +596×       @@ -225,7 +225,7 @@

      -194× +204×       @@ -236,7 +236,7 @@

      -378× +476×       @@ -244,13 +244,13 @@

      -845× -845× +878× +878×       -323× -323× +338× +338×       @@ -259,7 +259,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ERC20EnforcementModuleInternal} from "../../internal/ERC20EnforcementModuleInternal.sol";
@@ -370,7 +370,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ExtraInformationModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ExtraInformationModule.sol.html index 3563cf37..307dacf6 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ExtraInformationModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ExtraInformationModule.sol.html @@ -22,7 +22,7 @@

100% Statements - 21/21 + 23/23
87.5% @@ -32,12 +32,12 @@

100% Functions - 13/13 + 14/14
100% Lines - 29/29 + 34/34

@@ -204,7 +204,23 @@

159 160 161 -162  +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178        @@ -235,8 +251,8 @@

      -164× -82× +168× +86×       @@ -248,13 +264,13 @@

      -5402× +5942×   -5402× +5942×   -5402× +5942×   -5402× +5942×       @@ -295,8 +311,8 @@

      -26× -26× +28× +28×       @@ -312,62 +328,78 @@

      -58× -58× +118× +118×             -104× -104× +108× +108×             -28× -28× +26× +26× +  +  +  +  +            -5428× -5428× + + + +   +       -5430×   -5430× -5430× -5430×   -5430× +5968× +5968×       -5428× -5428×   +5968×   +5968× +5968× +5968×   +5968×       +5970× +5970×   -5774× +  +  +  +  +  +  +6382×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Openzeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -492,6 +524,22 @@ 

ExtraInformationModuleStorage storage $ = _getExtraInformationModuleStorage(); _setTerms($, terms_); } +  + /** + * @dev Update the terms document (uri + hash) while leaving the document name untouched. + * + * Used by the ERC-7551 `setTerms(bytes32,string)` overload, whose signature carries no name: + * forwarding an empty one through {_setTerms} would silently erase a name previously set via + * {setTerms(IERC1643CMTAT.DocumentInfo)}. + */ + function _setTermsDocument(bytes32 documentHash_, string memory uri_) internal virtual { + ExtraInformationModuleStorage storage $ = _getExtraInformationModuleStorage(); + $._terms.doc.documentHash = documentHash_; + $._terms.doc.uri = uri_; + $._terms.doc.lastModified = block.timestamp; + // Event + emit Terms($._terms); + }   function _setTokenId( ExtraInformationModuleStorage storage $, string memory tokenId_ @@ -532,7 +580,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/SnapshotEngineModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/SnapshotEngineModule.sol.html index f90652b0..e5c23c6c 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/SnapshotEngineModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/SnapshotEngineModule.sol.html @@ -173,8 +173,8 @@

      -343× -334× +349× +340×       @@ -208,9 +208,9 @@

      -334× -334× -325× +340× +340× +331×       @@ -220,8 +220,8 @@

      -3300× -3300× +3476× +3476×       @@ -230,15 +230,15 @@

      -343× -343× +349× +349×             -3652× +3834×       @@ -247,7 +247,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -352,7 +352,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol.html index 487976f4..8de03e08 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol.html @@ -22,12 +22,12 @@

100% Statements - 3/3 + 5/5
100% Branches - 4/4 + 6/6
100% @@ -37,7 +37,7 @@

100% Lines - 5/5 + 7/7

@@ -78,7 +78,33 @@

33 34 35 -36  +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54  +  +  +  +  +  +  +  +        @@ -104,18 +130,28 @@

      -808× -804× -28×   -776× +  +  +  +  +  +  +1150× +128× +  +1022× +972× 28×   +944× +52× +       
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== ValidationModule === */
 import {ValidationModuleCore} from "../../core/ValidationModuleCore.sol";
@@ -130,15 +166,33 @@ 

/** * @dev Reverts when allowance authorization cannot be performed. * - * Requirements: + * Requirements (for `value > 0`): * - contract must not be paused. * - `owner` must be allowed to send (`canSend` returns true). * - `spender` must be allowed to send (`canSend` returns true). + * + * Setting an allowance to zero is a **revocation**, never a new grant: it can only + * reduce what a spender may move. It is therefore always authorized, including while + * the contract is paused or when `owner`/`spender` is frozen or off the allowlist. + * Blocking it would leave a holder unable to sever ties with a compromised or + * sanctioned spender for the whole duration of the restriction, and would make the + * zero-first allowance mitigation documented on `approve` unusable exactly when it + * matters. No value can move while the restriction holds, since `transferFrom` is + * gated by the same checks. + * + * @param owner The account granting (or revoking) the allowance. + * @param spender The account being granted (or revoked). + * @param value The new allowance value; `0` means revocation. */ function _canAuthorizeAllowanceByModuleAndRevert( address owner, - address spender + address spender, + uint256 value ) internal view virtual { + // A revocation is always allowed + if (value == 0) { + return; + } _requireNotPaused(); if (!_canSend(owner)) { revert ERC7943CannotSend(owner); @@ -154,7 +208,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol.html index a40e2c4d..d65f48ac 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol.html @@ -203,7 +203,51 @@

158 159 160 -161  +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205        @@ -257,8 +301,33 @@

      -93× -93× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +95× +95×     @@ -269,7 +338,7 @@

      -11× +13×       @@ -305,14 +374,17 @@

      -199× -199× -199× -132× +  +  +  +190× +190× +190× +112×   42×   -25× +36×       @@ -322,17 +394,32 @@

      -189× -189× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +160× +160× 11×   -178× -178× -132× +149× +149× +92×   24×   -22× +33×       @@ -349,8 +436,9 @@

      -223× -33× +  +251× +39×   55×   @@ -359,13 +447,13 @@

11×     -113× +135×        
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
  
 /* ==== Tokenization === */
@@ -378,6 +466,31 @@ 

* * Useful for to restrict and validate transfers * Required a RuleEngine implementing the interface IRuleEngineERC1404 + * + * @custom:scope {detectTransferRestriction} and {detectTransferRestrictionFrom} describe the + * **holder transfer path only** — `transfer` and `transferFrom`. They do **not** govern the + * mint and burn entry points, and the `address(0)` encoding of the ERC-1404 rework draft + * (`from == address(0)` for a mint, `to == address(0)` for a burn) is **not** supported here: + * a query built that way is answered as if it were a holder transfer, so it can report a + * restriction the mint/burn path does not enforce (typically {PauseModule-paused}). + * + * The reason is structural, not an oversight. CMTAT exposes several entry points per + * supply-changing operation and the **pause rule differs between them**: + * - mint: `mint` / `batchMint` (`MINTER_ROLE`) are allowed while paused, `crosschainMint` + * (token bridge) is not; + * - burn: `burn(address,uint256[,bytes])` / `batchBurn` (`BURNER_ROLE`) are allowed while paused, + * `burnFrom` (`BURNER_FROM_ROLE`), `burn(uint256)` (`BURNER_SELF_ROLE`) and `crosschainBurn` + * are not. + * + * `(from, to, value)` — and `(spender, from, to, value)` — carry no entry-point discriminator, and + * the operator address does not identify one either (the same address may hold several burn roles), + * so no single return value can describe every mint or every burn. Rather than designate a predictor + * that would be right for one entry point and wrong for another, this module designates **none**. + * + * To predict a mint or a burn, use the module's own predicates instead — {canTransfer} / + * {canTransferFrom}, which branch on the `address(0)` encoding through + * {ValidationModule-_canTransferGenericByModule}, the same helper the enforcement path uses — and + * the role/pause requirements documented per entry point. */ abstract contract ValidationModuleERC1404 is ValidationModuleRuleEngine, IERC1404Extend @@ -459,6 +572,9 @@

* @param value uint256 the amount of tokens to be transferred * @return code of the rejection reason * @dev see {ERC-1404} + * @dev Scope: `transfer` / `transferFrom` only. Passing `address(0)` as `from` or `to` to query + * a mint or a burn is **not** supported — see the scope note on this contract; use + * {canTransfer} / {canTransferFrom} for those operations. */ function detectTransferRestriction( address from, @@ -476,6 +592,21 @@

} }   + /** + * @notice check if `spender` can transfer `value` token from `from` to `to` + * @param spender address The address initiating the delegated transfer + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 the amount of tokens to be transferred + * @return code of the rejection reason + * @dev see {ERC-1404} (rework draft, spender-aware extension) + * @dev Scope: `transferFrom` only. The `spender` argument is the delegated-transfer initiator, + * **not** a mint/burn operator: passing an operator with `from`/`to` set to `address(0)` to + * predict a mint or a burn is not supported — see the scope note on this contract. + * The `spender == from` case is deliberately evaluated through this path (no short-circuit to + * {detectTransferRestriction}), because a frozen initiator blocks `transferFrom` even when it + * owns the tokens. + */ function detectTransferRestrictionFrom( address spender, address from, @@ -503,6 +634,7 @@

  /** * @dev override this function to add further restriction + * @return code The restriction code (0 = no restriction). */ function _detectTransferRestriction( address from, @@ -529,7 +661,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol.html index 3626ce2f..d7a27d88 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol.html @@ -22,7 +22,7 @@

100% Statements - 25/25 + 26/26
100% @@ -32,12 +32,12 @@

100% Functions - 9/9 + 10/10
100% Lines - 26/26 + 27/27

@@ -192,7 +192,53 @@

147 148 149 -150  +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196        @@ -219,8 +265,9 @@

      -364× -361× +  +370× +367×       @@ -241,8 +288,8 @@

      -361× -358× +367× +364×       @@ -254,7 +301,7 @@

      -1009× +1068×       @@ -267,7 +314,7 @@

      -175× +177×       @@ -279,8 +326,8 @@

      -1009× -240× +1068× +299×   769×   @@ -292,8 +339,8 @@

      -175× -76× +177× +78×   99×   @@ -330,20 +377,65 @@

      -7282× -6851× -6851× -715× -703×   -12×         +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +7763× +7309× +7309× +733× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +725× +709× +  +16× +  +  +   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
  
 /* ==== Engine === */
@@ -365,6 +457,7 @@ 

* @notice Reverts if attempting to set the RuleEngine to its current value. */ error CMTAT_ValidationModule_SameValue(); +    /* ============ Modifier ============ */ modifier onlyRuleEngineManager() { @@ -478,15 +571,60 @@

function _authorizeRuleEngineManagement() internal virtual;   /* ============ State functions ============ */ + /** + * @dev + * @custom:security The RuleEngine callback is the only point at which a transfer hands control + * to an external contract, and it happens *before* the ERC-20 balances move: the active-balance + * (frozen) check in {CMTATBaseCommon-_checkTransferred} has already run against the pre-transfer + * state and is not re-evaluated afterwards. A RuleEngine that reenters the token during + * `transferred(...)` — because it is malicious, compromised, or because one of its rules calls + * untrusted code — is therefore validated twice against the same snapshot, and the outer and + * inner transfers can together move more than the holder's unfrozen balance, breaking the + * `frozenTokens <= balanceOf` invariant. + * + * The external call is isolated in {_callRuleEngineTransferred}, which is `virtual` so that a + * deployment variant can wrap it in a reentrancy guard by inheriting OpenZeppelin's + * `ReentrancyGuardTransient` and overriding {_callRuleEngineTransferred} with `nonReentrant` + * (see e.g. `contracts/deployment/CMTATStandardStandalone.sol`). + * + * WARNING - the guard is **not** enabled on every variant. It costs ~195 bytes of deployed + * bytecode, and several variants are within a few hundred bytes of the EIP-170 24 KiB limit, so + * enabling it there would make them undeployable. Variants without the guard rely on the standard + * CMTAT trust assumption: the RuleEngine is set by `DEFAULT_ADMIN_ROLE`, is fully trusted, and + * MUST NOT hand control to untrusted code during `transferred(...)`. See the module documentation + * for the per-variant table. + * + * The guard is entered only when a RuleEngine is set, so a deployment with no engine pays + * nothing, and it is released when the callback returns, so sequential hooks (batch operations, + * `burnAndMint`) are unaffected. + */ function _transferred(address spender, address from, address to, uint256 value) internal virtual{ _canTransferGenericByModuleAndRevert(spender, from, to); IRuleEngine ruleEngine_ = ruleEngine(); if (address(ruleEngine_) != address(0)){ - if(spender != address(0)){ - ruleEngine_.transferred(spender, from, to, value); - } else { - ruleEngine_.transferred(from, to, value); - } + _callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } + } +  + /** + * @dev Performs the RuleEngine `transferred` call. + * + * Declared `virtual` so a deployment variant can wrap it in a reentrancy guard by overriding it + * with `nonReentrant` (inheriting OpenZeppelin's `ReentrancyGuardTransient`). The base + * implementation is **unguarded**: see the security note on {_transferred} for which variants + * enable the guard and why it is not enabled everywhere. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual { + if(spender != address(0)){ + ruleEngine_.transferred(spender, from, to, value); + } else { + ruleEngine_.transferred(from, to, value); } } } @@ -496,7 +634,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/index.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/index.html index 6b741d89..4dfc4a6e 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/index.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/ValidationModule/index.html @@ -22,22 +22,22 @@

100% Statements - 69/69 + 72/72
100% Branches - 52/52 + 54/54
100% Functions - 14/14 + 15/15
100% Lines - 61/61 + 64/64
@@ -62,13 +62,13 @@

ValidationModuleAllowance.sol
100% - 3/3 + 5/5 100% - 4/4 + 6/6 100% 1/1 100% - 5/5 + 7/7 @@ -88,13 +88,13 @@

ValidationModuleRuleEngine.sol
100% - 25/25 + 26/26 100% 16/16 100% - 9/9 + 10/10 100% - 26/26 + 27/27 @@ -103,7 +103,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/extensions/index.html b/doc/test/coverage/lcov-report/modules/wrapper/extensions/index.html index 61a907a5..87798124 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/extensions/index.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/extensions/index.html @@ -22,22 +22,22 @@

100% Statements - 61/61 + 65/65
- 91.18% + 94.44% Branches - 31/34 + 34/36
100% Functions - 34/34 + 35/35
100% Lines - 84/84 + 91/91
@@ -62,13 +62,13 @@

DocumentERC1643Module.sol
100% - 18/18 - 90% - 9/10 + 20/20 + 100% + 12/12 100% 6/6 100% - 28/28 + 30/30 @@ -88,13 +88,13 @@

ExtraInformationModule.sol
100% - 21/21 + 23/23 87.5% 7/8 100% - 13/13 + 14/14 100% - 29/29 + 34/34 @@ -116,7 +116,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/AllowlistModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/AllowlistModule.sol.html index 0a95e263..01f302e6 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/AllowlistModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/AllowlistModule.sol.html @@ -164,8 +164,8 @@

      -978× -970× +1129× +1121×       @@ -186,7 +186,7 @@

      -292× +322×       @@ -196,7 +196,7 @@

      -532× +584×       @@ -206,8 +206,8 @@

      -142× -142× +211× +211×       @@ -223,15 +223,15 @@

      -1438× +1580×             -2396× -2396× +2626× +2626×       @@ -239,7 +239,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {IAllowlistModule} from "../../../interfaces/modules/IAllowlistModule.sol";
@@ -340,7 +340,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/CCIPModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/CCIPModule.sol.html index 31f4c771..3f105674 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/CCIPModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/CCIPModule.sol.html @@ -114,7 +114,8 @@

69 70 71 -72  +72 +73        @@ -168,6 +169,7 @@

      +  24× 24×   @@ -187,7 +189,7 @@

   
// SPDX-License-Identifier: MIT
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IGetCCIPAdmin} from "../../../interfaces/technical/IGetCCIPAdmin.sol";
 /**
@@ -237,6 +239,7 @@ 

  /** * Returns the current CCIPAdmin + * @return The current CCIP admin address. */ function getCCIPAdmin() public view virtual returns (address) { CCIPModuleStorage storage $ = _getCCIPModuleStorage(); @@ -262,7 +265,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/DebtEngineModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/DebtEngineModule.sol.html index 36efef1e..b9e52c29 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/DebtEngineModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/DebtEngineModule.sol.html @@ -263,7 +263,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Engine === */
 import {IDebtEngine, ICMTATDebt, ICMTATCreditEvents} from "../../../interfaces/engine/IDebtEngine.sol";
@@ -376,7 +376,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/DebtModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/DebtModule.sol.html index 5627a8ff..0b16fefb 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/DebtModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/DebtModule.sol.html @@ -257,7 +257,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Engine === */
 import {ICMTATDebt, ICMTATCreditEvents} from "../../../interfaces/engine/IDebtEngine.sol";
@@ -367,7 +367,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/DocumentEngineModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/DocumentEngineModule.sol.html index 0529410a..71184d00 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/DocumentEngineModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/DocumentEngineModule.sol.html @@ -22,12 +22,12 @@

100% Statements - 20/20 + 25/25
- 93.75% + 90% Branches - 15/16 + 18/20
100% @@ -37,7 +37,7 @@

100% Lines - 24/24 + 29/29

@@ -169,7 +169,21 @@

124 125 126 -127  +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141        @@ -197,8 +211,8 @@

      -34× -29× +55× +50×       @@ -211,7 +225,7 @@

      -37× +53×   @@ -225,8 +239,8 @@

      -15× -15× +19× +19×       @@ -252,26 +266,28 @@

      - - +18× +18×       - -     +15× +14×       + +         + + +   -18× -18× -15×       @@ -281,8 +297,20 @@

      -21× -21× +25× +25× +22× +  +  +  +  +  +  +  +  +  +28× +28×       @@ -290,14 +318,14 @@

      -64× +89×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin=== */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -313,7 +341,7 @@ 

*/ 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 === */ @@ -358,12 +386,12 @@

/** * @inheritdoc IERC1643 */ - function getDocument(bytes32 name) public view virtual override(IERC1643) returns (Document memory document){ + function getDocument(bytes32 name) public view virtual override(IERC1643) returns (string memory uri, bytes32 documentHash, uint256 lastModified){ DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage(); if(address($._documentEngine) != address(0)){ return $._documentEngine.getDocument(name); } else{ - return Document("", 0x0, 0); + return ("", 0x0, 0); } }   @@ -379,12 +407,26 @@

  function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) public virtual override(IERC1643) onlyDocumentManager { DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage(); + require(address($._documentEngine) != address(0), CMTAT_DocumentEngineModule_NoDocumentEngine()); + // Persist in the engine (which reverts on invalid input, e.g. the zero name), then re-emit + // the standard ERC-1643 event on the token's own address. ERC-1643 is a per-contract + // interface and integrators subscribe to the token that exposes {setDocument}; without this + // re-emission the update would only be observable on the engine's address. The engine also + // emits, on its own address. $._documentEngine.setDocument(name, uri, documentHash); + emit DocumentUpdated(name, uri, documentHash); }   function removeDocument(bytes32 name) public virtual override(IERC1643) onlyDocumentManager { DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage(); + Erequire(address($._documentEngine) != address(0), CMTAT_DocumentEngineModule_NoDocumentEngine()); + // Read the metadata before removal so the token can re-emit DocumentRemoved with the removed + // values (spec: "MUST emit DocumentRemoved with the removed metadata"). The forwarded + // removeDocument reverts if the document is missing, so the token only emits after a genuine + // removal. + (string memory uri, bytes32 documentHash, ) = $._documentEngine.getDocument(name); $._documentEngine.removeDocument(name); + emit DocumentRemoved(name, uri, documentHash); }   /* ============ Restricted Functions ============ */ @@ -427,7 +469,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/ERC20CrossChainModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/ERC20CrossChainModule.sol.html index e79f3552..b42be92a 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/ERC20CrossChainModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/ERC20CrossChainModule.sol.html @@ -178,7 +178,13 @@

133 134 135 -136  +136 +137 +138 +139 +140 +141 +142        @@ -210,8 +216,14 @@

      -266× -194× +  +  +  +  +  +  +254× +182×       @@ -222,7 +234,7 @@

      -96× +84× 48×     @@ -251,7 +263,7 @@

      -108× +96× 60×     @@ -281,7 +293,7 @@

      -84× +92×       @@ -315,7 +327,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {ERC165Upgradeable, IERC165} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
 /* ==== Module === */
@@ -345,6 +357,12 @@ 

modifier onlyTokenBridge() { // Token bridge should never be impersonated using a relayer/forwarder. Using msg.sender is preferable to // _msgSender() for security reasons. + // + // DEPLOYMENT CONSTRAINT - this is the only role gate in CMTAT that authorizes the raw msg.sender, so a + // bridge MUST call crosschainMint/crosschainBurn directly; a call relayed through the ERC-2771 forwarder + // reverts, because the forwarder is the raw caller. CROSS_CHAIN_ROLE MUST NOT be granted to that + // forwarder to work around it: every relayed call would then pass this gate, letting any user mint an + // arbitrary amount to any address. See doc/technical/cross-chain-bridge-integration.md _checkTokenBridge(msg.sender); _; } @@ -405,7 +423,7 @@

/** * @inheritdoc IBurnFromERC20 * @custom:access-control - * - Protected by the modifier onlyBurnerFrom + * - Protected by the modifier onlySelfBurn (BURNER_SELF_ROLE). */ function burn( uint256 value @@ -454,7 +472,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/ERC20EnforcementERC7551Module.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/ERC20EnforcementERC7551Module.sol.html index 2e232edb..a744fda6 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/ERC20EnforcementERC7551Module.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/ERC20EnforcementERC7551Module.sol.html @@ -152,7 +152,7 @@

      -452× +593×       @@ -161,7 +161,7 @@

      -432× +440×       @@ -171,14 +171,14 @@

      -74× -74× -74× -74× +98× +98× +90× +90× 24×   -74× -74× +90× +90×       @@ -188,8 +188,8 @@

      +56× 48× -40×       @@ -205,7 +205,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ERC20EnforcementModule} from "../extensions/ERC20EnforcementModule.sol";
@@ -289,7 +289,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/ERC2771Module.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/ERC2771Module.sol.html index b4034d57..bfa79f2c 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/ERC2771Module.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/ERC2771Module.sol.html @@ -91,7 +91,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC2771ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol";
@@ -118,7 +118,7 @@ 

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/ERC7551Module.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/ERC7551Module.sol.html index 99f786eb..82c8e1d3 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/ERC7551Module.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/ERC7551Module.sol.html @@ -22,7 +22,7 @@

100% Statements - 9/9 + 8/8
100% @@ -37,7 +37,7 @@

100% Lines - 11/11 + 10/10

@@ -130,8 +130,8 @@

85 86 87 -88  -  +88 +89        @@ -182,9 +182,11 @@

      - - - +  +  +  + +       @@ -197,7 +199,7 @@

      - +       @@ -219,12 +221,11 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ExtraInformationModule} from "../extensions/ExtraInformationModule.sol";
 /* ==== Tokenization === */
-import {IERC1643CMTAT} from "../../../interfaces/tokenization/draft-IERC1643CMTAT.sol";
 import {IERC7551Document} from "../../../interfaces/tokenization/draft-IERC7551.sol";
  
 /**
@@ -269,8 +270,10 @@ 

* - the caller must have the `EXTRA_INFORMATION_ROLE`. */ function setTerms(bytes32 hash_, string calldata uri_) public virtual override(IERC7551Document) onlyExtraInfoManager { - IERC1643CMTAT.DocumentInfo memory terms_ = IERC1643CMTAT.DocumentInfo("", uri_, hash_); - _setTerms(terms_); + // The ERC-7551 signature carries no document name, so only the document (uri + hash) is + // updated. Forwarding an empty name through _setTerms would silently erase a name set + // through the {ICMTATBase-setTerms} overload. + _setTermsDocument(hash_, uri_); emit Terms(hash_, uri_); }   @@ -310,7 +313,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/HolderListModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/options/HolderListModule.sol.html new file mode 100644 index 00000000..927dbd28 --- /dev/null +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/HolderListModule.sol.html @@ -0,0 +1,440 @@ + + + + Code coverage report for modules/wrapper/options/HolderListModule.sol + + + + + + + +
+
+

+ all files / modules/wrapper/options/ HolderListModule.sol +

+
+
+ 100% + Statements + 23/23 +
+
+ 92.86% + Branches + 13/14 +
+
+ 100% + Functions + 7/7 +
+
+ 100% + Lines + 26/26 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +28× +28× +  +  +  +  +  +  +22× +22× +  +  +  +  +  +  +  +  +  +10× +10× +10× + +  +  +  +  +  +  +10× +10× +  +  +  +  +  +  +  +  +22× +18× +18× +18× +16× +16× +10× +  +  +  +  +  +  +  +  +  +  +  +  +114× +114× +  +114× +10× +10× +  +  +  +114× +106× +104× +  +  +  +  +  +  +202× +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+/* ==== OpenZeppelin === */
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
+/* ==== Interfaces === */
+import {IHolderListModule} from "../../../interfaces/modules/IHolderListModule.sol";
+ 
+/**
+ * @title HolderList module
+ * @dev
+ *
+ * Maintains on-chain the set of addresses holding a non-zero balance, with paginated reads.
+ *
+ * The set is kept in sync inside {_update}, so every balance change is covered: transfer,
+ * transferFrom, mint, burn, forced transfer and cross-chain mint/burn.
+ *
+ * Gas: the first transfer to a new address writes two slots (EnumerableSet stores the value
+ * and its index), and the transfer emptying an account clears them. A transfer between
+ * existing holders that leaves both balances non-zero performs no storage write to the set
+ * (no add/remove, no event), but still reads balanceOf(from) and balanceOf(to) and does one
+ * EnumerableSet membership-check SLOAD in add(to) — roughly two warm + one cold SLOAD, no SSTORE.
+ */
+abstract contract HolderListModule is ERC20Upgradeable, IHolderListModule {
+    using EnumerableSet for EnumerableSet.AddressSet;
+ 
+    /* ============ ERC-7201 ============ */
+    // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.HolderListModule")) - 1)) & ~bytes32(uint256(0xff))
+    bytes32 private constant HolderListModuleStorageLocation = 0x93edd3717dec98b474d42a698cc89715a70e7eaf60a2dff7170cc742b7b8ca00;
+ 
+    /* ==== ERC-7201 State Variables === */
+    struct HolderListModuleStorage {
+        EnumerableSet.AddressSet _holders;
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============ View functions ============ */
+    /**
+    * @inheritdoc IHolderListModule
+    */
+    function holderCount() public view virtual returns (uint256) {
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        return $._holders.length();
+    }
+ 
+    /**
+    * @inheritdoc IHolderListModule
+    */
+    function isHolder(address account) public view virtual returns (bool) {
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        return $._holders.contains(account);
+    }
+ 
+    /**
+    * @inheritdoc IHolderListModule
+    * @dev The bound is checked here so that an out-of-range index reverts with
+    * {CMTAT_HolderListModule_IndexOutOfBounds} rather than with the `Panic(0x32)` that
+    * {EnumerableSet-at} raises on an out-of-bounds array access.
+    */
+    function holderByIndex(uint256 index) public view virtual returns (address) {
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        uint256 holderCountLocal = $._holders.length();
+        require(index < holderCountLocal, CMTAT_HolderListModule_IndexOutOfBounds(index, holderCountLocal));
+        return $._holders.at(index);
+    }
+ 
+    /**
+    * @inheritdoc IHolderListModule
+    */
+    function holders() public view virtual returns (address[] memory) {
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        return $._holders.values();
+    }
+ 
+    /**
+    * @inheritdoc IHolderListModule
+    * @dev The malformed-range check is evaluated before the upper-bound check, so an inverted
+    * range reverts with {CMTAT_HolderListModule_InvalidRange} regardless of where the bounds fall.
+    */
+    function holdersInRange(uint256 fromIndex, uint256 toIndex) public view virtual returns (address[] memory window) {
+        require(fromIndex <= toIndex, CMTAT_HolderListModule_InvalidRange(fromIndex, toIndex));
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        uint256 holderCountLocal = $._holders.length();
+        require(toIndex <= holderCountLocal, CMTAT_HolderListModule_IndexOutOfBounds(toIndex, holderCountLocal));
+        window = new address[](toIndex - fromIndex);
+        for (uint256 i = 0; i < window.length; ++i) {
+            window[i] = $._holders.at(fromIndex + i);
+        }
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /**
+    * @dev Update the holder set after the balances have been written by {ERC20Upgradeable-_update}.
+    * The post-update balance is what decides membership, so the sender is evaluated after it has
+    * been debited and the receiver after it has been credited.
+    */
+    function _update(address from, address to, uint256 value) internal virtual override(ERC20Upgradeable) {
+        super._update(from, to, value);
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        // address(0) is the mint source and the burn sink, never a holder
+        if (from != address(0) && balanceOf(from) == 0) {
+            Eif ($._holders.remove(from)) {
+                emit HolderRemoved(from);
+            }
+        }
+        // a zero-value transfer to a new address must not make it a holder
+        if (to != address(0) && balanceOf(to) != 0) {
+            if ($._holders.add(to)) {
+                emit HolderAdded(to);
+            }
+        }
+    }
+ 
+    /* ============ ERC-7201 ============ */
+    function _getHolderListModuleStorage() private pure returns (HolderListModuleStorage storage $) {
+        assembly {
+            $.slot := HolderListModuleStorageLocation
+        }
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/lcov-report/modules/wrapper/options/index.html b/doc/test/coverage/lcov-report/modules/wrapper/options/index.html index 09c6d4a6..b26b6a6d 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/options/index.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/options/index.html @@ -22,22 +22,22 @@

100% Statements - 96/96 + 123/123
- 92.19% + 91.46% Branches - 59/64 + 75/82
100% Functions - 58/58 + 65/65
100% Lines - 121/121 + 151/151
@@ -114,13 +114,13 @@

DocumentEngineModule.sol
100% - 20/20 - 93.75% - 15/16 + 25/25 + 90% + 18/20 100% 10/10 100% - 24/24 + 29/29 @@ -166,13 +166,26 @@

ERC7551Module.sol
100% - 9/9 + 8/8 100% 4/4 100% 6/6 100% - 11/11 + 10/10 + + + + HolderListModule.sol +
+ 100% + 23/23 + 92.86% + 13/14 + 100% + 7/7 + 100% + 26/26 @@ -181,7 +194,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/security/AccessControlModule.sol.html b/doc/test/coverage/lcov-report/modules/wrapper/security/AccessControlModule.sol.html index 782a55b3..e71599db 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/security/AccessControlModule.sol.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/security/AccessControlModule.sol.html @@ -94,7 +94,8 @@

49 50 51 -52  +52 +53        @@ -118,13 +119,13 @@

      -5688× +6262×         -5686× +6260×       @@ -138,16 +139,17 @@

      -20013× -12061×   -7952× +21844× +13326× +  +8518×        
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
@@ -181,8 +183,9 @@ 

/*////////////////////////////////////////////////////////////// PUBLIC/EXTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ - /** + /** * @dev Returns `true` if `account` has been granted `role`. + * @return True if `account` holds `role` (the default admin implicitly holds every role). */ function hasRole( bytes32 role, @@ -202,7 +205,7 @@

diff --git a/doc/test/coverage/lcov-report/modules/wrapper/security/index.html b/doc/test/coverage/lcov-report/modules/wrapper/security/index.html index b9f1cf8c..1aa359c9 100644 --- a/doc/test/coverage/lcov-report/modules/wrapper/security/index.html +++ b/doc/test/coverage/lcov-report/modules/wrapper/security/index.html @@ -77,7 +77,7 @@

diff --git a/doc/test/coverage/lcov.info b/doc/test/coverage/lcov.info index 1fb6769d..2ba99d7a 100644 --- a/doc/test/coverage/lcov.info +++ b/doc/test/coverage/lcov.info @@ -1,10 +1,10 @@ TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATStandaloneAllowlist.sol -FN:27,constructor +FN:26,constructor FNF:1 FNH:1 -FNDA:368,constructor -DA:29,368 +FNDA:458,constructor +DA:28,458 LF:1 LH:1 BRF:0 @@ -15,8 +15,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/allowlist/CMTATUpgradeable FN:18,constructor FNF:1 FNH:1 -FNDA:226,constructor -DA:20,226 +FNDA:247,constructor +DA:20,247 LF:1 LH:1 BRF:0 @@ -24,27 +24,37 @@ BRH:0 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardStandalone.sol -FN:29,constructor -FNF:1 -FNH:1 -FNDA:308,constructor -DA:31,308 -LF:1 -LH:1 -BRF:0 -BRH:0 +FN:32,constructor +FN:62,_callRuleEngineTransferred +FNF:2 +FNH:2 +FNDA:344,constructor +FNDA:142,_callRuleEngineTransferred +DA:34,344 +DA:63,142 +LF:2 +LH:2 +BRDA:62,1,0,142 +BRDA:62,1,1,4 +BRF:2 +BRH:2 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATStandardUpgradeable.sol -FN:20,constructor -FNF:1 -FNH:1 -FNDA:336,constructor -DA:22,336 -LF:1 -LH:1 -BRF:0 -BRH:0 +FN:23,constructor +FN:48,_callRuleEngineTransferred +FNF:2 +FNH:2 +FNDA:367,constructor +FNDA:237,_callRuleEngineTransferred +DA:25,367 +DA:49,237 +LF:2 +LH:2 +BRDA:48,1,0,237 +BRDA:48,1,1,4 +BRF:2 +BRH:2 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/CMTATUpgradeableUUPS.sol @@ -52,9 +62,9 @@ FN:20,constructor FN:32,_authorizeUpgrade FNF:2 FNH:2 -FNDA:450,constructor +FNDA:484,constructor FNDA:2,_authorizeUpgrade -DA:22,450 +DA:22,484 LF:1 LH:1 BRDA:32,1,0,2 @@ -67,8 +77,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATStandaloneDebt.s FN:19,constructor FNF:1 FNH:1 -FNDA:446,constructor -DA:26,446 +FNDA:482,constructor +DA:26,482 LF:1 LH:1 BRF:0 @@ -79,8 +89,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debt/CMTATUpgradeableDebt. FN:14,constructor FNF:1 FNH:1 -FNDA:456,constructor -DA:16,456 +FNDA:492,constructor +DA:16,492 LF:1 LH:1 BRF:0 @@ -91,8 +101,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATStandalone FN:19,constructor FNF:1 FNH:1 -FNDA:450,constructor -DA:26,450 +FNDA:486,constructor +DA:26,486 LF:1 LH:1 BRF:0 @@ -103,8 +113,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/debtEngine/CMTATUpgradeabl FN:14,constructor FNF:1 FNH:1 -FNDA:204,constructor -DA:16,204 +FNDA:222,constructor +DA:16,222 LF:1 LH:1 BRF:0 @@ -115,8 +125,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATStandaloneERC FN:29,constructor FNF:1 FNH:1 -FNDA:228,constructor -DA:31,228 +FNDA:245,constructor +DA:31,245 LF:1 LH:1 BRF:0 @@ -127,8 +137,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC1363/CMTATUpgradeableER FN:20,constructor FNF:1 FNH:1 -FNDA:268,constructor -DA:22,268 +FNDA:285,constructor +DA:22,285 LF:1 LH:1 BRF:0 @@ -136,23 +146,57 @@ BRH:0 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATStandaloneERC7551.sol -FN:28,constructor +FN:31,constructor +FN:66,_callRuleEngineTransferred +FNF:2 +FNH:2 +FNDA:248,constructor +FNDA:22,_callRuleEngineTransferred +DA:33,248 +DA:67,22 +LF:2 +LH:2 +BRDA:66,1,0,22 +BRDA:66,1,1,0 +BRF:2 +BRH:1 +end_of_record +TN: +SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol +FN:22,constructor +FN:47,_callRuleEngineTransferred +FNF:2 +FNH:2 +FNDA:248,constructor +FNDA:22,_callRuleEngineTransferred +DA:24,248 +DA:48,22 +LF:2 +LH:2 +BRDA:47,1,0,22 +BRDA:47,1,1,0 +BRF:2 +BRH:1 +end_of_record +TN: +SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATStandaloneHolderList.sol +FN:29,constructor FNF:1 FNH:1 -FNDA:230,constructor -DA:30,230 +FNDA:24,constructor +DA:31,24 LF:1 LH:1 BRF:0 BRH:0 end_of_record TN: -SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/ERC7551/CMTATUpgradeableERC7551.sol -FN:19,constructor +SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/holderList/CMTATUpgradeableHolderList.sol +FN:20,constructor FNF:1 FNH:1 -FNDA:230,constructor -DA:21,230 +FNDA:24,constructor +DA:22,24 LF:1 LH:1 BRF:0 @@ -163,8 +207,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATStandaloneLight FN:18,constructor FNF:1 FNH:1 -FNDA:125,constructor -DA:23,125 +FNDA:134,constructor +DA:23,134 LF:1 LH:1 BRF:0 @@ -175,8 +219,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/light/CMTATUpgradeableLigh FN:16,constructor FNF:1 FNH:1 -FNDA:122,constructor -DA:18,122 +FNDA:131,constructor +DA:18,131 LF:1 LH:1 BRF:0 @@ -187,8 +231,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATStandalonePerm FN:20,constructor FNF:1 FNH:1 -FNDA:228,constructor -DA:27,228 +FNDA:248,constructor +DA:27,248 LF:1 LH:1 BRF:0 @@ -199,8 +243,8 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/permit/CMTATUpgradeablePer FN:15,constructor FNF:1 FNH:1 -FNDA:230,constructor -DA:17,230 +FNDA:250,constructor +DA:17,250 LF:1 LH:1 BRF:0 @@ -208,27 +252,37 @@ BRH:0 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATStandaloneSnapshot.sol -FN:29,constructor -FNF:1 -FNH:1 -FNDA:327,constructor -DA:31,327 -LF:1 -LH:1 -BRF:0 -BRH:0 +FN:32,constructor +FN:62,_callRuleEngineTransferred +FNF:2 +FNH:2 +FNDA:344,constructor +FNDA:22,_callRuleEngineTransferred +DA:34,344 +DA:63,22 +LF:2 +LH:2 +BRDA:62,1,0,22 +BRDA:62,1,1,0 +BRF:2 +BRH:1 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/deployment/snapshot/CMTATUpgradeableSnapshot.sol -FN:20,constructor -FNF:1 -FNH:1 -FNDA:352,constructor -DA:22,352 -LF:1 -LH:1 -BRF:0 -BRH:0 +FN:23,constructor +FN:48,_callRuleEngineTransferred +FNF:2 +FNH:2 +FNDA:369,constructor +FNDA:22,_callRuleEngineTransferred +DA:25,369 +DA:49,22 +LF:2 +LH:2 +BRDA:48,1,0,22 +BRDA:48,1,1,0 +BRF:2 +BRH:1 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/engine/IDebtEngine.sol @@ -303,6 +357,15 @@ BRF:0 BRH:0 end_of_record TN: +SF:/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/IHolderListModule.sol +FNF:0 +FNH:0 +LF:0 +LH:0 +BRF:0 +BRH:0 +end_of_record +TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/modules/ISnapshotEngineModule.sol FNF:0 FNH:0 @@ -411,6 +474,15 @@ BRF:0 BRH:0 end_of_record TN: +SF:/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/draft-IERC8343.sol +FNF:0 +FNH:0 +LF:0 +LH:0 +BRF:0 +BRH:0 +end_of_record +TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/interfaces/tokenization/ICMTAT.sol FNF:0 FNH:0 @@ -448,46 +520,46 @@ BRH:0 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCommon.sol -FN:44,decimals -FN:58,name -FN:65,symbol -FN:71,transfer -FN:80,transferFrom -FN:106,burnAndMint -FN:115,_checkTransferred -FN:125,_mintOverride -FN:135,_burnOverride -FN:145,_minterTransferOverride +FN:46,decimals +FN:60,name +FN:67,symbol +FN:73,transfer +FN:82,transferFrom +FN:108,burnAndMint +FN:117,_checkTransferred +FN:128,_mintOverride +FN:139,_burnOverride +FN:150,_minterTransferOverride FNF:10 FNH:10 FNDA:22,decimals -FNDA:80,name -FNDA:68,symbol -FNDA:431,transfer -FNDA:278,transferFrom +FNDA:88,name +FNDA:70,symbol +FNDA:442,transfer +FNDA:306,transferFrom FNDA:110,burnAndMint -FNDA:8426,_checkTransferred -FNDA:6250,_mintOverride -FNDA:1175,_burnOverride -FNDA:292,_minterTransferOverride -DA:51,22 -DA:59,80 -DA:66,68 -DA:72,431 -DA:73,431 -DA:74,248 -DA:75,197 -DA:90,278 -DA:91,118 -DA:108,110 -DA:109,66 -DA:116,8426 -DA:126,6250 -DA:127,6063 -DA:136,1175 -DA:137,951 -DA:146,292 -DA:147,199 +FNDA:8968,_checkTransferred +FNDA:6737,_mintOverride +FNDA:1169,_burnOverride +FNDA:314,_minterTransferOverride +DA:53,22 +DA:61,88 +DA:68,70 +DA:74,442 +DA:75,442 +DA:76,252 +DA:77,190 +DA:92,306 +DA:93,174 +DA:110,110 +DA:111,66 +DA:118,8968 +DA:129,6737 +DA:130,6571 +DA:140,1169 +DA:141,957 +DA:151,314 +DA:152,199 LF:18 LH:18 BRF:0 @@ -495,122 +567,123 @@ BRH:0 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseCore.sol -FN:57,onlyERC20ForcedBurnManager -FN:74,initialize -FN:88,__CMTAT_init -FN:106,__CMTAT_openzeppelin_init_unchained -FN:116,__CMTAT_modules_init_unchained -FN:137,decimals -FN:151,name -FN:158,symbol -FN:170,supportsInterface -FN:178,transfer -FN:188,approve -FN:195,transferFrom -FN:222,burnAndMint -FN:236,forcedBurn -FN:248,_mintOverride -FN:254,_burnOverride -FN:262,_minterTransferOverride -FN:268,_authorizeForcedBurn -FN:270,_authorizeMint -FN:272,_authorizeBurn -FN:274,_authorizePause -FN:275,_authorizeDeactivate -FN:277,_authorizeFreeze -FN:279,_authorizeERC20AttributeManagement +FN:60,onlyERC20ForcedBurnManager +FN:77,initialize +FN:91,__CMTAT_init +FN:109,__CMTAT_openzeppelin_init_unchained +FN:119,__CMTAT_modules_init_unchained +FN:141,decimals +FN:155,name +FN:162,symbol +FN:174,supportsInterface +FN:182,transfer +FN:192,approve +FN:199,transferFrom +FN:226,burnAndMint +FN:244,forcedBurn +FN:256,_mintOverride +FN:262,_burnOverride +FN:270,_minterTransferOverride +FN:280,_authorizeForcedBurn +FN:282,_authorizeMint +FN:284,_authorizeBurn +FN:286,_authorizePause +FN:287,_authorizeDeactivate +FN:289,_authorizeFreeze +FN:291,_authorizeTokenAttributeManagement FNF:24 FNH:24 FNDA:4,onlyERC20ForcedBurnManager -FNDA:247,initialize -FNDA:284,__CMTAT_init -FNDA:284,__CMTAT_openzeppelin_init_unchained -FNDA:284,__CMTAT_modules_init_unchained +FNDA:265,initialize +FNDA:318,__CMTAT_init +FNDA:318,__CMTAT_openzeppelin_init_unchained +FNDA:318,__CMTAT_modules_init_unchained FNDA:2,decimals FNDA:6,name FNDA:6,symbol -FNDA:12,supportsInterface -FNDA:28,transfer -FNDA:30,approve -FNDA:14,transferFrom +FNDA:19,supportsInterface +FNDA:26,transfer +FNDA:54,approve +FNDA:18,transferFrom FNDA:10,burnAndMint FNDA:3,forcedBurn -FNDA:354,_mintOverride +FNDA:368,_mintOverride FNDA:76,_burnOverride -FNDA:18,_minterTransferOverride +FNDA:20,_minterTransferOverride FNDA:3,_authorizeForcedBurn -FNDA:284,_authorizeMint +FNDA:298,_authorizeMint FNDA:54,_authorizeBurn -FNDA:50,_authorizePause -FNDA:20,_authorizeDeactivate -FNDA:51,_authorizeFreeze -FNDA:4,_authorizeERC20AttributeManagement -DA:58,4 -DA:59,3 -DA:75,247 -DA:91,284 -DA:94,284 -DA:97,284 -DA:100,284 -DA:108,284 -DA:109,284 -DA:118,284 -DA:119,284 -DA:144,2 -DA:152,6 -DA:159,6 -DA:171,12 -DA:179,28 -DA:180,28 -DA:181,18 -DA:182,12 -DA:189,30 -DA:190,24 -DA:205,14 -DA:206,10 -DA:223,10 -DA:224,6 -DA:237,3 -DA:239,2 -DA:240,2 -DA:249,354 -DA:250,346 -DA:255,76 -DA:256,66 -DA:263,18 -DA:264,12 -LF:34 -LH:34 -BRDA:74,1,0,247 -BRDA:74,1,1,0 -BRDA:88,2,0,284 -BRDA:88,2,1,0 -BRDA:106,3,0,284 -BRDA:106,3,1,0 -BRDA:116,4,0,284 -BRDA:116,4,1,0 -BRDA:171,5,0,2 -BRDA:171,5,1,2 -BRDA:171,6,0,2 -BRDA:171,6,1,2 -BRDA:236,7,0,3 -BRDA:236,7,1,1 -BRDA:237,8,0,2 -BRDA:237,8,1,1 -BRDA:268,9,0,3 -BRDA:268,9,1,1 -BRDA:270,10,0,284 -BRDA:270,10,1,6 -BRDA:272,11,0,54 -BRDA:272,11,1,8 -BRDA:274,12,0,50 -BRDA:274,12,1,4 -BRDA:275,13,0,20 -BRDA:275,13,1,2 -BRDA:277,14,0,51 -BRDA:277,14,1,6 -BRDA:279,15,0,4 -BRDA:279,15,1,4 +FNDA:56,_authorizePause +FNDA:22,_authorizeDeactivate +FNDA:65,_authorizeFreeze +FNDA:4,_authorizeTokenAttributeManagement +DA:61,4 +DA:62,3 +DA:78,265 +DA:94,318 +DA:97,318 +DA:100,318 +DA:103,318 +DA:111,318 +DA:112,318 +DA:121,318 +DA:122,318 +DA:123,318 +DA:148,2 +DA:156,6 +DA:163,6 +DA:175,19 +DA:183,26 +DA:184,26 +DA:185,16 +DA:186,10 +DA:193,54 +DA:194,44 +DA:209,18 +DA:210,14 +DA:227,10 +DA:228,6 +DA:245,3 +DA:247,2 +DA:248,2 +DA:257,368 +DA:258,360 +DA:263,76 +DA:264,66 +DA:275,20 +DA:276,12 +LF:35 +LH:35 +BRDA:77,1,0,265 +BRDA:77,1,1,0 +BRDA:91,2,0,318 +BRDA:91,2,1,0 +BRDA:109,3,0,318 +BRDA:109,3,1,0 +BRDA:119,4,0,318 +BRDA:119,4,1,0 +BRDA:175,5,0,2 +BRDA:175,5,1,2 +BRDA:175,6,0,2 +BRDA:175,6,1,5 +BRDA:244,7,0,3 +BRDA:244,7,1,1 +BRDA:245,8,0,2 +BRDA:245,8,1,1 +BRDA:280,9,0,3 +BRDA:280,9,1,1 +BRDA:282,10,0,298 +BRDA:282,10,1,6 +BRDA:284,11,0,54 +BRDA:284,11,1,8 +BRDA:286,12,0,56 +BRDA:286,12,1,4 +BRDA:287,13,0,22 +BRDA:287,13,1,2 +BRDA:289,14,0,65 +BRDA:289,14,1,6 +BRDA:291,15,0,4 +BRDA:291,15,1,4 BRF:30 BRH:26 end_of_record @@ -623,28 +696,28 @@ FN:86,_authorizeDocumentManagement FN:87,_authorizeExtraInfoManagement FNF:5 FNH:5 -FNDA:62,__CMTAT_init -FNDA:62,__CMTAT_openzeppelin_init_unchained -FNDA:62,__CMTAT_modules_init_unchained -FNDA:11,_authorizeDocumentManagement +FNDA:72,__CMTAT_init +FNDA:72,__CMTAT_openzeppelin_init_unchained +FNDA:72,__CMTAT_modules_init_unchained +FNDA:16,_authorizeDocumentManagement FNDA:3,_authorizeExtraInfoManagement -DA:50,62 -DA:53,62 -DA:56,62 -DA:59,62 -DA:67,62 -DA:68,62 -DA:76,62 -DA:78,62 +DA:50,72 +DA:53,72 +DA:56,72 +DA:59,72 +DA:67,72 +DA:68,72 +DA:76,72 +DA:78,72 LF:8 LH:8 -BRDA:47,1,0,62 +BRDA:47,1,0,72 BRDA:47,1,1,0 -BRDA:65,2,0,62 +BRDA:65,2,0,72 BRDA:65,2,1,0 -BRDA:74,3,0,62 +BRDA:74,3,0,72 BRDA:74,3,1,0 -BRDA:86,4,0,11 +BRDA:86,4,0,16 BRDA:86,4,1,2 BRDA:87,5,0,3 BRDA:87,5,1,3 @@ -656,19 +729,19 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/0_CMTATBaseSnapshot.sol FN:19,_update FNF:1 FNH:1 -FNDA:2951,_update -DA:20,2951 -DA:21,2951 -DA:22,176 -DA:23,176 -DA:24,176 -DA:25,176 -DA:26,176 -DA:28,2775 +FNDA:3118,_update +DA:20,3118 +DA:21,3118 +DA:22,231 +DA:23,231 +DA:24,231 +DA:25,231 +DA:26,231 +DA:28,2887 LF:8 LH:8 -BRDA:21,1,0,176 -BRDA:21,1,1,2775 +BRDA:21,1,0,231 +BRDA:21,1,1,2887 BRF:2 BRH:2 end_of_record @@ -683,56 +756,59 @@ BRH:0 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/2_CMTATBaseAccessControl.sol -FN:32,__CMTAT_commonModules_init_unchained -FN:52,supportsInterface -FN:66,_authorizeERC20AttributeManagement -FN:72,_authorizeMint -FN:78,_authorizeBurn -FN:84,_authorizeDocumentManagement -FN:90,_authorizeExtraInfoManagement -FN:96,_authorizeERC20Enforcer -FN:102,_authorizeForcedTransfer +FN:34,__CMTAT_commonModules_init_unchained +FN:56,supportsInterface +FN:70,_authorizeTokenAttributeManagement +FN:76,_authorizeMint +FN:82,_authorizeBurn +FN:88,_authorizeDocumentManagement +FN:94,_authorizeExtraInfoManagement +FN:100,_authorizeERC20Enforcer +FN:106,_authorizeForcedTransfer FNF:9 FNH:9 -FNDA:5342,__CMTAT_commonModules_init_unchained -FNDA:42,supportsInterface -FNDA:46,_authorizeERC20AttributeManagement -FNDA:5366,_authorizeMint -FNDA:685,_authorizeBurn -FNDA:242,_authorizeDocumentManagement -FNDA:79,_authorizeExtraInfoManagement -FNDA:1226,_authorizeERC20Enforcer -FNDA:220,_authorizeForcedTransfer -DA:34,5342 -DA:36,5340 -DA:38,5340 -DA:53,42 -LF:4 -LH:4 -BRDA:32,1,0,5342 -BRDA:32,1,1,0 -BRDA:53,2,0,16 -BRDA:53,2,1,2 -BRDA:53,3,0,2 -BRDA:53,3,1,2 -BRDA:53,4,0,2 -BRDA:53,4,1,4 -BRDA:66,5,0,46 -BRDA:66,5,1,44 -BRDA:72,6,0,5366 -BRDA:72,6,1,66 -BRDA:78,7,0,685 -BRDA:78,7,1,88 -BRDA:84,8,0,242 -BRDA:84,8,1,44 -BRDA:90,9,0,79 -BRDA:90,9,1,79 -BRDA:96,10,0,1226 -BRDA:96,10,1,63 -BRDA:102,11,0,220 -BRDA:102,11,1,42 -BRF:22 -BRH:21 +FNDA:5872,__CMTAT_commonModules_init_unchained +FNDA:45,supportsInterface +FNDA:46,_authorizeTokenAttributeManagement +FNDA:5827,_authorizeMint +FNDA:691,_authorizeBurn +FNDA:355,_authorizeDocumentManagement +FNDA:83,_authorizeExtraInfoManagement +FNDA:1364,_authorizeERC20Enforcer +FNDA:298,_authorizeForcedTransfer +DA:36,5872 +DA:38,5870 +DA:39,5870 +DA:41,5870 +DA:57,45 +LF:5 +LH:5 +BRDA:34,1,0,5872 +BRDA:34,1,1,0 +BRDA:57,2,0,16 +BRDA:57,2,1,2 +BRDA:57,3,0,2 +BRDA:57,3,1,2 +BRDA:57,4,0,2 +BRDA:57,4,1,2 +BRDA:57,5,0,2 +BRDA:57,5,1,4 +BRDA:70,6,0,46 +BRDA:70,6,1,44 +BRDA:76,7,0,5827 +BRDA:76,7,1,66 +BRDA:82,8,0,691 +BRDA:82,8,1,88 +BRDA:88,9,0,355 +BRDA:88,9,1,44 +BRDA:94,10,0,83 +BRDA:94,10,1,79 +BRDA:100,11,0,1364 +BRDA:100,11,1,66 +BRDA:106,12,0,298 +BRDA:106,12,1,44 +BRF:24 +BRH:23 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseAllowlist.sol @@ -740,130 +816,128 @@ FN:56,initialize FN:72,__CMTAT_init FN:90,__CMTAT_openzeppelin_init_unchained FN:101,__CMTAT_modules_init_unchained -FN:122,approve -FN:127,transfer -FN:136,transferFrom -FN:145,decimals -FN:155,name -FN:165,symbol -FN:178,canTransfer -FN:195,canTransferFrom -FN:214,_authorizePause -FN:215,_authorizeDeactivate -FN:217,_authorizeFreeze -FN:219,_authorizeAllowlistManagement -FN:220,_authorizeERC20Enforcer -FN:223,_authorizeForcedTransfer -FN:231,_canMintBurnByModule -FN:237,_canMintByModuleAndRevert -FN:243,_canBurnByModuleAndRevert -FN:249,_canSend -FN:253,_canReceive -FN:257,_canTransferStandardByModule -FN:265,_canTransferStandardByModuleAndRevert -FN:273,_checkTransferred -FN:278,getFrozenTokens -FN:295,_msgSender -FN:307,_contextSuffixLength -FN:316,_msgData +FN:125,approve +FN:132,transfer +FN:141,transferFrom +FN:150,decimals +FN:160,name +FN:170,symbol +FN:183,canTransfer +FN:200,canTransferFrom +FN:219,_authorizePause +FN:220,_authorizeDeactivate +FN:222,_authorizeFreeze +FN:224,_authorizeAllowlistManagement +FN:225,_authorizeERC20Enforcer +FN:228,_authorizeForcedTransfer +FN:236,_canMintBurnByModule +FN:242,_canMintByModuleAndRevert +FN:248,_canBurnByModuleAndRevert +FN:254,_canSend +FN:258,_canReceive +FN:262,_canTransferStandardByModule +FN:270,_canTransferStandardByModuleAndRevert +FN:278,_checkTransferred +FN:283,getFrozenTokens +FN:301,_msgSender +FN:314,_contextSuffixLength +FN:324,_msgData FNF:30 FNH:30 -FNDA:594,initialize -FNDA:594,__CMTAT_init -FNDA:594,__CMTAT_openzeppelin_init_unchained -FNDA:594,__CMTAT_modules_init_unchained -FNDA:68,approve -FNDA:54,transfer -FNDA:35,transferFrom +FNDA:705,initialize +FNDA:705,__CMTAT_init +FNDA:705,__CMTAT_openzeppelin_init_unchained +FNDA:705,__CMTAT_modules_init_unchained +FNDA:116,approve +FNDA:58,transfer +FNDA:39,transferFrom FNDA:3,decimals FNDA:9,name FNDA:9,symbol -FNDA:240,canTransfer +FNDA:316,canTransfer FNDA:31,canTransferFrom -FNDA:75,_authorizePause -FNDA:30,_authorizeDeactivate -FNDA:75,_authorizeFreeze -FNDA:970,_authorizeAllowlistManagement -FNDA:132,_authorizeERC20Enforcer -FNDA:28,_authorizeForcedTransfer +FNDA:84,_authorizePause +FNDA:33,_authorizeDeactivate +FNDA:96,_authorizeFreeze +FNDA:1121,_authorizeAllowlistManagement +FNDA:200,_authorizeERC20Enforcer +FNDA:49,_authorizeForcedTransfer FNDA:12,_canMintBurnByModule -FNDA:740,_canMintByModuleAndRevert +FNDA:849,_canMintByModuleAndRevert FNDA:128,_canBurnByModuleAndRevert -FNDA:207,_canSend -FNDA:34,_canReceive -FNDA:191,_canTransferStandardByModule -FNDA:108,_canTransferStandardByModuleAndRevert -FNDA:992,_checkTransferred -FNDA:116,getFrozenTokens -FNDA:7381,_msgSender -FNDA:7383,_contextSuffixLength +FNDA:273,_canSend +FNDA:38,_canReceive +FNDA:245,_canTransferStandardByModule +FNDA:118,_canTransferStandardByModuleAndRevert +FNDA:1110,_checkTransferred +FNDA:235,getFrozenTokens +FNDA:8559,_msgSender +FNDA:8561,_contextSuffixLength FNDA:2,_msgData -DA:57,594 -DA:75,594 -DA:78,594 -DA:81,594 -DA:84,594 -DA:92,594 -DA:93,594 -DA:95,594 -DA:102,594 -DA:104,594 -DA:123,68 -DA:124,58 -DA:133,54 -DA:142,35 -DA:152,3 -DA:162,9 -DA:172,9 -DA:183,240 -DA:184,240 -DA:185,60 -DA:187,180 -DA:201,31 -DA:202,31 -DA:203,8 -DA:205,23 -DA:221,132 -DA:224,28 -DA:234,12 -DA:240,740 -DA:246,128 -DA:250,207 -DA:254,34 -DA:262,191 -DA:270,108 -DA:274,992 -DA:275,976 -DA:285,116 -DA:301,7381 -DA:310,7383 -DA:322,2 +DA:57,705 +DA:75,705 +DA:78,705 +DA:81,705 +DA:84,705 +DA:92,705 +DA:93,705 +DA:95,705 +DA:102,705 +DA:104,705 +DA:128,116 +DA:129,97 +DA:138,58 +DA:147,39 +DA:157,3 +DA:167,9 +DA:177,9 +DA:188,316 +DA:189,316 +DA:190,84 +DA:192,232 +DA:206,31 +DA:207,31 +DA:208,6 +DA:210,25 +DA:226,200 +DA:229,49 +DA:239,12 +DA:245,849 +DA:251,128 +DA:255,273 +DA:259,38 +DA:267,245 +DA:275,118 +DA:279,1110 +DA:280,1095 +DA:290,235 +DA:307,8559 +DA:317,8561 +DA:330,2 LF:40 LH:40 -BRDA:56,1,0,594 +BRDA:56,1,0,705 BRDA:56,1,1,0 -BRDA:72,2,0,594 +BRDA:72,2,0,705 BRDA:72,2,1,0 -BRDA:90,3,0,594 +BRDA:90,3,0,705 BRDA:90,3,1,0 -BRDA:101,4,0,594 +BRDA:101,4,0,705 BRDA:101,4,1,0 -BRDA:122,5,0,68 -BRDA:122,5,1,3 -BRDA:184,6,0,60 -BRDA:184,6,1,180 -BRDA:202,7,0,8 -BRDA:202,7,1,23 -BRDA:214,8,0,75 -BRDA:214,8,1,6 -BRDA:215,9,0,30 -BRDA:215,9,1,3 -BRDA:217,10,0,75 -BRDA:217,10,1,9 -BRDA:219,11,0,970 -BRDA:219,11,1,8 -BRF:22 -BRH:18 +BRDA:189,5,0,84 +BRDA:189,5,1,232 +BRDA:207,6,0,6 +BRDA:207,6,1,25 +BRDA:219,7,0,84 +BRDA:219,7,1,6 +BRDA:220,8,0,33 +BRDA:220,8,1,3 +BRDA:222,9,0,96 +BRDA:222,9,1,9 +BRDA:224,10,0,1121 +BRDA:224,10,1,8 +BRF:20 +BRH:16 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/3_CMTATBaseRuleEngine.sol @@ -873,84 +947,82 @@ FN:80,__CMTAT_init FN:100,__CMTAT_openzeppelin_init_unchained FN:111,__CMTAT_internal_init_unchained FN:118,__CMTAT_modules_init_unchained -FN:128,approve -FN:135,canTransfer -FN:151,canTransferFrom -FN:169,_authorizePause -FN:170,_authorizeDeactivate -FN:172,_authorizeFreeze -FN:174,_authorizeRuleEngineManagement -FN:177,_checkTransferred +FN:131,approve +FN:140,canTransfer +FN:156,canTransferFrom +FN:174,_authorizePause +FN:175,_authorizeDeactivate +FN:177,_authorizeFreeze +FN:179,_authorizeRuleEngineManagement +FN:182,_checkTransferred FNF:14 FNH:14 -FNDA:4748,initialize -FNDA:4748,_initialize -FNDA:4748,__CMTAT_init -FNDA:4748,__CMTAT_openzeppelin_init_unchained -FNDA:4748,__CMTAT_internal_init_unchained -FNDA:4748,__CMTAT_modules_init_unchained -FNDA:700,approve -FNDA:1579,canTransfer -FNDA:251,canTransferFrom -FNDA:573,_authorizePause -FNDA:238,_authorizeDeactivate -FNDA:551,_authorizeFreeze -FNDA:361,_authorizeRuleEngineManagement -FNDA:7434,_checkTransferred -DA:47,4748 -DA:64,4748 -DA:83,4748 -DA:86,4748 -DA:89,4748 -DA:91,4748 -DA:94,4748 -DA:102,4748 -DA:103,4748 -DA:105,4748 -DA:112,4748 -DA:119,4748 -DA:129,700 -DA:130,662 -DA:140,1579 -DA:141,1579 -DA:142,570 -DA:144,1009 -DA:157,251 -DA:158,251 -DA:159,76 -DA:161,175 -DA:178,7434 -DA:179,7282 +FNDA:5167,initialize +FNDA:5167,_initialize +FNDA:5167,__CMTAT_init +FNDA:5167,__CMTAT_openzeppelin_init_unchained +FNDA:5167,__CMTAT_internal_init_unchained +FNDA:5167,__CMTAT_modules_init_unchained +FNDA:958,approve +FNDA:1600,canTransfer +FNDA:215,canTransferFrom +FNDA:636,_authorizePause +FNDA:259,_authorizeDeactivate +FNDA:688,_authorizeFreeze +FNDA:367,_authorizeRuleEngineManagement +FNDA:7858,_checkTransferred +DA:47,5167 +DA:64,5167 +DA:83,5167 +DA:86,5167 +DA:89,5167 +DA:91,5167 +DA:94,5167 +DA:102,5167 +DA:103,5167 +DA:105,5167 +DA:112,5167 +DA:119,5167 +DA:134,958 +DA:135,863 +DA:145,1600 +DA:146,1600 +DA:147,532 +DA:149,1068 +DA:162,215 +DA:163,215 +DA:164,38 +DA:166,177 +DA:183,7858 +DA:184,7763 LF:24 LH:24 -BRDA:46,1,0,4748 +BRDA:46,1,0,5167 BRDA:46,1,1,4 -BRDA:63,2,0,4748 +BRDA:63,2,0,5167 BRDA:63,2,1,0 -BRDA:80,3,0,4748 +BRDA:80,3,0,5167 BRDA:80,3,1,0 -BRDA:100,4,0,4748 +BRDA:100,4,0,5167 BRDA:100,4,1,0 -BRDA:111,5,0,4748 +BRDA:111,5,0,5167 BRDA:111,5,1,0 -BRDA:118,6,0,4748 +BRDA:118,6,0,5167 BRDA:118,6,1,0 -BRDA:128,7,0,700 -BRDA:128,7,1,19 -BRDA:141,8,0,570 -BRDA:141,8,1,1009 -BRDA:158,9,0,76 -BRDA:158,9,1,175 -BRDA:169,10,0,573 -BRDA:169,10,1,39 -BRDA:170,11,0,238 -BRDA:170,11,1,19 -BRDA:172,12,0,551 -BRDA:172,12,1,57 -BRDA:174,13,0,361 -BRDA:174,13,1,3 -BRF:26 -BRH:21 +BRDA:146,7,0,532 +BRDA:146,7,1,1068 +BRDA:163,8,0,38 +BRDA:163,8,1,177 +BRDA:174,9,0,636 +BRDA:174,9,1,39 +BRDA:175,10,0,259 +BRDA:175,10,1,19 +BRDA:177,11,0,688 +BRDA:177,11,1,57 +BRDA:179,12,0,367 +BRDA:179,12,1,3 +BRF:24 +BRH:19 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseDebt.sol @@ -965,27 +1037,27 @@ FN:58,_authorizeDebtManagement FN:60,_authorizeSnapshots FNF:9 FNH:9 -FNDA:92,approve +FNDA:136,approve FNDA:82,transfer FNDA:44,transferFrom FNDA:4,decimals FNDA:12,name FNDA:12,symbol -FNDA:1250,_update +FNDA:1326,_update FNDA:12,_authorizeDebtManagement -FNDA:96,_authorizeSnapshots -DA:19,92 +FNDA:98,_authorizeSnapshots +DA:19,136 DA:25,82 DA:31,44 DA:37,4 DA:43,12 DA:49,12 -DA:55,1250 +DA:55,1326 LF:7 LH:7 BRDA:58,1,0,12 BRDA:58,1,1,12 -BRDA:60,2,0,96 +BRDA:60,2,0,98 BRDA:60,2,1,3 BRF:4 BRH:4 @@ -995,99 +1067,97 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/4_CMTATBaseERC1404.sol FN:31,messageForTransferRestriction FN:45,canTransfer FN:56,canTransferFrom -FN:68,_detectTransferRestriction -FNF:4 -FNH:4 -FNDA:159,messageForTransferRestriction -FNDA:1255,canTransfer -FNDA:207,canTransferFrom -FNDA:377,_detectTransferRestriction -DA:34,159 -DA:35,66 -DA:37,93 -DA:50,1255 -DA:62,207 -DA:73,377 -DA:74,377 -DA:75,198 -DA:76,198 -DA:77,22 -DA:79,176 -DA:80,176 -DA:81,132 -DA:84,223 -LF:14 -LH:14 -BRDA:34,1,0,66 -BRDA:34,1,1,93 -BRDA:74,2,0,198 -BRDA:74,2,1,179 -BRDA:76,3,0,22 -BRDA:76,3,1,176 -BRDA:80,4,0,132 -BRDA:80,4,1,44 +FN:75,supportsInterface +FN:94,_detectTransferRestriction +FNF:5 +FNH:5 +FNDA:139,messageForTransferRestriction +FNDA:1272,canTransfer +FNDA:179,canTransferFrom +FNDA:49,supportsInterface +FNDA:339,_detectTransferRestriction +DA:34,139 +DA:35,44 +DA:37,95 +DA:50,1272 +DA:62,179 +DA:78,49 +DA:99,339 +DA:100,339 +DA:101,88 +DA:103,251 +LF:10 +LH:10 +BRDA:34,1,0,44 +BRDA:34,1,1,95 +BRDA:79,2,0,2 +BRDA:79,2,1,2 +BRDA:79,3,0,2 +BRDA:79,3,1,26 +BRDA:100,4,0,88 +BRDA:100,4,1,251 BRF:8 BRH:8 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/5_CMTATBaseERC20CrossChain.sol -FN:23,approve -FN:26,transfer -FN:32,transferFrom -FN:50,decimals -FN:64,name -FN:71,symbol -FN:75,supportsInterface -FN:86,_mintOverride -FN:94,_burnOverride -FN:102,_minterTransferOverride -FN:113,_authorizeCCIPSetAdmin -FN:124,_checkTokenBridge -FN:133,_authorizeBurnFrom -FN:140,_authorizeSelfBurn +FN:25,approve +FN:28,transfer +FN:34,transferFrom +FN:52,decimals +FN:66,name +FN:73,symbol +FN:77,supportsInterface +FN:89,_mintOverride +FN:98,_burnOverride +FN:107,_minterTransferOverride +FN:118,_authorizeCCIPSetAdmin +FN:129,_checkTokenBridge +FN:138,_authorizeBurnFrom +FN:145,_authorizeSelfBurn FNF:14 FNH:14 -FNDA:627,approve -FNDA:295,transfer -FNDA:199,transferFrom +FNDA:822,approve +FNDA:302,transfer +FNDA:223,transferFrom FNDA:15,decimals -FNDA:59,name -FNDA:47,symbol -FNDA:66,supportsInterface -FNDA:4518,_mintOverride -FNDA:869,_burnOverride -FNDA:207,_minterTransferOverride +FNDA:67,name +FNDA:49,symbol +FNDA:73,supportsInterface +FNDA:4842,_mintOverride +FNDA:863,_burnOverride +FNDA:222,_minterTransferOverride FNDA:36,_authorizeCCIPSetAdmin -FNDA:218,_checkTokenBridge +FNDA:206,_checkTokenBridge FNDA:60,_authorizeBurnFrom FNDA:48,_authorizeSelfBurn -DA:24,627 -DA:27,295 -DA:42,199 -DA:57,15 -DA:65,59 -DA:72,47 -DA:76,66 -DA:88,4518 -DA:96,869 -DA:104,207 -DA:125,218 +DA:26,822 +DA:29,302 +DA:44,223 +DA:59,15 +DA:67,67 +DA:74,49 +DA:78,73 +DA:91,4842 +DA:100,863 +DA:109,222 +DA:130,206 LF:11 LH:11 -BRDA:76,1,0,24 -BRDA:76,1,1,24 -BRDA:113,2,0,36 -BRDA:113,2,1,12 -BRDA:124,3,0,218 -BRDA:124,3,1,48 -BRDA:133,4,0,84 -BRDA:133,4,1,12 -BRDA:133,5,0,60 -BRDA:133,5,1,24 -BRDA:140,6,0,72 -BRDA:140,6,1,24 -BRDA:140,7,0,48 -BRDA:140,7,1,24 +BRDA:78,1,0,24 +BRDA:78,1,1,30 +BRDA:118,2,0,36 +BRDA:118,2,1,12 +BRDA:129,3,0,206 +BRDA:129,3,1,48 +BRDA:138,4,0,84 +BRDA:138,4,1,12 +BRDA:138,5,0,60 +BRDA:138,5,1,24 +BRDA:145,6,0,72 +BRDA:145,6,1,12 +BRDA:145,7,0,48 +BRDA:145,7,1,24 BRF:14 BRH:14 end_of_record @@ -1104,19 +1174,19 @@ FN:68,_authorizeDebtEngineManagement FN:70,_authorizeSnapshots FNF:9 FNH:9 -FNDA:923,_update -FNDA:60,transfer +FNDA:978,_update +FNDA:58,transfer FNDA:33,transferFrom -FNDA:69,approve +FNDA:102,approve FNDA:3,decimals FNDA:9,name FNDA:9,symbol FNDA:15,_authorizeDebtEngineManagement -FNDA:49,_authorizeSnapshots -DA:25,923 -DA:31,60 +FNDA:50,_authorizeSnapshots +DA:25,978 +DA:31,58 DA:37,33 -DA:43,69 +DA:43,102 DA:49,3 DA:55,9 DA:61,9 @@ -1124,7 +1194,7 @@ LF:7 LH:7 BRDA:68,1,0,15 BRDA:68,1,1,3 -BRDA:70,2,0,49 +BRDA:70,2,0,50 BRDA:70,2,1,2 BRF:4 BRH:4 @@ -1132,55 +1202,55 @@ end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2612.sol FN:26,__CMTAT_openzeppelin_init_unchained -FN:40,permit -FN:57,approve -FN:67,transfer -FN:77,transferFrom -FN:94,decimals -FN:107,name -FN:120,symbol +FN:47,permit +FN:67,approve +FN:77,transfer +FN:87,transferFrom +FN:104,decimals +FN:117,name +FN:130,symbol FNF:8 FNH:8 -FNDA:460,__CMTAT_openzeppelin_init_unchained -FNDA:10,permit -FNDA:92,approve -FNDA:31,transfer +FNDA:500,__CMTAT_openzeppelin_init_unchained +FNDA:22,permit +FNDA:114,approve +FNDA:30,transfer FNDA:26,transferFrom FNDA:2,decimals -FNDA:18,name -FNDA:8,symbol -DA:27,460 -DA:28,460 -DA:29,460 -DA:30,460 -DA:49,10 -DA:50,4 -DA:61,92 -DA:71,31 -DA:87,26 -DA:101,2 -DA:114,18 -DA:127,8 +FNDA:26,name +FNDA:10,symbol +DA:27,500 +DA:28,500 +DA:29,500 +DA:30,500 +DA:56,22 +DA:57,16 +DA:71,114 +DA:81,30 +DA:97,26 +DA:111,2 +DA:124,26 +DA:137,10 LF:12 LH:12 -BRDA:26,1,0,460 +BRDA:26,1,0,500 BRDA:26,1,1,0 BRF:2 BRH:1 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/6_CMTATBaseERC2771.sol -FN:20,_msgSender -FN:32,_contextSuffixLength -FN:41,_msgData +FN:21,_msgSender +FN:34,_contextSuffixLength +FN:44,_msgData FNF:3 FNH:3 -FNDA:18475,_msgSender -FNDA:18481,_contextSuffixLength +FNDA:20226,_msgSender +FNDA:20232,_contextSuffixLength FNDA:6,_msgData -DA:26,18475 -DA:35,18481 -DA:47,6 +DA:27,20226 +DA:37,20232 +DA:50,6 LF:3 LH:3 BRF:0 @@ -1201,30 +1271,30 @@ FN:79,_contextSuffixLength FN:89,_authorizeSnapshots FNF:11 FNH:11 -FNDA:778,_update +FNDA:814,_update FNDA:58,transfer FNDA:26,transferFrom -FNDA:92,approve +FNDA:114,approve FNDA:2,decimals FNDA:6,name FNDA:6,symbol -FNDA:3814,_msgSender +FNDA:4035,_msgSender FNDA:2,_msgData -FNDA:3816,_contextSuffixLength -FNDA:189,_authorizeSnapshots -DA:24,778 +FNDA:4037,_contextSuffixLength +FNDA:192,_authorizeSnapshots +DA:24,814 DA:30,58 DA:36,26 -DA:42,92 +DA:42,114 DA:48,2 DA:54,6 DA:60,6 -DA:70,3814 +DA:70,4035 DA:76,2 -DA:82,3816 +DA:82,4037 LF:10 LH:10 -BRDA:89,1,0,189 +BRDA:89,1,0,192 BRDA:89,1,1,4 BRF:2 BRH:2 @@ -1245,30 +1315,30 @@ FN:99,decimals FN:107,getFrozenTokens FNF:12 FNH:12 -FNDA:390,_authorizeERC20Enforcer -FNDA:78,_authorizeForcedTransfer -FNDA:11591,_msgSender +FNDA:424,_authorizeERC20Enforcer +FNDA:98,_authorizeForcedTransfer +FNDA:12904,_msgSender FNDA:4,_msgData -FNDA:11595,_contextSuffixLength -FNDA:114,transfer -FNDA:90,transferFrom -FNDA:282,approve +FNDA:12908,_contextSuffixLength +FNDA:125,transfer +FNDA:114,transferFrom +FNDA:378,approve FNDA:20,name FNDA:18,symbol FNDA:6,decimals -FNDA:336,getFrozenTokens -DA:22,390 -DA:26,78 -DA:37,11591 +FNDA:358,getFrozenTokens +DA:22,424 +DA:26,98 +DA:37,12904 DA:45,4 -DA:53,11595 -DA:64,114 -DA:72,90 -DA:80,282 +DA:53,12908 +DA:64,125 +DA:72,114 +DA:80,378 DA:88,20 DA:96,18 DA:104,6 -DA:112,336 +DA:112,358 LF:12 LH:12 BRF:0 @@ -1277,47 +1347,47 @@ end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC1363.sol FN:25,__CMTAT_openzeppelin_init_unchained -FN:38,approve -FN:45,transfer -FN:52,transferFrom -FN:69,supportsInterface -FN:77,decimals -FN:91,name -FN:98,symbol -FN:113,_msgSender -FN:125,_contextSuffixLength -FN:134,_msgData +FN:41,approve +FN:48,transfer +FN:55,transferFrom +FN:74,supportsInterface +FN:82,decimals +FN:96,name +FN:103,symbol +FN:118,_msgSender +FN:130,_contextSuffixLength +FN:139,_msgData FNF:11 FNH:11 -FNDA:499,__CMTAT_openzeppelin_init_unchained -FNDA:93,approve -FNDA:39,transfer +FNDA:533,__CMTAT_openzeppelin_init_unchained +FNDA:115,approve +FNDA:37,transfer FNDA:28,transferFrom -FNDA:18,supportsInterface +FNDA:23,supportsInterface FNDA:2,decimals FNDA:6,name FNDA:6,symbol -FNDA:3508,_msgSender -FNDA:3510,_contextSuffixLength +FNDA:3728,_msgSender +FNDA:3730,_contextSuffixLength FNDA:2,_msgData -DA:26,499 -DA:27,499 -DA:39,93 -DA:46,39 -DA:62,28 -DA:70,18 -DA:84,2 -DA:92,6 -DA:99,6 -DA:119,3508 -DA:128,3510 -DA:140,2 +DA:26,533 +DA:27,533 +DA:42,115 +DA:49,37 +DA:65,28 +DA:75,23 +DA:89,2 +DA:97,6 +DA:104,6 +DA:124,3728 +DA:133,3730 +DA:145,2 LF:12 LH:12 -BRDA:25,1,0,499 +BRDA:25,1,0,533 BRDA:25,1,1,0 -BRDA:70,2,0,6 -BRDA:70,2,1,8 +BRDA:75,2,0,6 +BRDA:75,2,1,12 BRF:4 BRH:3 end_of_record @@ -1326,52 +1396,96 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseERC7551.sol FN:19,_authorizeExtraInfoManagement FNF:1 FNH:1 -FNDA:20,_authorizeExtraInfoManagement -DA:20,20 +FNDA:22,_authorizeExtraInfoManagement +DA:20,22 LF:1 LH:1 BRF:0 BRH:0 end_of_record TN: +SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/8_CMTATBaseHolderList.sol +FN:33,transfer +FN:44,transferFrom +FN:55,approve +FN:67,name +FN:78,symbol +FN:89,decimals +FN:97,supportsInterface +FN:112,_update +FN:125,_msgSender +FN:136,_msgData +FN:147,_contextSuffixLength +FNF:11 +FNH:4 +FNDA:8,transfer +FNDA:0,transferFrom +FNDA:0,approve +FNDA:0,name +FNDA:0,symbol +FNDA:0,decimals +FNDA:0,supportsInterface +FNDA:114,_update +FNDA:372,_msgSender +FNDA:0,_msgData +FNDA:372,_contextSuffixLength +DA:38,8 +DA:49,0 +DA:60,0 +DA:72,0 +DA:83,0 +DA:94,0 +DA:102,0 +DA:116,114 +DA:130,372 +DA:141,0 +DA:152,372 +LF:11 +LH:4 +BRDA:102,1,0,0 +BRDA:102,1,1,0 +BRF:2 +BRH:0 +end_of_record +TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/AllowlistModuleInternal.sol FN:29,__Allowlist_init_unchained FN:39,_addToAllowlist FN:44,_addToAllowlist FN:48,_addToAllowlist FN:59,_enableAllowlist -FN:68,_isAllowlisted -FN:76,_isAllowlistEnabled -FN:84,_getAllowlistModuleInternalStorage +FN:69,_isAllowlisted +FN:78,_isAllowlistEnabled +FN:86,_getAllowlistModuleInternalStorage FNF:8 FNH:8 -FNDA:594,__Allowlist_init_unchained -FNDA:296,_addToAllowlist -FNDA:2396,_addToAllowlist -FNDA:532,_addToAllowlist -FNDA:142,_enableAllowlist -FNDA:1438,_isAllowlisted -FNDA:1424,_isAllowlistEnabled -FNDA:4422,_getAllowlistModuleInternalStorage -DA:30,594 -DA:31,594 -DA:40,296 -DA:41,296 -DA:45,2396 -DA:49,532 -DA:50,528 -DA:51,528 -DA:52,2100 -DA:60,142 -DA:61,142 -DA:69,1438 -DA:70,1438 -DA:77,1424 -DA:78,1424 -DA:85,4422 +FNDA:705,__Allowlist_init_unchained +FNDA:326,_addToAllowlist +FNDA:2626,_addToAllowlist +FNDA:584,_addToAllowlist +FNDA:211,_enableAllowlist +FNDA:1580,_isAllowlisted +FNDA:1667,_isAllowlistEnabled +FNDA:5069,_getAllowlistModuleInternalStorage +DA:30,705 +DA:31,705 +DA:40,326 +DA:41,326 +DA:45,2626 +DA:49,584 +DA:50,580 +DA:51,580 +DA:52,2300 +DA:60,211 +DA:61,211 +DA:70,1580 +DA:71,1580 +DA:79,1667 +DA:80,1667 +DA:87,5069 LF:16 LH:16 -BRDA:29,1,0,594 +BRDA:29,1,0,705 BRDA:29,1,1,0 BRF:2 BRH:1 @@ -1381,14 +1495,14 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/common/EnforcementMo FN:15,_checkInput FNF:1 FNH:1 -FNDA:657,_checkInput -DA:16,657 -DA:19,630 +FNDA:734,_checkInput +DA:16,734 +DA:19,707 LF:2 LH:2 -BRDA:16,1,0,630 +BRDA:16,1,0,707 BRDA:16,1,1,27 -BRDA:19,2,0,603 +BRDA:19,2,0,680 BRDA:19,2,1,27 BRF:4 BRH:4 @@ -1398,235 +1512,241 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/EnforcementModuleInt FN:33,_addAddressToTheList FN:38,_addAddressToTheList FN:45,_addAddressesToTheList -FN:57,_addressIsListed -FN:63,_getEnforcementModuleInternalStorage +FN:58,_addressIsListed +FN:64,_getEnforcementModuleInternalStorage FNF:5 FNH:5 -FNDA:571,_addAddressToTheList -FNDA:721,_addAddressToTheList -FNDA:125,_addAddressesToTheList -FNDA:16612,_addressIsListed -FNDA:17258,_getEnforcementModuleInternalStorage -DA:34,571 -DA:35,571 -DA:39,721 +FNDA:719,_addAddressToTheList +FNDA:919,_addAddressToTheList +FNDA:150,_addAddressesToTheList +FNDA:18213,_addressIsListed +FNDA:19032,_getEnforcementModuleInternalStorage +DA:34,719 +DA:35,719 +DA:39,919 DA:40,75 -DA:42,646 -DA:46,125 -DA:47,75 -DA:48,75 -DA:49,150 -DA:58,16612 -DA:59,16612 -DA:64,17258 +DA:42,844 +DA:46,150 +DA:47,100 +DA:48,100 +DA:49,200 +DA:59,18213 +DA:60,18213 +DA:65,19032 LF:12 LH:12 BRDA:39,1,0,75 -BRDA:39,1,1,646 +BRDA:39,1,1,844 BRF:2 BRH:2 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20BurnModuleInternal.sol -FN:26,_batchBurn -FN:43,_burnOverride +FN:28,_batchBurn +FN:47,_burnOverride FNF:2 FNH:2 FNDA:330,_batchBurn -FNDA:1017,_burnOverride -DA:30,330 -DA:33,306 -DA:34,258 -DA:35,638 -DA:47,1017 +FNDA:1023,_burnOverride +DA:32,330 +DA:35,306 +DA:36,258 +DA:37,638 +DA:51,1023 LF:5 LH:5 -BRDA:30,1,0,306 -BRDA:30,1,1,24 -BRDA:33,2,0,258 -BRDA:33,2,1,48 +BRDA:32,1,0,306 +BRDA:32,1,1,24 +BRDA:35,2,0,258 +BRDA:35,2,1,48 BRF:4 BRH:4 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20EnforcementModuleInternal.sol -FN:33,_setFrozenTokens -FN:52,_freezePartialTokens -FN:67,_unfreezePartialTokens -FN:82,_unfreezeTokens -FN:103,_forcedTransfer -FN:128,_freezeTokensEmitEvents -FN:132,_unfreezeTokensEmitEvents -FN:137,_checkActiveBalanceAndRevert -FN:147,_checkActiveBalance -FN:168,_getFrozenTokens -FN:173,_getActiveBalanceOf -FN:185,_getEnforcementModuleStorage +FN:36,_setFrozenTokens +FN:62,_freezePartialTokens +FN:77,_unfreezePartialTokens +FN:92,_unfreezeTokens +FN:120,_forcedTransfer +FN:145,_freezeTokensEmitEvents +FN:149,_unfreezeTokensEmitEvents +FN:154,_checkActiveBalanceAndRevert +FN:166,_checkActiveBalance +FN:187,_getFrozenTokens +FN:192,_getActiveBalanceOf +FN:204,_getEnforcementModuleStorage FNF:12 FNH:12 -FNDA:378,_setFrozenTokens -FNDA:622,_freezePartialTokens -FNDA:226,_unfreezePartialTokens -FNDA:220,_unfreezeTokens -FNDA:220,_forcedTransfer -FNDA:845,_freezeTokensEmitEvents -FNDA:323,_unfreezeTokensEmitEvents -FNDA:8426,_checkActiveBalanceAndRevert -FNDA:10527,_checkActiveBalance -FNDA:12921,_getFrozenTokens -FNDA:432,_getActiveBalanceOf -FNDA:14720,_getEnforcementModuleStorage -DA:34,378 -DA:35,378 -DA:37,378 -DA:38,84 -DA:39,84 -DA:40,84 -DA:43,273 -DA:44,273 -DA:45,273 -DA:47,21 -DA:49,357 -DA:53,622 -DA:54,29 -DA:56,593 -DA:58,593 -DA:59,593 -DA:61,593 -DA:63,572 -DA:64,572 -DA:68,226 -DA:69,29 -DA:71,197 -DA:72,197 -DA:74,176 -DA:75,176 -DA:76,176 -DA:83,220 -DA:84,220 -DA:85,21 -DA:87,199 -DA:88,199 -DA:90,199 -DA:92,199 -DA:93,178 -DA:95,199 -DA:96,63 -DA:97,63 -DA:98,63 -DA:99,63 -DA:104,220 -DA:105,199 -DA:106,42 -DA:110,157 -DA:111,157 -DA:112,42 -DA:113,21 -DA:114,21 -DA:117,21 -DA:118,21 -DA:123,157 -DA:125,199 -DA:129,845 -DA:133,323 -DA:138,8426 -DA:139,8426 -DA:140,8426 -DA:141,8426 -DA:148,10527 -DA:149,10527 -DA:150,1533 -DA:152,1533 -DA:153,105 -DA:154,42 -DA:156,63 -DA:158,1428 -DA:159,1428 -DA:160,819 -DA:165,9603 -DA:169,12921 -DA:170,12921 -DA:174,432 -DA:175,432 -DA:176,432 -DA:178,432 -DA:179,32 -DA:181,400 -DA:186,14720 -LF:77 -LH:77 -BRDA:37,1,0,84 -BRDA:37,1,1,294 -BRDA:41,2,0,273 -BRDA:41,2,1,21 -BRDA:53,3,0,29 -BRDA:53,3,1,593 -BRDA:61,4,0,572 -BRDA:61,4,1,21 -BRDA:68,5,0,29 -BRDA:68,5,1,197 -BRDA:72,6,0,176 -BRDA:72,6,1,21 -BRDA:84,7,0,21 -BRDA:84,7,1,199 -BRDA:92,8,0,178 -BRDA:92,8,1,21 -BRDA:95,9,0,63 -BRDA:95,9,1,136 -BRDA:105,10,0,42 -BRDA:105,10,1,157 -BRDA:111,11,0,42 -BRDA:111,11,1,115 -BRDA:112,12,0,21 -BRDA:112,12,1,21 -BRDA:141,13,0,8258 -BRDA:141,13,1,168 -BRDA:149,14,0,1533 -BRDA:149,14,1,8994 -BRDA:152,15,0,105 -BRDA:152,15,1,1428 -BRDA:153,16,0,42 -BRDA:153,16,1,63 -BRDA:159,17,0,819 -BRDA:159,17,1,609 -BRDA:178,18,0,32 -BRDA:178,18,1,400 -BRF:36 -BRH:36 +FNDA:476,_setFrozenTokens +FNDA:652,_freezePartialTokens +FNDA:236,_unfreezePartialTokens +FNDA:276,_unfreezeTokens +FNDA:298,_forcedTransfer +FNDA:878,_freezeTokensEmitEvents +FNDA:338,_unfreezeTokensEmitEvents +FNDA:8968,_checkActiveBalanceAndRevert +FNDA:11469,_checkActiveBalance +FNDA:13719,_getFrozenTokens +FNDA:440,_getActiveBalanceOf +FNDA:15629,_getEnforcementModuleStorage +DA:41,476 +DA:42,88 +DA:44,388 +DA:45,388 +DA:47,388 +DA:48,88 +DA:49,88 +DA:50,88 +DA:53,278 +DA:54,278 +DA:55,278 +DA:57,22 +DA:59,366 +DA:63,652 +DA:64,30 +DA:66,622 +DA:68,622 +DA:69,622 +DA:71,622 +DA:73,600 +DA:74,600 +DA:78,236 +DA:79,30 +DA:81,206 +DA:82,206 +DA:84,184 +DA:85,184 +DA:86,184 +DA:93,276 +DA:94,276 +DA:95,22 +DA:97,254 +DA:98,254 +DA:100,254 +DA:102,254 +DA:103,232 +DA:105,254 +DA:106,66 +DA:107,66 +DA:108,66 +DA:109,66 +DA:122,298 +DA:123,276 +DA:124,254 +DA:125,44 +DA:129,210 +DA:130,210 +DA:132,44 +DA:133,44 +DA:134,44 +DA:138,44 +DA:140,210 +DA:142,254 +DA:146,878 +DA:150,338 +DA:155,8968 +DA:156,8968 +DA:157,8968 +DA:158,8968 +DA:167,11469 +DA:168,11469 +DA:169,1628 +DA:171,1628 +DA:172,132 +DA:173,66 +DA:175,66 +DA:177,1496 +DA:178,1496 +DA:179,792 +DA:184,10545 +DA:188,13719 +DA:189,13719 +DA:193,440 +DA:194,440 +DA:195,440 +DA:197,440 +DA:198,32 +DA:200,408 +DA:205,15629 +LF:79 +LH:79 +BRDA:41,1,0,88 +BRDA:41,1,1,388 +BRDA:47,2,0,88 +BRDA:47,2,1,300 +BRDA:51,3,0,278 +BRDA:51,3,1,22 +BRDA:63,4,0,30 +BRDA:63,4,1,622 +BRDA:71,5,0,600 +BRDA:71,5,1,22 +BRDA:78,6,0,30 +BRDA:78,6,1,206 +BRDA:82,7,0,184 +BRDA:82,7,1,22 +BRDA:94,8,0,22 +BRDA:94,8,1,254 +BRDA:102,9,0,232 +BRDA:102,9,1,22 +BRDA:105,10,0,66 +BRDA:105,10,1,188 +BRDA:122,11,0,276 +BRDA:122,11,1,22 +BRDA:124,12,0,44 +BRDA:124,12,1,210 +BRDA:130,13,0,44 +BRDA:130,13,1,166 +BRDA:132,14,0,22 +BRDA:132,14,1,22 +BRDA:158,15,0,8858 +BRDA:158,15,1,110 +BRDA:168,16,0,1628 +BRDA:168,16,1,9841 +BRDA:171,17,0,132 +BRDA:171,17,1,1496 +BRDA:172,18,0,66 +BRDA:172,18,1,66 +BRDA:178,19,0,792 +BRDA:178,19,1,704 +BRDA:197,20,0,32 +BRDA:197,20,1,408 +BRF:40 +BRH:40 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/internal/ERC20MintModuleInternal.sol FN:30,_batchMint FN:43,_batchTransfer -FN:63,_mintOverride -FN:67,_minterTransferOverride +FN:65,_mintOverride +FN:69,_minterTransferOverride FNF:4 FNH:4 -FNDA:730,_batchMint -FNDA:238,_batchTransfer -FNDA:6409,_mintOverride +FNDA:780,_batchMint +FNDA:262,_batchTransfer +FNDA:6931,_mintOverride FNDA:211,_minterTransferOverride -DA:34,730 -DA:37,706 -DA:38,658 -DA:39,1836 -DA:47,238 -DA:48,214 -DA:51,214 -DA:52,166 -DA:53,310 +DA:34,780 +DA:37,756 +DA:38,708 +DA:39,1936 +DA:47,262 +DA:48,238 +DA:51,238 +DA:52,190 +DA:53,334 DA:57,43 -DA:64,6409 -DA:70,211 +DA:66,6931 +DA:72,211 LF:12 LH:12 -BRDA:34,1,0,706 +BRDA:34,1,0,756 BRDA:34,1,1,24 -BRDA:37,2,0,658 +BRDA:37,2,0,708 BRDA:37,2,1,48 -BRDA:47,3,0,214 +BRDA:47,3,0,238 BRDA:47,3,1,24 -BRDA:51,4,0,166 +BRDA:51,4,0,190 BRDA:51,4,1,48 BRF:8 BRH:8 @@ -1639,24 +1759,24 @@ FN:65,_setRuleEngine FN:74,_getValidationModuleRuleEngineStorage FNF:4 FNH:4 -FNDA:4748,__ValidationRuleEngine_init_unchained -FNDA:8704,ruleEngine -FNDA:441,_setRuleEngine -FNDA:9145,_getValidationModuleRuleEngineStorage -DA:38,4748 +FNDA:5167,__ValidationRuleEngine_init_unchained +FNDA:9132,ruleEngine +FNDA:447,_setRuleEngine +FNDA:9579,_getValidationModuleRuleEngineStorage +DA:38,5167 DA:39,83 -DA:53,8704 -DA:54,8704 -DA:68,441 -DA:69,441 -DA:70,441 -DA:75,9145 +DA:53,9132 +DA:54,9132 +DA:68,447 +DA:69,447 +DA:70,447 +DA:75,9579 LF:8 LH:8 -BRDA:37,1,0,4748 +BRDA:37,1,0,5167 BRDA:37,1,1,0 BRDA:38,2,0,83 -BRDA:38,2,1,4665 +BRDA:38,2,1,5084 BRF:4 BRH:3 end_of_record @@ -1664,184 +1784,184 @@ TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModule.sol FN:26,canSend FN:31,canReceive -FN:42,_canTransferGenericByModule -FN:59,_canTransferGenericByModuleAndRevert -FN:81,_canMintBurnByModule -FN:97,_canMintByModuleAndRevert -FN:110,_canBurnByModuleAndRevert -FN:124,_canTransferisFrozen -FN:138,_canTransferisFrozenAndRevert -FN:152,_canTransferStandardByModule -FN:165,_canTransferStandardByModuleAndRevert -FN:185,_canSend -FN:194,_canReceive +FN:46,_canTransferGenericByModule +FN:63,_canTransferGenericByModuleAndRevert +FN:86,_canMintBurnByModule +FN:103,_canMintByModuleAndRevert +FN:117,_canBurnByModuleAndRevert +FN:135,_canTransferisFrozen +FN:149,_canTransferisFrozenAndRevert +FN:163,_canTransferStandardByModule +FN:176,_canTransferStandardByModuleAndRevert +FN:198,_canSend +FN:209,_canReceive FNF:13 FNH:13 -FNDA:352,canSend -FNDA:46,canReceive -FNDA:1437,_canTransferGenericByModule -FNDA:8325,_canTransferGenericByModuleAndRevert +FNDA:456,canSend +FNDA:50,canReceive +FNDA:1558,_canTransferGenericByModule +FNDA:8929,_canTransferGenericByModuleAndRevert FNDA:42,_canMintBurnByModule -FNDA:6606,_canMintByModuleAndRevert -FNDA:1247,_canBurnByModuleAndRevert -FNDA:1353,_canTransferisFrozen -FNDA:744,_canTransferisFrozenAndRevert -FNDA:1353,_canTransferStandardByModule -FNDA:911,_canTransferStandardByModuleAndRevert -FNDA:1906,_canSend +FNDA:7131,_canMintByModuleAndRevert +FNDA:1241,_canBurnByModuleAndRevert +FNDA:1464,_canTransferisFrozen +FNDA:842,_canTransferisFrozenAndRevert +FNDA:1464,_canTransferStandardByModule +FNDA:1013,_canTransferStandardByModuleAndRevert +FNDA:2342,_canSend FNDA:28,_canReceive -DA:27,352 -DA:32,46 -DA:48,1437 -DA:49,34 -DA:52,14 -DA:55,1389 -DA:65,8325 -DA:66,6229 -DA:69,1175 -DA:72,921 -DA:84,42 -DA:88,12 -DA:90,30 -DA:100,6606 -DA:101,6557 -DA:102,60 -DA:113,1247 -DA:114,1175 -DA:115,84 -DA:129,1353 -DA:132,240 -DA:134,1113 -DA:143,744 -DA:144,24 -DA:146,24 -DA:148,50 -DA:157,1353 -DA:159,384 -DA:161,969 -DA:175,911 -DA:176,744 -DA:186,1906 -DA:195,28 +DA:27,456 +DA:32,50 +DA:52,1558 +DA:53,34 +DA:56,14 +DA:59,1510 +DA:69,8929 +DA:70,6737 +DA:73,1169 +DA:76,1023 +DA:89,42 +DA:93,12 +DA:95,30 +DA:106,7131 +DA:107,7082 +DA:108,60 +DA:120,1241 +DA:121,1169 +DA:122,84 +DA:140,1464 +DA:143,312 +DA:145,1152 +DA:154,842 +DA:155,48 +DA:157,24 +DA:159,50 +DA:168,1464 +DA:170,460 +DA:172,1004 +DA:186,1013 +DA:187,842 +DA:199,2342 +DA:210,28 LF:33 LH:33 -BRDA:48,1,0,34 -BRDA:48,1,1,1403 -BRDA:51,2,0,14 -BRDA:51,2,1,1389 -BRDA:65,3,0,6229 -BRDA:65,3,1,2096 -BRDA:68,4,0,1175 -BRDA:68,4,1,921 -BRDA:84,5,0,12 -BRDA:84,5,1,30 -BRDA:84,6,0,0 -BRDA:84,6,1,12 -BRDA:101,7,0,60 -BRDA:101,7,1,6497 -BRDA:114,8,0,84 -BRDA:114,8,1,1091 -BRDA:129,9,0,240 -BRDA:129,9,1,1113 -BRDA:129,10,0,24 -BRDA:129,10,1,168 -BRDA:129,11,0,168 -BRDA:129,11,1,48 -BRDA:143,12,0,24 -BRDA:143,12,1,720 -BRDA:145,13,0,24 -BRDA:145,13,1,696 -BRDA:147,14,0,50 -BRDA:147,14,1,646 -BRDA:157,15,0,384 -BRDA:157,15,1,969 -BRDA:157,16,0,240 -BRDA:157,16,1,144 +BRDA:52,1,0,34 +BRDA:52,1,1,1524 +BRDA:55,2,0,14 +BRDA:55,2,1,1510 +BRDA:69,3,0,6737 +BRDA:69,3,1,2192 +BRDA:72,4,0,1169 +BRDA:72,4,1,1023 +BRDA:89,5,0,12 +BRDA:89,5,1,30 +BRDA:89,6,0,0 +BRDA:89,6,1,12 +BRDA:107,7,0,60 +BRDA:107,7,1,7022 +BRDA:121,8,0,84 +BRDA:121,8,1,1085 +BRDA:140,9,0,312 +BRDA:140,9,1,1152 +BRDA:140,10,0,24 +BRDA:140,10,1,240 +BRDA:140,11,0,240 +BRDA:140,11,1,48 +BRDA:154,12,0,48 +BRDA:154,12,1,794 +BRDA:156,13,0,24 +BRDA:156,13,1,770 +BRDA:158,14,0,50 +BRDA:158,14,1,720 +BRDA:168,15,0,460 +BRDA:168,15,1,1004 +BRDA:168,16,0,312 +BRDA:168,16,1,148 BRF:32 BRH:31 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/controllers/ValidationModuleAllowlist.sol -FN:24,_canMintBurnByModule -FN:37,_canTransferStandardByModuleAllowlist -FN:54,_canTransferStandardByModule -FN:66,_canSend -FN:75,_canReceive -FN:85,_canMintByModuleAndRevert -FN:96,_canBurnByModuleAndRevert -FN:106,_canTransferStandardByModuleAndRevert -FN:115,_canTransferStandardByModuleAllowlistAndRevert +FN:26,_canMintBurnByModule +FN:43,_canTransferStandardByModuleAllowlist +FN:64,_canTransferStandardByModule +FN:76,_canSend +FN:85,_canReceive +FN:95,_canMintByModuleAndRevert +FN:106,_canBurnByModuleAndRevert +FN:116,_canTransferStandardByModuleAndRevert +FN:125,_canTransferStandardByModuleAllowlistAndRevert FNF:9 FNH:9 FNDA:12,_canMintBurnByModule -FNDA:191,_canTransferStandardByModuleAllowlist -FNDA:191,_canTransferStandardByModule -FNDA:207,_canSend -FNDA:34,_canReceive -FNDA:740,_canMintByModuleAndRevert +FNDA:245,_canTransferStandardByModuleAllowlist +FNDA:245,_canTransferStandardByModule +FNDA:273,_canSend +FNDA:38,_canReceive +FNDA:849,_canMintByModuleAndRevert FNDA:128,_canBurnByModuleAndRevert -FNDA:108,_canTransferStandardByModuleAndRevert -FNDA:108,_canTransferStandardByModuleAllowlistAndRevert -DA:27,12 -DA:28,6 +FNDA:118,_canTransferStandardByModuleAndRevert +FNDA:118,_canTransferStandardByModuleAllowlistAndRevert +DA:29,12 DA:30,6 -DA:42,191 -DA:43,166 -DA:44,166 -DA:45,36 -DA:48,155 -DA:59,191 -DA:60,36 -DA:62,155 -DA:67,207 -DA:68,26 -DA:70,181 -DA:76,34 -DA:77,18 -DA:79,16 -DA:88,740 -DA:89,4 -DA:91,736 -DA:99,128 -DA:100,4 -DA:102,124 -DA:111,108 -DA:112,98 -DA:120,108 -DA:121,79 -DA:122,2 -DA:124,2 -DA:126,6 +DA:32,6 +DA:48,245 +DA:49,184 +DA:50,184 +DA:51,46 +DA:54,199 +DA:69,245 +DA:70,46 +DA:72,199 +DA:77,273 +DA:78,30 +DA:80,243 +DA:86,38 +DA:87,22 +DA:89,16 +DA:98,849 +DA:99,4 +DA:101,845 +DA:109,128 +DA:110,4 +DA:112,124 +DA:121,118 +DA:122,108 +DA:130,118 +DA:131,85 +DA:132,2 +DA:134,2 +DA:136,6 LF:30 LH:30 -BRDA:27,1,0,6 -BRDA:27,1,1,6 -BRDA:42,2,0,166 -BRDA:42,2,1,25 -BRDA:44,3,0,36 -BRDA:44,3,1,130 -BRDA:44,4,0,2 -BRDA:44,4,1,18 -BRDA:44,5,0,18 -BRDA:44,5,1,16 -BRDA:59,6,0,36 -BRDA:59,6,1,155 -BRDA:67,7,0,26 -BRDA:67,7,1,181 -BRDA:76,8,0,18 -BRDA:76,8,1,16 -BRDA:88,9,0,4 -BRDA:88,9,1,736 -BRDA:99,10,0,4 -BRDA:99,10,1,124 -BRDA:120,11,0,79 -BRDA:120,11,1,29 -BRDA:121,12,0,2 -BRDA:121,12,1,77 -BRDA:123,13,0,2 -BRDA:123,13,1,75 -BRDA:125,14,0,6 -BRDA:125,14,1,69 +BRDA:29,1,0,6 +BRDA:29,1,1,6 +BRDA:48,2,0,184 +BRDA:48,2,1,61 +BRDA:50,3,0,46 +BRDA:50,3,1,138 +BRDA:50,4,0,2 +BRDA:50,4,1,24 +BRDA:50,5,0,24 +BRDA:50,5,1,20 +BRDA:69,6,0,46 +BRDA:69,6,1,199 +BRDA:77,7,0,30 +BRDA:77,7,1,243 +BRDA:86,8,0,22 +BRDA:86,8,1,16 +BRDA:98,9,0,4 +BRDA:98,9,1,845 +BRDA:109,10,0,4 +BRDA:109,10,1,124 +BRDA:130,11,0,85 +BRDA:130,11,1,33 +BRDA:131,12,0,2 +BRDA:131,12,1,83 +BRDA:133,13,0,2 +BRDA:133,13,1,81 +BRDA:135,14,0,6 +BRDA:135,14,1,75 BRF:28 BRH:28 end_of_record @@ -1855,94 +1975,66 @@ FN:78,isFrozen FN:86,_addAddressToTheList FNF:6 FNH:6 -FNDA:771,onlyEnforcer -FNDA:271,setAddressFrozen -FNDA:300,setAddressFrozen -FNDA:125,batchSetAddressFrozen -FNDA:16612,isFrozen -FNDA:721,_addAddressToTheList -DA:27,771 -DA:28,696 -DA:42,271 -DA:60,300 -DA:71,125 -DA:79,16612 -DA:87,721 -DA:88,646 +FNDA:944,onlyEnforcer +FNDA:347,setAddressFrozen +FNDA:372,setAddressFrozen +FNDA:150,batchSetAddressFrozen +FNDA:18213,isFrozen +FNDA:919,_addAddressToTheList +DA:27,944 +DA:28,869 +DA:42,347 +DA:60,372 +DA:71,150 +DA:79,18213 +DA:87,919 +DA:88,844 LF:8 LH:8 -BRDA:41,1,0,271 +BRDA:41,1,0,347 BRDA:41,1,1,0 -BRDA:59,2,0,300 +BRDA:59,2,0,372 BRDA:59,2,1,50 -BRDA:70,3,0,125 +BRDA:70,3,0,150 BRDA:70,3,1,25 BRF:6 BRH:5 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BaseModule.sol -FN:38,onlyERC20AttributeManager -FN:54,__ERC20BaseModule_init_unchained -FN:73,transferFrom -FN:95,decimals -FN:103,name -FN:112,symbol -FN:124,setName -FN:133,setSymbol -FN:142,batchBalanceOf -FN:157,_getERC20BaseModuleStorage -FNF:10 -FNH:10 -FNDA:98,onlyERC20AttributeManager -FNDA:5624,__ERC20BaseModule_init_unchained -FNDA:128,transferFrom +FN:37,__ERC20BaseModule_init_unchained +FN:54,transferFrom +FN:76,decimals +FN:84,batchBalanceOf +FN:96,_getERC20BaseModuleStorage +FNF:5 +FNH:5 +FNDA:6188,__ERC20BaseModule_init_unchained +FNDA:188,transferFrom FNDA:24,decimals -FNDA:86,name -FNDA:74,symbol -FNDA:26,setName -FNDA:24,setSymbol FNDA:48,batchBalanceOf -FNDA:5858,_getERC20BaseModuleStorage -DA:39,98 -DA:40,50 -DA:55,5624 -DA:56,5624 -DA:57,5624 -DA:58,5624 -DA:78,128 -DA:80,80 -DA:83,80 -DA:86,80 -DA:96,24 -DA:97,24 -DA:104,86 -DA:105,86 -DA:113,74 -DA:114,74 -DA:125,26 -DA:126,26 -DA:127,26 -DA:134,24 -DA:135,24 -DA:136,24 -DA:143,48 -DA:144,48 -DA:145,24 -DA:147,48 -DA:158,5858 -LF:27 -LH:27 -BRDA:54,1,0,5624 -BRDA:54,1,1,0 -BRDA:80,2,0,80 -BRDA:80,2,1,0 -BRDA:124,3,0,26 -BRDA:124,3,1,24 -BRDA:133,4,0,24 -BRDA:133,4,1,24 -BRF:8 -BRH:6 +FNDA:6212,_getERC20BaseModuleStorage +DA:38,6188 +DA:39,6188 +DA:59,188 +DA:61,116 +DA:64,116 +DA:67,116 +DA:77,24 +DA:78,24 +DA:85,48 +DA:86,48 +DA:87,24 +DA:89,48 +DA:97,6212 +LF:13 +LH:13 +BRDA:37,1,0,6188 +BRDA:37,1,1,0 +BRDA:61,2,0,116 +BRDA:61,2,1,0 +BRF:4 +BRH:2 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ERC20BurnModule.sol @@ -1954,27 +2046,27 @@ FN:86,batchBurn FN:95,_burn FNF:6 FNH:6 -FNDA:835,onlyBurner +FNDA:841,onlyBurner FNDA:271,burn -FNDA:138,burn +FNDA:144,burn FNDA:254,batchBurn FNDA:76,batchBurn -FNDA:409,_burn -DA:26,835 -DA:27,739 +FNDA:415,_burn +DA:26,841 +DA:27,745 DA:45,271 -DA:57,138 +DA:57,144 DA:73,254 DA:74,91 DA:87,76 DA:88,74 -DA:100,409 -DA:101,292 +DA:100,415 +DA:101,298 LF:10 LH:10 BRDA:44,1,0,271 BRDA:44,1,1,72 -BRDA:56,2,0,138 +BRDA:56,2,0,144 BRDA:56,2,1,0 BRDA:72,3,0,254 BRDA:72,3,1,24 @@ -1993,30 +2085,30 @@ FN:88,batchTransfer FN:95,_mint FNF:6 FNH:6 -FNDA:5722,onlyMinter +FNDA:6197,onlyMinter FNDA:148,mint -FNDA:4534,mint -FNDA:730,batchMint -FNDA:238,batchTransfer -FNDA:4682,_mint -DA:28,5722 -DA:29,5650 +FNDA:4935,mint +FNDA:780,batchMint +FNDA:262,batchTransfer +FNDA:5083,_mint +DA:28,6197 +DA:29,6125 DA:44,148 -DA:60,4534 -DA:76,730 -DA:77,583 -DA:89,238 -DA:96,4682 -DA:97,4586 +DA:60,4935 +DA:76,780 +DA:77,633 +DA:89,262 +DA:96,5083 +DA:97,5008 LF:9 LH:9 BRDA:43,1,0,148 BRDA:43,1,1,24 -BRDA:59,2,0,4534 +BRDA:59,2,0,4935 BRDA:59,2,1,24 -BRDA:75,3,0,730 +BRDA:75,3,0,780 BRDA:75,3,1,24 -BRDA:88,4,0,238 +BRDA:88,4,0,262 BRDA:88,4,1,0 BRF:8 BRH:7 @@ -2034,65 +2126,110 @@ FN:118,_requireNotDeactivated FN:125,_getPauseModuleStorage FNF:9 FNH:9 -FNDA:763,onlyPauseManager -FNDA:318,onlyDeactivateContractManager -FNDA:637,pause -FNDA:75,unpause -FNDA:293,deactivateContract -FNDA:5339,paused -FNDA:8168,deactivated -FNDA:7853,_requireNotDeactivated -FNDA:8511,_getPauseModuleStorage -DA:41,763 -DA:42,712 -DA:46,318 -DA:47,293 -DA:60,637 -DA:69,75 -DA:70,75 +FNDA:841,onlyPauseManager +FNDA:344,onlyDeactivateContractManager +FNDA:713,pause +FNDA:77,unpause +FNDA:319,deactivateContract +FNDA:5018,paused +FNDA:8717,deactivated +FNDA:8372,_requireNotDeactivated +FNDA:9088,_getPauseModuleStorage +DA:41,841 +DA:42,790 +DA:46,344 +DA:47,319 +DA:60,713 +DA:69,77 +DA:70,77 DA:71,50 -DA:86,293 -DA:87,268 -DA:88,268 +DA:86,319 +DA:87,294 +DA:88,294 DA:89,25 -DA:91,243 -DA:92,243 -DA:100,5339 -DA:107,8168 -DA:108,8168 -DA:119,7853 +DA:91,269 +DA:92,269 +DA:100,5018 +DA:107,8717 +DA:108,8717 +DA:119,8372 DA:120,121 -DA:126,8511 +DA:126,9088 LF:20 LH:20 -BRDA:59,1,0,637 +BRDA:59,1,0,713 BRDA:59,1,1,26 -BRDA:68,2,0,75 +BRDA:68,2,0,77 BRDA:68,2,1,25 BRDA:70,3,0,50 -BRDA:70,3,1,25 -BRDA:83,4,0,293 +BRDA:70,3,1,27 +BRDA:83,4,0,319 BRDA:83,4,1,25 BRDA:88,5,0,25 -BRDA:88,5,1,243 +BRDA:88,5,1,269 BRDA:119,6,0,121 -BRDA:119,6,1,7732 +BRDA:119,6,1,8251 BRF:12 BRH:12 end_of_record TN: +SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/TokenAttributeModule.sol +FN:38,onlyTokenAttributeManager +FN:50,__TokenAttributeModule_init_unchained +FN:64,name +FN:73,symbol +FN:91,setName +FN:100,setSymbol +FN:113,_getTokenAttributeModuleStorage +FNF:7 +FNH:7 +FNDA:98,onlyTokenAttributeManager +FNDA:6188,__TokenAttributeModule_init_unchained +FNDA:94,name +FNDA:76,symbol +FNDA:26,setName +FNDA:24,setSymbol +FNDA:6408,_getTokenAttributeModuleStorage +DA:39,98 +DA:40,50 +DA:51,6188 +DA:52,6188 +DA:53,6188 +DA:65,94 +DA:66,94 +DA:74,76 +DA:75,76 +DA:92,26 +DA:93,26 +DA:94,26 +DA:101,24 +DA:102,24 +DA:103,24 +DA:114,6408 +LF:16 +LH:16 +BRDA:50,1,0,6188 +BRDA:50,1,1,0 +BRDA:91,2,0,26 +BRDA:91,2,1,24 +BRDA:100,3,0,24 +BRDA:100,3,1,24 +BRF:6 +BRH:5 +end_of_record +TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/core/ValidationModuleCore.sol FN:20,canTransfer FN:28,canTransferFrom -FN:44,_canTransferByModule +FN:48,_canTransferByModule FNF:3 FNH:3 -FNDA:1229,canTransfer -FNDA:208,canTransferFrom -FNDA:1437,_canTransferByModule -DA:25,1229 -DA:34,208 -DA:50,1437 +FNDA:1346,canTransfer +FNDA:212,canTransferFrom +FNDA:1558,_canTransferByModule +DA:25,1346 +DA:34,212 +DA:54,1558 LF:3 LH:3 BRF:0 @@ -2114,60 +2251,64 @@ TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/DocumentERC1643Module.sol FN:23,onlyDocumentManager FN:28,getDocument -FN:32,getAllDocuments -FN:36,setDocument -FN:51,removeDocument -FN:75,_getDocumentERC1643ModuleStorage +FN:33,getAllDocuments +FN:37,setDocument +FN:53,removeDocument +FN:77,_getDocumentERC1643ModuleStorage FNF:6 FNH:6 -FNDA:299,onlyDocumentManager -FNDA:138,getDocument -FNDA:46,getAllDocuments -FNDA:207,setDocument -FNDA:46,removeDocument -FNDA:437,_getDocumentERC1643ModuleStorage -DA:24,299 -DA:25,253 -DA:29,138 -DA:33,46 -DA:37,207 -DA:38,207 -DA:39,207 -DA:40,207 -DA:41,207 -DA:43,207 -DA:44,184 -DA:45,184 -DA:48,207 -DA:52,46 -DA:53,46 -DA:54,46 -DA:56,46 -DA:57,46 -DA:58,46 -DA:60,46 -DA:61,23 -DA:62,23 -DA:63,23 -DA:66,46 -DA:67,46 -DA:68,46 -DA:70,46 -DA:76,437 -LF:28 -LH:28 -BRDA:36,1,0,207 -BRDA:36,1,1,23 -BRDA:43,2,0,184 -BRDA:43,2,1,23 -BRDA:51,3,0,46 -BRDA:51,3,1,23 -BRDA:54,4,0,46 -BRDA:54,4,1,0 -BRDA:60,5,0,23 -BRDA:60,5,1,23 -BRF:10 -BRH:9 +FNDA:446,onlyDocumentManager +FNDA:152,getDocument +FNDA:49,getAllDocuments +FNDA:297,setDocument +FNDA:103,removeDocument +FNDA:576,_getDocumentERC1643ModuleStorage +DA:24,446 +DA:25,400 +DA:29,152 +DA:30,152 +DA:34,49 +DA:38,297 +DA:39,272 +DA:40,272 +DA:41,272 +DA:42,272 +DA:43,272 +DA:45,272 +DA:46,248 +DA:47,248 +DA:50,272 +DA:54,103 +DA:55,103 +DA:56,103 +DA:58,78 +DA:59,78 +DA:60,78 +DA:62,78 +DA:63,26 +DA:64,26 +DA:65,26 +DA:68,78 +DA:69,78 +DA:70,78 +DA:72,78 +DA:78,576 +LF:30 +LH:30 +BRDA:37,1,0,297 +BRDA:37,1,1,23 +BRDA:38,2,0,272 +BRDA:38,2,1,25 +BRDA:45,3,0,248 +BRDA:45,3,1,24 +BRDA:53,4,0,103 +BRDA:53,4,1,23 +BRDA:56,5,0,78 +BRDA:56,5,1,25 +BRDA:62,6,0,26 +BRDA:62,6,1,52 +BRF:12 +BRH:12 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ERC20EnforcementModule.sol @@ -2182,39 +2323,39 @@ FN:94,_freezeTokensEmitEvents FN:99,_unfreezeTokensEmitEvents FNF:9 FNH:9 -FNDA:1289,onlyERC20Enforcer -FNDA:262,onlyForcedTransferManager -FNDA:2246,getFrozenTokens -FNDA:146,forcedTransfer -FNDA:574,freezePartialTokens -FNDA:194,unfreezePartialTokens -FNDA:378,setFrozenTokens -FNDA:845,_freezeTokensEmitEvents -FNDA:323,_unfreezeTokensEmitEvents -DA:26,1289 -DA:27,1226 -DA:32,262 -DA:33,220 -DA:44,2246 -DA:55,146 -DA:56,125 -DA:66,574 -DA:76,194 -DA:87,378 -DA:95,845 -DA:96,845 -DA:100,323 -DA:101,323 +FNDA:1430,onlyERC20Enforcer +FNDA:342,onlyForcedTransferManager +FNDA:2062,getFrozenTokens +FNDA:200,forcedTransfer +FNDA:596,freezePartialTokens +FNDA:204,unfreezePartialTokens +FNDA:476,setFrozenTokens +FNDA:878,_freezeTokensEmitEvents +FNDA:338,_unfreezeTokensEmitEvents +DA:26,1430 +DA:27,1364 +DA:32,342 +DA:33,298 +DA:44,2062 +DA:55,200 +DA:56,164 +DA:66,596 +DA:76,204 +DA:87,476 +DA:95,878 +DA:96,878 +DA:100,338 +DA:101,338 LF:14 LH:14 -BRDA:54,1,0,146 -BRDA:54,1,1,42 -BRDA:65,2,0,574 -BRDA:65,2,1,21 -BRDA:75,3,0,194 -BRDA:75,3,1,21 -BRDA:85,4,0,378 -BRDA:85,4,1,21 +BRDA:54,1,0,200 +BRDA:54,1,1,44 +BRDA:65,2,0,596 +BRDA:65,2,1,22 +BRDA:75,3,0,204 +BRDA:75,3,1,22 +BRDA:85,4,0,476 +BRDA:85,4,1,22 BRF:8 BRH:8 end_of_record @@ -2229,63 +2370,70 @@ FN:100,tokenId FN:108,terms FN:116,information FN:124,_setTerms -FN:129,_setTokenId -FN:136,_setTerms -FN:147,_setInformation -FN:156,_getExtraInformationModuleStorage -FNF:13 -FNH:13 -FNDA:164,onlyExtraInfoManager -FNDA:5402,__ExtraInformationModule_init_unchained +FN:136,_setTermsDocument +FN:145,_setTokenId +FN:152,_setTerms +FN:163,_setInformation +FN:172,_getExtraInformationModuleStorage +FNF:14 +FNH:14 +FNDA:168,onlyExtraInfoManager +FNDA:5942,__ExtraInformationModule_init_unchained FNDA:26,setTokenId FNDA:26,setTerms -FNDA:26,setInformation +FNDA:28,setInformation FNDA:130,tokenId -FNDA:58,terms -FNDA:104,information -FNDA:28,_setTerms -FNDA:5428,_setTokenId -FNDA:5430,_setTerms -FNDA:5428,_setInformation -FNDA:5774,_getExtraInformationModuleStorage -DA:32,164 -DA:33,82 -DA:45,5402 -DA:47,5402 -DA:49,5402 -DA:51,5402 +FNDA:118,terms +FNDA:108,information +FNDA:26,_setTerms +FNDA:4,_setTermsDocument +FNDA:5968,_setTokenId +FNDA:5968,_setTerms +FNDA:5970,_setInformation +FNDA:6382,_getExtraInformationModuleStorage +DA:32,168 +DA:33,86 +DA:45,5942 +DA:47,5942 +DA:49,5942 +DA:51,5942 DA:68,26 DA:69,26 DA:79,26 -DA:92,26 -DA:93,26 +DA:92,28 +DA:93,28 DA:101,130 DA:102,130 -DA:109,58 -DA:110,58 -DA:117,104 -DA:118,104 -DA:125,28 -DA:126,28 -DA:132,5428 -DA:133,5428 -DA:138,5430 -DA:140,5430 -DA:141,5430 -DA:142,5430 -DA:144,5430 -DA:148,5428 -DA:149,5428 -DA:157,5774 -LF:29 -LH:29 -BRDA:44,1,0,5402 +DA:109,118 +DA:110,118 +DA:117,108 +DA:118,108 +DA:125,26 +DA:126,26 +DA:137,4 +DA:138,4 +DA:139,4 +DA:140,4 +DA:142,4 +DA:148,5968 +DA:149,5968 +DA:154,5968 +DA:156,5968 +DA:157,5968 +DA:158,5968 +DA:160,5968 +DA:164,5970 +DA:165,5970 +DA:173,6382 +LF:34 +LH:34 +BRDA:44,1,0,5942 BRDA:44,1,1,0 BRDA:67,2,0,26 BRDA:67,2,1,26 BRDA:78,3,0,26 BRDA:78,3,1,26 -BRDA:91,4,0,26 +BRDA:91,4,0,28 BRDA:91,4,1,26 BRF:8 BRH:7 @@ -2300,203 +2448,210 @@ FN:84,_setSnapshotEngine FN:94,_getSnapshotEngineModuleStorage FNF:6 FNH:6 -FNDA:343,onlySnapshooter +FNDA:349,onlySnapshooter FNDA:27,__SnapshotEngineModule_init_unchained -FNDA:334,setSnapshotEngine -FNDA:3300,snapshotEngine -FNDA:343,_setSnapshotEngine -FNDA:3652,_getSnapshotEngineModuleStorage -DA:30,343 -DA:31,334 +FNDA:340,setSnapshotEngine +FNDA:3476,snapshotEngine +FNDA:349,_setSnapshotEngine +FNDA:3834,_getSnapshotEngineModuleStorage +DA:30,349 +DA:31,340 DA:45,27 DA:46,18 DA:47,18 -DA:65,334 -DA:66,334 -DA:67,325 -DA:77,3300 -DA:78,3300 -DA:87,343 -DA:88,343 -DA:95,3652 +DA:65,340 +DA:66,340 +DA:67,331 +DA:77,3476 +DA:78,3476 +DA:87,349 +DA:88,349 +DA:95,3834 LF:13 LH:13 BRDA:44,1,0,27 BRDA:44,1,1,0 BRDA:45,2,0,18 BRDA:45,2,1,9 -BRDA:64,3,0,334 +BRDA:64,3,0,340 BRDA:64,3,1,9 -BRDA:66,4,0,325 +BRDA:66,4,0,331 BRDA:66,4,1,9 BRF:8 BRH:7 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol -FN:23,_canAuthorizeAllowanceByModuleAndRevert +FN:36,_canAuthorizeAllowanceByModuleAndRevert FNF:1 FNH:1 -FNDA:808,_canAuthorizeAllowanceByModuleAndRevert -DA:27,808 -DA:28,804 -DA:29,28 -DA:31,776 -DA:32,28 -LF:5 -LH:5 -BRDA:28,1,0,28 -BRDA:28,1,1,776 -BRDA:31,2,0,28 -BRDA:31,2,1,748 -BRF:4 -BRH:4 +FNDA:1150,_canAuthorizeAllowanceByModuleAndRevert +DA:42,1150 +DA:43,128 +DA:45,1022 +DA:46,972 +DA:47,28 +DA:49,944 +DA:50,52 +LF:7 +LH:7 +BRDA:42,1,0,128 +BRDA:42,1,1,1022 +BRDA:46,2,0,28 +BRDA:46,2,1,944 +BRDA:49,3,0,52 +BRDA:49,3,1,892 +BRF:6 +BRH:6 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol -FN:52,messageForTransferRestriction -FN:98,detectTransferRestriction -FN:114,detectTransferRestrictionFrom -FN:142,_detectTransferRestriction +FN:77,messageForTransferRestriction +FN:126,detectTransferRestriction +FN:157,detectTransferRestrictionFrom +FN:186,_detectTransferRestriction FNF:4 FNH:4 -FNDA:93,messageForTransferRestriction -FNDA:199,detectTransferRestriction -FNDA:189,detectTransferRestrictionFrom -FNDA:223,_detectTransferRestriction -DA:55,93 -DA:56,93 -DA:57,6 -DA:62,22 -DA:67,11 -DA:72,11 -DA:77,11 -DA:82,11 -DA:84,18 -DA:86,3 -DA:103,199 -DA:104,199 -DA:105,199 -DA:106,132 -DA:108,42 -DA:110,25 -DA:120,189 -DA:121,189 -DA:122,11 -DA:124,178 -DA:125,178 -DA:126,132 -DA:128,24 -DA:130,22 -DA:147,223 -DA:148,33 -DA:150,55 -DA:152,11 -DA:154,11 -DA:157,113 +FNDA:95,messageForTransferRestriction +FNDA:190,detectTransferRestriction +FNDA:160,detectTransferRestrictionFrom +FNDA:251,_detectTransferRestriction +DA:80,95 +DA:81,95 +DA:82,6 +DA:87,22 +DA:92,13 +DA:97,11 +DA:102,11 +DA:107,11 +DA:109,18 +DA:111,3 +DA:131,190 +DA:132,190 +DA:133,190 +DA:134,112 +DA:136,42 +DA:138,36 +DA:163,160 +DA:164,160 +DA:165,11 +DA:167,149 +DA:168,149 +DA:169,92 +DA:171,24 +DA:173,33 +DA:191,251 +DA:192,39 +DA:194,55 +DA:196,11 +DA:198,11 +DA:201,135 LF:30 LH:30 -BRDA:56,1,0,6 -BRDA:56,1,1,87 -BRDA:58,2,0,22 -BRDA:58,2,1,65 -BRDA:63,3,0,11 -BRDA:63,3,1,54 -BRDA:68,4,0,11 -BRDA:68,4,1,43 -BRDA:73,5,0,11 -BRDA:73,5,1,32 -BRDA:78,6,0,11 -BRDA:78,6,1,21 -BRDA:83,7,0,18 -BRDA:83,7,1,3 -BRDA:105,8,0,132 -BRDA:105,8,1,67 -BRDA:107,9,0,42 -BRDA:107,9,1,25 -BRDA:121,10,0,11 -BRDA:121,10,1,178 -BRDA:125,11,0,132 -BRDA:125,11,1,46 -BRDA:127,12,0,24 -BRDA:127,12,1,22 -BRDA:147,13,0,33 -BRDA:147,13,1,190 -BRDA:149,14,0,55 -BRDA:149,14,1,135 -BRDA:151,15,0,11 -BRDA:151,15,1,124 -BRDA:153,16,0,11 -BRDA:153,16,1,113 +BRDA:81,1,0,6 +BRDA:81,1,1,89 +BRDA:83,2,0,22 +BRDA:83,2,1,67 +BRDA:88,3,0,13 +BRDA:88,3,1,54 +BRDA:93,4,0,11 +BRDA:93,4,1,43 +BRDA:98,5,0,11 +BRDA:98,5,1,32 +BRDA:103,6,0,11 +BRDA:103,6,1,21 +BRDA:108,7,0,18 +BRDA:108,7,1,3 +BRDA:133,8,0,112 +BRDA:133,8,1,78 +BRDA:135,9,0,42 +BRDA:135,9,1,36 +BRDA:164,10,0,11 +BRDA:164,10,1,149 +BRDA:168,11,0,92 +BRDA:168,11,1,57 +BRDA:170,12,0,24 +BRDA:170,12,1,33 +BRDA:191,13,0,39 +BRDA:191,13,1,212 +BRDA:193,14,0,55 +BRDA:193,14,1,157 +BRDA:195,15,0,11 +BRDA:195,15,1,146 +BRDA:197,16,0,11 +BRDA:197,16,1,135 BRF:32 BRH:32 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol -FN:27,onlyRuleEngineManager -FN:49,setRuleEngine -FN:58,canTransfer -FN:70,canTransferFrom -FN:83,_canTransfer -FN:95,_canTransferFrom -FN:108,_canTransferFromWithRuleEngine -FN:121,_canTransferWithRuleEngine -FN:138,_transferred -FNF:9 -FNH:9 -FNDA:364,onlyRuleEngineManager -FNDA:361,setRuleEngine -FNDA:1009,canTransfer -FNDA:175,canTransferFrom -FNDA:1009,_canTransfer -FNDA:175,_canTransferFrom +FN:28,onlyRuleEngineManager +FN:50,setRuleEngine +FN:59,canTransfer +FN:71,canTransferFrom +FN:84,_canTransfer +FN:96,_canTransferFrom +FN:109,_canTransferFromWithRuleEngine +FN:122,_canTransferWithRuleEngine +FN:166,_transferred +FN:182,_callRuleEngineTransferred +FNF:10 +FNH:10 +FNDA:370,onlyRuleEngineManager +FNDA:367,setRuleEngine +FNDA:1068,canTransfer +FNDA:177,canTransferFrom +FNDA:1068,_canTransfer +FNDA:177,_canTransferFrom FNDA:99,_canTransferFromWithRuleEngine FNDA:769,_canTransferWithRuleEngine -FNDA:7282,_transferred -DA:28,364 -DA:29,361 -DA:50,361 -DA:51,358 -DA:63,1009 -DA:76,175 -DA:88,1009 -DA:89,240 -DA:91,769 -DA:101,175 -DA:102,76 -DA:104,99 -DA:114,99 +FNDA:7763,_transferred +FNDA:725,_callRuleEngineTransferred +DA:29,370 +DA:30,367 +DA:51,367 +DA:52,364 +DA:64,1068 +DA:77,177 +DA:89,1068 +DA:90,299 +DA:92,769 +DA:102,177 +DA:103,78 +DA:105,99 DA:115,99 -DA:116,30 -DA:118,69 -DA:126,769 +DA:116,99 +DA:117,30 +DA:119,69 DA:127,769 -DA:128,60 -DA:130,709 -DA:139,7282 -DA:140,6851 -DA:141,6851 -DA:142,715 -DA:143,703 -DA:145,12 -LF:26 -LH:26 -BRDA:49,1,0,361 -BRDA:49,1,1,3 -BRDA:50,2,0,358 -BRDA:50,2,1,3 -BRDA:88,3,0,240 -BRDA:88,3,1,769 -BRDA:101,4,0,76 -BRDA:101,4,1,99 -BRDA:115,5,0,30 -BRDA:115,5,1,69 -BRDA:127,6,0,60 -BRDA:127,6,1,709 -BRDA:141,7,0,715 -BRDA:141,7,1,6136 -BRDA:142,8,0,703 -BRDA:142,8,1,12 +DA:128,769 +DA:129,60 +DA:131,709 +DA:167,7763 +DA:168,7309 +DA:169,7309 +DA:170,733 +DA:189,725 +DA:190,709 +DA:192,16 +LF:27 +LH:27 +BRDA:50,1,0,367 +BRDA:50,1,1,3 +BRDA:51,2,0,364 +BRDA:51,2,1,3 +BRDA:89,3,0,299 +BRDA:89,3,1,769 +BRDA:102,4,0,78 +BRDA:102,4,1,99 +BRDA:116,5,0,30 +BRDA:116,5,1,69 +BRDA:128,6,0,60 +BRDA:128,6,1,709 +BRDA:169,7,0,733 +BRDA:169,7,1,6576 +BRDA:189,8,0,709 +BRDA:189,8,1,16 BRF:16 BRH:16 end_of_record @@ -2512,34 +2667,34 @@ FN:83,isAllowlisted FN:90,_addToAllowlist FNF:8 FNH:8 -FNDA:978,onlyAllowlistManager +FNDA:1129,onlyAllowlistManager FNDA:4,setAddressAllowlist -FNDA:292,setAddressAllowlist -FNDA:532,batchSetAddressAllowlist -FNDA:142,enableAllowlist +FNDA:322,setAddressAllowlist +FNDA:584,batchSetAddressAllowlist +FNDA:211,enableAllowlist FNDA:4,isAllowlistEnabled -FNDA:1438,isAllowlisted -FNDA:2396,_addToAllowlist -DA:25,978 -DA:26,970 +FNDA:1580,isAllowlisted +FNDA:2626,_addToAllowlist +DA:25,1129 +DA:26,1121 DA:37,4 -DA:47,292 -DA:57,532 -DA:67,142 -DA:68,142 +DA:47,322 +DA:57,584 +DA:67,211 +DA:68,211 DA:77,4 -DA:84,1438 -DA:91,2396 -DA:92,2396 +DA:84,1580 +DA:91,2626 +DA:92,2626 LF:11 LH:11 BRDA:36,1,0,4 BRDA:36,1,1,2 -BRDA:46,2,0,292 +BRDA:46,2,0,322 BRDA:46,2,1,4 -BRDA:56,3,0,532 +BRDA:56,3,0,584 BRDA:56,3,1,2 -BRDA:66,4,0,142 +BRDA:66,4,0,211 BRDA:66,4,1,0 BRF:8 BRH:7 @@ -2548,8 +2703,8 @@ TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/CCIPModule.sol FN:30,onlyCCIPSetAdmin FN:41,setCCIPAdmin -FN:54,getCCIPAdmin -FN:66,_getCCIPModuleStorage +FN:55,getCCIPAdmin +FN:67,_getCCIPModuleStorage FNF:4 FNH:4 FNDA:48,onlyCCIPSetAdmin @@ -2563,9 +2718,9 @@ DA:43,36 DA:44,36 DA:46,24 DA:48,24 -DA:55,24 DA:56,24 -DA:67,60 +DA:57,24 +DA:68,60 LF:10 LH:10 BRDA:41,1,0,36 @@ -2675,29 +2830,29 @@ FN:56,documentEngine FN:64,getDocument FN:76,getAllDocuments FN:83,setDocument -FN:88,removeDocument -FN:100,setDocumentEngine -FN:110,_setDocumentEngine -FN:121,_getDocumentEngineModuleStorage +FN:95,removeDocument +FN:114,setDocumentEngine +FN:124,_setDocumentEngine +FN:135,_getDocumentEngineModuleStorage FNF:10 FNH:10 -FNDA:34,onlyDocumentManager -FNDA:37,__DocumentEngineModule_init_unchained -FNDA:15,documentEngine +FNDA:55,onlyDocumentManager +FNDA:53,__DocumentEngineModule_init_unchained +FNDA:19,documentEngine FNDA:9,getDocument FNDA:5,getAllDocuments -FNDA:9,setDocument -FNDA:2,removeDocument -FNDA:18,setDocumentEngine -FNDA:21,_setDocumentEngine -FNDA:64,_getDocumentEngineModuleStorage -DA:29,34 -DA:30,29 -DA:43,37 +FNDA:18,setDocument +FNDA:7,removeDocument +FNDA:25,setDocumentEngine +FNDA:28,_setDocumentEngine +FNDA:89,_getDocumentEngineModuleStorage +DA:29,55 +DA:30,50 +DA:43,53 DA:44,6 DA:45,6 -DA:57,15 -DA:58,15 +DA:57,19 +DA:58,19 DA:65,9 DA:66,9 DA:67,6 @@ -2705,93 +2860,102 @@ DA:69,3 DA:77,5 DA:78,5 DA:79,2 -DA:84,9 -DA:85,9 -DA:89,2 -DA:90,2 -DA:101,18 -DA:102,18 -DA:103,15 -DA:113,21 -DA:114,21 -DA:122,64 -LF:24 -LH:24 -BRDA:42,1,0,37 +DA:84,18 +DA:85,18 +DA:91,15 +DA:92,14 +DA:96,7 +DA:97,7 +DA:102,7 +DA:103,7 +DA:104,6 +DA:115,25 +DA:116,25 +DA:117,22 +DA:127,28 +DA:128,28 +DA:136,89 +LF:29 +LH:29 +BRDA:42,1,0,53 BRDA:42,1,1,0 BRDA:43,2,0,6 -BRDA:43,2,1,31 +BRDA:43,2,1,47 BRDA:66,3,0,6 BRDA:66,3,1,3 BRDA:78,4,0,2 BRDA:78,4,1,3 -BRDA:83,5,0,9 +BRDA:83,5,0,18 BRDA:83,5,1,1 -BRDA:88,6,0,2 -BRDA:88,6,1,1 -BRDA:100,7,0,18 -BRDA:100,7,1,3 -BRDA:102,8,0,15 -BRDA:102,8,1,3 -BRF:16 -BRH:15 +BRDA:85,6,0,15 +BRDA:85,6,1,3 +BRDA:95,7,0,7 +BRDA:95,7,1,1 +BRDA:97,8,0,7 +BRDA:97,8,1,0 +BRDA:114,9,0,25 +BRDA:114,9,1,3 +BRDA:116,10,0,22 +BRDA:116,10,1,3 +BRF:20 +BRH:18 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC20CrossChainModule.sol FN:30,onlyTokenBridge -FN:38,onlyBurnerFrom -FN:44,onlySelfBurn -FN:60,crosschainMint -FN:73,crosschainBurn -FN:84,burnFrom -FN:97,burn -FN:103,supportsInterface -FN:110,_burnFrom -FN:119,_burnFromOperator +FN:44,onlyBurnerFrom +FN:50,onlySelfBurn +FN:66,crosschainMint +FN:79,crosschainBurn +FN:90,burnFrom +FN:103,burn +FN:109,supportsInterface +FN:116,_burnFrom +FN:125,_burnFromOperator FNF:10 FNH:10 -FNDA:266,onlyTokenBridge +FNDA:254,onlyTokenBridge FNDA:96,onlyBurnerFrom -FNDA:96,onlySelfBurn +FNDA:84,onlySelfBurn FNDA:86,crosschainMint -FNDA:108,crosschainBurn +FNDA:96,crosschainBurn FNDA:60,burnFrom FNDA:48,burn -FNDA:84,supportsInterface +FNDA:92,supportsInterface FNDA:60,_burnFrom FNDA:96,_burnFromOperator -DA:33,266 -DA:34,194 -DA:39,96 -DA:40,60 +DA:39,254 +DA:40,182 DA:45,96 -DA:46,48 -DA:61,86 -DA:62,62 -DA:74,108 -DA:75,60 -DA:86,60 -DA:87,60 -DA:98,48 -DA:99,48 -DA:104,84 -DA:112,60 -DA:115,48 -DA:116,48 -DA:120,96 +DA:46,60 +DA:51,84 +DA:52,48 +DA:67,86 +DA:68,62 +DA:80,96 +DA:81,60 +DA:92,60 +DA:93,60 +DA:104,48 +DA:105,48 +DA:110,92 +DA:118,60 DA:121,48 +DA:122,48 +DA:126,96 +DA:127,48 LF:20 LH:20 -BRDA:60,1,0,86 -BRDA:60,1,1,36 -BRDA:73,2,0,108 -BRDA:73,2,1,36 -BRDA:84,3,0,60 -BRDA:84,3,1,36 -BRDA:97,4,0,48 -BRDA:97,4,1,48 -BRDA:104,5,0,12 -BRDA:104,5,1,12 +BRDA:66,1,0,86 +BRDA:66,1,1,36 +BRDA:79,2,0,96 +BRDA:79,2,1,36 +BRDA:90,3,0,60 +BRDA:90,3,1,36 +BRDA:103,4,0,48 +BRDA:103,4,1,36 +BRDA:110,5,0,12 +BRDA:110,5,1,12 BRF:10 BRH:10 end_of_record @@ -2804,31 +2968,31 @@ FN:65,freezePartialTokens FN:76,unfreezePartialTokens FNF:5 FNH:5 -FNDA:452,getFrozenTokens -FNDA:432,getActiveBalanceOf -FNDA:74,forcedTransfer -FNDA:48,freezePartialTokens +FNDA:593,getFrozenTokens +FNDA:440,getActiveBalanceOf +FNDA:98,forcedTransfer +FNDA:56,freezePartialTokens FNDA:32,unfreezePartialTokens -DA:30,452 -DA:39,432 -DA:49,74 -DA:50,74 -DA:51,74 -DA:52,74 +DA:30,593 +DA:39,440 +DA:49,98 +DA:50,98 +DA:51,90 +DA:52,90 DA:53,24 -DA:55,74 -DA:56,74 -DA:66,48 -DA:67,40 +DA:55,90 +DA:56,90 +DA:66,56 +DA:67,48 DA:77,32 DA:78,24 LF:13 LH:13 -BRDA:48,1,0,74 +BRDA:48,1,0,98 BRDA:48,1,1,0 BRDA:52,2,0,24 -BRDA:52,2,1,50 -BRDA:65,3,0,48 +BRDA:52,2,1,66 +BRDA:65,3,0,56 BRDA:65,3,1,0 BRDA:76,4,0,32 BRDA:76,4,1,0 @@ -2840,7 +3004,7 @@ SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC2771Module FN:20,constructor FNF:1 FNH:1 -FNDA:3323,constructor +FNDA:3687,constructor LF:0 LH:0 BRF:0 @@ -2848,62 +3012,124 @@ BRH:0 end_of_record TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/ERC7551Module.sol -FN:42,setMetaData -FN:52,setTerms -FN:59,metaData -FN:67,termsHash -FN:74,_setMetaData -FN:82,_getERC7551ModuleStorage +FN:41,setMetaData +FN:51,setTerms +FN:60,metaData +FN:68,termsHash +FN:75,_setMetaData +FN:83,_getERC7551ModuleStorage FNF:6 FNH:6 FNDA:2,setMetaData -FNDA:2,setTerms +FNDA:4,setTerms FNDA:4,metaData -FNDA:2,termsHash +FNDA:4,termsHash FNDA:2,_setMetaData FNDA:6,_getERC7551ModuleStorage +DA:42,2 DA:43,2 -DA:44,2 -DA:53,2 -DA:54,2 -DA:55,2 -DA:60,4 +DA:55,4 +DA:56,4 DA:61,4 -DA:68,2 -DA:77,2 +DA:62,4 +DA:69,4 DA:78,2 -DA:83,6 -LF:11 -LH:11 -BRDA:42,1,0,2 -BRDA:42,1,1,2 -BRDA:52,2,0,2 -BRDA:52,2,1,2 +DA:79,2 +DA:84,6 +LF:10 +LH:10 +BRDA:41,1,0,2 +BRDA:41,1,1,2 +BRDA:51,2,0,4 +BRDA:51,2,1,2 BRF:4 BRH:4 end_of_record TN: +SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/options/HolderListModule.sol +FN:44,holderCount +FN:52,isHolder +FN:63,holderByIndex +FN:73,holders +FN:83,holdersInRange +FN:102,_update +FN:120,_getHolderListModuleStorage +FNF:7 +FNH:7 +FNDA:28,holderCount +FNDA:22,isHolder +FNDA:10,holderByIndex +FNDA:10,holders +FNDA:22,holdersInRange +FNDA:114,_update +FNDA:202,_getHolderListModuleStorage +DA:45,28 +DA:46,28 +DA:53,22 +DA:54,22 +DA:64,10 +DA:65,10 +DA:66,10 +DA:67,8 +DA:74,10 +DA:75,10 +DA:84,22 +DA:85,18 +DA:86,18 +DA:87,18 +DA:88,16 +DA:89,16 +DA:90,10 +DA:103,114 +DA:104,114 +DA:106,114 +DA:107,10 +DA:108,10 +DA:112,114 +DA:113,106 +DA:114,104 +DA:121,202 +LF:26 +LH:26 +BRDA:66,1,0,8 +BRDA:66,1,1,2 +BRDA:84,2,0,18 +BRDA:84,2,1,4 +BRDA:87,3,0,16 +BRDA:87,3,1,2 +BRDA:106,4,0,10 +BRDA:106,4,1,104 +BRDA:107,5,0,10 +BRDA:107,5,1,0 +BRDA:112,6,0,106 +BRDA:112,6,1,8 +BRDA:113,7,0,104 +BRDA:113,7,1,2 +BRF:14 +BRH:13 +end_of_record +TN: SF:/home/ryan/Pictures/dev/CMTAT/contracts/modules/wrapper/security/AccessControlModule.sol FN:24,__AccessControlModule_init_unchained -FN:40,hasRole +FN:41,hasRole FNF:2 FNH:2 -FNDA:5688,__AccessControlModule_init_unchained -FNDA:20013,hasRole -DA:25,5688 +FNDA:6262,__AccessControlModule_init_unchained +FNDA:21844,hasRole +DA:25,6262 DA:26,2 -DA:31,5686 -DA:45,20013 -DA:46,12061 -DA:48,7952 +DA:31,6260 +DA:46,21844 +DA:47,13326 +DA:49,8518 LF:6 LH:6 -BRDA:24,1,0,5688 +BRDA:24,1,0,6262 BRDA:24,1,1,0 BRDA:25,2,0,2 -BRDA:25,2,1,5686 -BRDA:45,3,0,12061 -BRDA:45,3,1,7952 +BRDA:25,2,1,6260 +BRDA:46,3,0,13326 +BRDA:46,3,1,8518 BRF:6 BRH:5 end_of_record diff --git a/doc/test/coverage/library/ERC1404ExtendInterfaceId.sol.html b/doc/test/coverage/library/ERC1404ExtendInterfaceId.sol.html index 6546f4fa..2c1db3b7 100644 --- a/doc/test/coverage/library/ERC1404ExtendInterfaceId.sol.html +++ b/doc/test/coverage/library/ERC1404ExtendInterfaceId.sol.html @@ -76,7 +76,7 @@

     
// SPDX-License-Identifier: MPL-2.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 library ERC1404ExtendInterfaceId {
       /**
@@ -97,7 +97,7 @@ 

diff --git a/doc/test/coverage/library/RuleEngineInterfaceId.sol.html b/doc/test/coverage/library/RuleEngineInterfaceId.sol.html index 55f6edc8..87587139 100644 --- a/doc/test/coverage/library/RuleEngineInterfaceId.sol.html +++ b/doc/test/coverage/library/RuleEngineInterfaceId.sol.html @@ -54,7 +54,7 @@

     
// SPDX-License-Identifier: MPL-2.0
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 library RuleEngineInterfaceId {
       bytes4 public constant RULE_ENGINE_INTERFACE_ID = 0x20c49ce7;
@@ -64,7 +64,7 @@ 

diff --git a/doc/test/coverage/library/index.html b/doc/test/coverage/library/index.html index ed18ad45..186a578a 100644 --- a/doc/test/coverage/library/index.html +++ b/doc/test/coverage/library/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/modules/0_CMTATBaseCommon.sol.html b/doc/test/coverage/modules/0_CMTATBaseCommon.sol.html index 8b130eac..f8894b6d 100644 --- a/doc/test/coverage/modules/0_CMTATBaseCommon.sol.html +++ b/doc/test/coverage/modules/0_CMTATBaseCommon.sol.html @@ -192,7 +192,14 @@

147 148 149 -150  +150 +151 +152 +153 +154 +155  +  +        @@ -250,23 +257,23 @@

      -80× +88×             -68× +70×           -431× -431× -248× -197× +442× +442× +252× +190×       @@ -281,8 +288,8 @@

      -278× -118× +306× +174×       @@ -307,7 +314,10 @@

      -8426× +8968× +  +  +        @@ -315,10 +325,10 @@

      +6737× +6571×     -6250× -6063×       @@ -326,9 +336,9 @@

      +1169× +957×   -1175× -951×       @@ -337,13 +347,13 @@

      -292× +314× 199×      
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
  
 /* ==== Wrapper === */
@@ -356,6 +366,7 @@ 

import {ERC20EnforcementModule, ERC20EnforcementModuleInternal} from "./wrapper/extensions/ERC20EnforcementModule.sol"; // options import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol"; +import {TokenAttributeModule} from "./wrapper/core/TokenAttributeModule.sol"; /* ==== Interface and other library === */ import {IBurnMintERC20} from "../interfaces/technical/IMintBurnToken.sol"; import {IERC5679} from "../interfaces/technical/IERC5679.sol"; @@ -366,6 +377,7 @@

ERC20MintModule, ERC20BurnModule, ERC20BaseModule, + TokenAttributeModule, // Extension ERC20EnforcementModule, ExtraInformationModule, @@ -396,17 +408,17 @@

    /** - * @inheritdoc ERC20BaseModule + * @inheritdoc TokenAttributeModule */ - function name() public view virtual override(ERC20Upgradeable, ERC20BaseModule) returns (string memory) { - return ERC20BaseModule.name(); + function name() public view virtual override(ERC20Upgradeable, TokenAttributeModule) returns (string memory) { + return TokenAttributeModule.name(); }   /** - * @inheritdoc ERC20BaseModule + * @inheritdoc TokenAttributeModule */ - function symbol() public view virtual override(ERC20Upgradeable, ERC20BaseModule) returns (string memory) { - return ERC20BaseModule.symbol(); + function symbol() public view virtual override(ERC20Upgradeable, TokenAttributeModule) returns (string memory) { + return TokenAttributeModule.symbol(); }     @@ -461,9 +473,10 @@

/* ==== Mint and Burn Operations ==== */ /** - * @dev + * @dev * Mint path * Check if the mint is valid + * @inheritdoc ERC20MintModuleInternal */ function _mintOverride(address account, uint256 value) internal virtual override(ERC20MintModuleInternal) { _checkTransferred(_msgSender(), address(0), account, value); @@ -471,9 +484,10 @@

}   /** - * @dev + * @dev * Burn path * Check if the burn is valid + * @inheritdoc ERC20BurnModuleInternal */ function _burnOverride(address account, uint256 value) internal virtual override(ERC20BurnModuleInternal) { _checkTransferred(_msgSender(), account, address(0), value); @@ -481,9 +495,10 @@

}   /** - * @dev + * @dev * Minter-initiated transfer path * Check if a minter transfer is valid + * @inheritdoc ERC20MintModuleInternal */ function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(ERC20MintModuleInternal) { _checkTransferred(_msgSender(), from, to, value); @@ -496,7 +511,7 @@

diff --git a/doc/test/coverage/modules/0_CMTATBaseCore.sol.html b/doc/test/coverage/modules/0_CMTATBaseCore.sol.html index 591c88a0..510c62dd 100644 --- a/doc/test/coverage/modules/0_CMTATBaseCore.sol.html +++ b/doc/test/coverage/modules/0_CMTATBaseCore.sol.html @@ -22,7 +22,7 @@

100% Statements - 33/33 + 34/34
86.67% @@ -37,7 +37,7 @@

100% Lines - 34/34 + 35/35

@@ -323,7 +323,22 @@

278 279 280 -281  +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293  +  +  +        @@ -397,7 +412,7 @@

      -247× +265×       @@ -413,16 +428,16 @@

      -284× +318×     -284× +318×     -284× +318×     -284× +318×       @@ -430,8 +445,8 @@

      -284× -284× +318× +318×       @@ -440,8 +455,9 @@

      -284× -284× +318× +318× +318×       @@ -493,7 +509,7 @@

      -12× +19×       @@ -501,18 +517,18 @@

      -28× -28× -18× -12× +26× +26× +16× +10×             -30× -24× +54× +44×       @@ -527,8 +543,8 @@

      +18× 14× -10×       @@ -559,6 +575,10 @@

      +  +  +  +    @@ -571,8 +591,8 @@

      -354× -346× +368× +360×       @@ -585,7 +605,11 @@

      -18× +  +  +  +  +20× 12×     @@ -605,7 +629,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -616,6 +640,7 @@ 

import {ERC20BurnModule, ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol"; import {ERC20MintModule, ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol"; import {ERC20BaseModule, ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol"; +import {TokenAttributeModule} from "./wrapper/core/TokenAttributeModule.sol";   // Other import {VersionModule} from "./wrapper/core/VersionModule.sol"; @@ -634,6 +659,7 @@

import {IERC7551ERC20EnforcementEvent} from "../interfaces/tokenization/draft-IERC7551.sol"; import {IERC7943FungibleTransferError} from "../interfaces/tokenization/draft-IERC7943.sol"; import {IERC5679} from "../interfaces/technical/IERC5679.sol"; +import {IERC8343} from "../interfaces/tokenization/draft-IERC8343.sol";   /** * @dev CMTAT with core modules @@ -648,6 +674,7 @@

ERC20BurnModule, ValidationModuleAllowance, ERC20BaseModule, + TokenAttributeModule, AccessControlModule, IForcedBurnERC20, IBurnMintERC20, @@ -721,7 +748,8 @@

function __CMTAT_modules_init_unchained(address admin, ICMTATConstructor.ERC20Attributes memory ERC20Attributes_ ) internal virtual EonlyInitializing { // AccessControlModule_init_unchained is called firstly due to inheritance __AccessControlModule_init_unchained(admin); - __ERC20BaseModule_init_unchained(ERC20Attributes_.decimalsIrrevocable, ERC20Attributes_.name, ERC20Attributes_.symbol); + __ERC20BaseModule_init_unchained(ERC20Attributes_.decimalsIrrevocable); + __TokenAttributeModule_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol); }     @@ -751,17 +779,17 @@

    /** - * @inheritdoc ERC20BaseModule + * @inheritdoc TokenAttributeModule */ - function name() public virtual override(ERC20Upgradeable, ERC20BaseModule) view returns (string memory) { - return ERC20BaseModule.name(); + function name() public virtual override(ERC20Upgradeable, TokenAttributeModule) view returns (string memory) { + return TokenAttributeModule.name(); }   /** - * @inheritdoc ERC20BaseModule + * @inheritdoc TokenAttributeModule */ - function symbol() public virtual override(ERC20Upgradeable, ERC20BaseModule) view returns (string memory) { - return ERC20BaseModule.symbol(); + function symbol() public virtual override(ERC20Upgradeable, TokenAttributeModule) view returns (string memory) { + return TokenAttributeModule.symbol(); }   /** @@ -770,10 +798,10 @@

* 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 (0x3edbb4c4) - * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate + * type(IERC8343).interfaceId (0xe9cd80b0) is the proposed ERC-8343 (draft) contract deactivation interface */ function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) { - return interfaceId == 0xd0017968 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId); + return interfaceId == 0xd0017968 || interfaceId == type(IERC8343).interfaceId || AccessControlUpgradeable.supportsInterface(interfaceId); }   /* ============ State Functions ============ */ @@ -791,7 +819,7 @@

* @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); } /* @@ -831,6 +859,10 @@

  /** * @inheritdoc IForcedBurnERC20 + * @dev Burns directly via `ERC20Upgradeable._burn`, so it bypasses the pause/deactivation + * validation used by the standard burn path. This is intentional — the Light variant's + * enforcement burn remains available **after deactivation** (per ERC-8343), so the enforcer + * can still cancel a frozen or migrated position on a terminated token. * @custom:access-control * - The caller must have the `DEFAULT_ADMIN_ROLE`. */ @@ -865,7 +897,11 @@

* @dev Check if a minter transfer is valid */ function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(ERC20MintModuleInternal) { - ValidationModule._canTransferGenericByModuleAndRevert(address(0), from, to); + // Pass the operator (_msgSender()) as spender, consistent with CMTATBaseCommon and the + // transferFrom path, instead of hardcoding address(0). A minter transfer moves the + // minter's own tokens, so `from == _msgSender()`; threading the spender keeps the + // spender-aware validation surface uniform across the Light and full bases (NM-5). + ValidationModule._canTransferGenericByModuleAndRevert(_msgSender(), from, to); ERC20MintModuleInternal._minterTransferOverride(from, to, value); }   @@ -881,7 +917,7 @@

  function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE){}   - function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) onlyRole(DEFAULT_ADMIN_ROLE){} + function _authorizeTokenAttributeManagement() internal virtual override(TokenAttributeModule) onlyRole(DEFAULT_ADMIN_ROLE){} }  

@@ -889,7 +925,7 @@

diff --git a/doc/test/coverage/modules/0_CMTATBaseGeneric.sol.html b/doc/test/coverage/modules/0_CMTATBaseGeneric.sol.html index 7caea995..378b2657 100644 --- a/doc/test/coverage/modules/0_CMTATBaseGeneric.sol.html +++ b/doc/test/coverage/modules/0_CMTATBaseGeneric.sol.html @@ -180,16 +180,16 @@

      -62× +72×     -62× +72×     -62× +72×     -62× +72×       @@ -197,8 +197,8 @@

      -62× -62× +72× +72×       @@ -206,9 +206,9 @@

      -62× +72×   -62× +72×       @@ -221,7 +221,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -313,7 +313,7 @@ 

diff --git a/doc/test/coverage/modules/0_CMTATBaseSnapshot.sol.html b/doc/test/coverage/modules/0_CMTATBaseSnapshot.sol.html index a91f20d9..045ffb5d 100644 --- a/doc/test/coverage/modules/0_CMTATBaseSnapshot.sol.html +++ b/doc/test/coverage/modules/0_CMTATBaseSnapshot.sol.html @@ -93,21 +93,21 @@

      -2951× -2951× -176× -176× -176× -176× -176× +3118× +3118× +231× +231× +231× +231× +231×   -2775× +2887×        
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -142,7 +142,7 @@ 

diff --git a/doc/test/coverage/modules/1_CMTATBaseDocument.sol.html b/doc/test/coverage/modules/1_CMTATBaseDocument.sol.html index c1b1fbec..5434259d 100644 --- a/doc/test/coverage/modules/1_CMTATBaseDocument.sol.html +++ b/doc/test/coverage/modules/1_CMTATBaseDocument.sol.html @@ -65,7 +65,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol";
  
@@ -79,7 +79,7 @@ 

diff --git a/doc/test/coverage/modules/2_CMTATBaseAccessControl.sol.html b/doc/test/coverage/modules/2_CMTATBaseAccessControl.sol.html index 34f84ab1..6496bf71 100644 --- a/doc/test/coverage/modules/2_CMTATBaseAccessControl.sol.html +++ b/doc/test/coverage/modules/2_CMTATBaseAccessControl.sol.html @@ -22,12 +22,12 @@

100% Statements - 4/4 + 5/5
- 95.45% + 95.83% Branches - 21/22 + 23/24
100% @@ -37,7 +37,7 @@

100% Lines - 4/4 + 5/5

@@ -147,7 +147,11 @@

102 103 104 -105  +105 +106 +107 +108 +109        @@ -180,13 +184,14 @@

      -5342×   -5340×   -5340× +5872×   +5870× +5870×   +5870×       @@ -199,7 +204,10 @@

      -42× +  +  +  +45×       @@ -253,7 +261,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
@@ -267,8 +275,10 @@ 

import {ExtraInformationModule} from "./wrapper/extensions/ExtraInformationModule.sol"; import {ERC20EnforcementModule} from "./wrapper/extensions/ERC20EnforcementModule.sol"; import {DocumentERC1643Module} from "./wrapper/extensions/DocumentERC1643Module.sol"; +import {IERC1643} from "../interfaces/tokenization/draft-IERC1643.sol"; +import {IERC8343} from "../interfaces/tokenization/draft-IERC8343.sol"; // options -import {ERC20BaseModule} from "./wrapper/core/ERC20BaseModule.sol"; +import {TokenAttributeModule} from "./wrapper/core/TokenAttributeModule.sol"; /* ==== Interface and other library === */ import {ICMTATConstructor} from "../interfaces/technical/ICMTATConstructor.sol"; import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol"; @@ -286,7 +296,8 @@

// AccessControlModule_init_unchained is called firstly due to inheritance __AccessControlModule_init_unchained(admin); // Core - __ERC20BaseModule_init_unchained(ERC20Attributes_.decimalsIrrevocable, ERC20Attributes_.name, ERC20Attributes_.symbol); + __ERC20BaseModule_init_unchained(ERC20Attributes_.decimalsIrrevocable); + __TokenAttributeModule_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol); /* Extensions */ __ExtraInformationModule_init_unchained(ExtraInformationModuleAttributes_.tokenId, ExtraInformationModuleAttributes_.terms, ExtraInformationModuleAttributes_.information); } @@ -300,10 +311,11 @@

* We can not use type(IERC5679).interfaceId instead of 0xd0017968 * because IERC5679 inherits from two interfaces (IERC5679Burn and Mint) * 0x3edbb4c4 is the interfaceId of ERC-7943 - * 0xe9cd80b0 is the interfaceId of ICMTATDeactivate + * type(IERC8343).interfaceId (0xe9cd80b0) is the proposed ERC-8343 (draft) contract deactivation interface + * type(IERC1643).interfaceId (0xecfecec8) is the ERC-1643 document management interface */ function supportsInterface(bytes4 interfaceId) public view virtual override(AccessControlUpgradeable, IERC165) returns (bool) { - return interfaceId == 0xd0017968 || interfaceId == 0x3edbb4c4 || interfaceId == 0xe9cd80b0 || AccessControlUpgradeable.supportsInterface(interfaceId); + return interfaceId == 0xd0017968 || interfaceId == 0x3edbb4c4 || interfaceId == type(IERC8343).interfaceId || interfaceId == type(IERC1643).interfaceId || AccessControlUpgradeable.supportsInterface(interfaceId); }     @@ -316,7 +328,7 @@

* @custom:access-control * - the caller must have the `DEFAULT_ADMIN_ROLE`. */ - function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) onlyRole(DEFAULT_ADMIN_ROLE){} + function _authorizeTokenAttributeManagement() internal virtual override(TokenAttributeModule) onlyRole(DEFAULT_ADMIN_ROLE){}   /** * @custom:access-control @@ -361,7 +373,7 @@

diff --git a/doc/test/coverage/modules/3_CMTATBaseAllowlist.sol.html b/doc/test/coverage/modules/3_CMTATBaseAllowlist.sol.html index 440d207a..903615c3 100644 --- a/doc/test/coverage/modules/3_CMTATBaseAllowlist.sol.html +++ b/doc/test/coverage/modules/3_CMTATBaseAllowlist.sol.html @@ -25,9 +25,9 @@

40/40
- 81.82% + 80% Branches - 18/22 + 16/20
100% @@ -367,7 +367,15 @@

322 323 324 -325  +325 +326 +327 +328 +329 +330 +331 +332 +333        @@ -423,7 +431,7 @@

      -594× +705×       @@ -441,16 +449,16 @@

      -594× +705×     -594× +705×     -594× +705×     -594× +705×       @@ -458,19 +466,19 @@

      -594× -594× +705× +705×   -594× +705×             -594× +705×   -594× +705×       @@ -489,8 +497,13 @@

      -68× -58× +  +  +  +  +  +116× +97×       @@ -499,7 +512,7 @@

      -54× +58×       @@ -508,7 +521,7 @@

      -35× +39×       @@ -549,11 +562,11 @@

      -240× -240× -60× +316× +316× +84×   -180× +232×       @@ -569,9 +582,9 @@

  31× 31× - +   -23× +25×       @@ -587,10 +600,10 @@

      -132× +200×     -28× +49×       @@ -606,7 +619,7 @@

      -740× +849×       @@ -616,11 +629,11 @@

      -207× +273×       -34× +38×       @@ -628,7 +641,7 @@

      -191× +245×       @@ -636,12 +649,12 @@

      -108× +118×       -992× -976× +1110× +1095×       @@ -651,7 +664,10 @@

      -116× +235× +  +  +        @@ -665,9 +681,9 @@

      +8559×     -7381×       @@ -675,8 +691,8 @@

      +8561×   -7383×       @@ -693,7 +709,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -805,15 +821,20 @@ 

Functions requiring several modules //////////////////////////////////////////////////////////////*/ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. * @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. + * @inheritdoc ERC20Upgradeable */ - function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) returns (bool) { + // The pause check lives in _canAuthorizeAllowanceByModuleAndRevert, which lets a + // revocation (value == 0) through. A `whenNotPaused` modifier here would block it. + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); }   @@ -984,6 +1005,7 @@

//////////////////////////////////////////////////////////////*/ /** * @dev This surcharge is not necessary if you do not use the ERC2771Module + * @inheritdoc ERC2771ContextUpgradeable */ function _msgSender() internal virtual @@ -996,8 +1018,9 @@

  /** * @dev This surcharge is not necessary if you do not use the ERC2771Module + * @inheritdoc ERC2771ContextUpgradeable */ - function _contextSuffixLength() internal virtual view + function _contextSuffixLength() internal virtual view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (uint256) { return ERC2771ContextUpgradeable._contextSuffixLength(); @@ -1005,6 +1028,7 @@

  /** * @dev This surcharge is not necessary if you do not use the ERC2771Module + * @inheritdoc ERC2771ContextUpgradeable */ function _msgData() internal virtual @@ -1021,7 +1045,7 @@

diff --git a/doc/test/coverage/modules/3_CMTATBaseRuleEngine.sol.html b/doc/test/coverage/modules/3_CMTATBaseRuleEngine.sol.html index 1779ad0b..41395bc7 100644 --- a/doc/test/coverage/modules/3_CMTATBaseRuleEngine.sol.html +++ b/doc/test/coverage/modules/3_CMTATBaseRuleEngine.sol.html @@ -25,9 +25,9 @@

24/24
- 80.77% + 79.17% Branches - 21/26 + 19/24
100% @@ -224,7 +224,12 @@

179 180 181 -182  +182 +183 +184 +185 +186 +187        @@ -270,7 +275,7 @@

      -4748× +5167×       @@ -287,7 +292,7 @@

      -4748× +5167×       @@ -306,18 +311,18 @@

      -4748× +5167×     -4748× +5167×     -4748× +5167×   -4748× +5167×     -4748× +5167×       @@ -325,24 +330,24 @@

      -4748× -4748× +5167× +5167×   -4748× +5167×             -4748× +5167×             -4748× +5167×       @@ -352,27 +357,27 @@

      -700× -662×           +958× +863×         -1579× -1579× -570×   -1009×         +1600× +1600× +532×   +1068×       @@ -380,16 +385,16 @@

      -251× -251× -76×   -175×         +215× +215× +38×   +177×       @@ -401,13 +406,18 @@

      -7434× -7282× +  +  +  +  +  +7858× +7763×      
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
 /* ==== OpenZeppelin === */
@@ -530,10 +540,15 @@ 

PUBLIC/EXTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. + * @inheritdoc ERC20Upgradeable */ - function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) { - _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender); + function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable) returns (bool) { + // The pause check lives in _canAuthorizeAllowanceByModuleAndRevert, which lets a + // revocation (value == 0) through. A `whenNotPaused` modifier here would block it. + _canAuthorizeAllowanceByModuleAndRevert(_msgSender(), spender, value); return ERC20Upgradeable.approve(spender, value); } /** @@ -592,7 +607,7 @@

diff --git a/doc/test/coverage/modules/4_CMTATBaseDebt.sol.html b/doc/test/coverage/modules/4_CMTATBaseDebt.sol.html index ffa1d3f6..8cc237a5 100644 --- a/doc/test/coverage/modules/4_CMTATBaseDebt.sol.html +++ b/doc/test/coverage/modules/4_CMTATBaseDebt.sol.html @@ -122,7 +122,7 @@

      -92× +136×       @@ -158,7 +158,7 @@

      -1250× +1326×       @@ -167,7 +167,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
 /* ==== Module === */
@@ -232,7 +232,7 @@ 

diff --git a/doc/test/coverage/modules/4_CMTATBaseERC1404.sol.html b/doc/test/coverage/modules/4_CMTATBaseERC1404.sol.html index 219fa36b..ae07497d 100644 --- a/doc/test/coverage/modules/4_CMTATBaseERC1404.sol.html +++ b/doc/test/coverage/modules/4_CMTATBaseERC1404.sol.html @@ -22,7 +22,7 @@

100% Statements - 14/14 + 10/10
100% @@ -32,12 +32,12 @@

100% Functions - 4/4 + 5/5
100% Lines - 14/14 + 10/10

@@ -129,7 +129,26 @@

84 85 86 -87  +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106        @@ -162,10 +181,10 @@

      -159× -66× +139× +44×   -93× +95×       @@ -178,7 +197,7 @@

      -1255× +1272×       @@ -190,7 +209,7 @@

      -207× +179×       @@ -201,33 +220,52 @@

      -377× -377× -198× -198× -22×   -176× -176× -132×     -223× +  +  +49× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +339× +339× +88× +  +251×      
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {CMTATBaseRuleEngine} from "./3_CMTATBaseRuleEngine.sol";
+import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
 /* ==== Wrapper === */
-// Use by detectTransferRestriction
+// re-exported to keep {CMTATBaseERC20CrossChain} importing ERC20Upgradeable through this file
 import {ERC20Upgradeable} from "./wrapper/core/ERC20BaseModule.sol";
-// Extensions
-import {ERC20EnforcementModule} from "./wrapper/extensions/ERC20EnforcementModule.sol";
 // Controllers
-import {ValidationModuleERC1404, IERC1404Extend} from "./wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol";
+import {ValidationModuleERC1404, IERC1404, IERC1404Extend} from "./wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol";
 import {ValidationModuleRuleEngine} from "./wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol";
+import {ERC1404ExtendInterfaceId} from "../library/ERC1404ExtendInterfaceId.sol";
  
 abstract contract CMTATBaseERC1404 is
     CMTATBaseRuleEngine,
@@ -278,26 +316,45 @@ 

) public virtual override (CMTATBaseRuleEngine, ValidationModuleRuleEngine) view returns (bool) { return CMTATBaseRuleEngine.canTransferFrom(spender, from, to, value); } +  + /** + * @notice ERC-165 interface detection + * @dev advertises support for both the canonical ERC-1404 interface + * (`IERC1404`, id `0xab84a5c8`) and its CMTAT extension + * (`IERC1404Extend`, id `0x78a8de7d`). + * @dev The extension id is taken from {ERC1404ExtendInterfaceId} because + * Solidity's `type(IERC1404Extend).interfaceId` excludes inherited + * functions and would therefore only cover `detectTransferRestrictionFrom`. + * @inheritdoc CMTATBaseAccessControl + */ + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(CMTATBaseAccessControl) returns (bool) { + return + interfaceId == type(IERC1404).interfaceId || + interfaceId == ERC1404ExtendInterfaceId.ERC1404EXTEND_INTERFACE_ID || + super.supportsInterface(interfaceId); + }   /*////////////////////////////////////////////////////////////// INTERNAL/PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////*/ + /** + * @dev Delegates the frozen-balance check to {ERC20EnforcementModuleInternal-_checkActiveBalance}, + * the same predicate the transfer path enforces, so the predicted restriction and the actual + * transfer outcome cannot drift. In particular a zero-value transfer, which `_checkActiveBalance` + * treats as always valid, is reported as unrestricted here as well. + * @return code The restriction code (0 = no restriction). + */ function _detectTransferRestriction( address from, address to, uint256 value ) internal virtual override( ValidationModuleERC1404) view returns (uint8 code) { - uint256 frozenTokensLocal = ERC20EnforcementModule.getFrozenTokens(from); - if(frozenTokensLocal > 0 ){ - 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); - } - } + (bool isValid, ) = _checkActiveBalance(from, value); + if (!isValid) { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE); + } return ValidationModuleERC1404._detectTransferRestriction(from, to, value); } } @@ -307,7 +364,7 @@

diff --git a/doc/test/coverage/modules/5_CMTATBaseERC20CrossChain.sol.html b/doc/test/coverage/modules/5_CMTATBaseERC20CrossChain.sol.html index 3c8da20c..0f4bf2d7 100644 --- a/doc/test/coverage/modules/5_CMTATBaseERC20CrossChain.sol.html +++ b/doc/test/coverage/modules/5_CMTATBaseERC20CrossChain.sol.html @@ -185,7 +185,12 @@

140 141 142 -143  +143 +144 +145 +146 +147 +148        @@ -208,12 +213,12 @@

      -627×     -295× +822×     +302×       @@ -226,7 +231,9 @@

      -199× +  +  +223×       @@ -249,18 +256,21 @@

      -59× +67× +  +  +        +49×       -47× +73×       -66×       @@ -270,17 +280,17 @@

      +4842×     -4518×             +863×   -869×       @@ -288,7 +298,7 @@

      -207× +222×       @@ -309,7 +319,7 @@

      -218× +206×       @@ -329,12 +339,11 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
 /* ==== Module === */
 import {CMTATBaseERC1404, CMTATBaseRuleEngine, ERC20Upgradeable} from "./4_CMTATBaseERC1404.sol";
-import {CMTATBaseAccessControl} from "./2_CMTATBaseAccessControl.sol";
 import {CMTATBaseCommon} from "./0_CMTATBaseCommon.sol";
 import {ERC20BurnModuleInternal} from "./wrapper/core/ERC20BurnModule.sol";
 import {ERC20MintModuleInternal} from "./wrapper/core/ERC20MintModule.sol";
@@ -347,7 +356,10 @@ 

abstract contract CMTATBaseERC20CrossChain is ERC20CrossChainModule, CCIPModule, CMTATBaseERC1404 { /* ============ State Functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. + * @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseRuleEngine) returns (bool) { return CMTATBaseRuleEngine.approve(spender, value); @@ -401,8 +413,8 @@

return CMTATBaseCommon.symbol(); }   - function supportsInterface(bytes4 _interfaceId) public view virtual override(CMTATBaseAccessControl, ERC20CrossChainModule) returns (bool) { - return ERC20CrossChainModule.supportsInterface(_interfaceId)|| CMTATBaseAccessControl.supportsInterface( _interfaceId); + function supportsInterface(bytes4 _interfaceId) public view virtual override(CMTATBaseERC1404, ERC20CrossChainModule) returns (bool) { + return ERC20CrossChainModule.supportsInterface(_interfaceId)|| CMTATBaseERC1404.supportsInterface( _interfaceId); }   /*////////////////////////////////////////////////////////////// @@ -411,6 +423,7 @@

/* ==== Mint and Burn Operations ==== */ /** * @dev Check if the mint is valid + * @inheritdoc ERC20MintModuleInternal */ function _mintOverride(address account, uint256 value) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) { // _checkTransferred is called by _mintOverride @@ -419,6 +432,7 @@

  /** * @dev Check if the burn is valid + * @inheritdoc ERC20BurnModuleInternal */ function _burnOverride(address account, uint256 value) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) { // _checkTransferred is called by _burnOverride @@ -427,6 +441,7 @@

  /** * @dev Check if a minter transfer is valid + * @inheritdoc ERC20MintModuleInternal */ function _minterTransferOverride(address from, address to, uint256 value) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) { // _checkTransferred is called by _minterTransferOverride @@ -475,7 +490,7 @@

diff --git a/doc/test/coverage/modules/6_CMTATBaseDebtEngine.sol.html b/doc/test/coverage/modules/6_CMTATBaseDebtEngine.sol.html index 46e263ea..8e9e0239 100644 --- a/doc/test/coverage/modules/6_CMTATBaseDebtEngine.sol.html +++ b/doc/test/coverage/modules/6_CMTATBaseDebtEngine.sol.html @@ -138,13 +138,13 @@

      -923× +978×           -60× +58×       @@ -156,7 +156,7 @@

      -69× +102×       @@ -187,7 +187,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -262,7 +262,7 @@ 

diff --git a/doc/test/coverage/modules/6_CMTATBaseERC2612.sol.html b/doc/test/coverage/modules/6_CMTATBaseERC2612.sol.html index 1befb769..a77b5fde 100644 --- a/doc/test/coverage/modules/6_CMTATBaseERC2612.sol.html +++ b/doc/test/coverage/modules/6_CMTATBaseERC2612.sol.html @@ -173,7 +173,17 @@

128 129 130 -131  +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141        @@ -199,10 +209,16 @@

      -460× -460× -460× -460× +500× +500× +500× +500× +  +  +  +  +  +        @@ -221,9 +237,9 @@

      -10× -   +22× +16×       @@ -233,17 +249,21 @@

      -92×         +114×           -31× +  +  +  +  +30×       @@ -286,7 +306,7 @@

      -18× +26×       @@ -299,13 +319,13 @@

      - +10×        
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20PermitUpgradeable.sol";
@@ -340,7 +360,14 @@ 

//////////////////////////////////////////////////////////////*/ /** * @inheritdoc ERC20PermitUpgradeable - * @dev Reverts if the contract is paused or if owner/spender is frozen. + * @dev Reverts if the contract is paused or if owner/spender is frozen, unless `value` + * is zero: a zero-value permit is a gasless revocation and stays available so an owner + * can always sever ties with a spender, even while restricted. + * + * The EIP-712 domain name is fixed at initialization and is **not** updated by + * {TokenAttributeModule-setName}. Signers must build the domain from the ERC-5267 + * {eip712Domain} function (or `DOMAIN_SEPARATOR()`), not from {name}, which may have + * been changed since deployment. */ function permit( address owner, @@ -351,13 +378,16 @@

bytes32 r, bytes32 s ) public virtual override(ERC20PermitUpgradeable) { - _canAuthorizeAllowanceByModuleAndRevert(owner, spender); + _canAuthorizeAllowanceByModuleAndRevert(owner, spender, value); ERC20PermitUpgradeable.permit(owner, spender, value, deadline, v, r, s); }   /* ============ State functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. + * @inheritdoc ERC20Upgradeable */ function approve( address spender, @@ -439,7 +469,7 @@

diff --git a/doc/test/coverage/modules/6_CMTATBaseERC2771.sol.html b/doc/test/coverage/modules/6_CMTATBaseERC2771.sol.html index 831cfd13..82475122 100644 --- a/doc/test/coverage/modules/6_CMTATBaseERC2771.sol.html +++ b/doc/test/coverage/modules/6_CMTATBaseERC2771.sol.html @@ -92,7 +92,10 @@

47 48 49 -50  +50 +51 +52 +53        @@ -117,8 +120,8 @@

      -18475×   +20226×       @@ -126,7 +129,10 @@

      -18481× +  +  +20232× +        @@ -143,7 +149,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
 /* ==== Module === */
@@ -159,6 +165,7 @@ 

//////////////////////////////////////////////////////////////*/ /** * @dev This surcharge is not necessary if you do not use the 2771Module + * @inheritdoc ERC2771ContextUpgradeable */ function _msgSender() internal virtual @@ -171,8 +178,9 @@

  /** * @dev This surcharge is not necessary if you do not use the 2771Module + * @inheritdoc ERC2771ContextUpgradeable */ - function _contextSuffixLength() internal virtual view + function _contextSuffixLength() internal virtual view override(ContextUpgradeable, ERC2771ContextUpgradeable) returns (uint256) { return ERC2771ContextUpgradeable._contextSuffixLength(); @@ -180,6 +188,7 @@

  /** * @dev This surcharge is not necessary if you do not use the 2771Module + * @inheritdoc ERC2771ContextUpgradeable */ function _msgData() internal virtual @@ -196,7 +205,7 @@

diff --git a/doc/test/coverage/modules/7_CMTATBaseERC2771Snapshot.sol.html b/doc/test/coverage/modules/7_CMTATBaseERC2771Snapshot.sol.html index fb1beb80..366cb80c 100644 --- a/doc/test/coverage/modules/7_CMTATBaseERC2771Snapshot.sol.html +++ b/doc/test/coverage/modules/7_CMTATBaseERC2771Snapshot.sol.html @@ -156,7 +156,7 @@

      -778× +814×       @@ -174,7 +174,7 @@

      -92× +114×       @@ -202,7 +202,7 @@

      -3814× +4035×       @@ -214,7 +214,7 @@

      -3816× +4037×       @@ -225,7 +225,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -319,7 +319,7 @@ 

diff --git a/doc/test/coverage/modules/7_CMTATBaseERC7551Enforcement.sol.html b/doc/test/coverage/modules/7_CMTATBaseERC7551Enforcement.sol.html index ac520563..9ac03d32 100644 --- a/doc/test/coverage/modules/7_CMTATBaseERC7551Enforcement.sol.html +++ b/doc/test/coverage/modules/7_CMTATBaseERC7551Enforcement.sol.html @@ -179,11 +179,11 @@

      -390× +424×       -78× +98×       @@ -194,7 +194,7 @@

      -11591× +12904×       @@ -210,7 +210,7 @@

      -11595× +12908×       @@ -221,7 +221,7 @@

      -114× +125×       @@ -229,7 +229,7 @@

      -90× +114×       @@ -237,7 +237,7 @@

      -282× +378×       @@ -269,13 +269,13 @@

      -336× +358×        
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
@@ -394,7 +394,7 @@ 

diff --git a/doc/test/coverage/modules/8_CMTATBaseERC1363.sol.html b/doc/test/coverage/modules/8_CMTATBaseERC1363.sol.html index fe878b19..28336bb2 100644 --- a/doc/test/coverage/modules/8_CMTATBaseERC1363.sol.html +++ b/doc/test/coverage/modules/8_CMTATBaseERC1363.sol.html @@ -185,7 +185,12 @@

140 141 142 -143  +143 +144 +145 +146 +147 +148        @@ -210,8 +215,8 @@

      -499× -499× +533× +533×       @@ -223,14 +228,17 @@

      -93×       +115×       -39× +  +  +  +37×       @@ -254,7 +262,9 @@

      -18× +  +  +23×       @@ -303,7 +313,7 @@

      -3508× +3728×       @@ -312,7 +322,7 @@

      -3510× +3730×       @@ -329,7 +339,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
 import {ERC1363Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC1363Upgradeable.sol";
@@ -362,7 +372,10 @@ 

/* ============ State functions ============ */ /** - * @dev revert if the contract is in pause state + * @dev revert if the contract is in pause state, unless `value` is zero: + * setting an allowance to zero is a revocation and stays available while paused + * or while the owner/spender is frozen or off the allowlist. + * @inheritdoc ERC20Upgradeable */ function approve(address spender, uint256 value) public virtual override(ERC20Upgradeable, CMTATBaseERC7551Enforcement, IERC20) returns (bool) { return CMTATBaseERC7551Enforcement.approve(spender, value); @@ -393,7 +406,9 @@

  /* ============ View functions ============ */ /** - * + * @notice Returns true if this contract implements the interface defined by `interfaceId`. + * @param interfaceId The ERC-165 interface identifier to query. + * @return True if `interfaceId` is supported by ERC-1363 or any inherited module. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1363Upgradeable, CMTATBaseERC20CrossChain) returns (bool) { return ERC1363Upgradeable.supportsInterface(interfaceId) || CMTATBaseERC20CrossChain.supportsInterface(interfaceId); @@ -475,7 +490,7 @@

diff --git a/doc/test/coverage/modules/8_CMTATBaseERC7551.sol.html b/doc/test/coverage/modules/8_CMTATBaseERC7551.sol.html index 14414f8c..7ae991e7 100644 --- a/doc/test/coverage/modules/8_CMTATBaseERC7551.sol.html +++ b/doc/test/coverage/modules/8_CMTATBaseERC7551.sol.html @@ -84,12 +84,12 @@

      -20× +22×      
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 /* ==== Module === */
@@ -115,7 +115,7 @@ 

diff --git a/doc/test/coverage/modules/8_CMTATBaseHolderList.sol.html b/doc/test/coverage/modules/8_CMTATBaseHolderList.sol.html new file mode 100644 index 00000000..cc5d18e8 --- /dev/null +++ b/doc/test/coverage/modules/8_CMTATBaseHolderList.sol.html @@ -0,0 +1,527 @@ + + + + Code coverage report for modules/8_CMTATBaseHolderList.sol + + + + + + + +
+
+

+ all files / modules/ 8_CMTATBaseHolderList.sol +

+
+
+ 36.36% + Statements + 4/11 +
+
+ 0% + Branches + 0/2 +
+
+ 36.36% + Functions + 4/11 +
+
+ 36.36% + Lines + 4/11 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +114× +  +  +  +  +  +  +  +  +  +  +  +  +  +372× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +372× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+/* ==== OpenZeppelin === */
+import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+/* ==== Module === */
+import {CMTATBaseERC20CrossChain} from "./5_CMTATBaseERC20CrossChain.sol";
+import {CMTATBaseERC7551Enforcement} from "./7_CMTATBaseERC7551Enforcement.sol";
+import {HolderListModule} from "./wrapper/options/HolderListModule.sol";
+/* ==== Interface and other library === */
+import {IHolderListModule} from "../interfaces/modules/IHolderListModule.sol";
+ 
+/**
+ * @title Extend the CMTAT standard path with the on-chain holder list
+ * @dev Same modules as the CMTAT standard version, plus {HolderListModule}.
+ *
+ * {HolderListModule} inherits {ERC20Upgradeable}, so the ERC-20 entry points are reachable
+ * through two branches of the inheritance graph and have to be disambiguated here. They all
+ * resolve to {CMTATBaseERC7551Enforcement}, which keeps the validation performed by the
+ * standard path. Only {_update} resolves to {HolderListModule}, which calls `super._update`
+ * and therefore still reaches {ERC20Upgradeable-_update}.
+ */
+abstract contract CMTATBaseHolderList is CMTATBaseERC7551Enforcement, HolderListModule {
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============ State functions ============ */
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function transfer(address to, uint256 value)
+        public virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (bool)
+    {
+        return CMTATBaseERC7551Enforcement.transfer(to, value);
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function transferFrom(address from, address to, uint256 value)
+        public virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (bool)
+    {
+        return CMTATBaseERC7551Enforcement.transferFrom(from, to, value);
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function approve(address spender, uint256 value)
+        public virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (bool)
+    {
+        return CMTATBaseERC7551Enforcement.approve(spender, value);
+    }
+ 
+    /* ============ View functions ============ */
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function name()
+        public view virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (string memory)
+    {
+        return CMTATBaseERC7551Enforcement.name();
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function symbol()
+        public view virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (string memory)
+    {
+        return CMTATBaseERC7551Enforcement.symbol();
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function decimals()
+        public view virtual
+        override(ERC20Upgradeable, CMTATBaseERC7551Enforcement)
+        returns (uint8)
+    {
+        return CMTATBaseERC7551Enforcement.decimals();
+    }
+ 
+    function supportsInterface(bytes4 interfaceId)
+        public view virtual
+        override(CMTATBaseERC20CrossChain)
+        returns (bool)
+    {
+        return interfaceId == type(IHolderListModule).interfaceId
+            || CMTATBaseERC20CrossChain.supportsInterface(interfaceId);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /**
+    * @inheritdoc HolderListModule
+    */
+    function _update(address from, address to, uint256 value)
+        internal virtual
+        override(ERC20Upgradeable, HolderListModule)
+    {
+        HolderListModule._update(from, to, value);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            ERC2771 MODULE
+    //////////////////////////////////////////////////////////////*/
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function _msgSender()
+        internal view virtual
+        override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
+        returns (address sender)
+    {
+        return CMTATBaseERC7551Enforcement._msgSender();
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function _msgData()
+        internal view virtual
+        override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
+        returns (bytes calldata)
+    {
+        return CMTATBaseERC7551Enforcement._msgData();
+    }
+ 
+    /**
+    * @inheritdoc CMTATBaseERC7551Enforcement
+    */
+    function _contextSuffixLength()
+        internal view virtual
+        override(ContextUpgradeable, CMTATBaseERC7551Enforcement)
+        returns (uint256)
+    {
+        return CMTATBaseERC7551Enforcement._contextSuffixLength();
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/modules/index.html b/doc/test/coverage/modules/index.html index fb6be627..5d5f71fb 100644 --- a/doc/test/coverage/modules/index.html +++ b/doc/test/coverage/modules/index.html @@ -20,24 +20,24 @@

- 100% + 97% Statements - 224/224 + 226/233
- 87.33% + 86% Branches - 131/150 + 129/150
- 100% + 96.26% Functions - 175/175 + 180/187
- 100% + 97.01% Lines - 225/225 + 227/234
@@ -75,13 +75,13 @@

0_CMTATBaseCore.sol
100% - 33/33 + 34/34 86.67% 26/30 100% 24/24 100% - 34/34 + 35/35 @@ -127,13 +127,13 @@

2_CMTATBaseAccessControl.sol
100% - 4/4 - 95.45% - 21/22 + 5/5 + 95.83% + 23/24 100% 9/9 100% - 4/4 + 5/5 @@ -141,8 +141,8 @@

100% 40/40 - 81.82% - 18/22 + 80% + 16/20 100% 30/30 100% @@ -154,8 +154,8 @@

100% 24/24 - 80.77% - 21/26 + 79.17% + 19/24 100% 14/14 100% @@ -179,13 +179,13 @@

4_CMTATBaseERC1404.sol
100% - 14/14 + 10/10 100% 8/8 100% - 4/4 + 5/5 100% - 14/14 + 10/10 @@ -292,13 +292,26 @@

1/1 + + 8_CMTATBaseHolderList.sol +
+ 36.36% + 4/11 + 0% + 0/2 + 36.36% + 4/11 + 36.36% + 4/11 + +
diff --git a/doc/test/coverage/modules/internal/AllowlistModuleInternal.sol.html b/doc/test/coverage/modules/internal/AllowlistModuleInternal.sol.html index bfeea6f5..cfd846bf 100644 --- a/doc/test/coverage/modules/internal/AllowlistModuleInternal.sol.html +++ b/doc/test/coverage/modules/internal/AllowlistModuleInternal.sol.html @@ -132,7 +132,9 @@

87 88 89 -90  +90 +91 +92        @@ -161,8 +163,8 @@

      -594× -594× +705× +705×       @@ -171,19 +173,19 @@

      -296× -296× +326× +326×       -2396× +2626×       -532× -528× -528× -2100× +584× +580× +580× +2300×       @@ -191,8 +193,8 @@

      -142× -142× +211× +211×       @@ -200,30 +202,32 @@

      -1438× -1438×   +1580× +1580×           -1424× -1424×     +1667× +1667×         -4422× +  +  +5069×          
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -287,6 +291,7 @@ 

/* ============ View functions ============ */ /** * @dev Returns true if the account is listed, and false otherwise. + * @return True if the account is allowlisted, false otherwise. */ function _isAllowlisted(address account) internal view virtual returns (bool) { AllowlistModuleInternalStorage storage $ = _getAllowlistModuleInternalStorage(); @@ -295,6 +300,7 @@

  /** * @dev Returns true if the list is enabled, false otherwise + * @return True if the allowlist is enabled, false otherwise. */ function _isAllowlistEnabled() internal view virtual returns (bool) { AllowlistModuleInternalStorage storage $ = _getAllowlistModuleInternalStorage(); @@ -316,7 +322,7 @@

diff --git a/doc/test/coverage/modules/internal/ERC20BurnModuleInternal.sol.html b/doc/test/coverage/modules/internal/ERC20BurnModuleInternal.sol.html index e1c36e99..be719894 100644 --- a/doc/test/coverage/modules/internal/ERC20BurnModuleInternal.sol.html +++ b/doc/test/coverage/modules/internal/ERC20BurnModuleInternal.sol.html @@ -94,7 +94,13 @@

49 50 51 -52  +52 +53 +54 +55 +56  +  +        @@ -140,14 +146,16 @@

      -1017× +  +  +1023×          
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -169,6 +177,8 @@ 

//////////////////////////////////////////////////////////////*/ /** * @dev internal function to burn in batch + * @param accounts The accounts to burn tokens from. + * @param values The amounts of tokens to burn, aligned with `accounts`. */ function _batchBurn( address[] calldata accounts, @@ -186,6 +196,8 @@

/** * @dev Internal function to burn * Can be override to perform supplementary check on burn action + * @param account The account to burn tokens from. + * @param value The amount of tokens to burn. */ function _burnOverride( address account, @@ -202,7 +214,7 @@

diff --git a/doc/test/coverage/modules/internal/ERC20EnforcementModuleInternal.sol.html b/doc/test/coverage/modules/internal/ERC20EnforcementModuleInternal.sol.html index ea8399c1..ede80c7e 100644 --- a/doc/test/coverage/modules/internal/ERC20EnforcementModuleInternal.sol.html +++ b/doc/test/coverage/modules/internal/ERC20EnforcementModuleInternal.sol.html @@ -22,12 +22,12 @@

100% Statements - 62/62 + 64/64
100% Branches - 36/36 + 40/40
100% @@ -37,7 +37,7 @@

100% Lines - 77/77 + 79/79

@@ -233,7 +233,26 @@

188 189 190 -191  +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210        @@ -266,169 +285,190 @@

      -378× -378×   -378× -84× -84× -84×     -273× -273× -273×   -21×   -357×     +476× +88×   +388× +388× +  +388× +88× +88× +88× +  +  +278× +278× +278× +  +22× +  +366× +  +  +  +652× +30× +  +622× +  +622× 622× -29×   -593× +622×   -593× -593× +600× +600×   -593×   -572× -572×   +236× +30×   +206× +206×   -226× -29× +184× +184× +184×   -197× -197×   -176× -176× -176×         +276× +276× +22×   +254× +254×   -220× -220× -21× +254×   -199× -199× +254× +232×   -199× +254× +66× +66× +66× +66×   -199× -178×   -199× -63× -63× -63× -63×         -220× -199× -42×       -157× -157× -42× -21× -21×     -21× -21×   +298× +276× +254× +44×       -157× +210× +210×   -199× +44× +44× +44×       -845× +44×   +210×   +254×   -323×     +878×     -8426× -8426× -8426× -8426×   +338×         +8968× +8968× +8968× +8968×   -10527× -10527× -1533×   -1533× -105× -42×   -63×   -1428× -1428× -819×         -9603× +11469× +11469× +1628×   +1628× +132× +66×   +66×   -12921× -12921× +1496× +1496× +792×       -432× -432× -432×   -432× +10545× +  +  +  +13719× +13719× +  +  +  +440× +440× +440× +  +440× 32×   -400× +408×         -14720× +15629×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+/* ==== Technical === */
+import {IERC20Allowance} from "../../interfaces/technical/IERC20Allowance.sol";
 /* ==== Tokenization === */
 import {IERC7943FungibleEnforcementEventAndError} from "../../interfaces/tokenization/draft-IERC7943.sol";
  
@@ -443,7 +483,8 @@ 

error CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed(); error CMTAT_ERC20EnforcementModule_ValueExceedsAvailableBalance(); error CMTAT_ERC20EnforcementModule_ValueExceedsFrozenBalance(); - error CMTAT_ERC20EnforcementModule_ValueEqualCurrentFrozenTokens(); + error CMTAT_ERC20EnforcementModule_ValueEqualCurrentFrozenTokens(); + error CMTAT_ERC20EnforcementModule_SelfTransferNotAllowed(); /* ============ ERC-7201 ============ */ // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.ERC20EnforcementModule")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant ERC20EnforcementModuleStorageLocation = 0x9d8059a24cb596f1948a937c2c163cf14465c2a24abfd3cd009eec4ac4c39800; @@ -456,6 +497,13 @@

INTERNAL/PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////*/ function _setFrozenTokens(address account, uint256 value) internal virtual returns(bool) { + // The zero address holds no balance, so a non-zero frozen amount on it would make + // _checkActiveBalance(address(0), value) fail for every value > 0 and revert the common + // mint path (mint, batchMint, crosschainMint, the mint leg of burnAndMint). + // Same guard as _freezePartialTokens / _unfreezePartialTokens. + if (account == address(0)) { + revert CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed(); + } ERC20EnforcementModuleStorage storage $ = _getEnforcementModuleStorage(); uint256 frozenTokensLocal = $._frozenTokens[account]; // Unfreeze path @@ -525,7 +573,16 @@

} }   + /** + * @dev + * Moves tokens through the ERC-20 `_update` primitive directly, without the pause/deactivation + * validation applied to holder transfers and standard issuance. This is intentional: forced + * transfer/burn is the enforcer's regulatory tool and, per ERC-8343, a named privileged operation + * that remains available **after deactivation** (e.g. to sweep a frozen or migrated position). + */ function _forcedTransfer(address from, address to, uint256 value) internal virtual { + // A self forced transfer moves no token, but _unfreezeTokens would still release the frozen ones + require(from != to, CMTAT_ERC20EnforcementModule_SelfTransferNotAllowed()); _unfreezeTokens(from, value); if(to == address(0)){ ERC20Upgradeable._burn(from, value); @@ -534,16 +591,14 @@

// See https://ethereum-magicians.org/t/erc-3643-the-t-rex-token-standard/6844/11 uint256 currentAllowance = allowance(from, to); if (currentAllowance > 0 && currentAllowance < type(uint256).max) { - if (currentAllowance < value) { - unchecked { - ERC20Upgradeable._approve(from, to, 0, false); - } - } else{ - unchecked { - ERC20Upgradeable._approve(from, to, currentAllowance - value, false); - } + // Amount actually taken from the from->to allowance (capped by the allowance) + uint256 spentAllowance = currentAllowance < value ? currentAllowance : value; + unchecked { + ERC20Upgradeable._approve(from, to, currentAllowance - spentAllowance, false); } - + // Emit Spend so the allowance consumption is observable, consistent with + // transferFrom / burnFrom. `_approve(..., false)` above still suppresses Approval. + emit IERC20Allowance.Spend(from, to, spentAllowance); } ERC20Upgradeable._transfer(from, to, value); } @@ -568,6 +623,8 @@

  /** * @dev we only check the balance if frozenTokens > 0 + * @return isValid True if `from` has enough unfrozen balance to move `value`. + * @return activeBalance The unfrozen (active) balance available for `from`. */ function _checkActiveBalance(address from, uint256 value) internal virtual view returns(bool isValid, uint256 activeBalance){ uint256 frozenTokensLocal = _getFrozenTokens(from); @@ -619,7 +676,7 @@

diff --git a/doc/test/coverage/modules/internal/ERC20MintModuleInternal.sol.html b/doc/test/coverage/modules/internal/ERC20MintModuleInternal.sol.html index 35de0daf..2c1e2342 100644 --- a/doc/test/coverage/modules/internal/ERC20MintModuleInternal.sol.html +++ b/doc/test/coverage/modules/internal/ERC20MintModuleInternal.sol.html @@ -115,7 +115,9 @@

70 71 72 -73  +73 +74 +75        @@ -148,12 +150,12 @@

      -730× +780×     -706× -658× -1836× +756× +708× +1936×       @@ -161,13 +163,13 @@

      +262× 238× -214×     -214× -166× -310× +238× +190× +334×       @@ -178,7 +180,9 @@

      -6409× +  +  +6931×       @@ -189,7 +193,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
@@ -248,6 +252,8 @@ 

  /** * @dev Can be override to emit event + * @param account The account to mint tokens to. + * @param value The amount of tokens to mint. */ function _mintOverride(address account, uint256 value) internal virtual { ERC20Upgradeable._mint(account, value); @@ -265,7 +271,7 @@

diff --git a/doc/test/coverage/modules/internal/EnforcementModuleInternal.sol.html b/doc/test/coverage/modules/internal/EnforcementModuleInternal.sol.html index a006b29b..d2f79fe4 100644 --- a/doc/test/coverage/modules/internal/EnforcementModuleInternal.sol.html +++ b/doc/test/coverage/modules/internal/EnforcementModuleInternal.sol.html @@ -111,7 +111,8 @@

66 67 68 -69  +69 +70        @@ -144,22 +145,23 @@

      -571× -571× +719× +719×       -721× +919× 75×   -646× +844×       -125× -75× -75× 150× +100× +100× +200× +        @@ -168,20 +170,20 @@

      -16612× -16612× +18213× +18213×         -17258× +19032×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
@@ -234,6 +236,7 @@ 

/* ============ View functions ============ */ /** * @dev Returns true if the account is frozen, and false otherwise. + * @return _isListed True if the account is listed (frozen), false otherwise. */ function _addressIsListed(address account) internal view virtual returns (bool _isListed) { EnforcementModuleInternalStorage storage $ = _getEnforcementModuleInternalStorage(); @@ -253,7 +256,7 @@

diff --git a/doc/test/coverage/modules/internal/ValidationModuleRuleEngineInternal.sol.html b/doc/test/coverage/modules/internal/ValidationModuleRuleEngineInternal.sol.html index 5d92c517..386c6e03 100644 --- a/doc/test/coverage/modules/internal/ValidationModuleRuleEngineInternal.sol.html +++ b/doc/test/coverage/modules/internal/ValidationModuleRuleEngineInternal.sol.html @@ -159,7 +159,7 @@

      -4748× +5167× 83×     @@ -174,8 +174,8 @@

      -8704× -8704× +9132× +9132×       @@ -189,21 +189,21 @@

      -441× -441× -441× +447× +447× +447×         -9145× +9579×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
@@ -286,7 +286,7 @@ 

diff --git a/doc/test/coverage/modules/internal/common/EnforcementModuleLibrary.sol.html b/doc/test/coverage/modules/internal/common/EnforcementModuleLibrary.sol.html index eb8df070..d4ceef49 100644 --- a/doc/test/coverage/modules/internal/common/EnforcementModuleLibrary.sol.html +++ b/doc/test/coverage/modules/internal/common/EnforcementModuleLibrary.sol.html @@ -79,15 +79,15 @@

      -657× +734×     -630× +707×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /**
  * @dev Enforcement module library
@@ -112,7 +112,7 @@ 

diff --git a/doc/test/coverage/modules/internal/common/index.html b/doc/test/coverage/modules/internal/common/index.html index cb751d5a..a54c07bd 100644 --- a/doc/test/coverage/modules/internal/common/index.html +++ b/doc/test/coverage/modules/internal/common/index.html @@ -77,7 +77,7 @@

diff --git a/doc/test/coverage/modules/internal/index.html b/doc/test/coverage/modules/internal/index.html index 1e741c0a..79dbc152 100644 --- a/doc/test/coverage/modules/internal/index.html +++ b/doc/test/coverage/modules/internal/index.html @@ -22,12 +22,12 @@

100% Statements - 106/106 + 108/108
- 96.43% + 96.67% Branches - 54/56 + 58/60
100% @@ -37,7 +37,7 @@

100% Lines - 130/130 + 132/132

@@ -88,13 +88,13 @@

ERC20EnforcementModuleInternal.sol
100% - 62/62 + 64/64 100% - 36/36 + 40/40 100% 12/12 100% - 77/77 + 79/79 @@ -142,7 +142,7 @@

diff --git a/doc/test/coverage/modules/wrapper/controllers/ValidationModule.sol.html b/doc/test/coverage/modules/wrapper/controllers/ValidationModule.sol.html index c0263de6..d30ea6c1 100644 --- a/doc/test/coverage/modules/wrapper/controllers/ValidationModule.sol.html +++ b/doc/test/coverage/modules/wrapper/controllers/ValidationModule.sol.html @@ -240,7 +240,22 @@

195 196 197 -198  +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213        @@ -266,12 +281,16 @@

      -352× +456× +  +  +  +  +50×         -46×       @@ -287,14 +306,14 @@

      -1437× +1558× 34×     14×     -1389× +1510×       @@ -304,14 +323,15 @@

      -8325× -6229× +8929× +6737×     -1175× +1169×     -921× +1023× +        @@ -339,8 +359,9 @@

      -6606× -6557× +  +7131× +7082× 60×     @@ -352,8 +373,9 @@

      -1247× -1175× +  +1241× +1169× 84×     @@ -368,22 +390,26 @@

      -1353×     -240×   -1113×   +1464×     +312×   +1152×         -744× -24× +  +  +  +  +842× +48×   24×   @@ -396,11 +422,12 @@

      -1353× +1464× +  +460×   -384× +1004×   -969×       @@ -413,9 +440,9 @@

      +1013× +842×   -911× -744×       @@ -425,7 +452,10 @@

      -1906× +  +2342× +  +        @@ -439,7 +469,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {PauseModule}  from "../core/PauseModule.sol";
@@ -475,8 +505,12 @@ 

//////////////////////////////////////////////////////////////*/ /* ============ View functions ============ */ /** - * @dev + * @dev * Entrypoint to check mint/burn/standard transfer + * @param spender The address initiating the transfer (address(0) for a direct transfer). + * @param from The address tokens move from (address(0) for a mint). + * @param to The address tokens move to (address(0) for a burn). + * @return True if the mint/burn/transfer is allowed by the pause and enforcement modules. */ function _canTransferGenericByModule( address spender, @@ -516,7 +550,8 @@

* @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 - */ + * @return True if the mint/burn is allowed (contract not deactivated and `target` not frozen). + */ function _canMintBurnByModule( address target ) internal view virtual returns (bool) { @@ -532,6 +567,7 @@

/** * @dev Reverts if mint is not allowed for `to`. * Checks deactivation and frozen status of the recipient. + * @param to The recipient whose mint is being validated. */ function _canMintByModuleAndRevert( address to @@ -545,6 +581,7 @@

/** * @dev Reverts if burn is not allowed for `from`. * Checks deactivation and frozen status of the token holder. + * @param from The holder whose burn is being validated. */ function _canBurnByModuleAndRevert( address from @@ -559,6 +596,10 @@

* @dev calls Pause and Enforcement module * check relevant for standard transfer * We don't check deactivated() because the contract must be in the pause state to be deactivated + * @param spender The address initiating the transfer. + * @param from The address tokens move from. + * @param to The address tokens move to. + * @return True if any of `spender`, `from` or `to` is frozen. */ function _canTransferisFrozen( address spender, @@ -620,6 +661,8 @@

* @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. + * @param account The account being checked. + * @return allowed True if `account` is allowed to send tokens. */ function _canSend(address account) internal view virtual returns (bool allowed) { return !EnforcementModule.isFrozen(account); @@ -629,6 +672,8 @@

* @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. + * @param account The account being checked. + * @return allowed True if `account` is allowed to receive tokens. */ function _canReceive(address account) internal view virtual returns (bool allowed) { return !EnforcementModule.isFrozen(account); @@ -640,7 +685,7 @@

diff --git a/doc/test/coverage/modules/wrapper/controllers/ValidationModuleAllowlist.sol.html b/doc/test/coverage/modules/wrapper/controllers/ValidationModuleAllowlist.sol.html index 2b0e18d3..749835aa 100644 --- a/doc/test/coverage/modules/wrapper/controllers/ValidationModuleAllowlist.sol.html +++ b/doc/test/coverage/modules/wrapper/controllers/ValidationModuleAllowlist.sol.html @@ -173,7 +173,19 @@

128 129 130 -131  +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141  +  +        @@ -214,13 +226,17 @@

      -191× -166× -166× -36×     -155× +  +  +245× +184× +184× +46× +  +  +199×       @@ -231,25 +247,29 @@

      -191× -36×   -155×       +245× +46×   -207× -26× +199×   -181×       +273× +30×   +243×   -34× -18× +  +  +  +  +38× +22×   16×   @@ -260,10 +280,10 @@

      -740× +849×   -736× +845×       @@ -283,8 +303,8 @@

      +118× 108× -98×       @@ -292,8 +312,8 @@

      -108× -79× +118× +85×   @@ -305,7 +325,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ValidationModule} from "./ValidationModule.sol";
@@ -325,6 +345,8 @@ 

/* ============ View functions ============ */ /** * @dev Use forcedTransfer (or forcedBurn) to burn tokens from an non-allowlist address + * @param account The account whose mint/burn is being validated. + * @return True if the mint/burn is allowed (allowlist check plus the base checks). */ function _canMintBurnByModule( address account @@ -338,6 +360,10 @@

  /** * @dev Add allowlist check for standard transfer + * @param spender The address initiating the transfer. + * @param from The address tokens move from. + * @param to The address tokens move to. + * @return True if the allowlist blocks the transfer (allowlist enabled and a party is not allowlisted). */ function _canTransferStandardByModuleAllowlist( address spender, @@ -355,6 +381,10 @@

  /** * @dev Add allowlist check for standard transfer + * @param spender The address initiating the transfer. + * @param from The address tokens move from. + * @param to The address tokens move to. + * @return True if the standard transfer is allowed (passes the allowlist and base checks). */ function _canTransferStandardByModule( address spender, @@ -439,7 +469,7 @@

diff --git a/doc/test/coverage/modules/wrapper/controllers/index.html b/doc/test/coverage/modules/wrapper/controllers/index.html index b080ccc7..5ae0b4e2 100644 --- a/doc/test/coverage/modules/wrapper/controllers/index.html +++ b/doc/test/coverage/modules/wrapper/controllers/index.html @@ -90,7 +90,7 @@

diff --git a/doc/test/coverage/modules/wrapper/core/ERC20BaseModule.sol.html b/doc/test/coverage/modules/wrapper/core/ERC20BaseModule.sol.html index 44bcf571..df75e93b 100644 --- a/doc/test/coverage/modules/wrapper/core/ERC20BaseModule.sol.html +++ b/doc/test/coverage/modules/wrapper/core/ERC20BaseModule.sol.html @@ -22,22 +22,22 @@

100% Statements - 17/17 + 8/8
- 75% + 50% Branches - 6/8 + 2/4
100% Functions - 10/10 + 5/5
100% Lines - 27/27 + 13/13
@@ -144,68 +144,7 @@

99 100 101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163  +102        @@ -242,9 +181,9 @@

      +6188× +6188×   -98× -50×       @@ -259,38 +198,19 @@

      -5624× -5624× -5624× -5624×         +188×   +116×     +116×     -  -  -  -  -  -  -  -  -  -  -128× -  -80× -  -  -80× -  -  -80× +116×       @@ -308,45 +228,6 @@

      -86× -86× -  -  -  -  -  -  -  -74× -74× -  -  -  -  -  -  -  -  -  -  -26× -26× -26× -  -  -  -  -  -  -24× -24× -24× -  -  -  -  -  -  48× 48× 24× @@ -359,72 +240,50 @@

      -  -  -  -5858× +6212×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
 /* ==== Technical === */
 import {IERC20Allowance} from "../../../interfaces/technical/IERC20Allowance.sol";
 import {IERC20BatchBalance} from "../../../interfaces/engine/ISnapshotEngine.sol";
-/* ==== Tokenization === */
-import {IERC3643ERC20Base} from "../../../interfaces/tokenization/IERC3643Partial.sol";
  
 /**
  * @title ERC20Base module
- * @dev 
+ * @dev
  *
  * Contains ERC-20 base functions and extension
  * Inherits from ERC-20
- * 
+ * The mutable name/symbol attributes are managed by {TokenAttributeModule}
  */
-abstract contract ERC20BaseModule is ERC20Upgradeable, IERC20Allowance, IERC3643ERC20Base, IERC20BatchBalance{
-    /* ============ Events ============ */
-    event Name(string indexed newNameIndexed, string newName);
-    event Symbol(string indexed newSymbolIndexed, string newSymbol);
- 
+abstract contract ERC20BaseModule is ERC20Upgradeable, IERC20Allowance, IERC20BatchBalance{
     /* ============ ERC-7201 ============ */
     // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.ERC20BaseModule")) - 1)) & ~bytes32(uint256(0xff))
     bytes32 private constant ERC20BaseModuleStorageLocation = 0x9bd8d607565c0370ae5f91651ca67fd26d4438022bf72037316600e29e6a3a00;
     /* ==== ERC-7201 State Variables === */
     struct ERC20BaseModuleStorage {
         uint8 _decimals;
-        // We don't use ERC20Upgradeable name and private because we can not modify them
-        string _name;
-        string _symbol;
-    }
- 
-    /* ============ Modifier ============ */
-    modifier onlyERC20AttributeManager() {
-        _authorizeERC20AttributeManagement();
-        _;
     }
  
     /* ============  Initializer Function ============ */
     /**
-     * @dev Initializers: Sets the values for decimals.
+     * @dev Initializers: Sets the value for decimals.
      *
      * this value is immutable: it can only be set once during
      * construction/initialization.
      */
     function __ERC20BaseModule_init_unchained(
-        uint8 decimals_,
-        string memory name_,
-        string memory symbol_
+        uint8 decimals_
     ) internal virtual EonlyInitializing {
         ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage();
         $._decimals = decimals_;
-        $._symbol = symbol_;
-        $._name = name_;
     }
     /*//////////////////////////////////////////////////////////////
                             PUBLIC/EXTERNAL FUNCTIONS
@@ -466,45 +325,6 @@ 

return $._decimals; }   - /** - * @notice Returns the name of the token. - */ - function name() public virtual override(ERC20Upgradeable) view returns (string memory) { - ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage(); - return $._name; - } -  - /** - * @notice Returns the symbol of the token, usually a shorter version of the - * name. - */ - function symbol() public virtual override(ERC20Upgradeable) view returns (string memory) { - ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage(); - return $._symbol; - } -  -  - /* ============ Custom functions ============ */ - /* ======== State Functions ======= */ - /** - * @inheritdoc IERC3643ERC20Base - * @dev - */ - function setName(string calldata name_) public virtual override(IERC3643ERC20Base) onlyERC20AttributeManager { - ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage(); - $._name = name_; - emit Name(name_, name_); - } -  - /** - * @inheritdoc IERC3643ERC20Base - */ - function setSymbol(string calldata symbol_) public virtual override(IERC3643ERC20Base) onlyERC20AttributeManager { - ERC20BaseModuleStorage storage $ = _getERC20BaseModuleStorage(); - $._symbol = symbol_; - emit Symbol(symbol_, symbol_); - } - /* ======== View functions ======= */ /** * @inheritdoc IERC20BatchBalance */ @@ -519,9 +339,6 @@

/*////////////////////////////////////////////////////////////// INTERNAL/PRIVATE FUNCTIONS //////////////////////////////////////////////////////////////*/ - /* ============ Access Control ============ */ - function _authorizeERC20AttributeManagement() internal virtual; -  /* ============ ERC-7201 ============ */ function _getERC20BaseModuleStorage() private pure returns (ERC20BaseModuleStorage storage $) { assembly { @@ -535,7 +352,7 @@

diff --git a/doc/test/coverage/modules/wrapper/core/ERC20BurnModule.sol.html b/doc/test/coverage/modules/wrapper/core/ERC20BurnModule.sol.html index 0a81e47d..db65c0d4 100644 --- a/doc/test/coverage/modules/wrapper/core/ERC20BurnModule.sol.html +++ b/doc/test/coverage/modules/wrapper/core/ERC20BurnModule.sol.html @@ -174,8 +174,8 @@

      -835× -739× +841× +745×       @@ -205,7 +205,7 @@

      -138× +144×       @@ -248,8 +248,8 @@

      -409× -292× +415× +298×       @@ -257,7 +257,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ERC20BurnModuleInternal} from "../../internal/ERC20BurnModuleInternal.sol";
@@ -367,7 +367,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/core/ERC20MintModule.sol.html b/doc/test/coverage/modules/wrapper/core/ERC20MintModule.sol.html index 5ab1eed4..bf04cb12 100644 --- a/doc/test/coverage/modules/wrapper/core/ERC20MintModule.sol.html +++ b/doc/test/coverage/modules/wrapper/core/ERC20MintModule.sol.html @@ -171,8 +171,8 @@

      -5722× -5650× +6197× +6125×       @@ -203,7 +203,7 @@

      -4534× +4935×       @@ -219,8 +219,8 @@

      -730× -583× +780× +633×       @@ -232,22 +232,22 @@

      -238× +262×             -4682× -4586× +5083× +5008×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ERC20MintModuleInternal} from "../../internal/ERC20MintModuleInternal.sol";
@@ -352,7 +352,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/core/EnforcementModule.sol.html b/doc/test/coverage/modules/wrapper/core/EnforcementModule.sol.html index 078f4f11..61cd7cb4 100644 --- a/doc/test/coverage/modules/wrapper/core/EnforcementModule.sol.html +++ b/doc/test/coverage/modules/wrapper/core/EnforcementModule.sol.html @@ -162,8 +162,8 @@

      -771× -696× +944× +869×       @@ -177,7 +177,7 @@

      -271× +347×       @@ -195,7 +195,7 @@

      -300× +372×       @@ -206,7 +206,7 @@

      -125× +150×       @@ -214,7 +214,7 @@

      -16612× +18213×       @@ -222,8 +222,8 @@

      -721× -646× +919× +844×       @@ -231,7 +231,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {EnforcementModuleInternal} from "../../internal/EnforcementModuleInternal.sol";
@@ -253,7 +253,7 @@ 

    /* ============ Modifier ============ */ - /// @dev Modifier to restrict access to the burner functions + /// @dev Modifier to restrict access to the address-freeze functions (via `_authorizeFreeze`, ENFORCER_ROLE) modifier onlyEnforcer() { _authorizeFreeze(); _; @@ -328,7 +328,7 @@

diff --git a/doc/test/coverage/modules/wrapper/core/PauseModule.sol.html b/doc/test/coverage/modules/wrapper/core/PauseModule.sol.html index 53a469c1..ea81eb34 100644 --- a/doc/test/coverage/modules/wrapper/core/PauseModule.sol.html +++ b/doc/test/coverage/modules/wrapper/core/PauseModule.sol.html @@ -213,13 +213,13 @@

      -763× -712× +841× +790×       -318× -293× +344× +319×       @@ -232,7 +232,7 @@

      -637× +713×       @@ -241,8 +241,8 @@

      -75× -75× +77× +77× 50×     @@ -258,13 +258,13 @@

      -293× -268× -268× +319× +294× +294× 25×   -243× -243× +269× +269×       @@ -272,15 +272,15 @@

      -5339× +5018×             -8168× -8168× +8717× +8717×       @@ -291,28 +291,28 @@

      -7853× +8372× 121×           -8511× +9088×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
 /* ==== Tokenization === */
 import {IERC3643Pause} from "../../../interfaces/tokenization/IERC3643Partial.sol";
 import {IERC7551Pause} from "../../../interfaces/tokenization/draft-IERC7551.sol";
-import {ICMTATDeactivate} from "../../../interfaces/tokenization/ICMTAT.sol";
+import {IERC8343} from "../../../interfaces/tokenization/draft-IERC8343.sol";
  
  
 /**
@@ -326,7 +326,7 @@ 

* period, or having an emergency switch for freezing all token transfers in the * event of a large bug. */ -abstract contract PauseModule is PausableUpgradeable, IERC3643Pause, IERC7551Pause, ICMTATDeactivate { +abstract contract PauseModule is PausableUpgradeable, IERC3643Pause, IERC7551Pause, IERC8343 { error CMTAT_PauseModule_ContractIsDeactivated(); error EnforcedDeactivation(); /* ============ State Variables ============ */ @@ -377,14 +377,14 @@

}   /** - * @inheritdoc ICMTATDeactivate + * @inheritdoc IERC8343 * @custom:access-control * - the caller must have the `DEFAULT_ADMIN_ROLE`. * @custom:devimpl * With a proxy architecture, it is still possible to rollback by deploying a new implementation which sets the variable to false. */ function deactivateContract() - public virtual override(ICMTATDeactivate) + public virtual override(IERC8343) onlyDeactivateContractManager { // Contract must be in pause state @@ -406,9 +406,9 @@

}   /** - * @inheritdoc ICMTATDeactivate + * @inheritdoc IERC8343 */ - function deactivated() public view virtual override(ICMTATDeactivate) returns (bool){ + function deactivated() public view virtual override(IERC8343) returns (bool){ PauseModuleStorage storage $ = _getPauseModuleStorage(); return $._isDeactivated; } @@ -439,7 +439,7 @@

diff --git a/doc/test/coverage/modules/wrapper/core/TokenAttributeModule.sol.html b/doc/test/coverage/modules/wrapper/core/TokenAttributeModule.sol.html new file mode 100644 index 00000000..54805629 --- /dev/null +++ b/doc/test/coverage/modules/wrapper/core/TokenAttributeModule.sol.html @@ -0,0 +1,419 @@ + + + + Code coverage report for modules/wrapper/core/TokenAttributeModule.sol + + + + + + + +
+
+

+ all files / modules/wrapper/core/ TokenAttributeModule.sol +

+
+
+ 100% + Statements + 10/10 +
+
+ 83.33% + Branches + 5/6 +
+
+ 100% + Functions + 7/7 +
+
+ 100% + Lines + 16/16 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +98× +50× +  +  +  +  +  +  +  +  +  +  +6188× +6188× +6188× +  +  +  +  +  +  +  +  +  +  +  +94× +94× +  +  +  +  +  +  +  +76× +76× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +26× +26× +26× +  +  +  +  +  +  +24× +24× +24× +  +  +  +  +  +  +  +  +  +  +6408× +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+ 
+/* ==== OpenZeppelin === */
+import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
+/* ==== Tokenization === */
+import {IERC3643ERC20Base} from "../../../interfaces/tokenization/IERC3643Partial.sol";
+ 
+/**
+ * @title TokenAttribute module
+ * @dev
+ *
+ * Manages the mutable token attributes (name and symbol) independently of the
+ * underlying token standard (ERC-20, ERC-7984, ...).
+ *
+ * The attributes are stored in this module's own ERC-7201 namespaced storage, so
+ * a contract that also inherits a token standard (e.g. `ERC20Upgradeable`) only
+ * has to override that standard's `name()` / `symbol()` to delegate here. This
+ * keeps the metadata management reusable by non ERC-20 (e.g. confidential) tokens.
+ */
+abstract contract TokenAttributeModule is Initializable, IERC3643ERC20Base {
+    /* ============ Events ============ */
+    event Name(string indexed newNameIndexed, string newName);
+    event Symbol(string indexed newSymbolIndexed, string newSymbol);
+ 
+    /* ============ ERC-7201 ============ */
+    // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.TokenAttributeModule")) - 1)) & ~bytes32(uint256(0xff))
+    bytes32 private constant TokenAttributeModuleStorageLocation = 0xc541cfc06cfa9bb7e38e614bc9457bd7310b58a2a620e4f19164873143c76d00;
+    /* ==== ERC-7201 State Variables === */
+    struct TokenAttributeModuleStorage {
+        // We don't use the underlying token standard's name/symbol because we can not modify them
+        string _name;
+        string _symbol;
+    }
+ 
+    /* ============ Modifier ============ */
+    modifier onlyTokenAttributeManager() {
+        _authorizeTokenAttributeManagement();
+        _;
+    }
+ 
+    /* ============  Initializer Function ============ */
+    /**
+     * @dev Initializers: sets the token name and symbol.
+     */
+    function __TokenAttributeModule_init_unchained(
+        string memory name_,
+        string memory symbol_
+    ) internal virtual EonlyInitializing {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        $._name = name_;
+        $._symbol = symbol_;
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ======== View functions ======= */
+    /**
+     * @notice Returns the name of the token.
+     * @return The token name.
+     */
+    function name() public view virtual returns (string memory) {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        return $._name;
+    }
+ 
+    /**
+     * @notice Returns the symbol of the token, usually a shorter version of the name.
+     * @return The token symbol.
+     */
+    function symbol() public view virtual returns (string memory) {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        return $._symbol;
+    }
+ 
+    /* ======== State functions ======= */
+    /**
+     *  @inheritdoc IERC3643ERC20Base
+     *  @dev
+     *  WARNING - on deployment variants that also support ERC-2612 (`permit`), renaming the token does **not**
+     *  change the EIP-712 domain separator. The domain name is captured at initialization by OpenZeppelin's
+     *  `EIP712Upgradeable` and, per its own documentation, "cannot be changed except through a smart contract
+     *  upgrade"; `DOMAIN_SEPARATOR()` therefore keeps using the original name after {setName}.
+     *
+     *  Existing and future permits remain valid: signers must simply build the EIP-712 domain from the ERC-5267
+     *  {eip712Domain} function (or from `DOMAIN_SEPARATOR()`), which reports the name actually in use — never
+     *  from {name}. A signature produced with the post-rename {name} is rejected with `ERC2612InvalidSigner`.
+     */
+    function setName(string calldata name_) public virtual override(IERC3643ERC20Base) onlyTokenAttributeManager {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        $._name = name_;
+        emit Name(name_, name_);
+    }
+ 
+    /**
+     * @inheritdoc IERC3643ERC20Base
+     */
+    function setSymbol(string calldata symbol_) public virtual override(IERC3643ERC20Base) onlyTokenAttributeManager {
+        TokenAttributeModuleStorage storage $ = _getTokenAttributeModuleStorage();
+        $._symbol = symbol_;
+        emit Symbol(symbol_, symbol_);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============ Access Control ============ */
+    function _authorizeTokenAttributeManagement() internal virtual;
+ 
+    /* ============ ERC-7201 ============ */
+    function _getTokenAttributeModuleStorage() private pure returns (TokenAttributeModuleStorage storage $) {
+        assembly {
+            $.slot := TokenAttributeModuleStorageLocation
+        }
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/modules/wrapper/core/ValidationModuleCore.sol.html b/doc/test/coverage/modules/wrapper/core/ValidationModuleCore.sol.html index 106e8ff7..10cb4641 100644 --- a/doc/test/coverage/modules/wrapper/core/ValidationModuleCore.sol.html +++ b/doc/test/coverage/modules/wrapper/core/ValidationModuleCore.sol.html @@ -95,7 +95,11 @@

50 51 52 -53  +53 +54 +55 +56 +57        @@ -119,7 +123,7 @@

      -1229× +1346×       @@ -128,7 +132,7 @@

      -208× +212×       @@ -144,12 +148,16 @@

      -1437× +  +  +  +  +1558×      
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ValidationModule} from "../controllers/ValidationModule.sol";
@@ -189,6 +197,10 @@ 

  /** * @dev function used by canTransfer and operateOnTransfer + * @param spender The address initiating the transfer. + * @param from The address tokens move from. + * @param to The address tokens move to. + * @return True if the transfer is allowed by the validation module. */ function _canTransferByModule( address spender, @@ -205,7 +217,7 @@

diff --git a/doc/test/coverage/modules/wrapper/core/VersionModule.sol.html b/doc/test/coverage/modules/wrapper/core/VersionModule.sol.html index 3397cb84..128e368e 100644 --- a/doc/test/coverage/modules/wrapper/core/VersionModule.sol.html +++ b/doc/test/coverage/modules/wrapper/core/VersionModule.sol.html @@ -105,7 +105,7 @@

   
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Tokenization === */
 import {IERC3643Version} from "../../../interfaces/tokenization/IERC3643Partial.sol";
@@ -122,7 +122,7 @@ 

* @dev * Get the current version of the smart contract */ - string private constant VERSION = "3.2.0"; + string private constant VERSION = "3.3.0"; /*////////////////////////////////////////////////////////////// PUBLIC/EXTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ @@ -139,7 +139,7 @@

diff --git a/doc/test/coverage/modules/wrapper/core/index.html b/doc/test/coverage/modules/wrapper/core/index.html index 343c477a..f6f683b2 100644 --- a/doc/test/coverage/modules/wrapper/core/index.html +++ b/doc/test/coverage/modules/wrapper/core/index.html @@ -22,22 +22,22 @@

100% Statements - 59/59 + 60/60
- 85.71% + 84.09% Branches - 36/42 + 37/44
100% Functions - 41/41 + 43/43
100% Lines - 78/78 + 80/80
@@ -62,13 +62,13 @@

ERC20BaseModule.sol
100% - 17/17 - 75% - 6/8 + 8/8 + 50% + 2/4 100% - 10/10 + 5/5 100% - 27/27 + 13/13 @@ -123,6 +123,19 @@

20/20 + + TokenAttributeModule.sol +
+ 100% + 10/10 + 83.33% + 5/6 + 100% + 7/7 + 100% + 16/16 + + ValidationModuleCore.sol
@@ -155,7 +168,7 @@

diff --git a/doc/test/coverage/modules/wrapper/extensions/DocumentERC1643Module.sol.html b/doc/test/coverage/modules/wrapper/extensions/DocumentERC1643Module.sol.html index 893e4865..532ebf3e 100644 --- a/doc/test/coverage/modules/wrapper/extensions/DocumentERC1643Module.sol.html +++ b/doc/test/coverage/modules/wrapper/extensions/DocumentERC1643Module.sol.html @@ -22,12 +22,12 @@

100% Statements - 18/18 + 20/20
- 90% + 100% Branches - 9/10 + 12/12
100% @@ -37,7 +37,7 @@

100% Lines - 28/28 + 30/30

@@ -123,7 +123,9 @@

78 79 80 -81  +81 +82 +83        @@ -146,66 +148,68 @@

      -299× -253× +446× +400×       -138× +152× +152×       -46× +49×       -207× -207× -207× -207× -207× +297× +272× +272× +272× +272× +272×   -207× -184× -184× +272× +248× +248×     -207× +272×       -46× -46× -46× +103× +103× +103×   -46× -46× -46× +78× +78× +78×   -46× -23× -23× -23× +78× +26× +26× +26×     -46× -46× -46× +78× +78× +78×   -46× +78×           -437× +576×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
 import {IERC1643} from "../../../interfaces/tokenization/draft-IERC1643.sol";
@@ -230,8 +234,9 @@ 

_; }   - function getDocument(bytes32 name) public view virtual override returns (Document memory document) { - return _getDocumentERC1643ModuleStorage()._documents[name]; + function getDocument(bytes32 name) public view virtual override returns (string memory uri, bytes32 documentHash, uint256 lastModified) { + Document storage document = _getDocumentERC1643ModuleStorage()._documents[name]; + return (document.uri, document.documentHash, document.lastModified); }   function getAllDocuments() public view virtual override returns (bytes32[] memory documentNames_) { @@ -239,6 +244,7 @@

}   function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) public virtual override onlyDocumentManager { + require(name != bytes32(0), ERC1643InvalidName()); DocumentERC1643ModuleStorage storage $ = _getDocumentERC1643ModuleStorage(); Document storage document = $._documents[name]; document.uri = uri; @@ -256,7 +262,7 @@

function removeDocument(bytes32 name) public virtual override onlyDocumentManager { DocumentERC1643ModuleStorage storage $ = _getDocumentERC1643ModuleStorage(); uint256 key = $._documentKey[name]; - Erequire(key != 0, "CMTAT: document does not exist"); + require(key != 0, ERC1643MissingDocument());   Document memory document = $._documents[name]; uint256 index = key - 1; @@ -289,7 +295,7 @@

diff --git a/doc/test/coverage/modules/wrapper/extensions/ERC20EnforcementModule.sol.html b/doc/test/coverage/modules/wrapper/extensions/ERC20EnforcementModule.sol.html index 321edcda..527e70fa 100644 --- a/doc/test/coverage/modules/wrapper/extensions/ERC20EnforcementModule.sol.html +++ b/doc/test/coverage/modules/wrapper/extensions/ERC20EnforcementModule.sol.html @@ -175,14 +175,14 @@

      -1289× -1226× +1430× +1364×         -262× -220× +342× +298×       @@ -193,7 +193,7 @@

      -2246× +2062×       @@ -204,8 +204,8 @@

      -146× -125× +200× +164×       @@ -215,7 +215,7 @@

      -574× +596×       @@ -225,7 +225,7 @@

      -194× +204×       @@ -236,7 +236,7 @@

      -378× +476×       @@ -244,13 +244,13 @@

      -845× -845× +878× +878×       -323× -323× +338× +338×       @@ -259,7 +259,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ERC20EnforcementModuleInternal} from "../../internal/ERC20EnforcementModuleInternal.sol";
@@ -370,7 +370,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/extensions/ExtraInformationModule.sol.html b/doc/test/coverage/modules/wrapper/extensions/ExtraInformationModule.sol.html index 3563cf37..307dacf6 100644 --- a/doc/test/coverage/modules/wrapper/extensions/ExtraInformationModule.sol.html +++ b/doc/test/coverage/modules/wrapper/extensions/ExtraInformationModule.sol.html @@ -22,7 +22,7 @@

100% Statements - 21/21 + 23/23
87.5% @@ -32,12 +32,12 @@

100% Functions - 13/13 + 14/14
100% Lines - 29/29 + 34/34

@@ -204,7 +204,23 @@

159 160 161 -162  +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178        @@ -235,8 +251,8 @@

      -164× -82× +168× +86×       @@ -248,13 +264,13 @@

      -5402× +5942×   -5402× +5942×   -5402× +5942×   -5402× +5942×       @@ -295,8 +311,8 @@

      -26× -26× +28× +28×       @@ -312,62 +328,78 @@

      -58× -58× +118× +118×             -104× -104× +108× +108×             -28× -28× +26× +26× +  +  +  +  +            -5428× -5428× + + + +   +       -5430×   -5430× -5430× -5430×   -5430× +5968× +5968×       -5428× -5428×   +5968×   +5968× +5968× +5968×   +5968×       +5970× +5970×   -5774× +  +  +  +  +  +  +6382×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Openzeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -492,6 +524,22 @@ 

ExtraInformationModuleStorage storage $ = _getExtraInformationModuleStorage(); _setTerms($, terms_); } +  + /** + * @dev Update the terms document (uri + hash) while leaving the document name untouched. + * + * Used by the ERC-7551 `setTerms(bytes32,string)` overload, whose signature carries no name: + * forwarding an empty one through {_setTerms} would silently erase a name previously set via + * {setTerms(IERC1643CMTAT.DocumentInfo)}. + */ + function _setTermsDocument(bytes32 documentHash_, string memory uri_) internal virtual { + ExtraInformationModuleStorage storage $ = _getExtraInformationModuleStorage(); + $._terms.doc.documentHash = documentHash_; + $._terms.doc.uri = uri_; + $._terms.doc.lastModified = block.timestamp; + // Event + emit Terms($._terms); + }   function _setTokenId( ExtraInformationModuleStorage storage $, string memory tokenId_ @@ -532,7 +580,7 @@

diff --git a/doc/test/coverage/modules/wrapper/extensions/SnapshotEngineModule.sol.html b/doc/test/coverage/modules/wrapper/extensions/SnapshotEngineModule.sol.html index f90652b0..e5c23c6c 100644 --- a/doc/test/coverage/modules/wrapper/extensions/SnapshotEngineModule.sol.html +++ b/doc/test/coverage/modules/wrapper/extensions/SnapshotEngineModule.sol.html @@ -173,8 +173,8 @@

      -343× -334× +349× +340×       @@ -208,9 +208,9 @@

      -334× -334× -325× +340× +340× +331×       @@ -220,8 +220,8 @@

      -3300× -3300× +3476× +3476×       @@ -230,15 +230,15 @@

      -343× -343× +349× +349×             -3652× +3834×       @@ -247,7 +247,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -352,7 +352,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol.html b/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol.html index 487976f4..8de03e08 100644 --- a/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol.html +++ b/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleAllowance.sol.html @@ -22,12 +22,12 @@

100% Statements - 3/3 + 5/5
100% Branches - 4/4 + 6/6
100% @@ -37,7 +37,7 @@

100% Lines - 5/5 + 7/7

@@ -78,7 +78,33 @@

33 34 35 -36  +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54  +  +  +  +  +  +  +  +        @@ -104,18 +130,28 @@

      -808× -804× -28×   -776× +  +  +  +  +  +  +1150× +128× +  +1022× +972× 28×   +944× +52× +       
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== ValidationModule === */
 import {ValidationModuleCore} from "../../core/ValidationModuleCore.sol";
@@ -130,15 +166,33 @@ 

/** * @dev Reverts when allowance authorization cannot be performed. * - * Requirements: + * Requirements (for `value > 0`): * - contract must not be paused. * - `owner` must be allowed to send (`canSend` returns true). * - `spender` must be allowed to send (`canSend` returns true). + * + * Setting an allowance to zero is a **revocation**, never a new grant: it can only + * reduce what a spender may move. It is therefore always authorized, including while + * the contract is paused or when `owner`/`spender` is frozen or off the allowlist. + * Blocking it would leave a holder unable to sever ties with a compromised or + * sanctioned spender for the whole duration of the restriction, and would make the + * zero-first allowance mitigation documented on `approve` unusable exactly when it + * matters. No value can move while the restriction holds, since `transferFrom` is + * gated by the same checks. + * + * @param owner The account granting (or revoking) the allowance. + * @param spender The account being granted (or revoked). + * @param value The new allowance value; `0` means revocation. */ function _canAuthorizeAllowanceByModuleAndRevert( address owner, - address spender + address spender, + uint256 value ) internal view virtual { + // A revocation is always allowed + if (value == 0) { + return; + } _requireNotPaused(); if (!_canSend(owner)) { revert ERC7943CannotSend(owner); @@ -154,7 +208,7 @@

diff --git a/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol.html b/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol.html index a40e2c4d..d65f48ac 100644 --- a/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol.html +++ b/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleERC1404.sol.html @@ -203,7 +203,51 @@

158 159 160 -161  +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205        @@ -257,8 +301,33 @@

      -93× -93× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +95× +95×     @@ -269,7 +338,7 @@

      -11× +13×       @@ -305,14 +374,17 @@

      -199× -199× -199× -132× +  +  +  +190× +190× +190× +112×   42×   -25× +36×       @@ -322,17 +394,32 @@

      -189× -189× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +160× +160× 11×   -178× -178× -132× +149× +149× +92×   24×   -22× +33×       @@ -349,8 +436,9 @@

      -223× -33× +  +251× +39×   55×   @@ -359,13 +447,13 @@

11×     -113× +135×        
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
  
 /* ==== Tokenization === */
@@ -378,6 +466,31 @@ 

* * Useful for to restrict and validate transfers * Required a RuleEngine implementing the interface IRuleEngineERC1404 + * + * @custom:scope {detectTransferRestriction} and {detectTransferRestrictionFrom} describe the + * **holder transfer path only** — `transfer` and `transferFrom`. They do **not** govern the + * mint and burn entry points, and the `address(0)` encoding of the ERC-1404 rework draft + * (`from == address(0)` for a mint, `to == address(0)` for a burn) is **not** supported here: + * a query built that way is answered as if it were a holder transfer, so it can report a + * restriction the mint/burn path does not enforce (typically {PauseModule-paused}). + * + * The reason is structural, not an oversight. CMTAT exposes several entry points per + * supply-changing operation and the **pause rule differs between them**: + * - mint: `mint` / `batchMint` (`MINTER_ROLE`) are allowed while paused, `crosschainMint` + * (token bridge) is not; + * - burn: `burn(address,uint256[,bytes])` / `batchBurn` (`BURNER_ROLE`) are allowed while paused, + * `burnFrom` (`BURNER_FROM_ROLE`), `burn(uint256)` (`BURNER_SELF_ROLE`) and `crosschainBurn` + * are not. + * + * `(from, to, value)` — and `(spender, from, to, value)` — carry no entry-point discriminator, and + * the operator address does not identify one either (the same address may hold several burn roles), + * so no single return value can describe every mint or every burn. Rather than designate a predictor + * that would be right for one entry point and wrong for another, this module designates **none**. + * + * To predict a mint or a burn, use the module's own predicates instead — {canTransfer} / + * {canTransferFrom}, which branch on the `address(0)` encoding through + * {ValidationModule-_canTransferGenericByModule}, the same helper the enforcement path uses — and + * the role/pause requirements documented per entry point. */ abstract contract ValidationModuleERC1404 is ValidationModuleRuleEngine, IERC1404Extend @@ -459,6 +572,9 @@

* @param value uint256 the amount of tokens to be transferred * @return code of the rejection reason * @dev see {ERC-1404} + * @dev Scope: `transfer` / `transferFrom` only. Passing `address(0)` as `from` or `to` to query + * a mint or a burn is **not** supported — see the scope note on this contract; use + * {canTransfer} / {canTransferFrom} for those operations. */ function detectTransferRestriction( address from, @@ -476,6 +592,21 @@

} }   + /** + * @notice check if `spender` can transfer `value` token from `from` to `to` + * @param spender address The address initiating the delegated transfer + * @param from address The address which you want to send tokens from + * @param to address The address which you want to transfer to + * @param value uint256 the amount of tokens to be transferred + * @return code of the rejection reason + * @dev see {ERC-1404} (rework draft, spender-aware extension) + * @dev Scope: `transferFrom` only. The `spender` argument is the delegated-transfer initiator, + * **not** a mint/burn operator: passing an operator with `from`/`to` set to `address(0)` to + * predict a mint or a burn is not supported — see the scope note on this contract. + * The `spender == from` case is deliberately evaluated through this path (no short-circuit to + * {detectTransferRestriction}), because a frozen initiator blocks `transferFrom` even when it + * owns the tokens. + */ function detectTransferRestrictionFrom( address spender, address from, @@ -503,6 +634,7 @@

  /** * @dev override this function to add further restriction + * @return code The restriction code (0 = no restriction). */ function _detectTransferRestriction( address from, @@ -529,7 +661,7 @@

diff --git a/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol.html b/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol.html index 3626ce2f..d7a27d88 100644 --- a/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol.html +++ b/doc/test/coverage/modules/wrapper/extensions/ValidationModule/ValidationModuleRuleEngine.sol.html @@ -22,7 +22,7 @@

100% Statements - 25/25 + 26/26
100% @@ -32,12 +32,12 @@

100% Functions - 9/9 + 10/10
100% Lines - 26/26 + 27/27

@@ -192,7 +192,53 @@

147 148 149 -150  +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196        @@ -219,8 +265,9 @@

      -364× -361× +  +370× +367×       @@ -241,8 +288,8 @@

      -361× -358× +367× +364×       @@ -254,7 +301,7 @@

      -1009× +1068×       @@ -267,7 +314,7 @@

      -175× +177×       @@ -279,8 +326,8 @@

      -1009× -240× +1068× +299×   769×   @@ -292,8 +339,8 @@

      -175× -76× +177× +78×   99×   @@ -330,20 +377,65 @@

      -7282× -6851× -6851× -715× -703×   -12×         +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +7763× +7309× +7309× +733× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +725× +709× +  +16× +  +  +   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
  
 /* ==== Engine === */
@@ -365,6 +457,7 @@ 

* @notice Reverts if attempting to set the RuleEngine to its current value. */ error CMTAT_ValidationModule_SameValue(); +    /* ============ Modifier ============ */ modifier onlyRuleEngineManager() { @@ -478,15 +571,60 @@

function _authorizeRuleEngineManagement() internal virtual;   /* ============ State functions ============ */ + /** + * @dev + * @custom:security The RuleEngine callback is the only point at which a transfer hands control + * to an external contract, and it happens *before* the ERC-20 balances move: the active-balance + * (frozen) check in {CMTATBaseCommon-_checkTransferred} has already run against the pre-transfer + * state and is not re-evaluated afterwards. A RuleEngine that reenters the token during + * `transferred(...)` — because it is malicious, compromised, or because one of its rules calls + * untrusted code — is therefore validated twice against the same snapshot, and the outer and + * inner transfers can together move more than the holder's unfrozen balance, breaking the + * `frozenTokens <= balanceOf` invariant. + * + * The external call is isolated in {_callRuleEngineTransferred}, which is `virtual` so that a + * deployment variant can wrap it in a reentrancy guard by inheriting OpenZeppelin's + * `ReentrancyGuardTransient` and overriding {_callRuleEngineTransferred} with `nonReentrant` + * (see e.g. `contracts/deployment/CMTATStandardStandalone.sol`). + * + * WARNING - the guard is **not** enabled on every variant. It costs ~195 bytes of deployed + * bytecode, and several variants are within a few hundred bytes of the EIP-170 24 KiB limit, so + * enabling it there would make them undeployable. Variants without the guard rely on the standard + * CMTAT trust assumption: the RuleEngine is set by `DEFAULT_ADMIN_ROLE`, is fully trusted, and + * MUST NOT hand control to untrusted code during `transferred(...)`. See the module documentation + * for the per-variant table. + * + * The guard is entered only when a RuleEngine is set, so a deployment with no engine pays + * nothing, and it is released when the callback returns, so sequential hooks (batch operations, + * `burnAndMint`) are unaffected. + */ function _transferred(address spender, address from, address to, uint256 value) internal virtual{ _canTransferGenericByModuleAndRevert(spender, from, to); IRuleEngine ruleEngine_ = ruleEngine(); if (address(ruleEngine_) != address(0)){ - if(spender != address(0)){ - ruleEngine_.transferred(spender, from, to, value); - } else { - ruleEngine_.transferred(from, to, value); - } + _callRuleEngineTransferred(ruleEngine_, spender, from, to, value); + } + } +  + /** + * @dev Performs the RuleEngine `transferred` call. + * + * Declared `virtual` so a deployment variant can wrap it in a reentrancy guard by overriding it + * with `nonReentrant` (inheriting OpenZeppelin's `ReentrancyGuardTransient`). The base + * implementation is **unguarded**: see the security note on {_transferred} for which variants + * enable the guard and why it is not enabled everywhere. + */ + function _callRuleEngineTransferred( + IRuleEngine ruleEngine_, + address spender, + address from, + address to, + uint256 value + ) internal virtual { + if(spender != address(0)){ + ruleEngine_.transferred(spender, from, to, value); + } else { + ruleEngine_.transferred(from, to, value); } } } @@ -496,7 +634,7 @@

diff --git a/doc/test/coverage/modules/wrapper/extensions/ValidationModule/index.html b/doc/test/coverage/modules/wrapper/extensions/ValidationModule/index.html index 6b741d89..4dfc4a6e 100644 --- a/doc/test/coverage/modules/wrapper/extensions/ValidationModule/index.html +++ b/doc/test/coverage/modules/wrapper/extensions/ValidationModule/index.html @@ -22,22 +22,22 @@

100% Statements - 69/69 + 72/72
100% Branches - 52/52 + 54/54
100% Functions - 14/14 + 15/15
100% Lines - 61/61 + 64/64
@@ -62,13 +62,13 @@

ValidationModuleAllowance.sol
100% - 3/3 + 5/5 100% - 4/4 + 6/6 100% 1/1 100% - 5/5 + 7/7 @@ -88,13 +88,13 @@

ValidationModuleRuleEngine.sol
100% - 25/25 + 26/26 100% 16/16 100% - 9/9 + 10/10 100% - 26/26 + 27/27 @@ -103,7 +103,7 @@

diff --git a/doc/test/coverage/modules/wrapper/extensions/index.html b/doc/test/coverage/modules/wrapper/extensions/index.html index 61a907a5..87798124 100644 --- a/doc/test/coverage/modules/wrapper/extensions/index.html +++ b/doc/test/coverage/modules/wrapper/extensions/index.html @@ -22,22 +22,22 @@

100% Statements - 61/61 + 65/65
- 91.18% + 94.44% Branches - 31/34 + 34/36
100% Functions - 34/34 + 35/35
100% Lines - 84/84 + 91/91
@@ -62,13 +62,13 @@

DocumentERC1643Module.sol
100% - 18/18 - 90% - 9/10 + 20/20 + 100% + 12/12 100% 6/6 100% - 28/28 + 30/30 @@ -88,13 +88,13 @@

ExtraInformationModule.sol
100% - 21/21 + 23/23 87.5% 7/8 100% - 13/13 + 14/14 100% - 29/29 + 34/34 @@ -116,7 +116,7 @@

diff --git a/doc/test/coverage/modules/wrapper/options/AllowlistModule.sol.html b/doc/test/coverage/modules/wrapper/options/AllowlistModule.sol.html index 0a95e263..01f302e6 100644 --- a/doc/test/coverage/modules/wrapper/options/AllowlistModule.sol.html +++ b/doc/test/coverage/modules/wrapper/options/AllowlistModule.sol.html @@ -164,8 +164,8 @@

      -978× -970× +1129× +1121×       @@ -186,7 +186,7 @@

      -292× +322×       @@ -196,7 +196,7 @@

      -532× +584×       @@ -206,8 +206,8 @@

      -142× -142× +211× +211×       @@ -223,15 +223,15 @@

      -1438× +1580×             -2396× -2396× +2626× +2626×       @@ -239,7 +239,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {IAllowlistModule} from "../../../interfaces/modules/IAllowlistModule.sol";
@@ -340,7 +340,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/options/CCIPModule.sol.html b/doc/test/coverage/modules/wrapper/options/CCIPModule.sol.html index 31f4c771..3f105674 100644 --- a/doc/test/coverage/modules/wrapper/options/CCIPModule.sol.html +++ b/doc/test/coverage/modules/wrapper/options/CCIPModule.sol.html @@ -114,7 +114,8 @@

69 70 71 -72  +72 +73        @@ -168,6 +169,7 @@

      +  24× 24×   @@ -187,7 +189,7 @@

   
// SPDX-License-Identifier: MIT
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 import {IGetCCIPAdmin} from "../../../interfaces/technical/IGetCCIPAdmin.sol";
 /**
@@ -237,6 +239,7 @@ 

  /** * Returns the current CCIPAdmin + * @return The current CCIP admin address. */ function getCCIPAdmin() public view virtual returns (address) { CCIPModuleStorage storage $ = _getCCIPModuleStorage(); @@ -262,7 +265,7 @@

diff --git a/doc/test/coverage/modules/wrapper/options/DebtEngineModule.sol.html b/doc/test/coverage/modules/wrapper/options/DebtEngineModule.sol.html index 36efef1e..b9e52c29 100644 --- a/doc/test/coverage/modules/wrapper/options/DebtEngineModule.sol.html +++ b/doc/test/coverage/modules/wrapper/options/DebtEngineModule.sol.html @@ -263,7 +263,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Engine === */
 import {IDebtEngine, ICMTATDebt, ICMTATCreditEvents} from "../../../interfaces/engine/IDebtEngine.sol";
@@ -376,7 +376,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/options/DebtModule.sol.html b/doc/test/coverage/modules/wrapper/options/DebtModule.sol.html index 5627a8ff..0b16fefb 100644 --- a/doc/test/coverage/modules/wrapper/options/DebtModule.sol.html +++ b/doc/test/coverage/modules/wrapper/options/DebtModule.sol.html @@ -257,7 +257,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Engine === */
 import {ICMTATDebt, ICMTATCreditEvents} from "../../../interfaces/engine/IDebtEngine.sol";
@@ -367,7 +367,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/options/DocumentEngineModule.sol.html b/doc/test/coverage/modules/wrapper/options/DocumentEngineModule.sol.html index 0529410a..71184d00 100644 --- a/doc/test/coverage/modules/wrapper/options/DocumentEngineModule.sol.html +++ b/doc/test/coverage/modules/wrapper/options/DocumentEngineModule.sol.html @@ -22,12 +22,12 @@

100% Statements - 20/20 + 25/25
- 93.75% + 90% Branches - 15/16 + 18/20
100% @@ -37,7 +37,7 @@

100% Lines - 24/24 + 29/29

@@ -169,7 +169,21 @@

124 125 126 -127  +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141        @@ -197,8 +211,8 @@

      -34× -29× +55× +50×       @@ -211,7 +225,7 @@

      -37× +53×   @@ -225,8 +239,8 @@

      -15× -15× +19× +19×       @@ -252,26 +266,28 @@

      - - +18× +18×       - -     +15× +14×       + +         + + +   -18× -18× -15×       @@ -281,8 +297,20 @@

      -21× -21× +25× +25× +22× +  +  +  +  +  +  +  +  +  +28× +28×       @@ -290,14 +318,14 @@

      -64× +89×          
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin=== */
 import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
@@ -313,7 +341,7 @@ 

*/ 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 === */ @@ -358,12 +386,12 @@

/** * @inheritdoc IERC1643 */ - function getDocument(bytes32 name) public view virtual override(IERC1643) returns (Document memory document){ + function getDocument(bytes32 name) public view virtual override(IERC1643) returns (string memory uri, bytes32 documentHash, uint256 lastModified){ DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage(); if(address($._documentEngine) != address(0)){ return $._documentEngine.getDocument(name); } else{ - return Document("", 0x0, 0); + return ("", 0x0, 0); } }   @@ -379,12 +407,26 @@

  function setDocument(bytes32 name, string calldata uri, bytes32 documentHash) public virtual override(IERC1643) onlyDocumentManager { DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage(); + require(address($._documentEngine) != address(0), CMTAT_DocumentEngineModule_NoDocumentEngine()); + // Persist in the engine (which reverts on invalid input, e.g. the zero name), then re-emit + // the standard ERC-1643 event on the token's own address. ERC-1643 is a per-contract + // interface and integrators subscribe to the token that exposes {setDocument}; without this + // re-emission the update would only be observable on the engine's address. The engine also + // emits, on its own address. $._documentEngine.setDocument(name, uri, documentHash); + emit DocumentUpdated(name, uri, documentHash); }   function removeDocument(bytes32 name) public virtual override(IERC1643) onlyDocumentManager { DocumentEngineModuleStorage storage $ = _getDocumentEngineModuleStorage(); + Erequire(address($._documentEngine) != address(0), CMTAT_DocumentEngineModule_NoDocumentEngine()); + // Read the metadata before removal so the token can re-emit DocumentRemoved with the removed + // values (spec: "MUST emit DocumentRemoved with the removed metadata"). The forwarded + // removeDocument reverts if the document is missing, so the token only emits after a genuine + // removal. + (string memory uri, bytes32 documentHash, ) = $._documentEngine.getDocument(name); $._documentEngine.removeDocument(name); + emit DocumentRemoved(name, uri, documentHash); }   /* ============ Restricted Functions ============ */ @@ -427,7 +469,7 @@

diff --git a/doc/test/coverage/modules/wrapper/options/ERC20CrossChainModule.sol.html b/doc/test/coverage/modules/wrapper/options/ERC20CrossChainModule.sol.html index e79f3552..b42be92a 100644 --- a/doc/test/coverage/modules/wrapper/options/ERC20CrossChainModule.sol.html +++ b/doc/test/coverage/modules/wrapper/options/ERC20CrossChainModule.sol.html @@ -178,7 +178,13 @@

133 134 135 -136  +136 +137 +138 +139 +140 +141 +142        @@ -210,8 +216,14 @@

      -266× -194× +  +  +  +  +  +  +254× +182×       @@ -222,7 +234,7 @@

      -96× +84× 48×     @@ -251,7 +263,7 @@

      -108× +96× 60×     @@ -281,7 +293,7 @@

      -84× +92×       @@ -315,7 +327,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
 /* ==== OpenZeppelin === */
 import {ERC165Upgradeable, IERC165} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
 /* ==== Module === */
@@ -345,6 +357,12 @@ 

modifier onlyTokenBridge() { // Token bridge should never be impersonated using a relayer/forwarder. Using msg.sender is preferable to // _msgSender() for security reasons. + // + // DEPLOYMENT CONSTRAINT - this is the only role gate in CMTAT that authorizes the raw msg.sender, so a + // bridge MUST call crosschainMint/crosschainBurn directly; a call relayed through the ERC-2771 forwarder + // reverts, because the forwarder is the raw caller. CROSS_CHAIN_ROLE MUST NOT be granted to that + // forwarder to work around it: every relayed call would then pass this gate, letting any user mint an + // arbitrary amount to any address. See doc/technical/cross-chain-bridge-integration.md _checkTokenBridge(msg.sender); _; } @@ -405,7 +423,7 @@

/** * @inheritdoc IBurnFromERC20 * @custom:access-control - * - Protected by the modifier onlyBurnerFrom + * - Protected by the modifier onlySelfBurn (BURNER_SELF_ROLE). */ function burn( uint256 value @@ -454,7 +472,7 @@

diff --git a/doc/test/coverage/modules/wrapper/options/ERC20EnforcementERC7551Module.sol.html b/doc/test/coverage/modules/wrapper/options/ERC20EnforcementERC7551Module.sol.html index 2e232edb..a744fda6 100644 --- a/doc/test/coverage/modules/wrapper/options/ERC20EnforcementERC7551Module.sol.html +++ b/doc/test/coverage/modules/wrapper/options/ERC20EnforcementERC7551Module.sol.html @@ -152,7 +152,7 @@

      -452× +593×       @@ -161,7 +161,7 @@

      -432× +440×       @@ -171,14 +171,14 @@

      -74× -74× -74× -74× +98× +98× +90× +90× 24×   -74× -74× +90× +90×       @@ -188,8 +188,8 @@

      +56× 48× -40×       @@ -205,7 +205,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ERC20EnforcementModule} from "../extensions/ERC20EnforcementModule.sol";
@@ -289,7 +289,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/options/ERC2771Module.sol.html b/doc/test/coverage/modules/wrapper/options/ERC2771Module.sol.html index b4034d57..bfa79f2c 100644 --- a/doc/test/coverage/modules/wrapper/options/ERC2771Module.sol.html +++ b/doc/test/coverage/modules/wrapper/options/ERC2771Module.sol.html @@ -91,7 +91,7 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {ERC2771ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/metatx/ERC2771ContextUpgradeable.sol";
@@ -118,7 +118,7 @@ 

diff --git a/doc/test/coverage/modules/wrapper/options/ERC7551Module.sol.html b/doc/test/coverage/modules/wrapper/options/ERC7551Module.sol.html index 99f786eb..82c8e1d3 100644 --- a/doc/test/coverage/modules/wrapper/options/ERC7551Module.sol.html +++ b/doc/test/coverage/modules/wrapper/options/ERC7551Module.sol.html @@ -22,7 +22,7 @@

100% Statements - 9/9 + 8/8
100% @@ -37,7 +37,7 @@

100% Lines - 11/11 + 10/10

@@ -130,8 +130,8 @@

85 86 87 -88  -  +88 +89        @@ -182,9 +182,11 @@

      - - - +  +  +  + +       @@ -197,7 +199,7 @@

      - +       @@ -219,12 +221,11 @@

   
// SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== Module === */
 import {ExtraInformationModule} from "../extensions/ExtraInformationModule.sol";
 /* ==== Tokenization === */
-import {IERC1643CMTAT} from "../../../interfaces/tokenization/draft-IERC1643CMTAT.sol";
 import {IERC7551Document} from "../../../interfaces/tokenization/draft-IERC7551.sol";
  
 /**
@@ -269,8 +270,10 @@ 

* - the caller must have the `EXTRA_INFORMATION_ROLE`. */ function setTerms(bytes32 hash_, string calldata uri_) public virtual override(IERC7551Document) onlyExtraInfoManager { - IERC1643CMTAT.DocumentInfo memory terms_ = IERC1643CMTAT.DocumentInfo("", uri_, hash_); - _setTerms(terms_); + // The ERC-7551 signature carries no document name, so only the document (uri + hash) is + // updated. Forwarding an empty name through _setTerms would silently erase a name set + // through the {ICMTATBase-setTerms} overload. + _setTermsDocument(hash_, uri_); emit Terms(hash_, uri_); }   @@ -310,7 +313,7 @@

diff --git a/doc/test/coverage/modules/wrapper/options/HolderListModule.sol.html b/doc/test/coverage/modules/wrapper/options/HolderListModule.sol.html new file mode 100644 index 00000000..927dbd28 --- /dev/null +++ b/doc/test/coverage/modules/wrapper/options/HolderListModule.sol.html @@ -0,0 +1,440 @@ + + + + Code coverage report for modules/wrapper/options/HolderListModule.sol + + + + + + + +
+
+

+ all files / modules/wrapper/options/ HolderListModule.sol +

+
+
+ 100% + Statements + 23/23 +
+
+ 92.86% + Branches + 13/14 +
+
+ 100% + Functions + 7/7 +
+
+ 100% + Lines + 26/26 +
+
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +28× +28× +  +  +  +  +  +  +22× +22× +  +  +  +  +  +  +  +  +  +10× +10× +10× + +  +  +  +  +  +  +10× +10× +  +  +  +  +  +  +  +  +22× +18× +18× +18× +16× +16× +10× +  +  +  +  +  +  +  +  +  +  +  +  +114× +114× +  +114× +10× +10× +  +  +  +114× +106× +104× +  +  +  +  +  +  +202× +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.24;
+/* ==== OpenZeppelin === */
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
+/* ==== Interfaces === */
+import {IHolderListModule} from "../../../interfaces/modules/IHolderListModule.sol";
+ 
+/**
+ * @title HolderList module
+ * @dev
+ *
+ * Maintains on-chain the set of addresses holding a non-zero balance, with paginated reads.
+ *
+ * The set is kept in sync inside {_update}, so every balance change is covered: transfer,
+ * transferFrom, mint, burn, forced transfer and cross-chain mint/burn.
+ *
+ * Gas: the first transfer to a new address writes two slots (EnumerableSet stores the value
+ * and its index), and the transfer emptying an account clears them. A transfer between
+ * existing holders that leaves both balances non-zero performs no storage write to the set
+ * (no add/remove, no event), but still reads balanceOf(from) and balanceOf(to) and does one
+ * EnumerableSet membership-check SLOAD in add(to) — roughly two warm + one cold SLOAD, no SSTORE.
+ */
+abstract contract HolderListModule is ERC20Upgradeable, IHolderListModule {
+    using EnumerableSet for EnumerableSet.AddressSet;
+ 
+    /* ============ ERC-7201 ============ */
+    // keccak256(abi.encode(uint256(keccak256("CMTAT.storage.HolderListModule")) - 1)) & ~bytes32(uint256(0xff))
+    bytes32 private constant HolderListModuleStorageLocation = 0x93edd3717dec98b474d42a698cc89715a70e7eaf60a2dff7170cc742b7b8ca00;
+ 
+    /* ==== ERC-7201 State Variables === */
+    struct HolderListModuleStorage {
+        EnumerableSet.AddressSet _holders;
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============ View functions ============ */
+    /**
+    * @inheritdoc IHolderListModule
+    */
+    function holderCount() public view virtual returns (uint256) {
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        return $._holders.length();
+    }
+ 
+    /**
+    * @inheritdoc IHolderListModule
+    */
+    function isHolder(address account) public view virtual returns (bool) {
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        return $._holders.contains(account);
+    }
+ 
+    /**
+    * @inheritdoc IHolderListModule
+    * @dev The bound is checked here so that an out-of-range index reverts with
+    * {CMTAT_HolderListModule_IndexOutOfBounds} rather than with the `Panic(0x32)` that
+    * {EnumerableSet-at} raises on an out-of-bounds array access.
+    */
+    function holderByIndex(uint256 index) public view virtual returns (address) {
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        uint256 holderCountLocal = $._holders.length();
+        require(index < holderCountLocal, CMTAT_HolderListModule_IndexOutOfBounds(index, holderCountLocal));
+        return $._holders.at(index);
+    }
+ 
+    /**
+    * @inheritdoc IHolderListModule
+    */
+    function holders() public view virtual returns (address[] memory) {
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        return $._holders.values();
+    }
+ 
+    /**
+    * @inheritdoc IHolderListModule
+    * @dev The malformed-range check is evaluated before the upper-bound check, so an inverted
+    * range reverts with {CMTAT_HolderListModule_InvalidRange} regardless of where the bounds fall.
+    */
+    function holdersInRange(uint256 fromIndex, uint256 toIndex) public view virtual returns (address[] memory window) {
+        require(fromIndex <= toIndex, CMTAT_HolderListModule_InvalidRange(fromIndex, toIndex));
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        uint256 holderCountLocal = $._holders.length();
+        require(toIndex <= holderCountLocal, CMTAT_HolderListModule_IndexOutOfBounds(toIndex, holderCountLocal));
+        window = new address[](toIndex - fromIndex);
+        for (uint256 i = 0; i < window.length; ++i) {
+            window[i] = $._holders.at(fromIndex + i);
+        }
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /**
+    * @dev Update the holder set after the balances have been written by {ERC20Upgradeable-_update}.
+    * The post-update balance is what decides membership, so the sender is evaluated after it has
+    * been debited and the receiver after it has been credited.
+    */
+    function _update(address from, address to, uint256 value) internal virtual override(ERC20Upgradeable) {
+        super._update(from, to, value);
+        HolderListModuleStorage storage $ = _getHolderListModuleStorage();
+        // address(0) is the mint source and the burn sink, never a holder
+        if (from != address(0) && balanceOf(from) == 0) {
+            Eif ($._holders.remove(from)) {
+                emit HolderRemoved(from);
+            }
+        }
+        // a zero-value transfer to a new address must not make it a holder
+        if (to != address(0) && balanceOf(to) != 0) {
+            if ($._holders.add(to)) {
+                emit HolderAdded(to);
+            }
+        }
+    }
+ 
+    /* ============ ERC-7201 ============ */
+    function _getHolderListModuleStorage() private pure returns (HolderListModuleStorage storage $) {
+        assembly {
+            $.slot := HolderListModuleStorageLocation
+        }
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/test/coverage/modules/wrapper/options/index.html b/doc/test/coverage/modules/wrapper/options/index.html index 09c6d4a6..b26b6a6d 100644 --- a/doc/test/coverage/modules/wrapper/options/index.html +++ b/doc/test/coverage/modules/wrapper/options/index.html @@ -22,22 +22,22 @@

100% Statements - 96/96 + 123/123
- 92.19% + 91.46% Branches - 59/64 + 75/82
100% Functions - 58/58 + 65/65
100% Lines - 121/121 + 151/151
@@ -114,13 +114,13 @@

DocumentEngineModule.sol
100% - 20/20 - 93.75% - 15/16 + 25/25 + 90% + 18/20 100% 10/10 100% - 24/24 + 29/29 @@ -166,13 +166,26 @@

ERC7551Module.sol
100% - 9/9 + 8/8 100% 4/4 100% 6/6 100% - 11/11 + 10/10 + + + + HolderListModule.sol +
+ 100% + 23/23 + 92.86% + 13/14 + 100% + 7/7 + 100% + 26/26 @@ -181,7 +194,7 @@

diff --git a/doc/test/coverage/modules/wrapper/security/AccessControlModule.sol.html b/doc/test/coverage/modules/wrapper/security/AccessControlModule.sol.html index 782a55b3..e71599db 100644 --- a/doc/test/coverage/modules/wrapper/security/AccessControlModule.sol.html +++ b/doc/test/coverage/modules/wrapper/security/AccessControlModule.sol.html @@ -94,7 +94,8 @@

49 50 51 -52  +52 +53        @@ -118,13 +119,13 @@

      -5688× +6262×         -5686× +6260×       @@ -138,16 +139,17 @@

      -20013× -12061×   -7952× +21844× +13326× +  +8518×        
//SPDX-License-Identifier: MPL-2.0
  
-pragma solidity ^0.8.20;
+pragma solidity ^0.8.24;
  
 /* ==== OpenZeppelin === */
 import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
@@ -181,8 +183,9 @@ 

/*////////////////////////////////////////////////////////////// PUBLIC/EXTERNAL FUNCTIONS //////////////////////////////////////////////////////////////*/ - /** + /** * @dev Returns `true` if `account` has been granted `role`. + * @return True if `account` holds `role` (the default admin implicitly holds every role). */ function hasRole( bytes32 role, @@ -202,7 +205,7 @@

diff --git a/doc/test/coverage/modules/wrapper/security/index.html b/doc/test/coverage/modules/wrapper/security/index.html index b9f1cf8c..1aa359c9 100644 --- a/doc/test/coverage/modules/wrapper/security/index.html +++ b/doc/test/coverage/modules/wrapper/security/index.html @@ -77,7 +77,7 @@

diff --git a/foundry.toml b/foundry.toml index 3f3a47ac..80798f1a 100644 --- a/foundry.toml +++ b/foundry.toml @@ -3,7 +3,7 @@ src = "contracts" test = "test" script = "script" out = "out" -solc_version = "0.8.34" +solc_version = "0.8.36" evm_version = "osaka" optimizer = true optimizer_runs = 200 diff --git a/hardhat.config.js b/hardhat.config.js index 4da5f063..d49163f5 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -4,6 +4,14 @@ require('solidity-coverage') require("hardhat-contract-sizer"); require("@nomicfoundation/hardhat-chai-matchers") +// solidity-coverage instruments every contract, and the instrumented bytecode of +// the largest deployment variants costs more than the EIP-7825 per-transaction +// gas cap (2**24 = 16,777,216 gas) to deploy, which the `osaka` hardfork enforces +// ("Transaction ran out of gas"). Coverage runs therefore fall back to `prague`, +// the last hardfork before that cap; HARDHAT_HARDFORK overrides both. +const isCoverageRun = process.argv.includes("coverage"); +const hardfork = process.env.HARDHAT_HARDFORK || (isCoverageRun ? "prague" : "osaka"); + const deactivateReportGas = process.env.DeactivateReportGas === "true" || process.env.DeactivateReportGas === "1"; const reportGas = !deactivateReportGas; if (reportGas) { @@ -12,6 +20,9 @@ if (reportGas) { module.exports = { networks: { hardhat: { + // `osaka` for the test run (same target as the compiler), `prague` under + // coverage — see the isCoverageRun comment above. + hardfork, blockGasLimit: 30000000, // Test-only: relaxes the runtime EIP-170 (24 KB) deploy check so oversized // test *mocks* (e.g. CMTATUpgradeableERC1363MsgDataMock, which extends the @@ -23,7 +34,7 @@ module.exports = { } }, solidity: { - version: '0.8.34', + version: '0.8.36', settings: { optimizer: { enabled: true, diff --git a/package-lock.json b/package-lock.json index 0012d8d5..636935f7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,7 +30,7 @@ "ethlint": "^1.2.5", "hardhat-contract-sizer": "^2.10.0", "hardhat-gas-reporter": "^1.0.9", - "npm": "^10.2.5", + "npm": "^12.0.1", "prettier": "^2.8.7", "prettier-plugin-solidity": "^1.1.3", "sol2uml": "^2.5.20", @@ -10709,15 +10709,17 @@ } }, "node_modules/npm": { - "version": "10.9.8", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.9.8.tgz", - "integrity": "sha512-fYwb6ODSmHkqrJQQaCxY3M2lPf/mpgC7ik0HSzzIwG5CGtabRp4bNqikatvCoT42b5INQSqudVH0R7yVmC9hVg==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/npm/-/npm-12.0.1.tgz", + "integrity": "sha512-L5T9i/YAQWQWqTS/xZxJkei/9zcu99hCeE4qi41IyBVV7mRQad3qc2JfuOktwmH+qwGI/V2rbCL+/UYxb1+RQA==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", "@npmcli/config", "@npmcli/fs", + "@npmcli/git", "@npmcli/map-workspaces", + "@npmcli/metavuln-calculator", "@npmcli/package-json", "@npmcli/promise-spawn", "@npmcli/redact", @@ -10725,10 +10727,11 @@ "@sigstore/tuf", "abbrev", "archy", + "bin-links", "cacache", "chalk", "ci-info", - "cli-columns", + "diff", "fastest-levenshtein", "fs-minipass", "glob", @@ -10742,7 +10745,6 @@ "libnpmdiff", "libnpmexec", "libnpmfund", - "libnpmhook", "libnpmorg", "libnpmpack", "libnpmpublish", @@ -10756,7 +10758,6 @@ "ms", "node-gyp", "nopt", - "normalize-package-data", "npm-audit-report", "npm-install-checks", "npm-package-arg", @@ -10779,8 +10780,7 @@ "tiny-relative-date", "treeverse", "validate-npm-package-name", - "which", - "write-file-atomic" + "which" ], "dev": true, "license": "Artistic-2.0", @@ -10793,80 +10793,80 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^8.0.5", - "@npmcli/config": "^9.0.0", - "@npmcli/fs": "^4.0.0", - "@npmcli/map-workspaces": "^4.0.2", - "@npmcli/package-json": "^6.2.0", - "@npmcli/promise-spawn": "^8.0.3", - "@npmcli/redact": "^3.2.2", - "@npmcli/run-script": "^9.1.0", - "@sigstore/tuf": "^3.1.1", - "abbrev": "^3.0.1", + "@npmcli/arborist": "^10.0.1", + "@npmcli/config": "^11.0.0", + "@npmcli/fs": "^6.0.0", + "@npmcli/git": "^8.0.0", + "@npmcli/map-workspaces": "^6.0.0", + "@npmcli/metavuln-calculator": "^10.0.0", + "@npmcli/package-json": "^8.0.0", + "@npmcli/promise-spawn": "^10.0.0", + "@npmcli/redact": "^5.0.0", + "@npmcli/run-script": "^11.0.0", + "@sigstore/tuf": "^5.0.0", + "abbrev": "^5.0.0", "archy": "~1.0.0", - "cacache": "^19.0.1", + "bin-links": "^7.0.0", + "cacache": "^21.0.1", "chalk": "^5.6.2", "ci-info": "^4.4.0", - "cli-columns": "^4.0.0", + "diff": "^8.0.2", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.5.0", + "glob": "^13.0.6", "graceful-fs": "^4.2.11", - "hosted-git-info": "^8.1.0", - "ini": "^5.0.0", - "init-package-json": "^7.0.2", - "is-cidr": "^5.1.1", - "json-parse-even-better-errors": "^4.0.0", - "libnpmaccess": "^9.0.0", - "libnpmdiff": "^7.0.5", - "libnpmexec": "^9.0.5", - "libnpmfund": "^6.0.5", - "libnpmhook": "^11.0.0", - "libnpmorg": "^7.0.0", - "libnpmpack": "^8.0.5", - "libnpmpublish": "^10.0.2", - "libnpmsearch": "^8.0.0", - "libnpmteam": "^7.0.0", - "libnpmversion": "^7.0.0", - "make-fetch-happen": "^14.0.3", - "minimatch": "^9.0.9", + "hosted-git-info": "^10.1.1", + "ini": "^7.0.0", + "init-package-json": "^9.0.0", + "is-cidr": "^7.0.0", + "json-parse-even-better-errors": "^6.0.0", + "libnpmaccess": "^11.0.0", + "libnpmdiff": "^9.0.1", + "libnpmexec": "^11.0.1", + "libnpmfund": "^8.0.1", + "libnpmorg": "^9.0.0", + "libnpmpack": "^10.0.1", + "libnpmpublish": "^12.0.0", + "libnpmsearch": "^10.0.0", + "libnpmteam": "^9.0.0", + "libnpmversion": "^9.0.0", + "make-fetch-happen": "^16.0.1", + "minimatch": "^10.2.5", "minipass": "^7.1.3", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", - "node-gyp": "^11.5.0", - "nopt": "^8.1.0", - "normalize-package-data": "^7.0.1", - "npm-audit-report": "^6.0.0", - "npm-install-checks": "^7.1.2", - "npm-package-arg": "^12.0.2", - "npm-pick-manifest": "^10.0.0", - "npm-profile": "^11.0.1", - "npm-registry-fetch": "^18.0.2", - "npm-user-validate": "^3.0.0", + "node-gyp": "^13.0.0", + "nopt": "^10.0.1", + "npm-audit-report": "^8.0.0", + "npm-install-checks": "^9.0.0", + "npm-package-arg": "^14.0.0", + "npm-pick-manifest": "^12.0.0", + "npm-profile": "^13.0.1", + "npm-registry-fetch": "^20.0.1", + "npm-user-validate": "^5.0.0", "p-map": "^7.0.4", - "pacote": "^19.0.1", - "parse-conflict-json": "^4.0.0", - "proc-log": "^5.0.0", + "pacote": "^22.0.0", + "parse-conflict-json": "^6.0.0", + "proc-log": "^7.0.0", "qrcode-terminal": "^0.12.0", - "read": "^4.1.0", - "semver": "^7.7.4", + "read": "^6.0.0", + "semver": "^7.8.5", "spdx-expression-parse": "^4.0.0", - "ssri": "^12.0.0", - "supports-color": "^9.4.0", - "tar": "^7.5.11", + "ssri": "^14.0.0", + "supports-color": "^10.2.2", + "tar": "^7.5.19", "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", + "tiny-relative-date": "^2.0.2", "treeverse": "^3.0.0", - "validate-npm-package-name": "^6.0.2", - "which": "^5.0.0", - "write-file-atomic": "^6.0.0" + "validate-npm-package-name": "^8.0.0", + "which": "^7.0.0" }, "bin": { "npm": "bin/npm-cli.js", "npx": "bin/npx-cli.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm-run-path": { @@ -10892,178 +10892,157 @@ "node": ">=4" } }, - "node_modules/npm/node_modules/@isaacs/cliui": { - "version": "8.0.2", + "node_modules/npm/node_modules/@gar/promise-retry": { + "version": "1.0.3", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, + "license": "MIT", "engines": { - "node": ">=12" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", "dev": true, "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "engines": { + "node": ">=18.0.0" } }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", "dev": true, "inBundle": true, - "license": "MIT" + "license": "ISC" }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "5.0.2", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "agent-base": "^9.0.0", + "http-proxy-agent": "^9.0.0", + "https-proxy-agent": "^9.0.0", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^10.0.0" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.2.0", + "node_modules/npm/node_modules/@npmcli/agent/node_modules/agent-base": { + "version": "9.0.0", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">= 20" } }, - "node_modules/npm/node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", + "node_modules/npm/node_modules/@npmcli/agent/node_modules/http-proxy-agent": { + "version": "9.1.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "minipass": "^7.0.4" + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" }, "engines": { - "node": ">=18.0.0" + "node": ">= 20" } }, - "node_modules/npm/node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/agent": { - "version": "3.0.0", + "node_modules/npm/node_modules/@npmcli/agent/node_modules/https-proxy-agent": { + "version": "9.1.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" + "agent-base": "9.0.0", + "debug": "^4.3.4", + "proxy-agent-negotiate": "1.1.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 20" } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "8.0.5", + "version": "10.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@gar/promise-retry": "^1.0.0", "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^4.0.0", - "@npmcli/installed-package-contents": "^3.0.0", - "@npmcli/map-workspaces": "^4.0.1", - "@npmcli/metavuln-calculator": "^8.0.0", - "@npmcli/name-from-folder": "^3.0.0", - "@npmcli/node-gyp": "^4.0.0", - "@npmcli/package-json": "^6.0.1", - "@npmcli/query": "^4.0.0", - "@npmcli/redact": "^3.0.0", - "@npmcli/run-script": "^9.0.1", - "bin-links": "^5.0.0", - "cacache": "^19.0.1", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^8.0.0", - "json-parse-even-better-errors": "^4.0.0", + "@npmcli/fs": "^6.0.0", + "@npmcli/installed-package-contents": "^5.0.0", + "@npmcli/map-workspaces": "^6.0.0", + "@npmcli/metavuln-calculator": "^10.0.0", + "@npmcli/name-from-folder": "^5.0.0", + "@npmcli/node-gyp": "^6.0.0", + "@npmcli/package-json": "^8.0.0", + "@npmcli/query": "^5.0.0", + "@npmcli/redact": "^5.0.0", + "@npmcli/run-script": "^11.0.0", + "bin-links": "^7.0.0", + "cacache": "^21.0.1", + "common-ancestor-path": "^2.0.0", + "diff": "^8.0.2", + "hosted-git-info": "^10.1.1", "json-stringify-nice": "^1.1.4", - "lru-cache": "^10.2.2", - "minimatch": "^9.0.4", - "nopt": "^8.0.0", - "npm-install-checks": "^7.1.0", - "npm-package-arg": "^12.0.0", - "npm-pick-manifest": "^10.0.0", - "npm-registry-fetch": "^18.0.1", - "pacote": "^19.0.0", - "parse-conflict-json": "^4.0.0", - "proc-log": "^5.0.0", - "proggy": "^3.0.0", + "lru-cache": "^11.2.1", + "minimatch": "^10.0.3", + "nopt": "^10.0.1", + "npm-install-checks": "^9.0.0", + "npm-package-arg": "^14.0.0", + "npm-pick-manifest": "^12.0.0", + "npm-registry-fetch": "^20.0.1", + "pacote": "^22.0.0", + "parse-conflict-json": "^6.0.0", + "proc-log": "^7.0.0", + "proggy": "^4.0.0", "promise-all-reject-late": "^1.0.0", "promise-call-limit": "^3.0.1", - "promise-retry": "^2.0.1", - "read-package-json-fast": "^4.0.0", "semver": "^7.3.7", - "ssri": "^12.0.0", + "ssri": "^14.0.0", "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" + "validate-npm-package-name": "^8.0.0", + "walk-up-path": "^4.0.0" }, "bin": { "arborist": "bin/index.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "9.0.0", + "version": "11.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/map-workspaces": "^4.0.1", - "@npmcli/package-json": "^6.0.1", + "@npmcli/map-workspaces": "^6.0.0", + "@npmcli/package-json": "^8.0.0", "ci-info": "^4.0.0", - "ini": "^5.0.0", - "nopt": "^8.0.0", - "proc-log": "^5.0.0", + "ini": "^7.0.0", + "nopt": "^10.0.1", + "proc-log": "^7.0.0", "semver": "^7.3.5", - "walk-up-path": "^3.0.1" + "walk-up-path": "^4.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/fs": { - "version": "4.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -11071,156 +11050,146 @@ "semver": "^7.3.5" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/git": { - "version": "6.0.3", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/promise-spawn": "^8.0.0", - "ini": "^5.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^10.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", + "@gar/promise-retry": "^1.0.0", + "@npmcli/promise-spawn": "^10.0.0", + "ini": "^7.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^12.0.0", + "proc-log": "^7.0.0", "semver": "^7.3.5", - "which": "^5.0.0" + "which": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "3.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-bundled": "^4.0.0", - "npm-normalize-package-bin": "^4.0.0" + "npm-bundled": "^6.0.0", + "npm-normalize-package-bin": "^6.0.0" }, "bin": { "installed-package-contents": "bin/index.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "4.0.2", + "node_modules/npm/node_modules/@npmcli/installed-package-contents/node_modules/npm-bundled": { + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/name-from-folder": "^3.0.0", - "@npmcli/package-json": "^6.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0" + "npm-normalize-package-bin": "^6.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "8.0.1", + "node_modules/npm/node_modules/@npmcli/installed-package-contents/node_modules/npm-normalize-package-bin": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cacache": "^19.0.0", - "json-parse-even-better-errors": "^4.0.0", - "pacote": "^20.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5" + "@npmcli/name-from-folder": "^5.0.0", + "@npmcli/package-json": "^8.0.0", + "glob": "^13.0.0", + "minimatch": "^10.0.3" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator/node_modules/pacote": { - "version": "20.0.1", + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "10.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^6.0.0", - "@npmcli/installed-package-contents": "^3.0.0", - "@npmcli/package-json": "^6.0.0", - "@npmcli/promise-spawn": "^8.0.0", - "@npmcli/run-script": "^9.0.0", - "cacache": "^19.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^12.0.0", - "npm-packlist": "^9.0.0", - "npm-pick-manifest": "^10.0.0", - "npm-registry-fetch": "^18.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "sigstore": "^3.0.0", - "ssri": "^12.0.0", - "tar": "^7.5.10" - }, - "bin": { - "pacote": "bin/index.js" + "cacache": "^21.0.1", + "json-parse-even-better-errors": "^6.0.0", + "pacote": "^22.0.0", + "proc-log": "^7.0.0", + "semver": "^7.3.5" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "3.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "4.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "6.2.0", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^6.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^8.0.0", - "json-parse-even-better-errors": "^4.0.0", - "proc-log": "^5.0.0", + "@npmcli/git": "^8.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^10.1.1", + "json-parse-even-better-errors": "^6.0.0", + "proc-log": "^7.0.0", "semver": "^7.5.3", - "validate-npm-package-license": "^3.0.4" + "spdx-expression-parse": "^4.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "8.0.3", + "version": "10.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "which": "^5.0.0" + "which": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "4.0.1", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -11228,68 +11197,57 @@ "postcss-selector-parser": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/@npmcli/redact": { - "version": "3.2.2", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "9.1.0", + "version": "11.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/node-gyp": "^4.0.0", - "@npmcli/package-json": "^6.0.0", - "@npmcli/promise-spawn": "^8.0.0", - "node-gyp": "^11.0.0", - "proc-log": "^5.0.0", - "which": "^5.0.0" + "@npmcli/node-gyp": "^6.0.0", + "@npmcli/package-json": "^8.0.0", + "@npmcli/promise-spawn": "^10.0.0", + "node-gyp": "^13.0.0", + "proc-log": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "3.1.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.4.0" + "@sigstore/protobuf-specs": "^0.5.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@sigstore/core": { - "version": "2.0.0", + "version": "4.0.1", "dev": true, "inBundle": true, "license": "Apache-2.0", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.4.3", + "version": "0.5.1", "dev": true, "inBundle": true, "license": "Apache-2.0", @@ -11298,47 +11256,47 @@ } }, "node_modules/npm/node_modules/@sigstore/sign": { - "version": "3.1.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^3.1.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.4.0", - "make-fetch-happen": "^14.0.2", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1" + "@gar/promise-retry": "^1.0.2", + "@sigstore/bundle": "^5.0.0", + "@sigstore/core": "^4.0.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^16.0.0", + "proc-log": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "3.1.1", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/protobuf-specs": "^0.4.1", - "tuf-js": "^3.0.1" + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^6.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@sigstore/verify": { - "version": "2.1.1", + "version": "4.1.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^3.1.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.4.1" + "@sigstore/bundle": "^5.0.0", + "@sigstore/core": "^4.0.1", + "@sigstore/protobuf-specs": "^0.5.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/@tufjs/canonical-json": { @@ -11350,43 +11308,26 @@ "node": "^16.14.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/abbrev": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/agent-base": { - "version": "7.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", + "node_modules/npm/node_modules/@tufjs/models": { + "version": "5.0.0", "dev": true, "inBundle": true, "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.2.1" + }, "engines": { - "node": ">=8" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/ansi-styles": { - "version": "6.2.3", + "node_modules/npm/node_modules/abbrev": { + "version": "5.0.0", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/aproba": { @@ -11402,69 +11343,100 @@ "license": "MIT" }, "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", + "version": "4.0.4", "dev": true, "inBundle": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/npm/node_modules/bin-links": { - "version": "5.0.0", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "cmd-shim": "^7.0.0", - "npm-normalize-package-bin": "^4.0.0", - "proc-log": "^5.0.0", - "read-cmd-shim": "^5.0.0", - "write-file-atomic": "^6.0.0" + "cmd-shim": "^9.0.0", + "npm-normalize-package-bin": "^6.0.0", + "proc-log": "^7.0.0", + "read-cmd-shim": "^7.0.0", + "write-file-atomic": "^8.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + } + }, + "node_modules/npm/node_modules/bin-links/node_modules/cmd-shim": { + "version": "9.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + } + }, + "node_modules/npm/node_modules/bin-links/node_modules/npm-normalize-package-bin": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + } + }, + "node_modules/npm/node_modules/bin-links/node_modules/read-cmd-shim": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/binary-extensions": { - "version": "2.3.0", + "version": "3.1.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.2", + "version": "5.0.7", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" } }, "node_modules/npm/node_modules/cacache": { - "version": "19.0.1", + "version": "21.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/fs": "^4.0.0", + "@npmcli/fs": "^6.0.0", "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", "minipass": "^7.0.3", "minipass-collect": "^2.0.1", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "p-map": "^7.0.2", - "ssri": "^12.0.0", - "tar": "^7.4.3", - "unique-filename": "^4.0.0" + "ssri": "^14.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/chalk": { @@ -11504,90 +11476,21 @@ } }, "node_modules/npm/node_modules/cidr-regex": { - "version": "4.1.3", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "^5.0.0" - }, "engines": { - "node": ">=14" + "node": ">=22" } }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "2.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, + "license": "BlueOak-1.0.0", "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/cmd-shim": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/npm/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.6", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" + "node": ">= 18" } }, "node_modules/npm/node_modules/cssesc": { @@ -11620,7 +11523,7 @@ } }, "node_modules/npm/node_modules/diff": { - "version": "5.2.2", + "version": "8.0.4", "dev": true, "inBundle": true, "license": "BSD-3-Clause", @@ -11628,28 +11531,6 @@ "node": ">=0.3.1" } }, - "node_modules/npm/node_modules/eastasianwidth": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, "node_modules/npm/node_modules/env-paths": { "version": "2.2.1", "dev": true, @@ -11659,12 +11540,6 @@ "node": ">=6" } }, - "node_modules/npm/node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, "node_modules/npm/node_modules/exponential-backoff": { "version": "3.1.3", "dev": true, @@ -11680,39 +11555,6 @@ "node": ">= 4.9.1" } }, - "node_modules/npm/node_modules/fdir": { - "version": "6.5.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/foreground-child": { - "version": "3.3.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/npm/node_modules/fs-minipass": { "version": "3.0.3", "dev": true, @@ -11726,20 +11568,17 @@ } }, "node_modules/npm/node_modules/glob": { - "version": "10.5.0", + "version": "13.0.6", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "minimatch": "^10.2.2", + "minipass": "^7.1.3", + "path-scurry": "^2.0.2" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -11752,15 +11591,15 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "8.1.0", + "version": "10.1.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "lru-cache": "^10.0.1" + "lru-cache": "^11.1.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/http-cache-semantics": { @@ -11769,34 +11608,8 @@ "inBundle": true, "license": "BSD-2-Clause" }, - "node_modules/npm/node_modules/http-proxy-agent": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.6", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", + "version": "0.7.3", "dev": true, "inBundle": true, "license": "MIT", @@ -11806,58 +11619,40 @@ }, "engines": { "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/ignore-walk": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minimatch": "^9.0.0" }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/npm/node_modules/ini": { - "version": "5.0.0", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/init-package-json": { - "version": "7.0.2", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/package-json": "^6.0.0", - "npm-package-arg": "^12.0.0", - "promzard": "^2.0.0", - "read": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^6.0.0" + "@npmcli/package-json": "^8.0.0", + "npm-package-arg": "^14.0.0", + "promzard": "^4.0.0", + "read": "^6.0.0", + "semver": "^7.7.2", + "validate-npm-package-name": "^8.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/ip-address": { - "version": "10.1.0", + "version": "10.2.0", "dev": true, "inBundle": true, "license": "MIT", @@ -11865,67 +11660,34 @@ "node": ">= 12" } }, - "node_modules/npm/node_modules/ip-regex": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/npm/node_modules/is-cidr": { - "version": "5.1.1", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "dependencies": { - "cidr-regex": "^4.1.1" + "cidr-regex": "^6.0.0" }, "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" + "node": ">=22" } }, "node_modules/npm/node_modules/isexe": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/jackspeak": { - "version": "3.4.3", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" + "engines": { + "node": ">=20" } }, "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "4.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/json-stringify-nice": { @@ -11959,209 +11721,202 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "9.0.0", + "version": "11.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^12.0.0", - "npm-registry-fetch": "^18.0.1" + "npm-package-arg": "^14.0.0", + "npm-registry-fetch": "^20.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "7.0.5", + "version": "9.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.5", - "@npmcli/installed-package-contents": "^3.0.0", - "binary-extensions": "^2.3.0", - "diff": "^5.1.0", - "minimatch": "^9.0.4", - "npm-package-arg": "^12.0.0", - "pacote": "^19.0.0", - "tar": "^7.5.11" + "@npmcli/arborist": "^10.0.1", + "@npmcli/installed-package-contents": "^5.0.0", + "binary-extensions": "^3.0.0", + "diff": "^8.0.2", + "minimatch": "^10.0.3", + "npm-package-arg": "^14.0.0", + "pacote": "^22.0.0", + "tar": "^7.5.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "9.0.5", + "version": "11.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.5", - "@npmcli/run-script": "^9.0.1", + "@gar/promise-retry": "^1.0.0", + "@npmcli/arborist": "^10.0.1", + "@npmcli/package-json": "^8.0.0", + "@npmcli/run-script": "^11.0.0", "ci-info": "^4.0.0", - "npm-package-arg": "^12.0.0", - "pacote": "^19.0.0", - "proc-log": "^5.0.0", - "read": "^4.0.0", - "read-package-json-fast": "^4.0.0", + "npm-package-arg": "^14.0.0", + "pacote": "^22.0.0", + "proc-log": "^7.0.0", + "read": "^6.0.0", "semver": "^7.3.7", - "walk-up-path": "^3.0.1" + "signal-exit": "^4.1.0", + "walk-up-path": "^4.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "6.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^8.0.5" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/libnpmhook": { - "version": "11.0.0", + "version": "8.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^18.0.1" + "@npmcli/arborist": "^10.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "7.0.0", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^18.0.1" + "npm-registry-fetch": "^20.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "8.0.5", + "version": "10.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^8.0.5", - "@npmcli/run-script": "^9.0.1", - "npm-package-arg": "^12.0.0", - "pacote": "^19.0.0" + "@npmcli/arborist": "^10.0.1", + "@npmcli/run-script": "^11.0.0", + "npm-package-arg": "^14.0.0", + "pacote": "^22.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "10.0.2", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { + "@npmcli/package-json": "^8.0.0", "ci-info": "^4.0.0", - "normalize-package-data": "^7.0.0", - "npm-package-arg": "^12.0.0", - "npm-registry-fetch": "^18.0.1", - "proc-log": "^5.0.0", + "npm-package-arg": "^14.0.0", + "npm-registry-fetch": "^20.0.1", + "proc-log": "^7.0.0", "semver": "^7.3.7", - "sigstore": "^3.0.0", - "ssri": "^12.0.0" + "sigstore": "^5.0.0", + "ssri": "^14.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmsearch": { - "version": "8.0.0", + "version": "10.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^18.0.1" + "npm-registry-fetch": "^20.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmteam": { - "version": "7.0.0", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { "aproba": "^2.0.0", - "npm-registry-fetch": "^18.0.1" + "npm-registry-fetch": "^20.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/libnpmversion": { - "version": "7.0.0", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^6.0.1", - "@npmcli/run-script": "^9.0.1", - "json-parse-even-better-errors": "^4.0.0", - "proc-log": "^5.0.0", + "@npmcli/git": "^8.0.0", + "@npmcli/run-script": "^11.0.0", + "json-parse-even-better-errors": "^6.0.0", + "proc-log": "^7.0.0", "semver": "^7.3.7" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/lru-cache": { - "version": "10.4.3", + "version": "11.5.2", "dev": true, "inBundle": true, - "license": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, "node_modules/npm/node_modules/make-fetch-happen": { - "version": "14.0.3", + "version": "16.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/agent": "^3.0.0", - "cacache": "^19.0.1", + "@gar/promise-retry": "^1.0.0", + "@npmcli/agent": "^5.0.0", + "@npmcli/redact": "^5.0.0", + "cacache": "^21.0.0", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", - "minipass-fetch": "^4.0.0", + "minipass-fetch": "^6.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "ssri": "^12.0.0" + "proc-log": "^7.0.0", + "ssri": "^14.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/minimatch": { - "version": "9.0.9", + "version": "10.2.5", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.2" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -12189,52 +11944,34 @@ } }, "node_modules/npm/node_modules/minipass-fetch": { - "version": "4.0.1", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", + "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" }, "optionalDependencies": { - "encoding": "^0.1.13" + "iconv-lite": "^0.7.2" } }, "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", + "version": "1.0.6", "dev": true, "inBundle": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.3" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, - "node_modules/npm/node_modules/minipass-flush/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/minipass-pipeline": { "version": "1.2.4", "dev": true, @@ -12266,35 +12003,17 @@ "license": "ISC" }, "node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", + "version": "2.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "yallist": "^4.0.0" + "minipass": "^7.1.2" }, "engines": { "node": ">=8" } }, - "node_modules/npm/node_modules/minipass-sized/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/npm/node_modules/minizlib": { "version": "3.1.0", "dev": true, @@ -12314,12 +12033,12 @@ "license": "MIT" }, "node_modules/npm/node_modules/mute-stream": { - "version": "2.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/negotiator": { @@ -12332,7 +12051,7 @@ } }, "node_modules/npm/node_modules/node-gyp": { - "version": "11.5.0", + "version": "13.0.0", "dev": true, "inBundle": true, "license": "MIT", @@ -12340,73 +12059,47 @@ "env-paths": "^2.2.0", "exponential-backoff": "^3.1.1", "graceful-fs": "^4.2.6", - "make-fetch-happen": "^14.0.3", - "nopt": "^8.0.0", - "proc-log": "^5.0.0", + "nopt": "^10.0.0", + "proc-log": "^7.0.0", "semver": "^7.3.5", - "tar": "^7.4.3", + "tar": "^7.5.4", "tinyglobby": "^0.2.12", - "which": "^5.0.0" + "undici": "^6.25.0", + "which": "^7.0.0" }, "bin": { "node-gyp": "bin/node-gyp.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/nopt": { - "version": "8.1.0", + "version": "10.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "abbrev": "^3.0.0" + "abbrev": "^5.0.0" }, "bin": { "nopt": "bin/nopt.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/normalize-package-data": { - "version": "7.0.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^8.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/npm-audit-report": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/npm-bundled": { - "version": "4.0.0", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^4.0.0" - }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/npm-install-checks": { - "version": "7.1.2", + "version": "9.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", @@ -12414,103 +12107,117 @@ "semver": "^7.1.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "4.0.0", + "node_modules/npm/node_modules/npm-package-arg": { + "version": "14.0.0", "dev": true, "inBundle": true, "license": "ISC", + "dependencies": { + "hosted-git-info": "^10.1.0", + "proc-log": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^8.0.0" + }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/npm-package-arg": { - "version": "12.0.2", + "node_modules/npm/node_modules/npm-packlist": { + "version": "11.3.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "hosted-git-info": "^8.0.0", - "proc-log": "^5.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^6.0.0" + "glob": "^13.0.6", + "ignore-walk": "^9.0.0", + "proc-log": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/npm-packlist": { + "node_modules/npm/node_modules/npm-packlist/node_modules/ignore-walk": { "version": "9.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "ignore-walk": "^7.0.0" + "minimatch": "^10.0.3" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "10.0.0", + "version": "12.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-install-checks": "^7.1.0", - "npm-normalize-package-bin": "^4.0.0", - "npm-package-arg": "^12.0.0", + "npm-install-checks": "^9.0.0", + "npm-normalize-package-bin": "^6.0.0", + "npm-package-arg": "^14.0.0", "semver": "^7.3.5" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest/node_modules/npm-normalize-package-bin": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/npm-profile": { - "version": "11.0.1", + "version": "13.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "npm-registry-fetch": "^18.0.0", - "proc-log": "^5.0.0" + "npm-registry-fetch": "^20.0.0", + "proc-log": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "18.0.2", + "version": "20.0.1", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/redact": "^3.0.0", + "@npmcli/redact": "^5.0.0", "jsonparse": "^1.3.1", - "make-fetch-happen": "^14.0.0", + "make-fetch-happen": "^16.0.0", "minipass": "^7.0.2", - "minipass-fetch": "^4.0.0", + "minipass-fetch": "^6.0.0", "minizlib": "^3.0.1", - "npm-package-arg": "^12.0.0", - "proc-log": "^5.0.0" + "npm-package-arg": "^14.0.0", + "proc-log": "^7.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/npm-user-validate": { - "version": "3.0.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "BSD-2-Clause", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/p-map": { - "version": "7.0.4", + "version": "7.0.5", "dev": true, "inBundle": true, "license": "MIT", @@ -12521,96 +12228,69 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/npm/node_modules/package-json-from-dist": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0" - }, "node_modules/npm/node_modules/pacote": { - "version": "19.0.2", + "version": "22.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/git": "^6.0.0", - "@npmcli/installed-package-contents": "^3.0.0", - "@npmcli/package-json": "^6.0.0", - "@npmcli/promise-spawn": "^8.0.0", - "@npmcli/run-script": "^9.0.0", - "cacache": "^19.0.0", + "@gar/promise-retry": "^1.0.0", + "@npmcli/git": "^8.0.0", + "@npmcli/installed-package-contents": "^5.0.0", + "@npmcli/package-json": "^8.0.0", + "@npmcli/promise-spawn": "^10.0.0", + "@npmcli/run-script": "^11.0.0", + "cacache": "^21.0.1", "fs-minipass": "^3.0.0", "minipass": "^7.0.2", - "npm-package-arg": "^12.0.0", - "npm-packlist": "^9.0.0", - "npm-pick-manifest": "^10.0.0", - "npm-registry-fetch": "^18.0.0", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1", - "sigstore": "^3.0.0", - "ssri": "^12.0.0", - "tar": "^7.5.10" + "npm-package-arg": "^14.0.0", + "npm-packlist": "^11.2.0", + "npm-pick-manifest": "^12.0.0", + "npm-registry-fetch": "^20.0.1", + "proc-log": "^7.0.0", + "sigstore": "^5.0.0", + "ssri": "^14.0.0", + "tar": "^7.4.3" }, "bin": { "pacote": "bin/index.js" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/parse-conflict-json": { - "version": "4.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^4.0.0", + "json-parse-even-better-errors": "^6.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/path-key": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/path-scurry": { - "version": "1.11.1", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/picomatch": { - "version": "4.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "7.1.1", + "version": "7.1.4", "dev": true, "inBundle": true, "license": "MIT", @@ -12623,21 +12303,21 @@ } }, "node_modules/npm/node_modules/proc-log": { - "version": "5.0.0", + "version": "7.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/proggy": { - "version": "3.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/npm/node_modules/promise-all-reject-late": { @@ -12658,29 +12338,33 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", + "node_modules/npm/node_modules/promzard": { + "version": "4.0.0", "dev": true, "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" + "read": "^6.0.0" }, "engines": { - "node": ">=10" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/promzard": { - "version": "2.0.0", + "node_modules/npm/node_modules/proxy-agent-negotiate": { + "version": "1.1.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "^4.0.0" - }, + "license": "MIT", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">= 20" + }, + "peerDependencies": { + "kerberos": "^2.0.0" + }, + "peerDependenciesMeta": { + "kerberos": { + "optional": true + } } }, "node_modules/npm/node_modules/qrcode-terminal": { @@ -12692,46 +12376,15 @@ } }, "node_modules/npm/node_modules/read": { - "version": "4.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "^2.0.0" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/read-cmd-shim": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/read-package-json-fast": { - "version": "4.0.0", + "version": "6.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "json-parse-even-better-errors": "^4.0.0", - "npm-normalize-package-bin": "^4.0.0" + "mute-stream": "^4.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/retry": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/safer-buffer": { @@ -12742,7 +12395,7 @@ "optional": true }, "node_modules/npm/node_modules/semver": { - "version": "7.7.4", + "version": "7.8.5", "dev": true, "inBundle": true, "license": "ISC", @@ -12753,27 +12406,6 @@ "node": ">=10" } }, - "node_modules/npm/node_modules/shebang-command": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/shebang-regex": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/npm/node_modules/signal-exit": { "version": "4.1.0", "dev": true, @@ -12787,20 +12419,20 @@ } }, "node_modules/npm/node_modules/sigstore": { - "version": "3.1.0", + "version": "5.0.0", "dev": true, "inBundle": true, "license": "Apache-2.0", "dependencies": { - "@sigstore/bundle": "^3.1.0", - "@sigstore/core": "^2.0.0", - "@sigstore/protobuf-specs": "^0.4.0", - "@sigstore/sign": "^3.1.0", - "@sigstore/tuf": "^3.1.0", - "@sigstore/verify": "^2.1.0" + "@sigstore/bundle": "^5.0.0", + "@sigstore/core": "^4.0.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^5.0.0", + "@sigstore/tuf": "^5.0.0", + "@sigstore/verify": "^4.0.0" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/smart-buffer": { @@ -12814,12 +12446,12 @@ } }, "node_modules/npm/node_modules/socks": { - "version": "2.8.7", + "version": "2.8.9", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "ip-address": "^10.0.1", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -12828,37 +12460,26 @@ } }, "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.5", + "version": "10.1.0", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { - "agent-base": "^7.1.2", + "agent-base": "9.0.0", "debug": "^4.3.4", "socks": "^2.8.3" }, "engines": { - "node": ">= 14" + "node": ">= 20" } }, - "node_modules/npm/node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { - "version": "3.0.1", + "node_modules/npm/node_modules/socks-proxy-agent/node_modules/agent-base": { + "version": "9.0.0", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "engines": { + "node": ">= 20" } }, "node_modules/npm/node_modules/spdx-exceptions": { @@ -12884,7 +12505,7 @@ "license": "CC0-1.0" }, "node_modules/npm/node_modules/ssri": { - "version": "12.0.0", + "version": "14.0.0", "dev": true, "inBundle": true, "license": "ISC", @@ -12892,77 +12513,23 @@ "minipass": "^7.0.3" }, "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/supports-color": { - "version": "9.4.0", + "version": "10.2.2", "dev": true, "inBundle": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/chalk/supports-color?sponsor=1" } }, "node_modules/npm/node_modules/tar": { - "version": "7.5.11", + "version": "7.5.19", "dev": true, "inBundle": true, "license": "BlueOak-1.0.0", @@ -12984,19 +12551,19 @@ "license": "MIT" }, "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", + "version": "2.0.2", "dev": true, "inBundle": true, "license": "MIT" }, "node_modules/npm/node_modules/tinyglobby": { - "version": "0.2.15", + "version": "0.2.17", "dev": true, "inBundle": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", - "picomatch": "^4.0.3" + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -13005,64 +12572,65 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/npm/node_modules/treeverse": { - "version": "3.0.0", + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/npm/node_modules/tuf-js": { - "version": "3.1.0", + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.5", "dev": true, "inBundle": true, "license": "MIT", - "dependencies": { - "@tufjs/models": "3.0.1", - "debug": "^4.4.1", - "make-fetch-happen": "^14.0.3" - }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/npm/node_modules/tuf-js/node_modules/@tufjs/models": { - "version": "3.0.1", + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.5" - }, + "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "node_modules/npm/node_modules/unique-filename": { - "version": "4.0.0", + "node_modules/npm/node_modules/tuf-js": { + "version": "6.0.0", "dev": true, "inBundle": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "unique-slug": "^5.0.0" + "@gar/promise-retry": "^1.0.3", + "@tufjs/models": "5.0.0", + "debug": "^4.4.3" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, - "node_modules/npm/node_modules/unique-slug": { - "version": "5.0.0", + "node_modules/npm/node_modules/undici": { + "version": "6.27.0", "dev": true, "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, + "license": "MIT", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": ">=18.17" } }, "node_modules/npm/node_modules/util-deprecate": { @@ -13071,176 +12639,49 @@ "inBundle": true, "license": "MIT" }, - "node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "6.0.2", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/walk-up-path": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/which": { - "version": "5.0.0", + "version": "4.0.0", "dev": true, "inBundle": true, "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/which/node_modules/isexe": { - "version": "3.1.5", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/wrap-ansi": { - "version": "8.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": "20 || >=22" } }, - "node_modules/npm/node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", + "node_modules/npm/node_modules/which": { "version": "7.0.0", "dev": true, "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.2.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" + "isexe": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" + "bin": { + "node-which": "bin/which.js" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/write-file-atomic": { - "version": "6.0.0", + "version": "8.0.0", "dev": true, "inBundle": true, "license": "ISC", "dependencies": { - "imurmurhash": "^0.1.4", "signal-exit": "^4.0.1" }, "engines": { - "node": "^18.17.0 || >=20.5.0" + "node": "^22.22.2 || ^24.15.0 || >=26.0.0" } }, "node_modules/npm/node_modules/yallist": { diff --git a/package.json b/package.json index c1b0134b..86bbcef4 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "ethlint": "^1.2.5", "hardhat-contract-sizer": "^2.10.0", "hardhat-gas-reporter": "^1.0.9", - "npm": "^10.2.5", + "npm": "^12.0.1", "prettier": "^2.8.7", "prettier-plugin-solidity": "^1.1.3", "sol2uml": "^2.5.20", diff --git a/test/common/AllowlistModuleCommon.js b/test/common/AllowlistModuleCommon.js index 712b1061..49ab8967 100644 --- a/test/common/AllowlistModuleCommon.js +++ b/test/common/AllowlistModuleCommon.js @@ -1,4 +1,4 @@ -const { ALLOWLIST_ROLE, ZERO_ADDRESS } = require('../utils') +const { ALLOWLIST_ROLE, ZERO_ADDRESS, MINTER_ROLE } = require('../utils') const { expect } = require('chai') const REASON_ALLOWLIST_STRING = 'testAllowlist' @@ -491,6 +491,34 @@ function AllowlistModuleCommon () { .withArgs(this.address1.address) }) + /* + * NM-3 (Nethermind AuditAgent v3.3.0-rc2): delisting a spender must not trap + * the holder's existing allowance. Revocation (value == 0) stays available. + */ + it('testCanRevokeAllowanceWhenSpenderIsNotAllowlisted', async function () { + const AMOUNT_TO_APPROVE = 10n + await this.cmtat + .connect(this.admin) + .setAddressAllowlist(this.address1, true, reasonAllowlist) + await this.cmtat + .connect(this.admin) + .setAddressAllowlist(this.address2, true, reasonAllowlist) + await this.cmtat + .connect(this.address1) + .approve(this.address2, AMOUNT_TO_APPROVE) + + // Spender falls out of compliance + await this.cmtat + .connect(this.admin) + .setAddressAllowlist(this.address2, false, reasonAllowlist) + + await expect(this.cmtat.connect(this.address1).approve(this.address2, 0)) + .to.not.be.reverted + expect( + await this.cmtat.allowance(this.address1, this.address2) + ).to.equal(0) + }) + it('testCannotApproveWhenSpenderIsNotAllowlisted', async function () { const AMOUNT_TO_APPROVE = 10n await this.cmtat @@ -551,6 +579,40 @@ function AllowlistModuleCommon () { .withArgs(this.address3) }) + it('testMinterNotAllowlistedCanStillMint', async function () { + // The operator/minter is NOT required to be allowlisted: mint validates the recipient, + // not the caller. A minter that is not on the allowlist can still mint to an allowlisted + // recipient. (The context beforeEach leaves every address de-allowlisted.) + await this.cmtat.connect(this.admin).grantRole(MINTER_ROLE, this.address1) + await this.cmtat + .connect(this.admin) + .setAddressAllowlist(this.address2, true, reasonAllowlist) + expect(await this.cmtat.isAllowlisted(this.address1)).to.equal(false) + + await expect(this.cmtat.connect(this.address1).mint(this.address2, 10n)).to + .not.be.reverted + expect(await this.cmtat.balanceOf(this.address2)).to.equal(10n) + }) + + it('testMinterNotAllowlistedCanStillBatchMint', async function () { + await this.cmtat.connect(this.admin).grantRole(MINTER_ROLE, this.address1) + await this.cmtat + .connect(this.admin) + .setAddressAllowlist(this.address2, true, reasonAllowlist) + await this.cmtat + .connect(this.admin) + .setAddressAllowlist(this.address3, true, reasonAllowlist) + expect(await this.cmtat.isAllowlisted(this.address1)).to.equal(false) + + await expect( + this.cmtat + .connect(this.address1) + .batchMint([this.address2.address, this.address3.address], [10n, 20n]) + ).to.not.be.reverted + expect(await this.cmtat.balanceOf(this.address2)).to.equal(10n) + expect(await this.cmtat.balanceOf(this.address3)).to.equal(20n) + }) + /* ////////////////////////////////////////////////////////////// FORCED TRANSFER ////////////////////////////////////////////////////////////// */ diff --git a/test/common/DocumentModule/DocumentModuleCommon.js b/test/common/DocumentModule/DocumentModuleCommon.js index 86b5026a..44d7441a 100644 --- a/test/common/DocumentModule/DocumentModuleCommon.js +++ b/test/common/DocumentModule/DocumentModuleCommon.js @@ -90,6 +90,54 @@ function DocumentModuleCommon () { expect(doc.lastModified).to.be.gt(0) }) + it('testSetDocumentEmitsDocumentUpdated', async function () { + const name = ethers.encodeBytes32String('doc1') + const uri = 'https://github.com/CMTA/CMTAT' + const documentHash = ethers.encodeBytes32String('hash1') + + // ERC-1643: setDocument MUST emit DocumentUpdated on create/update. + // On the DocumentEngine variant the token re-emits the event on its own address. + await expect( + this.cmtat.connect(this.admin).setDocument(name, uri, documentHash) + ) + .to.emit(this.cmtat, 'DocumentUpdated') + .withArgs(name, uri, documentHash) + }) + + it('testRemoveDocumentEmitsDocumentRemoved', async function () { + const name = ethers.encodeBytes32String('doc1') + const uri = 'https://github.com/CMTA/CMTAT' + const documentHash = ethers.encodeBytes32String('hash1') + await this.cmtat.connect(this.admin).setDocument(name, uri, documentHash) + + // ERC-1643: removeDocument MUST emit DocumentRemoved with the removed metadata. + await expect(this.cmtat.connect(this.admin).removeDocument(name)) + .to.emit(this.cmtat, 'DocumentRemoved') + .withArgs(name, uri, documentHash) + }) + + it('testCannotSetDocumentWithZeroName', async function () { + const uri = 'https://github.com/CMTA/CMTAT' + const documentHash = ethers.encodeBytes32String('hash1') + + // ERC-1643 (rework): setDocument SHOULD revert on name == bytes32(0) with ERC1643InvalidName. + await expect( + this.cmtat + .connect(this.admin) + .setDocument(ethers.ZeroHash, uri, documentHash) + ).to.be.revertedWithCustomError(this.cmtat, 'ERC1643InvalidName') + }) + + it('testCannotRemoveMissingDocument', async function () { + const name = ethers.encodeBytes32String('unknown') + + // ERC-1643: removeDocument MUST revert if the named document does not exist + // (ERC1643MissingDocument). + await expect( + this.cmtat.connect(this.admin).removeDocument(name) + ).to.be.revertedWithCustomError(this.cmtat, 'ERC1643MissingDocument') + }) + it('testCanGetNullValueIfNoDocument', async function () { const name = ethers.encodeBytes32String('doc1') const doc = await this.cmtat.getDocument(name) diff --git a/test/common/ERC20EnforcementModuleCommon.js b/test/common/ERC20EnforcementModuleCommon.js index 37b85016..ca1496fb 100644 --- a/test/common/ERC20EnforcementModuleCommon.js +++ b/test/common/ERC20EnforcementModuleCommon.js @@ -304,6 +304,10 @@ function ERC20EnforcementModuleCommon () { await expect(this.logs) .to.emit(this.cmtat, 'Transfer') .withArgs(this.address1, this.address2, AMOUNT_TO_TRANSFER) + // The allowance is fully consumed (10 < 20), so Spend reports the 10 actually taken + await expect(this.logs) + .to.emit(this.cmtat, 'Spend') + .withArgs(this.address1, this.address2, AMOUNT_TO_APPROVE) }) it('testCanForceTransferFromAddress1ToAddress2AsAdminAndReduceAllowance', async function () { @@ -342,6 +346,50 @@ function ERC20EnforcementModuleCommon () { await expect(this.logs) .to.emit(this.cmtat, 'Transfer') .withArgs(this.address1, this.address2, AMOUNT_TO_TRANSFER) + // Allowance sufficient (30 >= 20): Spend reports the 20 taken, allowance left at 10 + await expect(this.logs) + .to.emit(this.cmtat, 'Spend') + .withArgs(this.address1, this.address2, AMOUNT_TO_TRANSFER) + }) + + it('testForcedTransferWithoutAllowanceDoesNotEmitSpend', async function () { + // No allowance from from->to: the allowance branch is skipped, so no Spend is emitted + const AMOUNT_TO_TRANSFER = 20 + expect(await this.cmtat.allowance(this.address1, this.address2)).to.equal( + '0' + ) + this.logs = await forcedTransferCompat( + this, + this.admin, + this.address1, + this.address2, + AMOUNT_TO_TRANSFER, + REASON + ) + await expect(this.logs).to.not.emit(this.cmtat, 'Spend') + await expect(this.logs) + .to.emit(this.cmtat, 'ForcedTransfer(address,address,uint256)') + .withArgs(this.address1, this.address2, AMOUNT_TO_TRANSFER) + }) + + it('testForcedTransferWithInfiniteAllowanceDoesNotEmitSpend', async function () { + // Infinite allowance is never reduced (matches transferFrom/burnFrom), so no Spend either + const AMOUNT_TO_TRANSFER = 20 + await this.cmtat + .connect(this.address1) + .approve(this.address2, ethers.MaxUint256) + this.logs = await forcedTransferCompat( + this, + this.admin, + this.address1, + this.address2, + AMOUNT_TO_TRANSFER, + REASON + ) + await expect(this.logs).to.not.emit(this.cmtat, 'Spend') + expect(await this.cmtat.allowance(this.address1, this.address2)).to.equal( + ethers.MaxUint256 + ) }) it('testCanForceBurnWithForceTransferAsAdmin', async function () { @@ -1411,15 +1459,90 @@ function ERC20EnforcementModuleCommon () { ).to.equal(true) }) - it('testSetFrozenTokensOnZeroAddressDoesNotBreakMintFlow', async function () { - await this.cmtat.connect(this.admin).setFrozenTokens(ZERO_ADDRESS, 1) + /* + * Regression tests for NM-15/NM-17 (Nethermind AuditAgent v3.3.0-rc2). + * + * `_setFrozenTokens` must reject the zero address, exactly like + * `_freezePartialTokens` / `_unfreezePartialTokens` already do. Without the + * guard, a non-zero frozen amount on address(0) makes + * `_checkActiveBalance(address(0), value)` return false for every value > 0 + * (balanceOf(address(0)) == 0), which reverts the common mint path used by + * mint / batchMint / crosschainMint / burnAndMint. + */ + it('testCannotSetFrozenTokensOnZeroAddress', async function () { + await expect( + this.cmtat.connect(this.admin).setFrozenTokens(ZERO_ADDRESS, 1) + ).to.be.revertedWithCustomError( + this.cmtat, + 'CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed' + ) - await expect(this.cmtat.connect(this.admin).mint(this.address2, 1)) - .to.be.revertedWithCustomError( - this.cmtat, - 'ERC7943InsufficientUnfrozenBalance' - ) - .withArgs(ZERO_ADDRESS, 1, 0) + expect(await this.cmtat.getFrozenTokens(ZERO_ADDRESS)).to.equal(0) + }) + + it('testSetFrozenTokensOnZeroAddressCannotBrickMint', async function () { + await expect( + this.cmtat.connect(this.admin).setFrozenTokens(ZERO_ADDRESS, 1) + ).to.be.revertedWithCustomError( + this.cmtat, + 'CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed' + ) + + // Issuance must remain fully available + const balanceBefore = await this.cmtat.balanceOf(this.address2) + await expect(this.cmtat.connect(this.admin).mint(this.address2, 1)).to.not + .be.reverted + expect(await this.cmtat.balanceOf(this.address2)).to.equal( + balanceBefore + 1n + ) + }) + + it('testSetFrozenTokensOnZeroAddressCannotBrickBatchMint', async function () { + await expect( + this.cmtat.connect(this.admin).setFrozenTokens(ZERO_ADDRESS, 1) + ).to.be.revertedWithCustomError( + this.cmtat, + 'CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed' + ) + + const balance2Before = await this.cmtat.balanceOf(this.address2) + const balance3Before = await this.cmtat.balanceOf(this.address3) + await expect( + this.cmtat + .connect(this.admin) + .batchMint([this.address2.address, this.address3.address], [1, 2]) + ).to.not.be.reverted + expect(await this.cmtat.balanceOf(this.address2)).to.equal( + balance2Before + 1n + ) + expect(await this.cmtat.balanceOf(this.address3)).to.equal( + balance3Before + 2n + ) + }) + + it('testCannotSetFrozenTokensOnZeroAddressEvenToZero', async function () { + // The zero address is never a valid target, whatever the value + await expect( + this.cmtat.connect(this.admin).setFrozenTokens(ZERO_ADDRESS, 0) + ).to.be.revertedWithCustomError( + this.cmtat, + 'CMTAT_ERC20EnforcementModule_ZeroAddressNotAllowed' + ) + }) + + it('testSetFrozenTokensStillWorksOnRegularAddress', async function () { + // The guard must not regress the normal path + await expect( + this.cmtat + .connect(this.admin) + .setFrozenTokens(this.address1, FREEZE_AMOUNT) + ).to.not.be.reverted + expect(await this.cmtat.getFrozenTokens(this.address1)).to.equal( + FREEZE_AMOUNT + ) + expect(await getActiveBalance(this, this.address1)).to.equal( + INITIAL_BALANCE - FREEZE_AMOUNT + ) }) it('testCanTransferTokenIfActiveBalanceIsEnough', async function () { diff --git a/test/common/ERC20MintModuleCommon.js b/test/common/ERC20MintModuleCommon.js index 2fc41cd6..30239f7e 100644 --- a/test/common/ERC20MintModuleCommon.js +++ b/test/common/ERC20MintModuleCommon.js @@ -178,6 +178,35 @@ function ERC20MintModuleCommon () { ).to.be.revertedWithCustomError(this.cmtat, 'ERC7943CannotReceive') }) + it('testFrozenMinterCanStillMint', async function () { + // NM-5 / documented behaviour: CMTAT's own freeze logic does NOT block mint — only the + // recipient (and deactivation) is checked, not the operator. A frozen MINTER_ROLE holder + // can still mint. (Standard version: a configured RuleEngine could still reject via the + // spender it receives, but none is set by default here; Light has no RuleEngine.) + // To stop a compromised minter, revoke its role — freezing does not. + await this.cmtat.connect(this.admin).setAddressFrozen(this.admin, true) + expect(await this.cmtat.isFrozen(this.admin)).to.equal(true) + + await expect(this.cmtat.connect(this.admin).mint(this.address2, VALUE1)).to + .not.be.reverted + expect(await this.cmtat.balanceOf(this.address2)).to.equal(VALUE1) + }) + + it('testFrozenMinterCanStillBatchMint', async function () { + await this.cmtat.connect(this.admin).setAddressFrozen(this.admin, true) + + await expect( + this.cmtat + .connect(this.admin) + .batchMint([this.address2.address, this.address3.address], [ + VALUE1, + VALUE2 + ]) + ).to.not.be.reverted + expect(await this.cmtat.balanceOf(this.address2)).to.equal(VALUE1) + expect(await this.cmtat.balanceOf(this.address3)).to.equal(VALUE2) + }) + it('testMintPropagatesSpenderToRuleEngine', async function () { if (!this.cmtat.setRuleEngine) { this.skip() @@ -607,6 +636,21 @@ function ERC20MintModuleCommon () { .withArgs(TOKEN_HOLDER[1]) }) + it('testCannotBatchTransferIfMinterIsFrozen', async function () { + // NM-5: the minter-transfer path threads the operator (_msgSender()) as spender in + // every base (Light and full), so freezing the minter blocks its own batchTransfer. + const TOKEN_ADDRESS_TOS = [this.address1, this.address2, this.address3] + // The batchTransfer beforeEach minted TOKEN_AMOUNTS to the admin (the minter) + await this.cmtat.connect(this.admin).setAddressFrozen(this.admin, true) + await expect( + this.cmtat + .connect(this.admin) + .batchTransfer(TOKEN_ADDRESS_TOS, TOKEN_AMOUNTS) + ) + .to.be.revertedWithCustomError(this.cmtat, 'ERC7943CannotSend') + .withArgs(this.admin.address) + }) + it('testBatchTransferPropagatesSpenderToRuleEngine', async function () { if (!this.cmtat.setRuleEngine) { this.skip() diff --git a/test/common/ERC7551ModuleCommon.js b/test/common/ERC7551ModuleCommon.js index cd025e0f..1d87bcef 100644 --- a/test/common/ERC7551ModuleCommon.js +++ b/test/common/ERC7551ModuleCommon.js @@ -20,7 +20,8 @@ function ERC7551ModuleCommon () { }) it('testAdminCanUpdateTerms', async function () { const NEW_TERMS = [ - '', + // The ERC-7551 overload carries no name, so the existing one is kept (NM-22) + TERMS[0], 'https://example.com/doc2', '0xe405e5dad3b45f611e35717af4430b4560f12cd4054380b856446d286c341d05' ] @@ -42,6 +43,31 @@ function ERC7551ModuleCommon () { .to.emit(this.cmtat, 'Terms(bytes32,string)') .withArgs(NEW_TERMS[2], NEW_TERMS[1]) }) + /* + * NM-22 (Nethermind AuditAgent v3.3.0-rc2): the ERC-7551 `setTerms(bytes32,string)` + * overload carries no document name, so it must leave the existing one alone. + * Previously it forwarded an empty string and silently erased it. + */ + it('testERC7551SetTermsPreservesDocumentName', async function () { + const NEW_URI = 'https://example.com/doc3' + const NEW_HASH = + '0xe405e5dad3b45f611e35717af4430b4560f12cd4054380b856446d286c341d05' + // Arrange: the token is deployed with a named terms document + await checkTerms(this, TERMS) + + // Act: update through the ERC-7551 overload + await this.cmtat + .connect(this.admin) + .setTerms(ethers.Typed.bytes32(NEW_HASH), ethers.Typed.string(NEW_URI)) + + // Assert: uri and hash updated, name untouched + const result = await this.cmtat.terms() + expect(result[0]).to.equal(TERMS[0]) + expect(result[1][0]).to.equal(NEW_URI) + expect(result[1][1]).to.equal(NEW_HASH) + expect(await this.cmtat.termsHash()).to.equal(NEW_HASH) + }) + it('testCannotNonAdminUpdateTerms', async function () { // Arrange - Assert await checkTerms(this, TERMS) diff --git a/test/common/EnforcementModuleCommon.js b/test/common/EnforcementModuleCommon.js index c254db66..a965eb32 100644 --- a/test/common/EnforcementModuleCommon.js +++ b/test/common/EnforcementModuleCommon.js @@ -351,6 +351,60 @@ function EnforcementModuleCommon () { .withArgs(this.address2.address) }) + /* + * NM-3 (Nethermind AuditAgent v3.3.0-rc2): revoking an allowance must remain + * possible when the spender (or the owner) is frozen. Freezing a spender is + * precisely when a holder most needs to cut the approval, and the previous + * behaviour left the stale allowance live until the freeze was lifted. + */ + it('testCanRevokeAllowanceWhenSpenderIsFrozen', async function () { + if (this.generic) { + return + } + // Arrange: address1 approves address3, then address3 gets frozen + await this.cmtat.connect(this.address1).approve(this.address3, 20) + await this.cmtat + .connect(this.admin) + .setAddressFrozen(this.address3, true, reasonFreeze) + + // Act + Assert: revocation goes through + await expect(this.cmtat.connect(this.address1).approve(this.address3, 0)) + .to.not.be.reverted + expect( + await this.cmtat.allowance(this.address1, this.address3) + ).to.equal(0) + }) + + it('testCanRevokeAllowanceWhenOwnerIsFrozen', async function () { + if (this.generic) { + return + } + await this.cmtat.connect(this.address1).approve(this.address3, 20) + await this.cmtat + .connect(this.admin) + .setAddressFrozen(this.address1, true, reasonFreeze) + + await expect(this.cmtat.connect(this.address1).approve(this.address3, 0)) + .to.not.be.reverted + expect( + await this.cmtat.allowance(this.address1, this.address3) + ).to.equal(0) + }) + + it('testCannotGrantAllowanceWhenSpenderIsFrozen', async function () { + if (this.generic) { + return + } + // The carve-out must not open non-zero grants to a frozen spender + await this.cmtat + .connect(this.admin) + .setAddressFrozen(this.address3, true, reasonFreeze) + + await expect(this.cmtat.connect(this.address1).approve(this.address3, 20)) + .to.be.revertedWithCustomError(this.cmtat, 'ERC7943CannotSend') + .withArgs(this.address3.address) + }) + it('testCannotTransferTokenWhenSpenderIsFrozenWithTransferFrom', async function () { const AMOUNT_TO_TRANSFER = 10 // Arrange diff --git a/test/common/PauseModuleCommon.js b/test/common/PauseModuleCommon.js index ae4c9f42..e3f830e4 100644 --- a/test/common/PauseModuleCommon.js +++ b/test/common/PauseModuleCommon.js @@ -191,6 +191,63 @@ function PauseModuleCommon () { } }) + /* + * NM-3 (Nethermind AuditAgent v3.3.0-rc2): a holder must always be able to + * sever ties with a spender. Setting an allowance to zero is a revocation, + * never a new grant, so it must stay available while the token is paused — + * otherwise the zero-first mitigation documented on `approve` is unusable + * exactly when the holder needs it, and a compromised spender can back-run + * the unpause. + */ + it('testCanRevokeAllowanceWhenPaused', async function () { + if (this.generic) { + return + } + // Arrange: a live allowance, then pause + await this.cmtat.connect(this.address1).approve(this.address3, 20) + await this.cmtat.connect(this.admin).pause() + + // Act: revoking must be allowed despite the pause + await expect(this.cmtat.connect(this.address1).approve(this.address3, 0)) + .to.not.be.reverted + + // Assert + expect( + await this.cmtat.allowance(this.address1, this.address3) + ).to.equal(0) + }) + + it('testCannotGrantAllowanceWhenPaused', async function () { + if (this.generic) { + return + } + // The carve-out must be limited to revocation: a non-zero grant stays blocked + await this.cmtat.connect(this.admin).pause() + + await expect( + this.cmtat.connect(this.address1).approve(this.address3, 20) + ).to.be.revertedWithCustomError(this.cmtat, 'EnforcedPause') + + expect( + await this.cmtat.allowance(this.address1, this.address3) + ).to.equal(0) + }) + + it('testCanRevokeAllowanceWhenDeactivated', async function () { + if (this.generic) { + return + } + await this.cmtat.connect(this.address1).approve(this.address3, 20) + await this.cmtat.connect(this.admin).pause() + await this.cmtat.connect(this.admin).deactivateContract() + + await expect(this.cmtat.connect(this.address1).approve(this.address3, 0)) + .to.not.be.reverted + expect( + await this.cmtat.allowance(this.address1, this.address3) + ).to.equal(0) + }) + // reverts if address3 transfers tokens from address1 to address2 when paused it('testCannotTransferTokenWhenPausedWithTransferFrom', async function () { const AMOUNT_TO_TRANSFER = 10n diff --git a/test/common/PermitModuleCommon.js b/test/common/PermitModuleCommon.js index 167a9e57..1e546585 100644 --- a/test/common/PermitModuleCommon.js +++ b/test/common/PermitModuleCommon.js @@ -161,6 +161,46 @@ function PermitModuleCommon () { .to.be.revertedWithCustomError(this.cmtat, 'ERC7943CannotSend') .withArgs(spender) }) + + // NM-3 / NM-8: a zero-value permit is a *revocation* and must stay available even while paused + // or while the owner/spender is frozen — the same carve-out already tested for `approve`. + async function grantThenExpectZeroValuePermitAllowed (ctx, restrict) { + const owner = await ctx.permitOwner.getAddress() + const spender = await ctx.permitSpender.getAddress() + // Set a non-zero allowance first (unrestricted) + const grant = await ctx.signPermit() + await ctx.cmtat + .connect(ctx.address3) + .permit(owner, spender, grant.value, grant.deadline, grant.v, grant.r, grant.s) + expect(await ctx.cmtat.allowance(owner, spender)).to.equal(PERMIT_VALUE) + // Apply the restriction, then revoke with a zero-value permit + await restrict(owner, spender) + const revoke = await ctx.signPermit({ value: 0n }) + await expect( + ctx.cmtat + .connect(ctx.address3) + .permit(owner, spender, revoke.value, revoke.deadline, revoke.v, revoke.r, revoke.s) + ).to.not.be.reverted + expect(await ctx.cmtat.allowance(owner, spender)).to.equal(0n) + } + + it('allows a zero-value permit (revocation) while paused', async function () { + await grantThenExpectZeroValuePermitAllowed(this, async () => { + await this.cmtat.connect(this.admin).pause() + }) + }) + + it('allows a zero-value permit (revocation) when the owner is frozen', async function () { + await grantThenExpectZeroValuePermitAllowed(this, async (owner) => { + await this.cmtat.connect(this.admin).setAddressFrozen(owner, true) + }) + }) + + it('allows a zero-value permit (revocation) when the spender is frozen', async function () { + await grantThenExpectZeroValuePermitAllowed(this, async (owner, spender) => { + await this.cmtat.connect(this.admin).setAddressFrozen(spender, true) + }) + }) }) } diff --git a/test/common/SnapshotModuleCommon/SnapshotModuleCommonRescheduling.js b/test/common/SnapshotModuleCommon/SnapshotModuleCommonRescheduling.js index e98ebed7..a0f735ee 100644 --- a/test/common/SnapshotModuleCommon/SnapshotModuleCommonRescheduling.js +++ b/test/common/SnapshotModuleCommon/SnapshotModuleCommonRescheduling.js @@ -169,6 +169,12 @@ function SnapshotModuleCommonRescheduling () { it('reverts when trying to reschedule a snapshot in the past', async function () { const NEW_TIME = this.snapshotTime - time.duration.seconds(60) + // The revert reports the executing block's `block.timestamp`. Reading it + // with `time.latest()` while the call is in flight is a race (it returns + // the previous block on a fast run and the call's own block on a slow one, + // e.g. under `npm run coverage`), so pin it instead. + const EXECUTION_TIME = (await time.latest()) + time.duration.seconds(1) + await time.setNextBlockTimestamp(EXECUTION_TIME) await expect( this.transferEngineMock .connect(this.admin) @@ -178,7 +184,7 @@ function SnapshotModuleCommonRescheduling () { this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotScheduledInThePast' ) - .withArgs(NEW_TIME, (await time.latest()) + time.duration.seconds(1)) + .withArgs(NEW_TIME, EXECUTION_TIME) }) it('reverts when trying to reschedule a snapshot to a snapshot time already existing', async function () { diff --git a/test/common/SnapshotModuleCommon/SnapshotModuleCommonScheduling.js b/test/common/SnapshotModuleCommon/SnapshotModuleCommonScheduling.js index 8a4f1f3d..da87c175 100644 --- a/test/common/SnapshotModuleCommon/SnapshotModuleCommonScheduling.js +++ b/test/common/SnapshotModuleCommon/SnapshotModuleCommonScheduling.js @@ -73,6 +73,12 @@ function SnapshotModuleCommonScheduling () { it('reverts when trying to schedule a snapshot in the past', async function () { const SNAPSHOT_TIME = this.currentTime - time.duration.seconds(60) if (!this.dontCheckTimestamp) { + // The revert reports the executing block's `block.timestamp`. Reading it + // with `time.latest()` while the call is in flight is a race (it returns + // the previous block on a fast run and the call's own block on a slow + // one, e.g. under `npm run coverage`), so pin it instead. + const EXECUTION_TIME = (await time.latest()) + time.duration.seconds(1) + await time.setNextBlockTimestamp(EXECUTION_TIME) await expect( this.transferEngineMock .connect(this.admin) @@ -82,10 +88,7 @@ function SnapshotModuleCommonScheduling () { this.transferEngineMock, 'CMTAT_SnapshotModule_SnapshotScheduledInThePast' ) - .withArgs( - SNAPSHOT_TIME, - (await time.latest()) + time.duration.seconds(1) - ) + .withArgs(SNAPSHOT_TIME, EXECUTION_TIME) } else { await expect( this.transferEngineMock diff --git a/test/common/ValidationModule/RuleEngineReentrancyCommon.js b/test/common/ValidationModule/RuleEngineReentrancyCommon.js new file mode 100644 index 00000000..008f8acb --- /dev/null +++ b/test/common/ValidationModule/RuleEngineReentrancyCommon.js @@ -0,0 +1,160 @@ +const { expect } = require('chai') + +/* + * NM-7 / NM-9 / NM-11 / NM-16 / NM-18 (Nethermind AuditAgent v3.3.0-rc2). + * + * `_checkTransferred` performs the active-balance (frozen) check and then calls + * `ruleEngine.transferred(...)` BEFORE `ERC20Upgradeable._transfer` moves any balance. + * A rule engine that reenters the token during that callback is validated against the + * same pre-transfer snapshot, so without a guard the outer and inner transfers each pass + * the frozen-balance check and together move more than the unfrozen amount, breaking the + * `frozenTokens <= balanceOf` invariant. + * + * Reproduced before the fix: balance 100 / frozen 60 / active 40, an outer transferFrom of + * 40 plus a nested transferFrom of 40 moved 80 and left frozen(60) > balance(20). + * + * The RuleEngine is a trusted, admin-set component, so this is defence in depth rather than + * a live vulnerability — but the guard makes the invariant hold even if a rule engine is + * compromised or hands control to untrusted code. + */ +function RuleEngineReentrancyCommon () { + context('RuleEngine reentrancy (NM-7 cluster)', function () { + const BALANCE = 100n + const FROZEN = 60n + const ACTIVE = BALANCE - FROZEN // 40 + + beforeEach(async function () { + this.attackEngine = await ethers.deployContract('RuleEngineReentrantMock') + + await this.cmtat.connect(this.admin).mint(this.address1, BALANCE) + await this.cmtat + .connect(this.admin) + .setFrozenTokens(this.address1, FROZEN) + + // The attacker is an approved spender for the full balance + await this.cmtat.connect(this.address1).approve(this.address2, BALANCE) + // NM-9 precondition: the rule engine itself holds an allowance from the holder, so its + // nested transferFrom is authorized. (Equivalently, an engine that calls attacker-controlled + // code lets the attacker's own allowance be used - NM-16.) + await this.cmtat + .connect(this.address1) + .approve(this.attackEngine.target, BALANCE) + + await this.cmtat + .connect(this.admin) + .setRuleEngine(this.attackEngine.target) + + this.arm = async () => + this.attackEngine.arm( + this.cmtat.target, + this.address1.address, + this.address2.address, + ACTIVE + ) + }) + + it('testFrozenTokensCannotBeDrainedByReentrantRuleEngine', async function () { + await this.arm() + + // Outer transfer of exactly the unfrozen amount; the engine attempts a second one + await this.cmtat + .connect(this.address2) + .transferFrom(this.address1, this.address2, ACTIVE) + + // Only the legitimate unfrozen amount moved - not twice it + expect(await this.cmtat.balanceOf(this.address2)).to.equal(ACTIVE) + expect(await this.cmtat.balanceOf(this.address1)).to.equal( + BALANCE - ACTIVE + ) + // The freeze invariant holds + expect(await this.cmtat.getFrozenTokens(this.address1)).to.equal(FROZEN) + expect(await this.cmtat.getFrozenTokens(this.address1)).to.be.lte( + await this.cmtat.balanceOf(this.address1) + ) + }) + + it('testReentrantRuleEngineCallbackIsRejected', async function () { + await this.arm() + + await this.cmtat + .connect(this.address2) + .transferFrom(this.address1, this.address2, ACTIVE) + + // The engine did attempt the nested call, and the guard rejected it + expect(await this.attackEngine.reentered()).to.equal(true) + expect(await this.attackEngine.reentrySucceeded()).to.equal(false) + }) + + it('testReentrantCallRevertsWithDedicatedError', async function () { + await this.arm() + // Let the nested revert bubble up instead of being swallowed by the engine + await this.attackEngine.setBubbleRevert(true) + + await expect( + this.cmtat + .connect(this.address2) + .transferFrom(this.address1, this.address2, ACTIVE) + ).to.be.revertedWithCustomError( + this.cmtat, + 'ReentrancyGuardReentrantCall' + ) + + // Nothing moved + expect(await this.cmtat.balanceOf(this.address1)).to.equal(BALANCE) + expect(await this.cmtat.balanceOf(this.address2)).to.equal(0n) + }) + + it('testReentrancyIsAlsoBlockedOnTransfer', async function () { + // Same guard on the direct transfer path (spender == address(0), 3-arg callback) + await this.arm() + await this.attackEngine.setBubbleRevert(true) + + await expect( + this.cmtat.connect(this.address1).transfer(this.address3, 1n) + ).to.be.revertedWithCustomError( + this.cmtat, + 'ReentrancyGuardReentrantCall' + ) + }) + + it('testNonReentrantRuleEngineTransferStillWorks', async function () { + // Engine left unarmed: a normal transfer through the same engine must be unaffected + await expect( + this.cmtat + .connect(this.address2) + .transferFrom(this.address1, this.address2, ACTIVE) + ).to.not.be.reverted + + expect(await this.cmtat.balanceOf(this.address1)).to.equal( + BALANCE - ACTIVE + ) + expect(await this.cmtat.balanceOf(this.address2)).to.equal(ACTIVE) + }) + + it('testConsecutiveTransfersAreNotBlockedByTheGuard', async function () { + // The guard must be released after each callback, not leak across calls + await this.cmtat + .connect(this.address2) + .transferFrom(this.address1, this.address2, 10n) + await expect( + this.cmtat + .connect(this.address2) + .transferFrom(this.address1, this.address2, 10n) + ).to.not.be.reverted + expect(await this.cmtat.balanceOf(this.address2)).to.equal(20n) + }) + + it('testBatchOperationsAreNotBlockedByTheGuard', async function () { + // batchMint invokes the hook once per item in a single transaction + await expect( + this.cmtat + .connect(this.admin) + .batchMint( + [this.address2.address, this.address3.address], + [10n, 20n] + ) + ).to.not.be.reverted + }) + }) +} +module.exports = RuleEngineReentrancyCommon diff --git a/test/common/ValidationModule/RuleEngineSpenderDispatchCommon.js b/test/common/ValidationModule/RuleEngineSpenderDispatchCommon.js new file mode 100644 index 00000000..7c8eb046 --- /dev/null +++ b/test/common/ValidationModule/RuleEngineSpenderDispatchCommon.js @@ -0,0 +1,58 @@ +const { expect } = require('chai') + +/* + * Spender-aware dispatch of the RuleEngine `transferred` callback + * ({ValidationModuleRuleEngine-_callRuleEngineTransferred}). + * + * The `spender != address(0)` branch selects the spender-aware 4-argument overload + * `transferred(spender, from, to, value)` for a `transferFrom`, and the legacy 3-argument + * overload `transferred(from, to, value)` for a direct `transfer` / `mint` / `burn` + * (where the spender is address(0)). The 4-arg overload forwards the real spender to the + * engine (`canTransferFrom` / spender-aware hooks); the 3-arg overload does not. + * + * These tests drive both paths through CMTAT with a recording RuleEngine and assert which + * overload was invoked and which spender it received, so inverting the condition (or routing + * the wrong overload) is caught - a gap that plain transfer tests leave open because both + * overloads are permissive and otherwise indistinguishable. + */ +function RuleEngineSpenderDispatchCommon () { + context('RuleEngine transferred - spender dispatch', function () { + const BALANCE = 100n + const AMOUNT = 10n + + beforeEach(async function () { + this.recorderEngine = await ethers.deployContract( + 'RuleEngineSpenderRecorderMock' + ) + // Mint before wiring the engine so the recorder only sees the call under test + await this.cmtat.connect(this.admin).mint(this.address1, BALANCE) + await this.cmtat + .connect(this.admin) + .setRuleEngine(this.recorderEngine.target) + }) + + it('testTransferFromUsesSpenderAwareOverload', async function () { + // A non-zero spender (approved third party) must route to the 4-arg overload + await this.cmtat.connect(this.address1).approve(this.address2, AMOUNT) + await this.cmtat + .connect(this.address2) + .transferFrom(this.address1, this.address3, AMOUNT) + + expect(await this.recorderEngine.lastWasSpenderOverload()).to.equal(true) + expect(await this.recorderEngine.lastSpender()).to.equal( + this.address2.address + ) + }) + + it('testDirectTransferUsesLegacyOverload', async function () { + // A direct transfer has spender == address(0) and must route to the 3-arg overload + await this.cmtat.connect(this.address1).transfer(this.address3, AMOUNT) + + expect(await this.recorderEngine.lastWasSpenderOverload()).to.equal(false) + expect(await this.recorderEngine.lastSpender()).to.equal( + ethers.ZeroAddress + ) + }) + }) +} +module.exports = RuleEngineSpenderDispatchCommon diff --git a/test/proxy/modules/ValidationModule/ValidationModuleReentrancy.test.js b/test/proxy/modules/ValidationModule/ValidationModuleReentrancy.test.js new file mode 100644 index 00000000..dbd4fa39 --- /dev/null +++ b/test/proxy/modules/ValidationModule/ValidationModuleReentrancy.test.js @@ -0,0 +1,19 @@ +const RuleEngineReentrancyCommon = require('../../../common/ValidationModule/RuleEngineReentrancyCommon') +const { + deployCMTATProxy, + fixture, + loadFixture +} = require('../../../deploymentUtils') + +describe('Proxy - ValidationModule - RuleEngine reentrancy', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(fixture)) + this.cmtat = await deployCMTATProxy( + this._.address, + this.admin.address, + this.deployerAddress.address + ) + }) + + RuleEngineReentrancyCommon() +}) diff --git a/test/proxy/modules/ValidationModule/ValidationModuleSpenderDispatch.test.js b/test/proxy/modules/ValidationModule/ValidationModuleSpenderDispatch.test.js new file mode 100644 index 00000000..e8e1e530 --- /dev/null +++ b/test/proxy/modules/ValidationModule/ValidationModuleSpenderDispatch.test.js @@ -0,0 +1,19 @@ +const RuleEngineSpenderDispatchCommon = require('../../../common/ValidationModule/RuleEngineSpenderDispatchCommon') +const { + deployCMTATProxy, + fixture, + loadFixture +} = require('../../../deploymentUtils') + +describe('Proxy - ValidationModule - RuleEngine spender dispatch', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(fixture)) + this.cmtat = await deployCMTATProxy( + this._.address, + this.admin.address, + this.deployerAddress.address + ) + }) + + RuleEngineSpenderDispatchCommon() +}) diff --git a/test/standard/modules/ValidationModule/ValidationModuleReentrancy.test.js b/test/standard/modules/ValidationModule/ValidationModuleReentrancy.test.js new file mode 100644 index 00000000..052e5a71 --- /dev/null +++ b/test/standard/modules/ValidationModule/ValidationModuleReentrancy.test.js @@ -0,0 +1,19 @@ +const RuleEngineReentrancyCommon = require('../../../common/ValidationModule/RuleEngineReentrancyCommon') +const { + deployCMTATStandalone, + fixture, + loadFixture +} = require('../../../deploymentUtils') + +describe('Standard - ValidationModule - RuleEngine reentrancy', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(fixture)) + this.cmtat = await deployCMTATStandalone( + this._.address, + this.admin.address, + this.deployerAddress.address + ) + }) + + RuleEngineReentrancyCommon() +}) diff --git a/test/standard/modules/ValidationModule/ValidationModuleSpenderDispatch.test.js b/test/standard/modules/ValidationModule/ValidationModuleSpenderDispatch.test.js new file mode 100644 index 00000000..e2256297 --- /dev/null +++ b/test/standard/modules/ValidationModule/ValidationModuleSpenderDispatch.test.js @@ -0,0 +1,19 @@ +const RuleEngineSpenderDispatchCommon = require('../../../common/ValidationModule/RuleEngineSpenderDispatchCommon') +const { + deployCMTATStandalone, + fixture, + loadFixture +} = require('../../../deploymentUtils') + +describe('Standard - ValidationModule - RuleEngine spender dispatch', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(fixture)) + this.cmtat = await deployCMTATStandalone( + this._.address, + this.admin.address, + this.deployerAddress.address + ) + }) + + RuleEngineSpenderDispatchCommon() +})