diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..f0ce2d4 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: Hardhat CI + +on: + push: + branches: [dev, master, main] + pull_request: + branches: [dev, master, main] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@de808b1eea699e761c404bda44ba8f21aba30b2c #v1.3.1 + with: + version: nightly + + - name: Setup NodeJS 20.5.0 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 #v4.4.0 + with: + node-version: 20.5.0 + + - name: Show NodeJS version + run: npm --version + + - name: Checkout submodules + run: git submodule update --init --recursive + + - name: Install Project Dependencies + run: npm install + + - name: Run Hardhat Test + run: npx hardhat test diff --git a/.gitignore b/.gitignore index 9a5aced..da48275 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,10 @@ lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +# Slither reports (keep directory via .gitkeep) +reports/* +!reports/.gitkeep + # Runtime data pids *.pid @@ -18,10 +22,6 @@ pids # Directory for instrumented libs generated by jscoverage/JSCover lib-cov -# Coverage directory used by tools like istanbul -coverage -*.lcov - # nyc test coverage .nyc_output @@ -41,6 +41,9 @@ build/Release node_modules/ jspm_packages/ +# Python virtual environment +cct/ + # Snowpack dependency directory (https://snowpack.dev/) web_modules/ @@ -137,3 +140,24 @@ dist # Vite logs files vite.config.js.timestamp-* vite.config.ts.timestamp-* + +node_modules +.env + +# Hardhat files +/cache +/artifacts + +# TypeChain files +/typechain +/typechain-types + +# Hardhat Ignition default folder for deployments against a local node +ignition/deployments/chain-31337 + +# Foudry files +/cache_hardhat + +# custom local directory +history +.codex diff --git a/.gitmodules b/.gitmodules index 95947c6..a0db00b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,7 @@ -[submodule "CMTAT"] - path = CMTAT +[submodule "submodules/CMTAT"] + path = submodules/CMTAT url = https://github.com/CMTA/CMTAT + branch = master +[submodule "submodules/RuleEngine"] + path = submodules/RuleEngine + url = https://github.com/CMTA/RuleEngine diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..49e5e1c --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ +node_modules/ +submodules/ +artifacts/ +cache_hardhat/ +typechain-types/ +doc/ \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..886649d --- /dev/null +++ b/.prettierrc @@ -0,0 +1,22 @@ +{ + "semi": true, + "singleQuote": true, + "trailingComma": "all", + "tabWidth": 2, + "printWidth": 100, + "plugins": ["prettier-plugin-solidity"], + "overrides": [ + { + "files": "*.sol", + "options": { + "parser": "slang", + "printWidth": 120, + "tabWidth": 4, + "useTabs": false, + "singleQuote": false, + "bracketSpacing": false, + "compiler": "0.8.20" + } + } + ] +} diff --git a/.solcover.js b/.solcover.js new file mode 100644 index 0000000..8270e4e --- /dev/null +++ b/.solcover.js @@ -0,0 +1,13 @@ +const fs = require('fs'); +const path = require('path'); + +module.exports = { + istanbulFolder: 'doc/coverage', + skipFiles: ['modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol'], + onIstanbulComplete: async function () { + const rootCoverageJson = path.join(process.cwd(), 'coverage.json'); + if (fs.existsSync(rootCoverageJson)) { + fs.unlinkSync(rootCoverageJson); + } + }, +}; diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..cfe1872 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,30 @@ +# AGENTS Guidelines + +## Sync Policy (Mandatory) + +- `AGENTS.md` and `CLAUDE.md` must always contain exactly the same content. +- Any edit to one file must be mirrored in the other file in the same change. + +## Testing Policy (Mandatory) + +- Always add or update automated tests for every new feature, behavior change, bug fix, or security hardening change. +- A code change is not complete unless tests validating the change are included in the same PR/commit series. +- At minimum, include: + - positive-path test(s), + - negative-path/revert test(s) when applicable, + - event assertion(s) when state changes emit events. +- Run relevant tests locally before finalizing changes. If a full suite cannot be run, clearly state what was run and what was skipped. + +## Codebase Summary + +- This repository integrates **CMTA CMTAT** token modules with **Chainlink ACE PolicyEngine**. +- There are two deployment variants: + - **Standard**: policy-authoritative access/compliance via ACE (`runPolicy`) with `OwnableUpgradeable`. + - **Lite**: keeps CMTAT role-based module access control and uses ACE mainly for transfer validation. +- Core custom contracts are under: + - `contracts/modules/standard/` + - `contracts/modules/lite/` + - `contracts/modules/chainlink-ace/custom/` + - `contracts/modules/chainlink-ace/modified/` +- Tests are primarily under `test/`, with transfer-policy coverage in `test/custom/transferValidationPolicy.test.js`. +- External dependencies are vendored as git submodules in `submodules/` (notably `CMTAT`, `chainlink-ace`, and `RuleEngine`). diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..fdc8388 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,46 @@ +# CHANGELOG + +All notable changes to this project will be documented in this file. + +Please follow [https://changelog.md](https://changelog.md) conventions and the other conventions below + +## Semantic Version 2.0.0 + +Given a version number MAJOR.MINOR.PATCH, increment the: + +1. MAJOR version when the new version makes: + - Incompatible proxy **storage** change internally or through the upgrade of an external library (OpenZeppelin) + - A significant change in external APIs (public/external functions) or in the internal architecture +2. MINOR version when the new version adds functionality in a backward compatible manner +3. PATCH version when the new version makes backward compatible bug fixes + +See [https://semver.org](https://semver.org) + +## Type of changes + +- `Added` for new features. +- `Changed` for changes in existing functionality. +- `Deprecated` for soon-to-be removed features. +- `Removed` for now removed features. +- `Fixed` for any bug fixes. +- `Security` in case of vulnerabilities. + +Reference: [keepachangelog.com/en/1.1.0/](https://keepachangelog.com/en/1.1.0/) + +Custom changelog tag: `Dependencies`, `Documentation`, `Testing` + +## [0.1.0] - + +### Added + +- Initial release of **CMTAT-ACE**, integrating CMTAT modules with Chainlink ACE PolicyEngine. +- Two deployment variants: + - **Standard**: policy-authoritative access and compliance through ACE `runPolicy`. + - **Lite**: CMTAT role-based module access control with ACE-based transfer validation. +- Core tokenization and compliance modules under: + - `contracts/modules/standard/` + - `contracts/modules/lite/` + - `contracts/modules/chainlink-ace/custom/` + - `contracts/modules/chainlink-ace/modified/` +- Deployment flows for standalone, upgradeable, and UUPS variants. +- Automated test suite covering deployment, policy integration, and transfer validation behavior. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..cfe1872 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,30 @@ +# AGENTS Guidelines + +## Sync Policy (Mandatory) + +- `AGENTS.md` and `CLAUDE.md` must always contain exactly the same content. +- Any edit to one file must be mirrored in the other file in the same change. + +## Testing Policy (Mandatory) + +- Always add or update automated tests for every new feature, behavior change, bug fix, or security hardening change. +- A code change is not complete unless tests validating the change are included in the same PR/commit series. +- At minimum, include: + - positive-path test(s), + - negative-path/revert test(s) when applicable, + - event assertion(s) when state changes emit events. +- Run relevant tests locally before finalizing changes. If a full suite cannot be run, clearly state what was run and what was skipped. + +## Codebase Summary + +- This repository integrates **CMTA CMTAT** token modules with **Chainlink ACE PolicyEngine**. +- There are two deployment variants: + - **Standard**: policy-authoritative access/compliance via ACE (`runPolicy`) with `OwnableUpgradeable`. + - **Lite**: keeps CMTAT role-based module access control and uses ACE mainly for transfer validation. +- Core custom contracts are under: + - `contracts/modules/standard/` + - `contracts/modules/lite/` + - `contracts/modules/chainlink-ace/custom/` + - `contracts/modules/chainlink-ace/modified/` +- Tests are primarily under `test/`, with transfer-policy coverage in `test/custom/transferValidationPolicy.test.js`. +- External dependencies are vendored as git submodules in `submodules/` (notably `CMTAT`, `chainlink-ace`, and `RuleEngine`). diff --git a/CMTAT b/CMTAT deleted file mode 160000 index 9c96c8e..0000000 --- a/CMTAT +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 9c96c8eed903cb092e37b089316515ecefbd10fe diff --git a/README.md b/README.md index 2a1521a..578324d 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,648 @@ -# CMTAT-ACE +# CMTAT ACE integration project + +## Introduction + +This repository combines two components: + +- **CMTAT (CMTA Token)**: an open security-token standard from the [Capital Markets and Technology Association (CMTA)](https://www.cmta.ch/), with compliance-oriented modules such as conditional transfer controls, account freeze/enforcement, token pause, document and snapshot engines, and token lifecycle controls. +- **Chainlink ACE (Automated Compliance Engine)**: a policy engine that evaluates configurable compliance and authorization policies at runtime for protected contract functions. + +In this integration, CMTAT provides the token feature set and module structure, while ACE provides dynamic policy enforcement. +The goal is to let issuers update compliance behavior through policy configuration without changing core token business logic. + +## Table of Contents + +- [Deployment versions](#deployment-versions) +- [Changes from CMTAT](#changes-from-cmtat) +- [TransferValidationPolicy](#transfervalidationpolicy) +- [ERC-165 Interface Support](#erc-165-interface-support) +- [Library](#library) +- [Initialize submodules](#initialize-submodules) +- [Install dependencies](#install-dependencies) +- [Compile contracts](#compile-contracts) +- [Testing](#testing) +- [Linting & Formatting](#linting--formatting) +- [Scripts](#scripts) +- [Audit Reports Summary](#audit-reports-summary) +- [Policy-Protected Functions (Current Integration)](#policy-protected-functions-current-integration) +- [FAQ for Issuers Using CMTAT with ACE Policies](#faq-for-issuers-using-cmtat-with-ace-policies) + +## Deployment versions + +Two versions are available: + +- **Lite**: substitutes RuleEngine with Chainlink ACE PolicyEngine for transfer validation, while keeping CMTAT role-based module authorization. +- **Standard**: uses Chainlink ACE PolicyEngine as the authorization/compliance gate for state-changing operations, replacing local role-based authorization with policy checks. + +### Standard + +Replaces CMTAT's `AccessControlUpgradeable` (role-based) with `OwnableUpgradeable` (single owner) and integrates Chainlink ACE `PolicyProtectedBaseUpgradeable` for access control and compliance validation on state-changing operations (mint, burn, transfer, enforcement, admin functions). + +| Contract | Proxy type | +| ------------------------------------- | ------------------ | +| `ComplianceTokenCMTATStandalone` | None | +| `ComplianceTokenCMTATUpgradeable` | Transparent | +| `ComplianceTokenCMTATUUPSUpgradeable` | UUPS (`onlyOwner`) | + +### Lite + +Keeps CMTAT's `AccessControlUpgradeable` (role-based) for module authorization and adds Chainlink ACE PolicyEngine for transfer validation only, replacing CMTAT's RuleEngine. + +| Contract | Proxy type | +| ----------------------------------------- | ------------------------------------- | +| `ComplianceTokenCMTATLiteStandalone` | None | +| `ComplianceTokenCMTATLiteUpgradeable` | Transparent | +| `ComplianceTokenCMTATLiteUUPSUpgradeable` | UUPS (`onlyRole(PROXY_UPGRADE_ROLE)`) | + +## Changes from CMTAT + +### Warning (Standard Variant) + +In the **Standard** variant, critical operations are authorized through ACE `runPolicy` checks instead of local `onlyRole(...)` checks. This includes core actions such as `mint`, burn functions, forced transfer/enforcement actions, and sensitive admin/configuration operations. + +This means `PolicyEngine` configuration is security-critical infrastructure. A bad config change can unintentionally allow or block sensitive actions. +It also introduces a direct runtime dependency on Chainlink ACE contracts (PolicyEngine, attached policies, extractor/mapper configuration): if ACE contracts are unavailable, misconfigured, or incorrectly upgraded, authorization and compliance checks in the token are directly affected. +For `runPolicy` context handling, cleanup is best-effort on success only: context is cleared after the guarded function completes successfully. If the guarded call reverts, cleanup is not reached, and previously stored context remains in storage. + +Treat the following as privileged governance actions: + +- `addPolicy` / `removePolicy` +- `setExtractor` / `setPolicyMapper` +- `setDefaultAllow` +- `attachPolicyEngine` + +### Access Control + +| Aspect | CMTAT | Standard | Lite | +| --------------- | ---------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------- | +| Base model | `AccessControlUpgradeable` with 9+ roles | `OwnableUpgradeable` (single owner) | `AccessControlUpgradeable` (unchanged) | +| Authorization | `onlyRole(MINTER_ROLE)`, etc. | `runPolicy` modifier via PolicyEngine | `onlyRole()` for modules, PolicyEngine for transfers | +| Role management | `grantRole()` / `revokeRole()` | Managed externally via `RoleBasedAccessControlPolicy` | CMTAT roles preserved | + +### Validation & Compliance + +| Aspect | CMTAT | Standard | Lite | +| ---------------- | ----------------------------------------------------- | -------------------------------------------------- | --------------------------------------------------------------- | +| Validation layer | `CMTATBaseRuleEngine` → `ValidationModuleRuleEngine` | `PolicyProtectedBaseUpgradeable` → `IPolicyEngine` | `ValidationModulePolicyEngine` → `IPolicyEngine` | +| Engine type | RuleEngine (custom interface) | Chainlink ACE PolicyEngine | Chainlink ACE PolicyEngine | +| Transfer check | `_canTransferGenericByModuleAndRevert()` + RuleEngine | PolicyEngine `run()` via `runPolicy` modifier | `_canTransferGenericByModuleAndRevert()` + PolicyEngine `run()` | +| ERC-1404 support | Via `ValidationModuleERC1404` | Not applicable (no module-level checks) | Via `PolicyValidationModuleERC1404` | + +### Initialization + +The `Engine` struct parameter is replaced with `address policyEngine_`, `ISnapshotEngine snapshotEngine_`, and `IERC1643 documentEngine_`: + +```solidity +// CMTAT +constructor(forwarder, admin, ..., ICMTATConstructor.Engine memory engines_) + +// ComplianceTokenCMTAT (Standard & Lite) +constructor(admin, ..., address policyEngine_, ISnapshotEngine snapshotEngine_, IERC1643 documentEngine_) +``` + +ERC-2771 (gasless transaction forwarding) has been removed from all deployment contracts. The standalone contracts no longer take a `forwarderIrrevocable` parameter, and the upgradeable contracts have parameterless constructors. + +### Modules + +All CMTAT functional modules are preserved in both variants: + +- ERC20MintModule, ERC20BurnModule +- ERC20EnforcementModule (freeze/enforcement) +- PauseModule (Standard: `pause()`/`unpause()`/`deactivateContract()` are not exposed on the token — pausing is enforced externally via a PausePolicy on the PolicyEngine which rejects operations when paused; Lite: native `onlyRole(PAUSER_ROLE)`) +- SnapshotEngineModule, DocumentEngineModule +- ExtraInformationModule +- ERC20CrossChainModule, CCIPModule + +### Removed from Standard + +- `CMTATBaseAccessControl` — replaced by `OwnableUpgradeable` +- `AccessControlModule` — role management removed from contract +- `CMTATBaseRuleEngine` — replaced by `PolicyProtectedBaseUpgradeable` +- `ValidationModuleRuleEngine` — replaced by direct PolicyEngine calls +- All `onlyRole()` authorization functions — replaced by `runPolicy` modifier +- `pause()`, `unpause()`, `deactivateContract()` — not exposed on the token contract; the `_authorizePause` and `_authorizeDeactivate` hooks are intentionally left unimplemented so these functions remain abstract and are excluded from the compiled contract. Pausing is enforced externally via a PausePolicy attached to the PolicyEngine, which rejects protected operations when paused + +### Design notes + +#### Why `approve()` is not policy-protected + +`approve()` is intentionally not gated by `runPolicy` in either variant. An approval by itself does not move tokens — it only sets an allowance. The actual token movement happens via `transferFrom()`, which **is** policy-protected. Protecting `approve()` would add gas overhead without security benefit, since: + +1. A malicious or excessive approval has no effect until `transferFrom()` is called, at which point the PolicyEngine validates the transfer. +2. The `ERC20TransferFromExtractor` extracts the `spender` address from `transferFrom()` calls, so policies can restrict which spenders are allowed to move tokens regardless of existing approvals. +3. In the Lite variant, `approve()` is gated by `whenNotPaused` as a convenience (matching upstream CMTAT behavior), but this is not a security-critical check. + +### Removed from both variants + +- `ERC2771Module` — gasless transaction forwarding is not supported (ACE does not currently support ERC-2771) + +### Added + +- `PolicyProtectedBaseUpgradeable` — Chainlink ACE integration with ERC-7201 storage, `runPolicy` modifier, and policy engine lifecycle management +- `ValidationModulePolicyEngine` (Lite) — hybrid validation combining CMTAT module checks with PolicyEngine +- `PolicyValidationModuleERC1404` (Lite) — ERC-1404 transfer restriction codes with PolicyEngine awareness +- `TransferValidationPolicy` — Chainlink ACE policy that validates transfers using CMTAT's `IRule` interface (see [TransferValidationPolicy](#transfervalidationpolicy) below) +- `ERC20TransferFromExtractor` — Extractor that produces 4 parameters (`spender`, `from`, `to`, `amount`) for `transfer()` and `transferFrom()` + +## TransferValidationPolicy + +`TransferValidationPolicy` is a Chainlink ACE policy that bridges CMTAT's `IRule` interface with the PolicyEngine, enabling reuse of existing transfer restriction rules as ACE policies. + +### How it works + +The policy accepts an array of `IRule` contracts. When the PolicyEngine invokes the policy during a `transfer()` or `transferFrom()`, each rule is evaluated in order. If any rule returns a non-zero restriction code, the policy reverts with `PolicyRejected` containing the rule's human-readable message. + +It supports two extractor layouts: + +| Extractor | Parameters | Used by | +| ---------------------------- | ----------------------------- | ---------------------------------------------------------------- | +| `ERC20TransferExtractor` | `[from, to, amount]` | Calls `detectTransferRestriction(from, to, amount)` | +| `ERC20TransferFromExtractor` | `[spender, from, to, amount]` | Calls `detectTransferRestrictionFrom(spender, from, to, amount)` | + +### Mock rules + +Two mock `IRule` implementations are provided in `contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol` for testing and demonstration: + +- **`MaxAmountRule`** — Rejects transfers where the amount exceeds a configurable maximum (restriction code `13`) +- **`RestrictedAddressRule`** — Rejects transfers involving addresses on a configurable restricted list (codes `14`/`15` for sender/recipient) + +### Setup + +1. Deploy the extractor and set it on the PolicyEngine: + +```javascript +const extractor = await ethers.deployContract('ERC20TransferFromExtractor'); +const transferSelector = cmtat.interface.getFunction('transfer(address,uint256)').selector; +const transferFromSelector = cmtat.interface.getFunction( + 'transferFrom(address,address,uint256)', +).selector; + +await policyEngine.setExtractor(transferSelector, await extractor.getAddress()); +await policyEngine.setExtractor(transferFromSelector, await extractor.getAddress()); +``` + +2. Deploy rule contracts and the policy: + +```javascript +const maxAmountRule = await ethers.deployContract('MaxAmountRule', [1000n]); +const restrictedRule = await ethers.deployContract('RestrictedAddressRule', [[]]); + +const configParams = abiCoder.encode( + ['address[]'], + [[await maxAmountRule.getAddress(), await restrictedRule.getAddress()]], +); + +const policy = await upgrades.deployProxy( + await ethers.getContractFactory('TransferValidationPolicy'), + [policyEngineAddress, adminAddress, configParams], + { + initializer: 'initialize', + unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], + }, +); +``` + +3. Register the policy for transfer selectors with parameter names: + +```javascript +const PARAM_SPENDER = keccak256(toUtf8Bytes('spender')); +const PARAM_FROM = keccak256(toUtf8Bytes('from')); +const PARAM_TO = keccak256(toUtf8Bytes('to')); +const PARAM_AMOUNT = keccak256(toUtf8Bytes('amount')); + +await policyEngine.addPolicy(cmtatAddress, transferSelector, policyAddress, [ + PARAM_SPENDER, + PARAM_FROM, + PARAM_TO, + PARAM_AMOUNT, +]); +await policyEngine.addPolicy(cmtatAddress, transferFromSelector, policyAddress, [ + PARAM_SPENDER, + PARAM_FROM, + PARAM_TO, + PARAM_AMOUNT, +]); +``` + +4. Rules can be updated at any time by the policy owner: + +```javascript +await policy.setRules([newRuleAddress1, newRuleAddress2]); +``` + +### Writing custom rules + +Implement the `IRule` interface to create custom transfer restriction logic: + +```solidity +contract MyCustomRule is IRule { + function detectTransferRestriction( + address from, + address to, + uint256 amount + ) public view override returns (uint8) { + // Return 0 for allowed, non-zero for rejected + } + + function detectTransferRestrictionFrom( + address spender, + address from, + address to, + uint256 amount + ) public view override returns (uint8) { + // Validate spender + transfer params + } + + function messageForTransferRestriction( + uint8 code + ) external pure override returns (string memory) { + // Return human-readable rejection reason + } + + // ... canTransfer(), canReturnTransferRestrictionCode() +} +``` + +## ERC-165 Interface Support + +This integration includes ERC-165 interface discovery for both the protected token side and policy side: + +- **Protected-token interface support**: `PolicyProtectedBaseUpgradeable` exposes `IPolicyProtected` via `supportsInterface`, and the Standard/Lite token bases propagate that support through their own `supportsInterface` overrides. +- **Policy interface support**: `TransferValidationPolicy` extends Chainlink ACE `Policy`, and `Policy` exposes `IPolicy` via ERC-165. +- **Rule interface support in mocks**: the included `TransferRuleMocks` expose `IRule` via `supportsInterface` for compatibility testing. + +This allows integrators and tooling to programmatically verify interface compatibility before wiring policies, engines, and rule contracts together. ## Library -- CMTAT [v.3.1.0](https://github.com/CMTA/CMTAT/releases/tag/v3.1.0) +- CMTAT [v3.2.0](https://github.com/CMTA/CMTAT/releases/tag/v3.2.0) +- Chainlink ACE `1.0.0` +- OpenZeppelin Contracts `5.6.1` +- OpenZeppelin Contracts Upgradeable `5.6.1` -## Installation +## Initialize submodules + +```shell +git submodule update --init --recursive +``` + +## Install dependencies + +You can use any package manager either npm, yarn or pnpm. For example you can type: + +```shell +bun install +``` + +## Compile contracts + +To compile + +```shell +bunx hardhat compile +``` + +## Testing + +To run tests: + +```shell +bunx hardhat test +``` + +## Linting & Formatting + +## ESLint + +Lint JavaScript files (tests, scripts, config): + +```shell +bun run lint +``` + +Auto-fix fixable issues: + +```shell +bun run lint:fix +``` + +## Prettier + +Check formatting for JS, JSON, Markdown, and Solidity: + +```shell +bun run format:check +``` -Clone the git repository, with the option `--recurse-submodules` to fetch the submodules: +Auto-format all files: + +```shell +bun run format +``` + +Solidity formatting uses [prettier-plugin-solidity](https://github.com/prettier-solidity/prettier-plugin-solidity) and is scoped to `contracts/**/*.sol` only (submodules and dependencies are excluded). + +## Scripts + +## Deployment scripts + +Individual deployment scripts are available for each contract variant: + +| Script | Description | +| ------------------------------------------------- | ------------------------------ | +| `scripts/lite/deploy-lite-standalone.js` | Lite standalone (no proxy) | +| `scripts/lite/deploy-lite-upgradeable.js` | Lite transparent proxy | +| `scripts/lite/deploy-lite-uups.js` | Lite UUPS proxy | +| `scripts/standard/deploy-standard-standalone.js` | Standard standalone (no proxy) | +| `scripts/standard/deploy-standard-upgradeable.js` | Standard transparent proxy | +| `scripts/standard/deploy-standard-uups.js` | Standard UUPS proxy | + +Run any script with: + +```shell +bunx hardhat run scripts/lite/deploy-lite-standalone.js +``` + +## Demo script + +`scripts/demo.js` provides a complete end-to-end deployment of the Standard variant with the full Chainlink ACE policy stack. It deploys and wires together all contracts in the correct order: + +1. **PolicyEngine** (proxy) — central policy orchestrator with `defaultAllow = true` +2. **DocumentEngineMock** + **SnapshotEngineMock** — mock engine contracts for document/snapshot support +3. **ComplianceTokenCMTATStandalone** — the token contract, attached to the PolicyEngine and engines +4. **PausePolicy** (proxy) — added to all state-changing selectors (mint, burn, transfer, enforcement, admin) +5. **RoleBasedAccessControlPolicy** (proxy) — added to admin selectors with role-to-selector mappings +6. **MockV3Aggregator** — mock Chainlink reserve price feed (Hardhat network only) +7. **SecureMintPolicy** (proxy) — added to `mint()`, enforces reserve-backed minting via price feed +8. **MintBurnExtractor** — set for `mint()` selector, extracts `account` and `amount` parameters +9. **ERC20TransferExtractor** — set for `transfer()` selector +10. **ERC20TransferFromExtractor** — set for `transferFrom()` selector +11. **MaxAmountRule** + **RestrictedAddressRule** — mock IRule contracts for transfer validation +12. **TransferValidationPolicy** (proxy) — added to `transfer()` and `transferFrom()` with both rules + +The script also configures RBAC operation allowances and grants roles (`MINTER_ROLE`, `BURNER_ROLE`, `BURNER_FROM_ROLE`, `ENFORCER_ROLE`, `ERC20ENFORCER_ROLE`, `DOCUMENT_ROLE`, `SNAPSHOOTER_ROLE`) to the admin account. + +Policy execution order per function: + +- `mint()` → PausePolicy → RBAC → SecureMintPolicy +- `transfer()` / `transferFrom()` → PausePolicy → TransferValidationPolicy +- All other state-changing functions → PausePolicy → RBAC + +Run the demo on a local Hardhat network: + +```shell +bunx hardhat run scripts/demo.js +``` + +## Audit Reports Summary + +This section summarizes the static-analysis reports available in this repository. + +### Slither + +Here is the list of report performed with [Slither](https://github.com/crytic/slither) + +Setup: + +```shell +python3 -m venv cct +chmod +x cct/bin/activate +source cct/bin/activate +pip install slither-analyzer +slither --version +``` + +Run: + +```shell +source cct/bin/activate +bun run slither +``` + +```bash +slither . --checklist > doc/audits/tools/slither-report.md +``` + +`bun run slither` generates timestamped reports in the `reports/` directory: + +- **JSON** — `reports/slither-report-.json` +- **Markdown** — `reports/slither-report-.md` + +The direct `slither ... --checklist` command above writes a checklist-style report to `doc/audits/tools/slither-report.md`. + +When done, deactivate the virtual environment: + +```shell +deactivate +``` + +| Version | Report | Assessment | +| ------- | --------------------------------------------------------- | --------------------------------------------------------------------------- | +| current | [slither-report.md](./doc/audits/tools/slither-report.md) | [slither-report-feedback.md](./doc/audits/tools/slither-report-feedback.md) | + +Report scope: repo-focused filtered checklist run. + +0 High · 9 Medium · 10 Low · 27 Informational + +| ID | Finding | Instances | Assessment | +| --- | --------------------- | --------- | ------------------------------------------------------------------------------------------------- | +| M-1 | `reentrancy-no-eth` | 3 | Contextual; expected external policy-engine calls and hook flow. Manual review required. | +| M-2 | `uninitialized-local` | 6 | Likely analyzer limitation in extractor decode paths; treated as likely false positive. | +| L-1 | `calls-loop` | 8 | Accepted by design where policy/rule chains iterate; monitor gas/complexity. | +| L-2 | `reentrancy-events` | 2 | Informational reentrancy/event-order signal; no confirmed exploitable issue from checklist alone. | +| I-1 | `assembly` | 2 | Expected in storage-slot patterns; informational. | +| I-2 | `dead-code` | 2 | Cleanup candidate; not a direct security issue. | +| I-3 | `naming-convention` | 23 | Style-only informational findings. | + +### Aderyn + +Here is the list of report performed with [Aderyn](https://github.com/Cyfrin/aderyn) + +```bash +aderyn -x mocks --output doc/audits/tools/aderyn-report.md +``` + +| Version | Report | Assessment | +| ------- | ------------------------------------------------------- | ------------------------------------------------------------------------- | +| current | [aderyn-report.md](./doc/audits/tools/aderyn-report.md) | [aderyn-report-feedback.md](./doc/audits/tools/aderyn-report-feedback.md) | + +Report scope: 17 Solidity files, 959 nSLOC. + +2 High · 10 Low + +| ID | Finding | Instances | Assessment | +| ---- | ----------------------------------------- | --------- | --------------------------------------------------------------------------------------------------- | +| H-1 | Arbitrary `from` passed to `transferFrom` | 1 | Accepted in context — policy-gated flow; not treated as exploitable in this integration design. | +| H-2 | Contract locks Ether without withdraw | 2 | Accepted false positive — token deployments are not intended as ETH custody contracts. | +| L-1 | Centralization Risk | 11 | Accepted by design — privileged governance/control is intentional. | +| L-2 | Unsafe ERC20 Operation | 7 | Accepted false positive — primarily selector/module-flow usage, not unsafe token transfer wrappers. | +| L-3 | Unspecific Solidity Pragma | 17 | Accepted by design — version ranges are intentionally used in this codebase. | +| L-4 | Literal Instead of Constant | 2 | Informational — optional quality improvement. | +| L-5 | PUSH0 Opcode | 17 | Environment-dependent informational finding in this setup. | +| L-6 | Empty Block | 22 | Accepted by design — authorization hook pattern. | +| L-7 | Loop Contains `require`/`revert` | 4 | Accepted by design — atomic validation and explicit failure signaling. | +| L-8 | Unused State Variable | 1 | False positive — `STORAGE_LOCATION` is used via inline assembly in `_getStorage()`. | +| L-9 | Costly operations inside loop | 2 | Accepted — expected tradeoff in policy/rule iteration paths. | +| L-10 | Unused Import | 9 | Partially fixed; remaining cases are intentional (artifact/NatSpec/doc reasons). | + +## Coverage + +Writes coverage files to _doc/coverage_ using **solidity-coverage** hardhat plugin with config at **.solcover.js** ```bash -git clone git@github.com:CMTA/CMTAT-ACE.git --recurse-submodules +bunx hardhat coverage ``` +## Policy-Protected Functions (Current Integration) + +This project now documents the policy-protected function selectors explicitly. +The list below reflects the selectors wired in deployment/test flows (`scripts/demo.js`, `test/deploymentUtils.js`). + +### Core transfer selectors (Standard + Lite) + +| Function signature | Selector | +| --------------------------------------- | ------------ | +| `transfer(address,uint256)` | `0xa9059cbb` | +| `transferFrom(address,address,uint256)` | `0x23b872dd` | + +### Admin/lifecycle selectors (Standard policy-authoritative flow) + +| Function signature | Selector | +| ----------------------------------------- | ------------ | +| `mint(address,uint256)` | `0x40c10f19` | +| `burn(address,uint256)` | `0x9dc29fac` | +| `burn(uint256)` | `0x42966c68` | +| `burnFrom(address,uint256)` | `0x79cc6790` | +| `forcedTransfer(address,address,uint256)` | `0x9fc1d0e7` | +| `freezePartialTokens(address,uint256)` | `0x125c4a33` | +| `unfreezePartialTokens(address,uint256)` | `0x1fe56f7d` | +| `setName(string)` | `0xc47f0027` | +| `setSymbol(string)` | `0xb84c8246` | +| `setTokenId(string)` | `0xdcfd616f` | +| `setDocumentEngine(address)` | `0x33611079` | +| `setSnapshotEngine(address)` | `0xe236aabf` | +| `setCCIPAdmin(address)` | `0xa8fa343c` | +| `crosschainMint(address,uint256)` | `0x18bf5077` | +| `crosschainBurn(address,uint256)` | `0x2b8c49e3` | + +Note: exact policy chains per selector (PausePolicy, RBAC, TransferValidationPolicy, etc.) can vary by deployment configuration. + +## FAQ for Issuers Using CMTAT with ACE Policies + +> Warning: This FAQ is best-effort guidance for this repository integration. It may be incomplete and is not a substitute for official ACE documentation, legal advice, or a professional security review. + +### 1. What does ACE add to CMTAT? + +ACE moves compliance checks into separate policy contracts. This lets you update compliance rules without redeploying the token. + +### 2. Do I still need CMTAT roles if ACE controls authorization? + +Yes. + +- Keep CMTAT roles where possible as a second safety layer, so a policy misconfiguration alone is less likely to enable sensitive actions. +- Treat ACE policy configuration as high-privilege admin control: changing policies, ordering, extractors, or `defaultAllow` can effectively allow or block critical token operations. + +### 3. Which CMTAT version should I choose: lite or standard? + +Use `lite` if you mainly need policy checks on transfers. Use `standard` if you also want policy checks on admin and lifecycle actions. + +### 4. Who should own and manage the PolicyEngine? + +Use a highly trusted governance setup, such as a multisig, DAO, or timelock. Whoever controls PolicyEngine settings effectively controls token compliance behavior. + +### 5. What is the minimum policy set for a production issuer? + +For token issuers, a common baseline is: + +- Pause policy. +- Role-based access policy. +- Transfer restriction policy (for example KYC/sanctions/rule checks). +- A clearly defined default result (`defaultAllow=true` or `defaultAllow=false`). + +### 6. Should default policy outcome be allow or reject? + +Choose based on your operating model: + +- `defaultAllow=true`: allow by default, and block only when a policy rejects. +- `defaultAllow=false`: reject by default, and allow only when policies explicitly allow. + +In ACE, `true` is the usual default behavior; confirm and document your choice before launch. + +### 7. How do I avoid policy ordering mistakes? + +Start with restrictive checks, then business-limit checks, and place permissive/bypass behavior only where intentionally needed. A policy that returns `Allow` stops evaluation of later policies. + +### 8. What happens if extractor or parameter mapping is wrong? + +Policies may read the wrong values or fail unexpectedly. Treat extractor and parameter mapping as security-critical configuration, and test them like contract code. + +### 9. Can I enforce different policies for transfer and transferFrom? + +Yes. `transfer` and `transferFrom` use different selectors, so configure and test both paths separately. Include spender-specific checks for `transferFrom`. + +### 10. How should I use context safely? + +Use one of the two ACE patterns: + +- Preferred for custom functions: pass `context` directly with `runPolicyWithContext(context)`. +- For fixed interfaces (like ERC-20 functions): call `setContext(...)` and consume it in the same atomic transaction. + +Do not leave context pending across transactions. + +### 11. What governance process should I use for policy changes? + +Use a staged process: + +1. Propose the change and simulate it in staging. +2. Review policy order, extractor mapping, and default outcome. +3. Execute through timelock/multisig. +4. Monitor events and transfer behavior after deployment. + +### 12. What should I monitor in production? + +Monitor: + +- Policy add/remove actions. +- Extractor and mapping changes. +- `defaultAllow` changes (this flips the fallback behavior when all policies return `Continue`: `true` = allow, `false` = reject). +- Policy execution failures. +- Sudden increases in rejected or bypassed actions. + +### 13. How do I prepare for regulator or auditor questions? + +Maintain an audit-ready change log with policy versions, activation times, approval records, and test evidence for each policy update. + +### 14. What are common integration mistakes? + +- Wrong policy order (accidental early bypass). +- Missing extractor for a protected selector. +- Incorrect parameter names or mapping. +- No tests for revert/context behavior. +- Weak governance around PolicyEngine admin changes. + +### 15. What should my pre-mainnet checklist include? + +- Role/admin key setup completed. +- Policy chain and order reviewed. +- Extractor and parameter mapping tested for each selector. +- Default outcome verified for each contract. +- Pause and incident runbook tested. +- Upgrade and rollback plan approved. + +### 16. How do I handle an incident (bad policy push or false rejects)? + +Use an incident runbook with clear authority to pause sensitive actions, revert bad policy settings, communicate with counterparties, and re-enable flows in controlled phases. + +### 17. Do I need separate testing for upgrades? + +Yes. Run compliance regression tests for every upgrade, including policy-chain behavior, extractor decoding, and role/authorization invariants. + +### 18. What documentation should I publish to integrators? + +Publish a short integration guide that includes: + +- Which functions are policy-protected (function names/selectors). +- What each policy does in normal operation. +- Common failure cases and the revert reasons integrators may see. +- How admin/policy changes are approved and announced. +- Who to contact for support and incident escalation. diff --git a/contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol b/contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol new file mode 100644 index 0000000..8ceb545 --- /dev/null +++ b/contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol"; +import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol"; +import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol"; +import {IERC1643} from "CMTAT/interfaces/tokenization/draft-IERC1643.sol"; + +/** + * @title ComplianceTokenCMTATLite + * @author Chainlink + * @notice Standalone Compliance Token contract with Chainlink ACE policy validation on CMTA transfers + */ +contract ComplianceTokenCMTATLiteStandalone is CCTCMTATBaseERC20CrossChain { + /** + * @notice Contract version for standalone deployment + * @param admin address of the admin of contract (Access Control) + * @param ERC20Attributes_ ERC20 name, symbol and decimals + * @param extraInformationAttributes_ tokenId, terms, information + * @param policyEngine_ address of the policy engine + * @param snapshotEngine_ address of the snapshot engine + * @param documentEngine_ address of the document engine + */ + constructor( + address admin, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_, + address policyEngine_, + ISnapshotEngine snapshotEngine_, + IERC1643 documentEngine_ + ) { + // Initialize the contract to avoid front-running + initialize( + admin, + ERC20Attributes_, + extraInformationAttributes_, + policyEngine_, + snapshotEngine_, + documentEngine_ + ); + } +} diff --git a/contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol b/contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol new file mode 100644 index 0000000..70d5f55 --- /dev/null +++ b/contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; +import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol"; + +/** + * @title ComplianceTokenCMTATLiteUUPSUpgradeable + * @author Chainlink + * @notice UUPS upgradeable lite ComplianceToken contract with Chainlink ACE policy validation on CMTA transfers + */ +contract ComplianceTokenCMTATLiteUUPSUpgradeable is CCTCMTATBaseERC20CrossChain, UUPSUpgradeable { + bytes32 public constant PROXY_UPGRADE_ROLE = keccak256("PROXY_UPGRADE_ROLE"); + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + // Disable the possibility to initialize the implementation + _disableInitializers(); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL/PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////*/ + function _authorizeUpgrade( + address newImplementation + ) internal virtual override(UUPSUpgradeable) onlyRole(PROXY_UPGRADE_ROLE) {} +} diff --git a/contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol b/contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol new file mode 100644 index 0000000..5e2a52d --- /dev/null +++ b/contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol"; + +/** + * @title ComplianceTokenCMTATLite + * @author Chainlink + * @notice Standalone upgradeable lite Compliance Token contract with Chainlink ACE policy validation on CMTA transfers + */ +contract ComplianceTokenCMTATLiteUpgradeable is CCTCMTATBaseERC20CrossChain { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + // Disable the possibility to initialize the implementation + _disableInitializers(); + } +} diff --git a/contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol b/contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol new file mode 100644 index 0000000..02953d6 --- /dev/null +++ b/contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {CCTCommon} from "../../modules/standard/CCTCommon.sol"; +import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol"; +import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol"; +import {IERC1643} from "CMTAT/interfaces/engine/IDocumentEngine.sol"; + +/** + * @title ComplianceTokenCMTATStandalone + * @author Chainlink + * @notice Standalone ComplianceToken contract with Chainlink ACE policy validation on state-changing operations + */ +contract ComplianceTokenCMTATStandalone is CCTCommon { + /** + * @notice Contract version for standalone deployment + * @param admin_ address of the admin/owner + * @param ERC20Attributes_ ERC20 name, symbol and decimals + * @param extraInformationAttributes_ tokenId, terms, information + * @param policyEngine_ address of the policy engine + * @param snapshotEngine_ address of the snapshot engine + * @param documentEngine_ address of the document engine + */ + constructor( + address admin_, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_, + address policyEngine_, + ISnapshotEngine snapshotEngine_, + IERC1643 documentEngine_ + ) { + // Initialize the contract to avoid front-running + initialize( + admin_, + ERC20Attributes_, + extraInformationAttributes_, + policyEngine_, + snapshotEngine_, + documentEngine_ + ); + } +} diff --git a/contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol b/contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol new file mode 100644 index 0000000..c5bc751 --- /dev/null +++ b/contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol"; +import {CCTCommon} from "../../modules/standard/CCTCommon.sol"; + +/** + * @title ComplianceTokenCMTATUUPSUpgradeable + * @author Chainlink + * @notice UUPS upgradeable ComplianceToken contract with Chainlink ACE policy validation on state-changing operations + */ +contract ComplianceTokenCMTATUUPSUpgradeable is CCTCommon, UUPSUpgradeable { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + // Disable the possibility to initialize the implementation + _disableInitializers(); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL/PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////*/ + function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyOwner {} +} diff --git a/contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol b/contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol new file mode 100644 index 0000000..7bc8dc2 --- /dev/null +++ b/contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {CCTCommon} from "../../modules/standard/CCTCommon.sol"; + +/** + * @title ComplianceTokenCMTATUpgradeable + * @author Chainlink + * @notice Upgradeable ComplianceToken contract with Chainlink ACE policy validation on state-changing operations + */ +contract ComplianceTokenCMTATUpgradeable is CCTCommon { + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() { + // Disable the possibility to initialize the implementation + _disableInitializers(); + } +} diff --git a/contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol b/contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol new file mode 100644 index 0000000..0229dd1 --- /dev/null +++ b/contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol @@ -0,0 +1,55 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.20; + +import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol"; +import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +/** + * @title ERC20TransferFromExtractor + * @notice Extends the standard ERC20TransferExtractor by also extracting the + * spender address, enabling policies to validate transferFrom approvals. + * @dev Handles: + * - transfer(address to, uint256 amount): + * spender = sender, from = sender, to = decoded, amount = decoded + * - transferFrom(address from, address to, uint256 amount): + * spender = sender, from = decoded, to = decoded, amount = decoded + * + * Returns 4 parameters: [spender, from, to, amount] + */ +contract ERC20TransferFromExtractor is IExtractor { + string public constant override typeAndVersion = "ERC20TransferFromExtractor 1.0.0"; + + bytes32 public constant PARAM_SPENDER = keccak256("spender"); + bytes32 public constant PARAM_FROM = keccak256("from"); + bytes32 public constant PARAM_TO = keccak256("to"); + bytes32 public constant PARAM_AMOUNT = keccak256("amount"); + + function extract( + IPolicyEngine.Payload calldata payload + ) external pure override returns (IPolicyEngine.Parameter[] memory) { + address spender; + address from; + address to; + uint256 amount; + + if (payload.selector == IERC20.transfer.selector) { + spender = payload.sender; + from = payload.sender; + (to, amount) = abi.decode(payload.data, (address, uint256)); + } else if (payload.selector == IERC20.transferFrom.selector) { + spender = payload.sender; + (from, to, amount) = abi.decode(payload.data, (address, address, uint256)); + } else { + revert IPolicyEngine.UnsupportedSelector(payload.selector); + } + + IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](4); + result[0] = IPolicyEngine.Parameter(PARAM_SPENDER, abi.encode(spender)); + result[1] = IPolicyEngine.Parameter(PARAM_FROM, abi.encode(from)); + result[2] = IPolicyEngine.Parameter(PARAM_TO, abi.encode(to)); + result[3] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount)); + + return result; + } +} diff --git a/contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol b/contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol new file mode 100644 index 0000000..aa191ee --- /dev/null +++ b/contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.20; + +import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol"; +import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol"; + +/** + * @title MintBurnExtractor + * @notice Extracts parameters from CMTAT mint and burn function calls. + * @dev Handles: + * - mint(address account, uint256 amount) → 0x40c10f19 + * - burnFrom(address account, uint256 amount) → 0x79cc6790 + * - burn(uint256 amount) → 0x42966c68 + */ +contract MintBurnExtractor is IExtractor { + string public constant override typeAndVersion = "MintBurnExtractor 1.0.0"; + + bytes32 public constant PARAM_ACCOUNT = keccak256("account"); + bytes32 public constant PARAM_AMOUNT = keccak256("amount"); + + // mint(address,uint256) + bytes4 private constant MINT_SELECTOR = bytes4(keccak256("mint(address,uint256)")); + // burnFrom(address,uint256) + bytes4 private constant BURN_FROM_SELECTOR = bytes4(keccak256("burnFrom(address,uint256)")); + // burn(uint256) + bytes4 private constant BURN_SELECTOR = bytes4(keccak256("burn(uint256)")); + + function extract( + IPolicyEngine.Payload calldata payload + ) external pure override returns (IPolicyEngine.Parameter[] memory) { + address account; + uint256 amount; + + if (payload.selector == MINT_SELECTOR || payload.selector == BURN_FROM_SELECTOR) { + (account, amount) = abi.decode(payload.data, (address, uint256)); + } else if (payload.selector == BURN_SELECTOR) { + account = payload.sender; + (amount) = abi.decode(payload.data, (uint256)); + } else { + revert IPolicyEngine.UnsupportedSelector(payload.selector); + } + + IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](2); + result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account)); + result[1] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount)); + return result; + } +} diff --git a/contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol b/contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol new file mode 100644 index 0000000..7cffce4 --- /dev/null +++ b/contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol @@ -0,0 +1,140 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {Policy} from "@chainlink/policy-management/core/Policy.sol"; +import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol"; +import {IRule} from "CMTAT/mocks/RuleEngine/interfaces/IRule.sol"; + +/** + * @title TransferValidationPolicy + * @notice A policy that validates ERC-20 transfers by running an array of IRule + * contracts, mimicking CMTAT's _canTransferWithRuleEngine() behavior. + * @dev Works with both ERC20TransferExtractor (3 params) and + * ERC20TransferFromExtractor (4 params): + * + * 3 parameters: [from, to, amount] + * → uses detectTransferRestriction(from, to, amount) + * + * 4 parameters: [spender, from, to, amount] + * → uses detectTransferRestrictionFrom(spender, from, to, amount) + * + * Each IRule is checked in order. If any rule returns a non-zero code + * the policy reverts with PolicyRejected containing the rule's message. + */ +contract TransferValidationPolicy is Policy { + error InvalidParametersLength(uint256 length); + + string public constant override typeAndVersion = "TransferValidationPolicy 1.0.0"; + event RulesUpdated(uint256 previousCount, uint256 newCount); + + /// @custom:storage-location erc7201:cmta.TransferValidationPolicy + struct TransferValidationStorage { + IRule[] rules; + } + + // keccak256(abi.encode(uint256(keccak256("cmta.TransferValidationPolicy")) - 1)) & ~bytes32(uint256(0xff)) + bytes32 private constant STORAGE_LOCATION = 0xd90ded5881f9295c61e86b2e3b551acbb5fe06f9f79d0cec87ddc5bb60d48e00; + + function _getStorage() private pure returns (TransferValidationStorage storage $) { + assembly { + $.slot := STORAGE_LOCATION + } + } + + /** + * @inheritdoc Policy + * @dev Decodes an array of IRule addresses to set as initial rules. + * Pass empty bytes if no initial rules are needed. + */ + function configure(bytes calldata parameters) internal override onlyInitializing { + if (parameters.length > 0) { + address[] memory ruleAddrs = abi.decode(parameters, (address[])); + TransferValidationStorage storage $ = _getStorage(); + for (uint256 i = 0; i < ruleAddrs.length; ++i) { + require(ruleAddrs[i] != address(0), "Rule address cannot be zero"); + $.rules.push(IRule(ruleAddrs[i])); + } + } + } + + /** + * @notice Replaces all rules with a new set. + * @param rules_ The new array of IRule contracts. + */ + function setRules(IRule[] calldata rules_) external onlyOwner { + TransferValidationStorage storage $ = _getStorage(); + uint256 previousCount = $.rules.length; + delete $.rules; + for (uint256 i = 0; i < rules_.length; ++i) { + require(address(rules_[i]) != address(0), "Rule address cannot be zero"); + $.rules.push(rules_[i]); + } + emit RulesUpdated(previousCount, rules_.length); + } + + /** + * @notice Returns the current rules. + */ + function rules() external view returns (IRule[] memory) { + return _getStorage().rules; + } + + /** + * @notice Returns the number of rules. + */ + function rulesCount() external view returns (uint256) { + return _getStorage().rules.length; + } + + /** + * @inheritdoc Policy + * @dev Supports both 3-param (transfer) and 4-param (transferFrom) layouts. + * With 4 parameters, uses detectTransferRestrictionFrom to also validate + * the spender. + */ + function run( + address /* caller */, + address /* subject */, + bytes4 /* selector */, + bytes[] calldata parameters, + bytes calldata /* context */ + ) public view override returns (IPolicyEngine.PolicyResult) { + TransferValidationStorage storage $ = _getStorage(); + uint256 len = $.rules.length; + + if (parameters.length == 4) { + // ERC20TransferFromExtractor layout: [spender, from, to, amount] + address spender = abi.decode(parameters[0], (address)); + address from = abi.decode(parameters[1], (address)); + address to = abi.decode(parameters[2], (address)); + uint256 amount = abi.decode(parameters[3], (uint256)); + + for (uint256 i = 0; i < len; ++i) { + uint8 code = $.rules[i].detectTransferRestrictionFrom(spender, from, to, amount); + if (code != 0) { + string memory message = $.rules[i].messageForTransferRestriction(code); + revert IPolicyEngine.PolicyRejected(message); + } + } + } else if (parameters.length == 3) { + // ERC20TransferExtractor layout: [from, to, amount] + address from = abi.decode(parameters[0], (address)); + address to = abi.decode(parameters[1], (address)); + uint256 amount = abi.decode(parameters[2], (uint256)); + + for (uint256 i = 0; i < len; ++i) { + uint8 code = $.rules[i].detectTransferRestriction(from, to, amount); + if (code != 0) { + string memory message = $.rules[i].messageForTransferRestriction(code); + revert IPolicyEngine.PolicyRejected(message); + } + } + } else { + // This should never happen due to the initial length check, but included for completeness + revert InvalidParametersLength(parameters.length); + } + + return IPolicyEngine.PolicyResult.Continue; + } +} diff --git a/contracts/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol b/contracts/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol new file mode 100644 index 0000000..ccb3893 --- /dev/null +++ b/contracts/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity ^0.8.20; + +import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol"; +import {ValidationModulePolicyEngine} from "../../lite/ValidationModulePolicyEngine.sol"; + +contract MockPolicyEngine is IPolicyEngine { + Payload public lastPayload; + uint256 public attachCalls; + uint256 public detachCalls; + bool public detachShouldRevert; + + function setDetachShouldRevert(bool value) external { + detachShouldRevert = value; + } + + function typeAndVersion() external pure override returns (string memory) { + return "MockPolicyEngine 1.0.0"; + } + + function attach() external override { + attachCalls++; + } + + function detach() external override { + detachCalls++; + if (detachShouldRevert) { + revert("MockPolicyEngine: detach failed"); + } + } + + function run(Payload calldata payload) external override { + lastPayload = payload; + } + + function check(Payload calldata) external pure override {} + + function setExtractor(bytes4, address) external pure override {} + + function setExtractors(bytes4[] calldata, address) external pure override {} + + function getExtractor(bytes4) external pure override returns (address) { + return address(0); + } + + function setPolicyMapper(address, address) external pure override {} + + function getPolicyMapper(address) external pure override returns (address) { + return address(0); + } + + function addPolicy(address, bytes4, address, bytes32[] calldata) external pure override {} + + function addPolicyAt(address, bytes4, address, bytes32[] calldata, uint256) external pure override {} + + function removePolicy(address, bytes4, address) external pure override {} + + function getPolicies(address, bytes4) external pure override returns (address[] memory) { + return new address[](0); + } + + function setPolicyConfiguration(address, uint256, bytes4, bytes calldata) external pure override {} + + function getPolicyConfigVersion(address) external pure override returns (uint256) { + return 0; + } + + function upgradePolicy(address, address, bytes calldata) external pure override {} + + function setDefaultPolicyAllow(bool) external pure override {} + + function setTargetDefaultPolicyAllow(address, bool) external pure override {} +} + +contract ValidationModulePolicyEngineHarness is ValidationModulePolicyEngine { + function initializeWithPolicyEngine(address policyEngine) external initializer { + __PolicyProtectedBase_init(policyEngine); + } + + function _authorizeAttachPolicyEngine(address) internal pure override {} + + function _authorizePause() internal pure override {} + + function _authorizeDeactivate() internal pure override {} + + function _authorizeFreeze() internal pure override {} + + function exposedTryCheckPolicies( + bytes4 selector, + address sender, + bytes calldata data + ) external view returns (bool) { + return _tryCheckPolicies(selector, sender, data); + } + + function exposedTransferred(address spender, address from, address to, uint256 value) external returns (bool) { + return _transferred(spender, from, to, value); + } +} diff --git a/contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol b/contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol new file mode 100644 index 0000000..859a4df --- /dev/null +++ b/contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {IRule} from "../../../../submodules/RuleEngine/src/interfaces/IRule.sol"; + +/** + * @dev WARNING: Mock rule contracts for tests/examples only. + * Not designed, reviewed, or hardened for production deployments. + */ + +/** + * @title MaxAmountRule + * @notice Rejects transfers where the amount exceeds a configurable maximum. + */ +contract MaxAmountRule is IRule { + uint256 public immutable maxAmount; + uint8 constant AMOUNT_TOO_HIGH = 13; + + constructor(uint256 maxAmount_) { + maxAmount = maxAmount_; + } + + function detectTransferRestriction( + address /* from */, + address /* to */, + uint256 amount + ) public view override returns (uint8) { + return amount > maxAmount ? AMOUNT_TOO_HIGH : uint8(REJECTED_CODE_BASE.TRANSFER_OK); + } + + function detectTransferRestrictionFrom( + address /* spender */, + address from, + address to, + uint256 amount + ) public view override returns (uint8) { + return detectTransferRestriction(from, to, amount); + } + + function canTransfer(address from, address to, uint256 amount) public view override returns (bool) { + return detectTransferRestriction(from, to, amount) == 0; + } + + function canTransferFrom( + address /* spender */, + address from, + address to, + uint256 amount + ) external view override returns (bool) { + return canTransfer(from, to, amount); + } + + function transferred(address /* from */, address /* to */, uint256 /* value */) external pure override {} + + function transferred( + address /* spender */, + address /* from */, + address /* to */, + uint256 /* value */ + ) external pure override {} + + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return interfaceId == type(IRule).interfaceId; + } + + function canReturnTransferRestrictionCode(uint8 code) public pure override returns (bool) { + return code == AMOUNT_TOO_HIGH; + } + + function messageForTransferRestriction(uint8 code) external pure override returns (string memory) { + return code == AMOUNT_TOO_HIGH ? "Amount exceeds maximum" : "Unknown code"; + } +} + +/** + * @title RestrictedAddressRule + * @notice Rejects transfers involving addresses on a restricted list. + */ +contract RestrictedAddressRule is IRule { + uint8 constant FROM_RESTRICTED = 14; + uint8 constant TO_RESTRICTED = 15; + + mapping(address => bool) public restricted; + address public immutable owner; + + modifier onlyOwner() { + require(msg.sender == owner, "only owner"); + _; + } + + constructor(address[] memory restricted_) { + owner = msg.sender; + for (uint256 i = 0; i < restricted_.length; ++i) { + restricted[restricted_[i]] = true; + } + } + + function setRestricted(address account, bool status) external onlyOwner { + restricted[account] = status; + } + + function detectTransferRestriction( + address from, + address to, + uint256 /* amount */ + ) public view override returns (uint8) { + if (restricted[from]) return FROM_RESTRICTED; + if (restricted[to]) return TO_RESTRICTED; + return uint8(REJECTED_CODE_BASE.TRANSFER_OK); + } + + function detectTransferRestrictionFrom( + address /* spender */, + address from, + address to, + uint256 amount + ) public view override returns (uint8) { + return detectTransferRestriction(from, to, amount); + } + + function canTransfer(address from, address to, uint256 amount) public view override returns (bool) { + return detectTransferRestriction(from, to, amount) == 0; + } + + function canTransferFrom( + address /* spender */, + address from, + address to, + uint256 amount + ) external view override returns (bool) { + return canTransfer(from, to, amount); + } + + function transferred(address /* from */, address /* to */, uint256 /* value */) external pure override {} + + function transferred( + address /* spender */, + address /* from */, + address /* to */, + uint256 /* value */ + ) external pure override {} + + function supportsInterface(bytes4 interfaceId) external pure override returns (bool) { + return interfaceId == type(IRule).interfaceId; + } + + function canReturnTransferRestrictionCode(uint8 code) public pure override returns (bool) { + return code == FROM_RESTRICTED || code == TO_RESTRICTED; + } + + function messageForTransferRestriction(uint8 code) external pure override returns (string memory) { + if (code == FROM_RESTRICTED) return "Sender is restricted"; + if (code == TO_RESTRICTED) return "Recipient is restricted"; + return "Unknown code"; + } +} diff --git a/contracts/modules/lite/CCTCMTATBaseERC1404.sol b/contracts/modules/lite/CCTCMTATBaseERC1404.sol new file mode 100644 index 0000000..d39eb4f --- /dev/null +++ b/contracts/modules/lite/CCTCMTATBaseERC1404.sol @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {CCTCMTATBasePolicyEngine} from "./CCTCMTATBasePolicyEngine.sol"; +import {PolicyValidationModuleERC1404, IERC1404, IERC1404Extend} from "./PolicyValidationModuleERC1404.sol"; +import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol"; +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import { + ERC20EnforcementModule, + ERC20EnforcementModuleInternal +} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol"; + +abstract contract CCTCMTATBaseERC1404 is CCTCMTATBasePolicyEngine, PolicyValidationModuleERC1404 { + /** + * @dev ERC20EnforcementModule error text + */ + string internal constant TEXT_TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE = + "AddrFrom:insufficientActiveBalance"; + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + /** + * @inheritdoc PolicyValidationModuleERC1404 + */ + function messageForTransferRestriction( + uint8 restrictionCode + ) public view virtual override(PolicyValidationModuleERC1404) returns (string memory message) { + if ( + restrictionCode == + uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE) + ) { + return TEXT_TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE; + } else { + return PolicyValidationModuleERC1404.messageForTransferRestriction(restrictionCode); + } + } + + /** + * @inheritdoc CCTCMTATBasePolicyEngine + */ + function canTransfer( + address from, + address to, + uint256 value + ) public view virtual override(CCTCMTATBasePolicyEngine, ValidationModuleCore) returns (bool) { + return CCTCMTATBasePolicyEngine.canTransfer(from, to, value); + } + + /** + * @inheritdoc CCTCMTATBasePolicyEngine + */ + function canTransferFrom( + address spender, + address from, + address to, + uint256 value + ) public view virtual override(CCTCMTATBasePolicyEngine, ValidationModuleCore) returns (bool) { + return CCTCMTATBasePolicyEngine.canTransferFrom(spender, from, to, value); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL/PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////*/ + function _detectTransferRestriction( + address from, + address to, + uint256 value + ) internal view virtual override(PolicyValidationModuleERC1404) returns (uint8 code) { + uint256 frozenTokensLocal = ERC20EnforcementModule.getFrozenTokens(from); + if (frozenTokensLocal > 0) { + uint256 activeBalance = ERC20Upgradeable.balanceOf(from) - frozenTokensLocal; + if (value > activeBalance) { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE); + } + } + return PolicyValidationModuleERC1404._detectTransferRestriction(from, to, value); + } + + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(CCTCMTATBasePolicyEngine) returns (bool) { + return CCTCMTATBasePolicyEngine.supportsInterface(interfaceId); + } +} diff --git a/contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol b/contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol new file mode 100644 index 0000000..48f380f --- /dev/null +++ b/contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {ERC20CrossChainModule} from "CMTAT/modules/wrapper/options/ERC20CrossChainModule.sol"; +import {CCIPModule} from "CMTAT/modules/wrapper/options/CCIPModule.sol"; +import {CCTCMTATBaseERC1404} from "./CCTCMTATBaseERC1404.sol"; +import {CMTATBaseCommon} from "CMTAT/modules/0_CMTATBaseCommon.sol"; +import {ERC20MintModule, ERC20MintModuleInternal} from "CMTAT/modules/wrapper/core/ERC20MintModule.sol"; +import {ERC20BurnModule, ERC20BurnModuleInternal} from "CMTAT/modules/wrapper/core/ERC20BurnModule.sol"; +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; + +abstract contract CCTCMTATBaseERC20CrossChain is ERC20CrossChainModule, CCIPModule, CCTCMTATBaseERC1404 { + /* ============ State Functions ============ */ + /** + * @dev revert if the contract is in pause state + */ + function approve( + address spender, + uint256 value + ) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) { + return ERC20Upgradeable.approve(spender, value); + } + function transfer( + address to, + uint256 value + ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (bool) { + return CMTATBaseCommon.transfer(to, value); + } + /* + * @inheritdoc ERC20BaseModule + */ + function transferFrom( + address from, + address to, + uint256 value + ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (bool) { + return CMTATBaseCommon.transferFrom(from, to, value); + } + /** + * @dev Check if the mint is valid + */ + function _mintOverride( + address account, + uint256 value + ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) { + _checkTransferred(address(0), address(0), account, value); + ERC20MintModuleInternal._mintOverride(account, value); + } + + /** + * @dev Check if the burn is valid + */ + function _burnOverride( + address account, + uint256 value + ) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) { + _checkTransferred(address(0), account, address(0), value); + ERC20BurnModuleInternal._burnOverride(account, value); + } + + /** + * @dev Check if a minter transfer is valid + */ + function _minterTransferOverride( + address from, + address to, + uint256 value + ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) { + _checkTransferred(address(0), from, to, value); + ERC20MintModuleInternal._minterTransferOverride(from, to, value); + } + + /** + * @inheritdoc CMTATBaseCommon + */ + function decimals() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (uint8) { + return CMTATBaseCommon.decimals(); + } + + /** + * @inheritdoc CMTATBaseCommon + */ + function name() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) { + return CMTATBaseCommon.name(); + } + + /** + * @inheritdoc CMTATBaseCommon + */ + function symbol() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) { + return CMTATBaseCommon.symbol(); + } + + /* ============ View functions ============ */ + function supportsInterface( + bytes4 _interfaceId + ) public view virtual override(ERC20CrossChainModule, CCTCMTATBaseERC1404) returns (bool) { + return + ERC20CrossChainModule.supportsInterface(_interfaceId) || + CCTCMTATBaseERC1404.supportsInterface(_interfaceId); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL/PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /* ==== Access Control ==== */ + + /** + * @custom:access-control + * - the caller must have the `DEFAULT_ADMIN_ROLE`. + */ + function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {} + + /** + * @dev + * A cross-chain bridge could call the OpenZeppelin function `renounceRole` to lose their privileges (CROSS_CHAIN_ROLE) + * While it is not intended,this has no other effect than depriving the bridge of burn/mint tokens + * An attacker could use this to disrupt minting/burning if they can get the bridge to execute calls. + * However, in this case, the bridge should still be considered compromised and not used again. + * @custom:access-control + * - the caller must have the `CROSS_CHAIN_ROLE`. + */ + function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule) whenNotPaused { + AccessControlUpgradeable._checkRole(CROSS_CHAIN_ROLE, caller); + } + + /** + * @custom:access-control + * - the caller must have the `BURNER_FROM_ROLE`. + * - We don't allow token holder to burn their own tokens if they don't have this role. + */ + function _authorizeBurnFrom() + internal + virtual + override(ERC20CrossChainModule) + onlyRole(BURNER_FROM_ROLE) + whenNotPaused + {} + + /** + * @custom:access-control + * - the caller must have the `BURNER_SELF_ROLE`. + * - We don't allow token holder to burn their own tokens if they don't have this role. + */ + function _authorizeSelfBurn() + internal + virtual + override(ERC20CrossChainModule) + onlyRole(BURNER_SELF_ROLE) + whenNotPaused + {} + + /* ==== ERC-20 OpenZeppelin ==== */ + function _update( + address from, + address to, + uint256 amount + ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) { + return CMTATBaseCommon._update(from, to, amount); + } +} diff --git a/contracts/modules/lite/CCTCMTATBasePolicyEngine.sol b/contracts/modules/lite/CCTCMTATBasePolicyEngine.sol new file mode 100644 index 0000000..faf573d --- /dev/null +++ b/contracts/modules/lite/CCTCMTATBasePolicyEngine.sol @@ -0,0 +1,200 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {CMTATBaseCommon, CMTATBaseAccessControl} from "CMTAT/modules/1_CMTATBaseAccessControl.sol"; +import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol"; +import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol"; +import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol"; +import {IERC1643} from "CMTAT/interfaces/tokenization/draft-IERC1643.sol"; +import {ValidationModulePolicyEngine} from "./ValidationModulePolicyEngine.sol"; +import {PauseModule} from "CMTAT/modules/wrapper/core/PauseModule.sol"; +import {EnforcementModule} from "CMTAT/modules/wrapper/core/EnforcementModule.sol"; +import {IERC7943FungibleTransferError} from "CMTAT/interfaces/tokenization/draft-IERC7943.sol"; +// Extensions +import { + ERC20EnforcementModule, + ERC20EnforcementModuleInternal +} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol"; + +abstract contract CCTCMTATBasePolicyEngine is + CMTATBaseAccessControl, + ValidationModulePolicyEngine, + IERC7943FungibleTransferError +{ + /*////////////////////////////////////////////////////////////// + INITIALIZER FUNCTION + //////////////////////////////////////////////////////////////*/ + /** + * @notice + * initialize the proxy contract + * The calls to this function will revert if the contract was deployed without a proxy + * @param admin address of the admin of contract (Access Control) + * @param ERC20Attributes_ ERC20 name, symbol and decimals + * @param extraInformationAttributes_ tokenId, terms, information + * @param policyEngine_ address of the policy engine + * @dev + * If you override the public function initialize, + * call inside directly the internal function, not the public one which is protected by the initializer modifier + */ + function initialize( + address admin, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_, + address policyEngine_, + ISnapshotEngine snapshotEngine_, + IERC1643 documentEngine_ + ) public virtual initializer { + _initialize( + admin, + ERC20Attributes_, + extraInformationAttributes_, + policyEngine_, + snapshotEngine_, + documentEngine_ + ); + } + + /** + * @dev don't call the initializer modifer + */ + function _initialize( + address admin, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_, + address policyEngine_, + ISnapshotEngine snapshotEngine_, + IERC1643 documentEngine_ + ) internal virtual onlyInitializing { + __CMTAT_init( + admin, + ERC20Attributes_, + extraInformationAttributes_, + policyEngine_, + snapshotEngine_, + documentEngine_ + ); + } + + /** + * @dev calls the different initialize functions from the different modules + */ + function __CMTAT_init( + address admin, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_, + address policyEngine_, + ISnapshotEngine snapshotEngine_, + IERC1643 documentEngine_ + ) internal virtual onlyInitializing { + /* OpenZeppelin library */ + // OZ init_unchained functions are called firstly due to inheritance + __Context_init_unchained(); + + // AccessControlUpgradeable inherits from ERC165Upgradeable + __ERC165_init_unchained(); + + // Openzeppelin + __CMTAT_openzeppelin_init_unchained(ERC20Attributes_); + + /* Wrapper modules */ + __CMTAT_commonModules_init_unchained(admin, ERC20Attributes_, extraInformationAttributes_); + + /* Engine modules */ + __SnapshotEngineModule_init_unchained(snapshotEngine_); + __DocumentEngineModule_init_unchained(documentEngine_); + + /* Chainlink-ACE policy module */ + __PolicyProtectedBase_init_unchained(policyEngine_); + } + + /* + * @dev OpenZeppelin + */ + function __CMTAT_openzeppelin_init_unchained( + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_ + ) internal virtual onlyInitializing { + // Note that the Openzeppelin functions name() and symbol() are overriden in ERC20BaseModule + __ERC20_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol); + } + + /* + * @dev CMTAT wrapper modules + */ + function __CMTAT_modules_init_unchained( + address admin, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_ + ) internal virtual onlyInitializing { + __CMTAT_commonModules_init_unchained(admin, ERC20Attributes_, extraInformationAttributes_); + } + + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /** + * @inheritdoc ValidationModulePolicyEngine + */ + function canTransfer( + address from, + address to, + uint256 value + ) public view virtual override(ValidationModulePolicyEngine) returns (bool) { + (bool isValid, ) = ERC20EnforcementModuleInternal._checkActiveBalance(from, value); + if (!isValid) { + return false; + } else { + return ValidationModulePolicyEngine.canTransfer(from, to, value); + } + } + + /** + * @inheritdoc ValidationModulePolicyEngine + */ + function canTransferFrom( + address spender, + address from, + address to, + uint256 value + ) public view virtual override(ValidationModulePolicyEngine) returns (bool) { + (bool isValid, ) = ERC20EnforcementModuleInternal._checkActiveBalance(from, value); + if (!isValid) { + return false; + } else { + return ValidationModulePolicyEngine.canTransferFrom(spender, from, to, value); + } + } + + function _authorizeAttachPolicyEngine(address) internal virtual override onlyRole(DEFAULT_ADMIN_ROLE) {} + + /*////////////////////////////////////////////////////////////// + INTERNAL/PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /* ==== Access Control ==== */ + function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE) {} + function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE) {} + + function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE) {} + + /* ==== Transfer/mint/burn restriction ==== */ + function _checkTransferred( + address spender, + address from, + address to, + uint256 value + ) internal virtual override(CMTATBaseCommon) { + CMTATBaseCommon._checkTransferred(spender, from, to, value); + require( + ValidationModulePolicyEngine._transferred(spender, from, to, value), + ERC7943CannotTransfer(from, to, value) + ); + } + + function supportsInterface( + bytes4 interfaceId + ) public view virtual override(CMTATBaseAccessControl, PolicyProtectedBaseUpgradeable) returns (bool) { + return + CMTATBaseAccessControl.supportsInterface(interfaceId) || + PolicyProtectedBaseUpgradeable.supportsInterface(interfaceId); + } +} diff --git a/contracts/modules/lite/PolicyValidationModuleERC1404.sol b/contracts/modules/lite/PolicyValidationModuleERC1404.sol new file mode 100644 index 0000000..d2d30e0 --- /dev/null +++ b/contracts/modules/lite/PolicyValidationModuleERC1404.sol @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +/* ==== Tokenization === */ +import {IERC1404, IERC1404Extend} from "CMTAT/interfaces/tokenization/draft-IERC1404.sol"; +import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol"; + +/** + * @dev Validation module (ERC-1404) + * + * Useful to restrict and validate transfers + */ +abstract contract PolicyValidationModuleERC1404 is ValidationModuleCore, IERC1404Extend { + /* ============ State Variables ============ */ + string constant TEXT_TRANSFER_OK = "NoRestriction"; + string constant TEXT_UNKNOWN_CODE = "UnknownCode"; + + /* EnforcementModule */ + string internal constant TEXT_TRANSFER_REJECTED_FROM_FROZEN = "AddrFromIsFrozen"; + + string internal constant TEXT_TRANSFER_REJECTED_TO_FROZEN = "AddrToIsFrozen"; + + string internal constant TEXT_TRANSFER_REJECTED_SPENDER_FROZEN = "AddrSpenderIsFrozen"; + + /* PauseModule */ + string internal constant TEXT_TRANSFER_REJECTED_PAUSED = "EnforcedPause"; + + /* Contract deactivated */ + string internal constant TEXT_TRANSFER_REJECTED_DEACTIVATED = "ContractDeactivated"; + + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /** + * @notice returns the human readable explanation + * corresponding to the error code returned by detectTransferRestriction + * @param restrictionCode The error code returned by detectTransferRestriction + * @return message The human readable explanation corresponding to the error code returned by detectTransferRestriction + * @dev see {ERC-1404} + */ + function messageForTransferRestriction( + uint8 restrictionCode + ) public view virtual override(IERC1404) returns (string memory message) { + if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) { + return TEXT_TRANSFER_OK; + } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED)) { + return TEXT_TRANSFER_REJECTED_PAUSED; + } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_DEACTIVATED)) { + return TEXT_TRANSFER_REJECTED_DEACTIVATED; + } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN)) { + return TEXT_TRANSFER_REJECTED_FROM_FROZEN; + } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN)) { + return TEXT_TRANSFER_REJECTED_TO_FROZEN; + } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN)) { + return TEXT_TRANSFER_REJECTED_SPENDER_FROZEN; + } else { + return TEXT_UNKNOWN_CODE; + } + } + + /** + * @notice check if value token can be transferred from `from` to `to` + * @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} + */ + function detectTransferRestriction( + address from, + address to, + uint256 value + ) public view virtual override(IERC1404) returns (uint8 code) { + uint8 codeReturn = _detectTransferRestriction(from, to, value); + if (codeReturn != uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) { + return codeReturn; + } else { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK); + } + } + + function detectTransferRestrictionFrom( + address spender, + address from, + address to, + uint256 value + ) public view virtual override(IERC1404Extend) returns (uint8 code) { + if (isFrozen(spender)) { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN); + } else { + uint8 codeReturn = _detectTransferRestriction(from, to, value); + if (codeReturn != uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) { + return codeReturn; + } else { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK); + } + } + } + + /*////////////////////////////////////////////////////////////// + INTERNAL/PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + /** + * @dev override this function to add further restriction + */ + function _detectTransferRestriction( + address from, + address to, + uint256 /* value */ + ) internal view virtual returns (uint8 code) { + if (deactivated()) { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_DEACTIVATED); + } else if (paused()) { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED); + } else if (isFrozen(from)) { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN); + } else if (isFrozen(to)) { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN); + } else { + return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK); + } + } +} diff --git a/contracts/modules/lite/ValidationModulePolicyEngine.sol b/contracts/modules/lite/ValidationModulePolicyEngine.sol new file mode 100644 index 0000000..8d7fd33 --- /dev/null +++ b/contracts/modules/lite/ValidationModulePolicyEngine.sol @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol"; +import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol"; +import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +abstract contract ValidationModulePolicyEngine is ValidationModuleCore, PolicyProtectedBaseUpgradeable { + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + /* ============ View functions ============ */ + /** + * @inheritdoc ValidationModuleCore + * @dev call the policy engine if set + */ + function canTransfer( + address from, + address to, + uint256 value + ) public view virtual override(ValidationModuleCore) returns (bool) { + return _canTransfer(from, to, value); + } + + /** + * @inheritdoc ValidationModuleCore + * @dev call the policy engine if set + */ + function canTransferFrom( + address spender, + address from, + address to, + uint256 value + ) public view virtual override(ValidationModuleCore) returns (bool) { + return _canTransferFrom(spender, from, to, value); + } + + /*////////////////////////////////////////////////////////////// + INTERNAL/PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /* ============ View functions ============ */ + function _canTransfer(address from, address to, uint256 value) internal view virtual returns (bool) { + if (!ValidationModuleCore.canTransfer(from, to, value)) { + return false; + } else { + return _canTransferWithPolicyEngine(from, to, value); + } + } + + function _canTransferFrom( + address spender, + address from, + address to, + uint256 value + ) internal view virtual returns (bool) { + if (!ValidationModuleCore.canTransferFrom(spender, from, to, value)) { + return false; + } else { + return _canTransferFromWithPolicyEngine(spender, from, to, value); + } + } + + function _canTransferFromWithPolicyEngine( + address spender, + address from, + address to, + uint256 value + ) internal view virtual returns (bool) { + return _tryCheckPolicies(IERC20.transferFrom.selector, spender, abi.encode(from, to, value)); + } + + function _canTransferWithPolicyEngine( + address from, + address to, + uint256 value + ) internal view virtual returns (bool) { + return _tryCheckPolicies(IERC20.transfer.selector, from, abi.encode(to, value)); + } + + function _tryCheckPolicies(bytes4 selector, address sender, bytes memory data) internal view returns (bool) { + IPolicyEngine policyEngine_ = IPolicyEngine(getPolicyEngine()); + if (address(policyEngine_) != address(0)) { + bytes memory context = getContext(); + try + policyEngine_.check( + IPolicyEngine.Payload({selector: selector, sender: sender, data: data, context: context}) + ) + { + return true; + } catch { + return false; + } + } else { + return true; + } + } + + /* ============ State functions ============ */ + function _transferred( + address spender, + address from, + address to, + uint256 /* value */ + ) internal virtual returns (bool) { + _canTransferGenericByModuleAndRevert(spender, from, to); + IPolicyEngine policyEngine_ = IPolicyEngine(getPolicyEngine()); + if (address(policyEngine_) != address(0)) { + bytes memory context = getContext(); + policyEngine_.run( + IPolicyEngine.Payload({selector: msg.sig, sender: _msgSender(), data: msg.data[4:], context: context}) + ); + if (context.length > 0) { + clearContext(); + } + } + return true; + } +} diff --git a/contracts/modules/standard/CCTCommon.sol b/contracts/modules/standard/CCTCommon.sol new file mode 100644 index 0000000..a3cc459 --- /dev/null +++ b/contracts/modules/standard/CCTCommon.sol @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: MPL-2.0 + +pragma solidity ^0.8.20; + +/* ==== OpenZeppelin === */ +import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol"; +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; +import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; + +/* ==== CMTAT === */ +import {CMTATBaseCommon} from "CMTAT/modules/0_CMTATBaseCommon.sol"; +/* = Base = */ +/* = Core = */ +import {ERC20BurnModule, ERC20BurnModuleInternal} from "CMTAT/modules/wrapper/core/ERC20BurnModule.sol"; +import {ERC20MintModule, ERC20MintModuleInternal} from "CMTAT/modules/wrapper/core/ERC20MintModule.sol"; +import {ERC20BaseModule} from "CMTAT/modules/wrapper/core/ERC20BaseModule.sol"; +/* = Option & Extension = */ +import {ERC20CrossChainModule} from "CMTAT/modules/wrapper/options/ERC20CrossChainModule.sol"; +import {CCIPModule} from "CMTAT/modules/wrapper/options/CCIPModule.sol"; +import {ExtraInformationModule} from "CMTAT/modules/wrapper/extensions/ExtraInformationModule.sol"; +import { + ERC20EnforcementModule, + ERC20EnforcementModuleInternal +} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol"; +import {DocumentEngineModule, IERC1643} from "CMTAT/modules/wrapper/extensions/DocumentEngineModule.sol"; +import {SnapshotEngineModule} from "CMTAT/modules/wrapper/extensions/SnapshotEngineModule.sol"; +/* = Interface = */ +import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol"; +import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol"; +/* ==== Chainlink ACE === */ +import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol"; + +abstract contract CCTCommon is + OwnableUpgradeable, + ERC20CrossChainModule, + PolicyProtectedBaseUpgradeable, + CMTATBaseCommon, + CCIPModule +{ + function initialize( + address admin, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_, + address policyEngine, + ISnapshotEngine snapshotEngine_, + IERC1643 documentEngine_ + ) public virtual initializer { + _initialize( + admin, + ERC20Attributes_, + extraInformationAttributes_, + policyEngine, + snapshotEngine_, + documentEngine_ + ); + } + + function _initialize( + address admin, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_, + address policyEngine, + ISnapshotEngine snapshotEngine_, + IERC1643 documentEngine_ + ) internal virtual onlyInitializing { + __CMTAT_init( + admin, + ERC20Attributes_, + extraInformationAttributes_, + policyEngine, + snapshotEngine_, + documentEngine_ + ); + } + + /** + * @dev calls the different initialize functions from the different modules + */ + function __CMTAT_init( + address admin, + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory ExtraInformationAttributes_, + address policyEngine, + ISnapshotEngine snapshotEngine_, + IERC1643 documentEngine_ + ) internal virtual onlyInitializing { + __Ownable_init_unchained(admin); + /* OpenZeppelin library */ + // OZ init_unchained functions are called firstly due to inheritance + __Context_init_unchained(); + + // AccessControlUpgradeable inherits from ERC165Upgradeable + __ERC165_init_unchained(); + + // Openzeppelin + __CMTAT_openzeppelin_init_unchained(ERC20Attributes_); + + __PolicyProtectedBase_init_unchained(policyEngine); + + /* Wrapper modules */ + __CMTAT_modules_init_unchained(ERC20Attributes_, ExtraInformationAttributes_); + + /* Engine modules */ + __SnapshotEngineModule_init_unchained(snapshotEngine_); + __DocumentEngineModule_init_unchained(documentEngine_); + } + + /* + * @dev OpenZeppelin + */ + function __CMTAT_openzeppelin_init_unchained( + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_ + ) internal virtual onlyInitializing { + // Note that the Openzeppelin functions name() and symbol() are overriden in ERC20BaseModule + __ERC20_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol); + } + + /* + * @dev CMTAT wrapper modules + */ + function __CMTAT_modules_init_unchained( + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_ + ) internal virtual onlyInitializing { + __CMTAT_commonModules_init_unchained(ERC20Attributes_, extraInformationAttributes_); + } + + function __CMTAT_commonModules_init_unchained( + ICMTATConstructor.ERC20Attributes memory ERC20Attributes_, + ICMTATConstructor.ExtraInformationAttributes memory ExtraInformationModuleAttributes_ + ) internal virtual onlyInitializing { + // Core + __ERC20BaseModule_init_unchained( + ERC20Attributes_.decimalsIrrevocable, + ERC20Attributes_.name, + ERC20Attributes_.symbol + ); + /* Extensions */ + __ExtraInformationModule_init_unchained( + ExtraInformationModuleAttributes_.tokenId, + ExtraInformationModuleAttributes_.terms, + ExtraInformationModuleAttributes_.information + ); + } + + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /* ============ State Functions ============ */ + function transfer( + address to, + uint256 value + ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) runPolicy returns (bool) { + return CMTATBaseCommon.transfer(to, value); + } + /* + * @inheritdoc ERC20BaseModule + */ + function transferFrom( + address from, + address to, + uint256 value + ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) runPolicy returns (bool) { + return CMTATBaseCommon.transferFrom(from, to, value); + } + + function _authorizeAttachPolicyEngine(address) internal virtual override onlyOwner {} + + /* ============ View functions ============ */ + + /** + * @inheritdoc CMTATBaseCommon + */ + function decimals() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (uint8) { + return CMTATBaseCommon.decimals(); + } + + /** + * @inheritdoc CMTATBaseCommon + */ + function name() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) { + return CMTATBaseCommon.name(); + } + + /** + * @inheritdoc CMTATBaseCommon + */ + function symbol() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) { + return CMTATBaseCommon.symbol(); + } + + function supportsInterface( + bytes4 _interfaceId + ) public view virtual override(IERC165, ERC20CrossChainModule, PolicyProtectedBaseUpgradeable) returns (bool) { + return + ERC20CrossChainModule.supportsInterface(_interfaceId) || + PolicyProtectedBaseUpgradeable.supportsInterface(_interfaceId); + } + + /* ==== Mint and Burn Operations ==== */ + /** + * @dev Check if the mint is valid + */ + function _mintOverride( + address account, + uint256 value + ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) { + CMTATBaseCommon._mintOverride(account, value); + } + + /** + * @dev Check if the burn is valid + */ + function _burnOverride( + address account, + uint256 value + ) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) { + CMTATBaseCommon._burnOverride(account, value); + } + + /** + * @dev Check if a minter transfer is valid + */ + function _minterTransferOverride( + address from, + address to, + uint256 value + ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) { + CMTATBaseCommon._minterTransferOverride(from, to, value); + } + + /* ==== Access Control Functions ==== */ + + /** + * @custom:access-control + * - the caller must have the `DEFAULT_ADMIN_ROLE`. + */ + function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `MINTER_ROLE`. + */ + function _authorizeMint() internal virtual override(ERC20MintModule) runPolicy {} + + /** + * @custom:access-control + * - The caller must have the `BURNER_ROLE`. + */ + function _authorizeBurn() internal virtual override(ERC20BurnModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `DOCUMENT_ROLE`. + */ + function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `EXTRA_INFORMATION_ROLE`. + */ + function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `ERC20ENFORCER_ROLE`. + */ + function _authorizeERC20Enforcer() internal virtual override(ERC20EnforcementModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `DEFAULT_ADMIN_ROLE`. + */ + function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `SNAPSHOOTER_ROLE`. + */ + function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `DEFAULT_ADMIN_ROLE`. + */ + function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) runPolicy {} + + /** + * @dev + * A cross-chain bridge could call the OpenZeppelin function `renounceRole` to lose their privileges (CROSS_CHAIN_ROLE) + * While it is not intended,this has no other effect than depriving the bridge of burn/mint tokens + * An attacker could use this to disrupt minting/burning if they can get the bridge to execute calls. + * However, in this case, the bridge should still be considered compromised and not used again. + * @custom:access-control + * - the caller must have the `CROSS_CHAIN_ROLE`. + */ + function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `BURNER_FROM_ROLE`. + * - We don't allow token holder to burn their own tokens if they don't have this role. + */ + function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) runPolicy {} + + /** + * @custom:access-control + * - the caller must have the `BURNER_ROLE`. + * - We don't allow token holder to burn their own tokens if they don't have this role. + */ + function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) runPolicy {} + + /* ==== ERC-20 OpenZeppelin ==== */ + function _update( + address from, + address to, + uint256 amount + ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) { + return CMTATBaseCommon._update(from, to, amount); + } +} diff --git a/doc/audits/tools/aderyn-report-feedback.md b/doc/audits/tools/aderyn-report-feedback.md new file mode 100644 index 0000000..bf1bd85 --- /dev/null +++ b/doc/audits/tools/aderyn-report-feedback.md @@ -0,0 +1,73 @@ +# Aderyn Report Feedback + +Here is the list of report performed with [Aderyn](https://github.com/Cyfrin/aderyn) + +```bash +aderyn -x mocks --output doc/audits/tools/aderyn-report.md +``` + +| Version | Report | Assessment | +| --- | --- | --- | +| current | `doc/audits/tools/aderyn-report.md` | `doc/audits/tools/aderyn-report-feedback.md` | + +Report scope: 17 Solidity files, 959 nSLOC. + +2 High · 10 Low + +| ID | Finding | Instances | Assessment | +| --- | --- | --- | --- | +| H-1 | Arbitrary `from` passed to `transferFrom` | 1 | Accepted in context — policy-gated flow; not treated as exploitable in this integration design. | +| H-2 | Contract locks Ether without withdraw | 2 | Accepted false positive — token deployments are not intended as ETH custody contracts. | +| L-1 | Centralization risk | 11 | Accepted by design — privileged governance/control is intentional. | +| L-2 | Costly operations inside loop | 2 | Accepted — expected tradeoff in policy/rule iteration paths. | +| L-3 | Empty block | 22 | Accepted by design — authorization hook pattern. | +| L-4 | Literal instead of constant | 2 | Informational — optional quality improvement. | +| L-5 | PUSH0 opcode | 15 | Environment-dependent informational; not a direct vulnerability finding in this deployment context. | +| L-6 | Loop contains `require`/`revert` | 4 | Accepted by design — atomic validation and explicit failure signaling. | +| L-7 | Unsafe ERC20 operation | 7 | Accepted false positive — primarily selector/module-flow usage, not unsafe token transfer wrappers. | +| L-8 | Unspecific Solidity pragma | 15 | Accepted by design — version ranges are intentionally used in this codebase. | +| L-9 | Unused state variable | 1 | False positive — `STORAGE_LOCATION` is used via inline assembly in `_getStorage()`. | + + +## Executive triage + +- Total findings reported: **12** (2 High, 10 Low) +- Immediate action items in this repo: **none classified as confirmed exploitable vulnerabilities** +- Main status: **mostly false positives, design choices, or dependency-level noise** + +## High findings + +### H-1: Arbitrary `from` passed to `transferFrom` + +- Location: `contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol` +- Status: **Accepted / not a vulnerability in this context** +- Rationale: this call path is policy-gated through ACE + CMTAT authorization flow; this is expected ERC20/CMTAT behavior and not an unguarded arbitrary transfer primitive. + +### H-2: Contract locks Ether without withdraw + +- Location: UUPS deployment contracts +- Status: **Accepted false positive** +- Rationale: these token deployments are not designed to custody native ETH; no payable business flow requires ETH withdrawal. + +## Low findings (grouped) + +### L-1 (centralization), L-8 (pragma), L-2/L-3/L-4/L-5/L-6 + +- Status: **Informational / accepted** +- Rationale: these are style/governance/design heuristics and do not by themselves indicate exploitable defects in this integration. + +### L-7: Unsafe ERC20 operation + +- Status: **Accepted false positive** +- Rationale: flagged sites are interface selectors/existing token-module flows, not unsafe raw token transfer integrations requiring `SafeERC20` wrappers. + +### L-9: Unused state variable + +- Status: **False positive** +- Rationale: flagged constant `STORAGE_LOCATION` is consumed in inline assembly (`_getStorage()`), which static analyzers may miss. + + +## Recommended follow-up + +1. Document `L-8` as an inline-assembly false positive in audit triage notes. +2. Continue prioritizing repo-owned paths over dependency findings in audit triage. \ No newline at end of file diff --git a/doc/audits/tools/aderyn-report.md b/doc/audits/tools/aderyn-report.md new file mode 100644 index 0000000..0c59fa0 --- /dev/null +++ b/doc/audits/tools/aderyn-report.md @@ -0,0 +1,687 @@ +# Aderyn Analysis Report + +This report was generated by [Aderyn](https://github.com/Cyfrin/aderyn), a static analysis tool built by [Cyfrin](https://cyfrin.io), a blockchain security company. This report is not a substitute for manual audit or security review. It should not be relied upon for any purpose other than to assist in the identification of potential security vulnerabilities. +# Table of Contents + +- [Summary](#summary) + - [Files Summary](#files-summary) + - [Files Details](#files-details) + - [Issue Summary](#issue-summary) +- [High Issues](#high-issues) + - [H-1: Arbitrary `from` Passed to `transferFrom`](#h-1-arbitrary-from-passed-to-transferfrom) + - [H-2: Contract locks Ether without a withdraw function](#h-2-contract-locks-ether-without-a-withdraw-function) +- [Low Issues](#low-issues) + - [L-1: Centralization Risk](#l-1-centralization-risk) + - [L-2: Costly operations inside loop](#l-2-costly-operations-inside-loop) + - [L-3: Empty Block](#l-3-empty-block) + - [L-4: Literal Instead of Constant](#l-4-literal-instead-of-constant) + - [L-5: PUSH0 Opcode](#l-5-push0-opcode) + - [L-6: Loop Contains `require`/`revert`](#l-6-loop-contains-requirerevert) + - [L-7: Unsafe ERC20 Operation](#l-7-unsafe-erc20-operation) + - [L-8: Unspecific Solidity Pragma](#l-8-unspecific-solidity-pragma) + - [L-9: Unused State Variable](#l-9-unused-state-variable) + + +# Summary + +## Files Summary + +| Key | Value | +| --- | --- | +| .sol Files | 15 | +| Total nSLOC | 871 | + + +## Files Details + +| Filepath | nSLOC | +| --- | --- | +| contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol | 24 | +| contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol | 12 | +| contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol | 7 | +| contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol | 24 | +| contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol | 9 | +| contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol | 7 | +| contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol | 35 | +| contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol | 29 | +| contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol | 82 | +| contracts/modules/lite/CCTCMTATBaseERC1404.sol | 59 | +| contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol | 99 | +| contracts/modules/lite/CCTCMTATBasePolicyEngine.sol | 133 | +| contracts/modules/lite/PolicyValidationModuleERC1404.sol | 77 | +| contracts/modules/lite/ValidationModulePolicyEngine.sol | 92 | +| contracts/modules/standard/CCTCommon.sol | 182 | +| **Total** | **871** | + + +## Issue Summary + +| Category | No. of Issues | +| --- | --- | +| High | 2 | +| Low | 9 | + + +# High Issues + +## H-1: Arbitrary `from` Passed to `transferFrom` + +Passing an arbitrary `from` address to `transferFrom` (or `safeTransferFrom`) can lead to loss of funds, because anyone can transfer tokens from the `from` address if an approval is made. + +
1 Found Instances + + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 45](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L45) + + ```solidity + return CMTATBaseCommon.transferFrom(from, to, value); + ``` + +
+ + + +## H-2: Contract locks Ether without a withdraw function + +It appears that the contract includes a payable function to accept Ether but lacks a corresponding function to withdraw it, which leads to the Ether being locked in the contract. To resolve this issue, please implement a public or external function that allows for the withdrawal of Ether from the contract. + +
3 Found Instances + + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol [Line: 13](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol#L13) + + ```solidity + contract ComplianceTokenCMTATLiteUUPSUpgradeable is CCTCMTATBaseERC20CrossChain, UUPSUpgradeable { + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol [Line: 13](../../../contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol#L13) + + ```solidity + contract ComplianceTokenCMTATUUPSUpgradeable is CCTCommon, UUPSUpgradeable { + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 25](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L25) + + ```solidity + contract TransferValidationPolicy is Policy { + ``` + +
+ + + +# Low Issues + +## L-1: Centralization Risk + +Contracts have owners with privileged rights to perform admin tasks and need to be trusted to not perform malicious updates or drain funds. + +
11 Found Instances + + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol [Line: 27](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol#L27) + + ```solidity + ) internal virtual override(UUPSUpgradeable) onlyRole(PROXY_UPGRADE_ROLE) {} + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol [Line: 23](../../../contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol#L23) + + ```solidity + function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyOwner {} + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 65](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L65) + + ```solidity + function setRules(IRule[] calldata rules_) external onlyOwner { + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 120](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L120) + + ```solidity + function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 144](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L144) + + ```solidity + onlyRole(BURNER_FROM_ROLE) + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 157](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L157) + + ```solidity + onlyRole(BURNER_SELF_ROLE) + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 171](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L171) + + ```solidity + function _authorizeAttachPolicyEngine(address) internal virtual override onlyRole(DEFAULT_ADMIN_ROLE) {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 177](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L177) + + ```solidity + function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE) {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 178](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L178) + + ```solidity + function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE) {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 180](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L180) + + ```solidity + function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE) {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 176](../../../contracts/modules/standard/CCTCommon.sol#L176) + + ```solidity + function _authorizeAttachPolicyEngine(address) internal virtual override onlyOwner {} + ``` + +
+ + + +## L-2: Costly operations inside loop + +Invoking `SSTORE` operations in loops may waste gas. Use a local variable to hold the loop computation result. + +
2 Found Instances + + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 54](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L54) + + ```solidity + for (uint256 i = 0; i < ruleAddrs.length; ++i) { + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 69](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L69) + + ```solidity + for (uint256 i = 0; i < rules_.length; ++i) { + ``` + +
+ + + +## L-3: Empty Block + +Consider removing empty blocks. + +
22 Found Instances + + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol [Line: 25](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol#L25) + + ```solidity + function _authorizeUpgrade( + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol [Line: 23](../../../contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol#L23) + + ```solidity + function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyOwner {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 120](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L120) + + ```solidity + function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 140](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L140) + + ```solidity + function _authorizeBurnFrom() + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 153](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L153) + + ```solidity + function _authorizeSelfBurn() + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 171](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L171) + + ```solidity + function _authorizeAttachPolicyEngine(address) internal virtual override onlyRole(DEFAULT_ADMIN_ROLE) {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 177](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L177) + + ```solidity + function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE) {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 178](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L178) + + ```solidity + function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE) {} + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 180](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L180) + + ```solidity + function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE) {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 176](../../../contracts/modules/standard/CCTCommon.sol#L176) + + ```solidity + function _authorizeAttachPolicyEngine(address) internal virtual override onlyOwner {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 247](../../../contracts/modules/standard/CCTCommon.sol#L247) + + ```solidity + function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 253](../../../contracts/modules/standard/CCTCommon.sol#L253) + + ```solidity + function _authorizeMint() internal virtual override(ERC20MintModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 259](../../../contracts/modules/standard/CCTCommon.sol#L259) + + ```solidity + function _authorizeBurn() internal virtual override(ERC20BurnModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 265](../../../contracts/modules/standard/CCTCommon.sol#L265) + + ```solidity + function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 271](../../../contracts/modules/standard/CCTCommon.sol#L271) + + ```solidity + function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 277](../../../contracts/modules/standard/CCTCommon.sol#L277) + + ```solidity + function _authorizeERC20Enforcer() internal virtual override(ERC20EnforcementModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 283](../../../contracts/modules/standard/CCTCommon.sol#L283) + + ```solidity + function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 289](../../../contracts/modules/standard/CCTCommon.sol#L289) + + ```solidity + function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 295](../../../contracts/modules/standard/CCTCommon.sol#L295) + + ```solidity + function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 306](../../../contracts/modules/standard/CCTCommon.sol#L306) + + ```solidity + function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 313](../../../contracts/modules/standard/CCTCommon.sol#L313) + + ```solidity + function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) runPolicy {} + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 320](../../../contracts/modules/standard/CCTCommon.sol#L320) + + ```solidity + function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) runPolicy {} + ``` + +
+ + + +## L-4: Literal Instead of Constant + +Define and use `constant` variables instead of using literals. If the same constant literal value is used multiple times, create a constant state variable and reference it throughout the contract. + +
2 Found Instances + + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 106](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L106) + + ```solidity + if (parameters.length != 3 && parameters.length != 4) { + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 110](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L110) + + ```solidity + if (parameters.length == 4) { + ``` + +
+ + + +## L-5: PUSH0 Opcode + +Solc compiler version 0.8.20 switches the default target EVM version to Shanghai, which means that the generated bytecode will include PUSH0 opcodes. Be sure to select the appropriate EVM version in case you intend to deploy on a chain other than mainnet like L2 chains that may not support PUSH0, otherwise deployment of your contracts will fail. + +
15 Found Instances + + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol [Line: 3](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol [Line: 3](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol [Line: 3](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol [Line: 3](../../../contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol [Line: 3](../../../contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol [Line: 3](../../../contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol [Line: 2](../../../contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L2) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol [Line: 2](../../../contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol#L2) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 3](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC1404.sol [Line: 3](../../../contracts/modules/lite/CCTCMTATBaseERC1404.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 3](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 3](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/PolicyValidationModuleERC1404.sol [Line: 3](../../../contracts/modules/lite/PolicyValidationModuleERC1404.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/ValidationModulePolicyEngine.sol [Line: 3](../../../contracts/modules/lite/ValidationModulePolicyEngine.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 3](../../../contracts/modules/standard/CCTCommon.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +
+ + + +## L-6: Loop Contains `require`/`revert` + +Avoid `require` / `revert` statements in a loop because a single bad item can cause the whole transaction to fail. It's better to forgive on fail and return failed elements post processing of the loop + +
4 Found Instances + + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 54](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L54) + + ```solidity + for (uint256 i = 0; i < ruleAddrs.length; ++i) { + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 69](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L69) + + ```solidity + for (uint256 i = 0; i < rules_.length; ++i) { + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 117](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L117) + + ```solidity + for (uint256 i = 0; i < len; ++i) { + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 130](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L130) + + ```solidity + for (uint256 i = 0; i < len; ++i) { + ``` + +
+ + + +## L-7: Unsafe ERC20 Operation + +ERC20 functions may not behave as expected. For example: return values are not always meaningful. It is recommended to use OpenZeppelin's SafeERC20 library. + +
7 Found Instances + + +- Found in contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol [Line: 36](../../../contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L36) + + ```solidity + if (payload.selector == IERC20.transfer.selector) { + ``` + +- Found in contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol [Line: 40](../../../contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L40) + + ```solidity + } else if (payload.selector == IERC20.transferFrom.selector) { + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 29](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L29) + + ```solidity + return ERC20Upgradeable.approve(spender, value); + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 35](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L35) + + ```solidity + return CMTATBaseCommon.transfer(to, value); + ``` + +- Found in contracts/modules/lite/ValidationModulePolicyEngine.sol [Line: 72](../../../contracts/modules/lite/ValidationModulePolicyEngine.sol#L72) + + ```solidity + return _tryCheckPolicies(IERC20.transferFrom.selector, spender, abi.encode(from, to, value)); + ``` + +- Found in contracts/modules/lite/ValidationModulePolicyEngine.sol [Line: 80](../../../contracts/modules/lite/ValidationModulePolicyEngine.sol#L80) + + ```solidity + return _tryCheckPolicies(IERC20.transfer.selector, from, abi.encode(to, value)); + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 163](../../../contracts/modules/standard/CCTCommon.sol#L163) + + ```solidity + return CMTATBaseCommon.transfer(to, value); + ``` + +
+ + + +## L-8: Unspecific Solidity Pragma + +Consider using a specific version of Solidity in your contracts instead of a wide version. For example, instead of `pragma solidity ^0.8.0;`, use `pragma solidity 0.8.0;` + +
15 Found Instances + + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol [Line: 3](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol [Line: 3](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol [Line: 3](../../../contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol [Line: 3](../../../contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol [Line: 3](../../../contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol [Line: 3](../../../contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol [Line: 2](../../../contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L2) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol [Line: 2](../../../contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol#L2) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 3](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC1404.sol [Line: 3](../../../contracts/modules/lite/CCTCMTATBaseERC1404.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol [Line: 3](../../../contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/CCTCMTATBasePolicyEngine.sol [Line: 3](../../../contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/PolicyValidationModuleERC1404.sol [Line: 3](../../../contracts/modules/lite/PolicyValidationModuleERC1404.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/lite/ValidationModulePolicyEngine.sol [Line: 3](../../../contracts/modules/lite/ValidationModulePolicyEngine.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +- Found in contracts/modules/standard/CCTCommon.sol [Line: 3](../../../contracts/modules/standard/CCTCommon.sol#L3) + + ```solidity + pragma solidity ^0.8.20; + ``` + +
+ + + +## L-9: Unused State Variable + +State variable appears to be unused. No analysis has been performed to see if any inline assembly references it. Consider removing this unused variable. + +
1 Found Instances + + +- Found in contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol [Line: 37](../../../contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L37) + + ```solidity + bytes32 private constant STORAGE_LOCATION = 0xd90ded5881f9295c61e86b2e3b551acbb5fe06f9f79d0cec87ddc5bb60d48e00; + ``` + +
+ + + diff --git a/doc/audits/tools/slither-report-feedback.md b/doc/audits/tools/slither-report-feedback.md new file mode 100644 index 0000000..c0abbe4 --- /dev/null +++ b/doc/audits/tools/slither-report-feedback.md @@ -0,0 +1,40 @@ +# Slither Report Feedback + +Here is the list of report performed with [Slither](https://github.com/crytic/slither) v0.11.5. + +```bash +slither . --checklist --filter-paths "openzeppelin-contracts|test|forge-std|mocks" > doc/audits/tools/slither-report.md +``` + +| Version | Report | Assessment | +| --- | --- | --- | +| current | `doc/audits/tools/slither-report.md` | `doc/audits/tools/slither-report-feedback.md` | + +Report scope: repo-focused filtered checklist run. + +0 High · 9 Medium · 10 Low · 27 Informational + +| ID | Finding | Instances | Assessment | +| --- | --- | --- | --- | +| M-1 | `uninitialized-local` | 6 | Likely analyzer limitation in extractor decode paths; treated as likely false positive. | +| L-1 | `calls-loop` | 8 | Accepted by design where policy/rule chains iterate; monitor gas/complexity. | +| I-1 | `assembly` | 2 | Expected in storage-slot patterns; informational. | +| I-2 | `dead-code` | 1 | False positive | +| I-3 | `naming-convention` | 20 | Style-only informational findings. | + +## Executive triage + +- Updated report is now focused on repo-owned contracts after removing non-target components from scan scope. +- Current findings are mainly pattern-based warnings (`calls-loop`, `uninitialized-local`) requiring contextual validation. +- No confirmed exploitable vulnerability is established from checklist output alone. + +## Key observations +### `uninitialized-local` in `ERC20TransferFromExtractor` + +- Status: **Likely analyzer limitation / false positive** +- Rationale: variables are populated by branch decode paths before use in valid selector flows. + +### Informational categories + +- `assembly`, `dead-code`, `naming-convention`. +- Status: **Non-blocking quality signals**. \ No newline at end of file diff --git a/doc/audits/tools/slither-report.md b/doc/audits/tools/slither-report.md new file mode 100644 index 0000000..7dc917e --- /dev/null +++ b/doc/audits/tools/slither-report.md @@ -0,0 +1,259 @@ +**THIS CHECKLIST IS NOT COMPLETE**. Use `--show-ignored-findings` to show all the results. +Summary + - [uninitialized-local](#uninitialized-local) (6 results) (Medium) + - [calls-loop](#calls-loop) (8 results) (Low) + - [assembly](#assembly) (1 results) (Informational) + - [dead-code](#dead-code) (1 results) (Informational) + - [naming-convention](#naming-convention) (20 results) (Informational) +## uninitialized-local +Impact: Medium +Confidence: Medium + - [ ] ID-0 +[ERC20TransferFromExtractor.extract(IPolicyEngine.Payload).from](contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L32) is a local variable never initialized + +contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L32 + + + - [ ] ID-1 +[ERC20TransferFromExtractor.extract(IPolicyEngine.Payload).to](contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L33) is a local variable never initialized + +contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L33 + + + - [ ] ID-2 +[ERC20TransferFromExtractor.extract(IPolicyEngine.Payload).amount](contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L34) is a local variable never initialized + +contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L34 + + + - [ ] ID-3 +[MintBurnExtractor.extract(IPolicyEngine.Payload).account](contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol#L34) is a local variable never initialized + +contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol#L34 + + + - [ ] ID-4 +[ERC20TransferFromExtractor.extract(IPolicyEngine.Payload).spender](contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L31) is a local variable never initialized + +contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol#L31 + + + - [ ] ID-5 +[MintBurnExtractor.extract(IPolicyEngine.Payload).amount](contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol#L35) is a local variable never initialized + +contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol#L35 + + +## calls-loop +Impact: Low +Confidence: Medium + - [ ] ID-6 +[TransferValidationPolicy.run(address,address,bytes4,bytes[],bytes)](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L96-L140) has external calls inside a loop: [code = $.rules[i].detectTransferRestrictionFrom(spender,from,to,amount)](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L118) + +contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L96-L140 + + + - [ ] ID-7 +[TransferValidationPolicy.run(address,address,bytes4,bytes[],bytes)](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L96-L140) has external calls inside a loop: [code_scope_4 = $.rules[i_scope_3].detectTransferRestriction(from_scope_0,to_scope_1,amount_scope_2)](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L131) + +contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L96-L140 + + + - [ ] ID-8 +[TransferValidationPolicy.run(address,address,bytes4,bytes[],bytes)](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L96-L140) has external calls inside a loop: [message_scope_5 = $.rules[i_scope_3].messageForTransferRestriction(code_scope_4)](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L133) + +contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L96-L140 + + + - [ ] ID-9 +[TransferValidationPolicy.run(address,address,bytes4,bytes[],bytes)](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L96-L140) has external calls inside a loop: [message = $.rules[i].messageForTransferRestriction(code)](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L120) + +contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L96-L140 + + + - [ ] ID-10 +[ValidationModulePolicyEngine._transferred(address,address,address,uint256)](contracts/modules/lite/ValidationModulePolicyEngine.sol#L102-L120) has external calls inside a loop: [policyEngine_.run(IPolicyEngine.Payload({selector:msg.sig,sender:_msgSender(),data:msg.data,context:context}))](contracts/modules/lite/ValidationModulePolicyEngine.sol#L112-L114) + Calls stack containing the loop: + ERC20BurnModule.batchBurn(address[],uint256[]) + ERC20BurnModuleInternal._batchBurn(address[],uint256[]) + CCTCMTATBaseERC20CrossChain._burnOverride(address,uint256) + CCTCMTATBasePolicyEngine._checkTransferred(address,address,address,uint256) + +contracts/modules/lite/ValidationModulePolicyEngine.sol#L102-L120 + + + - [ ] ID-11 +[ValidationModulePolicyEngine._transferred(address,address,address,uint256)](contracts/modules/lite/ValidationModulePolicyEngine.sol#L102-L120) has external calls inside a loop: [policyEngine_.run(IPolicyEngine.Payload({selector:msg.sig,sender:_msgSender(),data:msg.data,context:context}))](contracts/modules/lite/ValidationModulePolicyEngine.sol#L112-L114) + Calls stack containing the loop: + ERC20MintModule.batchMint(address[],uint256[]) + ERC20MintModuleInternal._batchMint(address[],uint256[]) + CCTCMTATBaseERC20CrossChain._mintOverride(address,uint256) + CCTCMTATBasePolicyEngine._checkTransferred(address,address,address,uint256) + +contracts/modules/lite/ValidationModulePolicyEngine.sol#L102-L120 + + + - [ ] ID-12 +[ValidationModulePolicyEngine._transferred(address,address,address,uint256)](contracts/modules/lite/ValidationModulePolicyEngine.sol#L102-L120) has external calls inside a loop: [policyEngine_.run(IPolicyEngine.Payload({selector:msg.sig,sender:_msgSender(),data:msg.data,context:context}))](contracts/modules/lite/ValidationModulePolicyEngine.sol#L112-L114) + Calls stack containing the loop: + ERC20MintModule.batchTransfer(address[],uint256[]) + ERC20MintModuleInternal._batchTransfer(address[],uint256[]) + CCTCMTATBaseERC20CrossChain._minterTransferOverride(address,address,uint256) + CCTCMTATBasePolicyEngine._checkTransferred(address,address,address,uint256) + +contracts/modules/lite/ValidationModulePolicyEngine.sol#L102-L120 + + + - [ ] ID-13 +[ValidationModulePolicyEngine._transferred(address,address,address,uint256)](contracts/modules/lite/ValidationModulePolicyEngine.sol#L102-L120) has external calls inside a loop: [policyEngine_.run(IPolicyEngine.Payload({selector:msg.sig,sender:_msgSender(),data:msg.data,context:context}))](contracts/modules/lite/ValidationModulePolicyEngine.sol#L112-L114) + Calls stack containing the loop: + ERC20BurnModule.batchBurn(address[],uint256[],bytes) + ERC20BurnModuleInternal._batchBurn(address[],uint256[]) + CCTCMTATBaseERC20CrossChain._burnOverride(address,uint256) + CCTCMTATBasePolicyEngine._checkTransferred(address,address,address,uint256) + +contracts/modules/lite/ValidationModulePolicyEngine.sol#L102-L120 + + +## assembly +Impact: Informational +Confidence: High + - [ ] ID-14 +[TransferValidationPolicy._getStorage()](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L39-L43) uses assembly + - [INLINE ASM](contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L40-L42) + +contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol#L39-L43 + + +## dead-code +Impact: Informational +Confidence: Medium + - [ ] ID-15 +[CCTCMTATBasePolicyEngine.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L127-L133) is never used and should be removed + +contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L127-L133 + + +## naming-convention +Impact: Informational +Confidence: High + - [ ] ID-16 +Parameter [CCTCMTATBaseERC20CrossChain.supportsInterface(bytes4)._interfaceId](contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L104) is not in mixedCase + +contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol#L104 + + + - [ ] ID-17 +Parameter [CCTCommon.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,address,ISnapshotEngine,IERC1643).ExtraInformationAttributes_](contracts/modules/standard/CCTCommon.sol#L91) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L91 + + + - [ ] ID-18 +Parameter [CCTCommon.__CMTAT_commonModules_init_unchained(ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/standard/CCTCommon.sol#L138) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L138 + + + - [ ] ID-19 +Function [CCTCMTATBasePolicyEngine.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,address,ISnapshotEngine,IERC1643)](contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L85-L112) is not in mixedCase + +contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L85-L112 + + + - [ ] ID-20 +Parameter [CCTCommon.supportsInterface(bytes4)._interfaceId](contracts/modules/standard/CCTCommon.sol#L202) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L202 + + + - [ ] ID-21 +Function [CCTCMTATBasePolicyEngine.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes)](contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L117-L122) is not in mixedCase + +contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L117-L122 + + + - [ ] ID-22 +Function [CCTCommon.__CMTAT_commonModules_init_unchained(ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/standard/CCTCommon.sol#L137-L153) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L137-L153 + + + - [ ] ID-23 +Function [CCTCMTATBasePolicyEngine.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L127-L133) is not in mixedCase + +contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L127-L133 + + + - [ ] ID-24 +Parameter [CCTCMTATBasePolicyEngine.__CMTAT_modules_init_unchained(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L129) is not in mixedCase + +contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L129 + + + - [ ] ID-25 +Parameter [CCTCMTATBasePolicyEngine.initialize(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,address,ISnapshotEngine,IERC1643).ERC20Attributes_](contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L45) is not in mixedCase + +contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L45 + + + - [ ] ID-26 +Parameter [CCTCommon.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/standard/CCTCommon.sol#L121) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L121 + + + - [ ] ID-27 +Parameter [CCTCommon.__CMTAT_commonModules_init_unchained(ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ExtraInformationModuleAttributes_](contracts/modules/standard/CCTCommon.sol#L139) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L139 + + + - [ ] ID-28 +Function [CCTCommon.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,address,ISnapshotEngine,IERC1643)](contracts/modules/standard/CCTCommon.sol#L88-L115) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L88-L115 + + + - [ ] ID-29 +Parameter [CCTCommon.__CMTAT_modules_init_unchained(ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes).ERC20Attributes_](contracts/modules/standard/CCTCommon.sol#L131) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L131 + + + - [ ] ID-30 +Function [CCTCommon.__CMTAT_modules_init_unchained(ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes)](contracts/modules/standard/CCTCommon.sol#L130-L135) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L130-L135 + + + - [ ] ID-31 +Function [CCTCommon.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes)](contracts/modules/standard/CCTCommon.sol#L120-L125) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L120-L125 + + + - [ ] ID-32 +Parameter [CCTCMTATBasePolicyEngine.__CMTAT_openzeppelin_init_unchained(ICMTATConstructor.ERC20Attributes).ERC20Attributes_](contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L118) is not in mixedCase + +contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L118 + + + - [ ] ID-33 +Parameter [CCTCommon.initialize(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,address,ISnapshotEngine,IERC1643).ERC20Attributes_](contracts/modules/standard/CCTCommon.sol#L51) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L51 + + + - [ ] ID-34 +Parameter [CCTCommon.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,address,ISnapshotEngine,IERC1643).ERC20Attributes_](contracts/modules/standard/CCTCommon.sol#L90) is not in mixedCase + +contracts/modules/standard/CCTCommon.sol#L90 + + + - [ ] ID-35 +Parameter [CCTCMTATBasePolicyEngine.__CMTAT_init(address,ICMTATConstructor.ERC20Attributes,ICMTATConstructor.ExtraInformationAttributes,address,ISnapshotEngine,IERC1643).ERC20Attributes_](contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L87) is not in mixedCase + +contracts/modules/lite/CCTCMTATBasePolicyEngine.sol#L87 + + diff --git a/doc/coverage/base.css b/doc/coverage/base.css new file mode 100644 index 0000000..29737bc --- /dev/null +++ b/doc/coverage/base.css @@ -0,0 +1,213 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.medium .chart { border:1px solid #f9cd0b; } +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } +/* light gray */ +span.cline-neutral { background: #eaeaea; } + +.cbranch-no { background: yellow !important; color: #111; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/doc/coverage/coverage-final.json b/doc/coverage/coverage-final.json new file mode 100644 index 0000000..2cbbf68 --- /dev/null +++ b/doc/coverage/coverage-final.json @@ -0,0 +1,17 @@ +{ +"contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol":{"l":{"34":51},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol","s":{"1":51},"b":{},"f":{"1":51},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":42,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1480}}},"branchMap":{}}, +"contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol":{"l":{"16":1},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol","s":{"1":1},"b":{},"f":{"1":1},"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/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol":{"l":{"19":1},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol","s":{"1":1},"b":{"1":[2,1]},"f":{"1":1,"2":2},"fnMap":{"1":{"name":"constructor","line":17,"loc":{"start":{"line":17,"column":4},"end":{"line":20,"column":4}}},"2":{"name":"_authorizeUpgrade","line":27,"loc":{"start":{"line":25,"column":4},"end":{"line":27,"column":79}}}},"statementMap":{"1":{"start":{"line":19,"column":8},"end":{"line":19,"column":29}}},"branchMap":{"1":{"line":27,"type":"if","locations":[{"start":{"line":27,"column":49},"end":{"line":27,"column":49}},{"start":{"line":27,"column":49},"end":{"line":27,"column":49}}]}}}, +"contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol":{"l":{"34":8},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol","s":{"1":8},"b":{},"f":{"1":8},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":42,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1416}}},"branchMap":{}}, +"contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol":{"l":{"16":1},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol","s":{"1":1},"b":{},"f":{"1":1},"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/standard/ComplianceTokenCMTATUUPSUpgradeable.sol":{"l":{"17":1},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol","s":{"1":1},"b":{"1":[2,1]},"f":{"1":1,"2":2},"fnMap":{"1":{"name":"constructor","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":18,"column":4}}},"2":{"name":"_authorizeUpgrade","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":23,"column":112}}}},"statementMap":{"1":{"start":{"line":17,"column":8},"end":{"line":17,"column":29}}},"branchMap":{"1":{"line":23,"type":"if","locations":[{"start":{"line":23,"column":101},"end":{"line":23,"column":101}},{"start":{"line":23,"column":101},"end":{"line":23,"column":101}}]}}}, +"contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol":{"l":{"31":34,"32":34,"33":34,"34":34,"36":34,"37":30,"38":30,"39":30,"41":4,"42":4,"44":0,"47":34,"48":34,"49":34,"50":34,"51":34,"53":34},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol","s":{"1":34,"2":34,"3":34,"4":34,"5":34,"6":4,"7":34,"8":34},"b":{"1":[30,4],"2":[4,0]},"f":{"1":34},"fnMap":{"1":{"name":"extract","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":54,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":23}},"2":{"start":{"line":32,"column":8},"end":{"line":32,"column":20}},"3":{"start":{"line":33,"column":8},"end":{"line":33,"column":18}},"4":{"start":{"line":34,"column":8},"end":{"line":34,"column":22}},"5":{"start":{"line":36,"column":8},"end":{"line":36,"column":1498}},"6":{"start":{"line":40,"column":15},"end":{"line":40,"column":1711}},"7":{"start":{"line":47,"column":8},"end":{"line":47,"column":82}},"8":{"start":{"line":53,"column":8},"end":{"line":53,"column":21}}},"branchMap":{"1":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":8},"end":{"line":36,"column":8}},{"start":{"line":36,"column":8},"end":{"line":36,"column":8}}]},"2":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":15},"end":{"line":40,"column":15}},{"start":{"line":40,"column":15},"end":{"line":40,"column":15}}]}}}, +"contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol":{"l":{"34":4,"35":4,"37":4,"38":2,"40":1,"41":1,"43":1,"46":3,"47":3,"48":3,"49":3},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol","s":{"1":4,"2":4,"3":4,"4":2,"5":3,"6":3},"b":{"1":[2,2],"2":[1,1],"3":[1,1]},"f":{"1":4},"fnMap":{"1":{"name":"extract","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":23}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":22}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":1615}},"4":{"start":{"line":39,"column":15},"end":{"line":39,"column":1791}},"5":{"start":{"line":46,"column":8},"end":{"line":46,"column":82}},"6":{"start":{"line":49,"column":8},"end":{"line":49,"column":21}}},"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":37,"type":"cond-expr","locations":[{"start":{"line":37,"column":12},"end":{"line":37,"column":44}},{"start":{"line":37,"column":49},"end":{"line":37,"column":86}}]},"3":{"line":39,"type":"if","locations":[{"start":{"line":39,"column":15},"end":{"line":39,"column":15}},{"start":{"line":39,"column":15},"end":{"line":39,"column":15}}]}}}, +"contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol":{"l":{"40":77,"51":37,"52":34,"53":34,"54":34,"55":41,"56":41,"66":2,"67":2,"68":2,"69":2,"70":2,"71":2,"73":2,"80":1,"87":1,"103":39,"104":39,"106":39,"107":4,"110":35,"112":33,"113":33,"114":33,"115":33,"117":33,"118":35,"119":35,"120":13,"121":13,"126":2,"127":2,"128":2,"130":2,"131":2,"132":2,"133":1,"134":1,"139":21},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol","s":{"1":37,"2":34,"3":34,"4":34,"5":41,"6":41,"7":2,"8":2,"9":2,"10":2,"11":2,"12":2,"13":1,"14":1,"15":39,"16":39,"17":39,"18":35,"19":33,"20":33,"21":33,"22":33,"23":33,"24":35,"25":35,"26":13,"27":2,"28":2,"29":2,"30":2,"31":2,"32":2,"33":1,"34":21},"b":{"1":[37,0],"2":[34,3],"3":[41,0],"4":[2,1],"5":[2,0],"6":[4,35],"7":[33,2],"8":[13,22],"9":[1,1]},"f":{"1":77,"2":37,"3":2,"4":1,"5":1,"6":39},"fnMap":{"1":{"name":"_getStorage","line":39,"loc":{"start":{"line":39,"column":4},"end":{"line":43,"column":4}}},"2":{"name":"configure","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":59,"column":4}}},"3":{"name":"setRules","line":65,"loc":{"start":{"line":65,"column":4},"end":{"line":74,"column":4}}},"4":{"name":"rules","line":79,"loc":{"start":{"line":79,"column":4},"end":{"line":81,"column":4}}},"5":{"name":"rulesCount","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":88,"column":4}}},"6":{"name":"run","line":96,"loc":{"start":{"line":96,"column":4},"end":{"line":140,"column":4}}}},"statementMap":{"1":{"start":{"line":51,"column":8},"end":{"line":51,"column":2053}},"2":{"start":{"line":52,"column":12},"end":{"line":52,"column":76}},"3":{"start":{"line":53,"column":12},"end":{"line":53,"column":63}},"4":{"start":{"line":54,"column":12},"end":{"line":54,"column":2241}},"5":{"start":{"line":55,"column":16},"end":{"line":55,"column":81}},"6":{"start":{"line":56,"column":16},"end":{"line":56,"column":48}},"7":{"start":{"line":66,"column":8},"end":{"line":66,"column":59}},"8":{"start":{"line":67,"column":8},"end":{"line":67,"column":46}},"9":{"start":{"line":69,"column":8},"end":{"line":69,"column":2782}},"10":{"start":{"line":70,"column":12},"end":{"line":70,"column":83}},"11":{"start":{"line":71,"column":12},"end":{"line":71,"column":34}},"12":{"start":{"line":73,"column":8},"end":{"line":73,"column":55}},"13":{"start":{"line":80,"column":8},"end":{"line":80,"column":34}},"14":{"start":{"line":87,"column":8},"end":{"line":87,"column":41}},"15":{"start":{"line":103,"column":8},"end":{"line":103,"column":59}},"16":{"start":{"line":104,"column":8},"end":{"line":104,"column":36}},"17":{"start":{"line":106,"column":8},"end":{"line":106,"column":3947}},"18":{"start":{"line":110,"column":8},"end":{"line":110,"column":4085}},"19":{"start":{"line":112,"column":12},"end":{"line":112,"column":66}},"20":{"start":{"line":113,"column":12},"end":{"line":113,"column":63}},"21":{"start":{"line":114,"column":12},"end":{"line":114,"column":61}},"22":{"start":{"line":115,"column":12},"end":{"line":115,"column":65}},"23":{"start":{"line":117,"column":12},"end":{"line":117,"column":4473}},"24":{"start":{"line":118,"column":16},"end":{"line":118,"column":96}},"25":{"start":{"line":119,"column":16},"end":{"line":119,"column":4627}},"26":{"start":{"line":120,"column":20},"end":{"line":120,"column":90}},"27":{"start":{"line":126,"column":12},"end":{"line":126,"column":63}},"28":{"start":{"line":127,"column":12},"end":{"line":127,"column":61}},"29":{"start":{"line":128,"column":12},"end":{"line":128,"column":65}},"30":{"start":{"line":130,"column":12},"end":{"line":130,"column":5120}},"31":{"start":{"line":131,"column":16},"end":{"line":131,"column":83}},"32":{"start":{"line":132,"column":16},"end":{"line":132,"column":5261}},"33":{"start":{"line":133,"column":20},"end":{"line":133,"column":90}},"34":{"start":{"line":139,"column":8},"end":{"line":139,"column":50}}},"branchMap":{"1":{"line":50,"type":"if","locations":[{"start":{"line":50,"column":68},"end":{"line":50,"column":68}},{"start":{"line":50,"column":68},"end":{"line":50,"column":68}}]},"2":{"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}}]},"3":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":16},"end":{"line":55,"column":16}},{"start":{"line":55,"column":16},"end":{"line":55,"column":16}}]},"4":{"line":65,"type":"if","locations":[{"start":{"line":65,"column":56},"end":{"line":65,"column":56}},{"start":{"line":65,"column":56},"end":{"line":65,"column":56}}]},"5":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":12},"end":{"line":70,"column":12}},{"start":{"line":70,"column":12},"end":{"line":70,"column":12}}]},"6":{"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}}]},"7":{"line":110,"type":"if","locations":[{"start":{"line":110,"column":8},"end":{"line":110,"column":8}},{"start":{"line":110,"column":8},"end":{"line":110,"column":8}}]},"8":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":16},"end":{"line":119,"column":16}},{"start":{"line":119,"column":16},"end":{"line":119,"column":16}}]},"9":{"line":132,"type":"if","locations":[{"start":{"line":132,"column":16},"end":{"line":132,"column":16}},{"start":{"line":132,"column":16},"end":{"line":132,"column":16}}]}}}, +"contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol":{"l":{"21":30,"29":25,"38":23,"42":0,"51":0,"64":0,"68":0,"72":8,"88":3,"89":3,"93":14,"94":14,"95":12,"100":3,"108":12,"109":10,"110":6,"119":12,"123":0,"132":0,"145":0,"149":0,"153":6,"154":4,"155":0},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol","s":{"1":25,"2":23,"3":0,"4":0,"5":0,"6":0,"7":8,"8":3,"9":14,"10":12,"11":2,"12":10,"13":4,"14":6,"15":12,"16":0,"17":0,"18":0,"19":0,"20":6,"21":2,"22":4,"23":4,"24":0},"b":{"1":[8,17],"2":[8,0],"3":[3,0],"4":[3,0],"5":[2,10],"6":[4,6],"7":[0,0],"8":[2,4],"9":[4,0]},"f":{"1":30,"2":25,"3":23,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":8,"11":3,"12":14,"13":3,"14":12,"15":12,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":6},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":22,"column":4}}},"2":{"name":"detectTransferRestriction","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":30,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":39,"column":4}}},"4":{"name":"canTransfer","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":4}}},"5":{"name":"canTransferFrom","line":45,"loc":{"start":{"line":45,"column":5},"end":{"line":52,"column":4}}},"6":{"name":"transferred","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":54,"column":108}}},"7":{"name":"transferred","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":61,"column":30}}},"8":{"name":"supportsInterface","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":4}}},"9":{"name":"canReturnTransferRestrictionCode","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":69,"column":4}}},"10":{"name":"messageForTransferRestriction","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":73,"column":4}}},"11":{"name":"onlyOwner","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":90,"column":4}}},"12":{"name":"constructor","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":97,"column":4}}},"13":{"name":"setRestricted","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":101,"column":4}}},"14":{"name":"detectTransferRestriction","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":111,"column":4}}},"15":{"name":"detectTransferRestrictionFrom","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":120,"column":4}}},"16":{"name":"canTransfer","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":124,"column":4}}},"17":{"name":"canTransferFrom","line":126,"loc":{"start":{"line":126,"column":4},"end":{"line":133,"column":4}}},"18":{"name":"transferred","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":135,"column":108}}},"19":{"name":"transferred","line":137,"loc":{"start":{"line":137,"column":4},"end":{"line":142,"column":30}}},"20":{"name":"supportsInterface","line":144,"loc":{"start":{"line":144,"column":4},"end":{"line":146,"column":4}}},"21":{"name":"canReturnTransferRestrictionCode","line":148,"loc":{"start":{"line":148,"column":4},"end":{"line":150,"column":4}}},"22":{"name":"messageForTransferRestriction","line":152,"loc":{"start":{"line":152,"column":4},"end":{"line":156,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":91}},"2":{"start":{"line":38,"column":8},"end":{"line":38,"column":58}},"3":{"start":{"line":42,"column":8},"end":{"line":42,"column":63}},"4":{"start":{"line":51,"column":8},"end":{"line":51,"column":44}},"5":{"start":{"line":64,"column":8},"end":{"line":64,"column":53}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":38}},"7":{"start":{"line":72,"column":8},"end":{"line":72,"column":82}},"8":{"start":{"line":88,"column":8},"end":{"line":88,"column":49}},"9":{"start":{"line":94,"column":8},"end":{"line":94,"column":2794}},"10":{"start":{"line":108,"column":8},"end":{"line":108,"column":52}},"11":{"start":{"line":108,"column":30},"end":{"line":108,"column":52}},"12":{"start":{"line":109,"column":8},"end":{"line":109,"column":48}},"13":{"start":{"line":109,"column":28},"end":{"line":109,"column":48}},"14":{"start":{"line":110,"column":8},"end":{"line":110,"column":52}},"15":{"start":{"line":119,"column":8},"end":{"line":119,"column":58}},"16":{"start":{"line":123,"column":8},"end":{"line":123,"column":63}},"17":{"start":{"line":132,"column":8},"end":{"line":132,"column":44}},"18":{"start":{"line":145,"column":8},"end":{"line":145,"column":53}},"19":{"start":{"line":149,"column":8},"end":{"line":149,"column":63}},"20":{"start":{"line":153,"column":8},"end":{"line":153,"column":66}},"21":{"start":{"line":153,"column":37},"end":{"line":153,"column":66}},"22":{"start":{"line":154,"column":8},"end":{"line":154,"column":67}},"23":{"start":{"line":154,"column":35},"end":{"line":154,"column":67}},"24":{"start":{"line":155,"column":8},"end":{"line":155,"column":29}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":36},"end":{"line":29,"column":50}},{"start":{"line":29,"column":54},"end":{"line":29,"column":90}}]},"2":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":41},"end":{"line":72,"column":64}},{"start":{"line":72,"column":68},"end":{"line":72,"column":81}}]},"3":{"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}}]},"4":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":66},"end":{"line":99,"column":66}},{"start":{"line":99,"column":66},"end":{"line":99,"column":66}}]},"5":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":8},"end":{"line":108,"column":8}},{"start":{"line":108,"column":8},"end":{"line":108,"column":8}}]},"6":{"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}}]},"7":{"line":149,"type":"cond-expr","locations":[{"start":{"line":149,"column":15},"end":{"line":149,"column":37}},{"start":{"line":149,"column":42},"end":{"line":149,"column":62}}]},"8":{"line":153,"type":"if","locations":[{"start":{"line":153,"column":8},"end":{"line":153,"column":8}},{"start":{"line":153,"column":8},"end":{"line":153,"column":8}}]},"9":{"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}}]}}}, +"contracts/modules/lite/CCTCMTATBaseERC1404.sol":{"l":{"30":10,"34":1,"36":9,"48":233,"60":35,"71":8,"72":8,"73":1,"74":1,"75":1,"78":7,"84":6},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/CCTCMTATBaseERC1404.sol","s":{"1":10,"2":1,"3":9,"4":233,"5":35,"6":8,"7":8,"8":1,"9":1,"10":1,"11":7,"12":6},"b":{"1":[1,9],"2":[1,7],"3":[1,0]},"f":{"1":10,"2":233,"3":35,"4":8,"5":6},"fnMap":{"1":{"name":"messageForTransferRestriction","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":38,"column":4}}},"2":{"name":"canTransfer","line":43,"loc":{"start":{"line":43,"column":4},"end":{"line":49,"column":4}}},"3":{"name":"canTransferFrom","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":61,"column":4}}},"4":{"name":"_detectTransferRestriction","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":79,"column":4}}},"5":{"name":"supportsInterface","line":81,"loc":{"start":{"line":81,"column":4},"end":{"line":85,"column":4}}}},"statementMap":{"1":{"start":{"line":30,"column":8},"end":{"line":30,"column":1324}},"2":{"start":{"line":34,"column":12},"end":{"line":34,"column":74}},"3":{"start":{"line":36,"column":12},"end":{"line":36,"column":95}},"4":{"start":{"line":48,"column":8},"end":{"line":48,"column":68}},"5":{"start":{"line":60,"column":8},"end":{"line":60,"column":81}},"6":{"start":{"line":71,"column":8},"end":{"line":71,"column":80}},"7":{"start":{"line":72,"column":8},"end":{"line":72,"column":2858}},"8":{"start":{"line":73,"column":12},"end":{"line":73,"column":88}},"9":{"start":{"line":74,"column":12},"end":{"line":74,"column":2993}},"10":{"start":{"line":75,"column":16},"end":{"line":75,"column":114}},"11":{"start":{"line":78,"column":8},"end":{"line":78,"column":88}},"12":{"start":{"line":84,"column":8},"end":{"line":84,"column":70}}},"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":72,"type":"if","locations":[{"start":{"line":72,"column":8},"end":{"line":72,"column":8}},{"start":{"line":72,"column":8},"end":{"line":72,"column":8}}]},"3":{"line":74,"type":"if","locations":[{"start":{"line":74,"column":12},"end":{"line":74,"column":12}},{"start":{"line":74,"column":12},"end":{"line":74,"column":12}}]}}}, +"contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol":{"l":{"29":119,"35":81,"45":29,"54":735,"55":720,"65":144,"66":120,"77":27,"78":18,"85":3,"92":10,"99":10,"106":12,"132":39,"167":943},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol","s":{"1":119,"2":81,"3":29,"4":735,"5":720,"6":144,"7":120,"8":27,"9":18,"10":3,"11":10,"12":10,"13":12,"14":39,"15":943},"b":{"1":[119,3],"2":[6,3],"3":[9,3],"4":[39,12],"5":[15,3],"6":[9,6],"7":[18,6],"8":[12,6]},"f":{"1":119,"2":81,"3":29,"4":735,"5":144,"6":27,"7":3,"8":10,"9":10,"10":12,"11":9,"12":39,"13":9,"14":12,"15":943},"fnMap":{"1":{"name":"approve","line":28,"loc":{"start":{"line":25,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"transfer","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":36,"column":4}}},"3":{"name":"transferFrom","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":46,"column":4}}},"4":{"name":"_mintOverride","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":56,"column":4}}},"5":{"name":"_burnOverride","line":61,"loc":{"start":{"line":61,"column":4},"end":{"line":67,"column":4}}},"6":{"name":"_minterTransferOverride","line":72,"loc":{"start":{"line":72,"column":4},"end":{"line":79,"column":4}}},"7":{"name":"decimals","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":86,"column":4}}},"8":{"name":"name","line":91,"loc":{"start":{"line":91,"column":4},"end":{"line":93,"column":4}}},"9":{"name":"symbol","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":100,"column":4}}},"10":{"name":"supportsInterface","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":109,"column":4}}},"11":{"name":"_authorizeCCIPSetAdmin","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":120,"column":106}}},"12":{"name":"_checkTokenBridge","line":131,"loc":{"start":{"line":131,"column":4},"end":{"line":133,"column":4}}},"13":{"name":"_authorizeBurnFrom","line":145,"loc":{"start":{"line":140,"column":4},"end":{"line":146,"column":5}}},"14":{"name":"_authorizeSelfBurn","line":158,"loc":{"start":{"line":153,"column":4},"end":{"line":159,"column":5}}},"15":{"name":"_update","line":162,"loc":{"start":{"line":162,"column":4},"end":{"line":168,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":55}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":50}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":60}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":64}},"5":{"start":{"line":55,"column":8},"end":{"line":55,"column":60}},"6":{"start":{"line":65,"column":8},"end":{"line":65,"column":64}},"7":{"start":{"line":66,"column":8},"end":{"line":66,"column":60}},"8":{"start":{"line":77,"column":8},"end":{"line":77,"column":53}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":71}},"10":{"start":{"line":85,"column":8},"end":{"line":85,"column":41}},"11":{"start":{"line":92,"column":8},"end":{"line":92,"column":37}},"12":{"start":{"line":99,"column":8},"end":{"line":99,"column":39}},"13":{"start":{"line":106,"column":8},"end":{"line":106,"column":3715}},"14":{"start":{"line":132,"column":8},"end":{"line":132,"column":68}},"15":{"start":{"line":167,"column":8},"end":{"line":167,"column":56}}},"branchMap":{"1":{"line":28,"type":"if","locations":[{"start":{"line":28,"column":48},"end":{"line":28,"column":48}},{"start":{"line":28,"column":48},"end":{"line":28,"column":48}}]},"2":{"line":107,"type":"cond-expr","locations":[{"start":{"line":107,"column":12},"end":{"line":107,"column":64}},{"start":{"line":108,"column":12},"end":{"line":108,"column":62}}]},"3":{"line":120,"type":"if","locations":[{"start":{"line":120,"column":76},"end":{"line":120,"column":76}},{"start":{"line":120,"column":76},"end":{"line":120,"column":76}}]},"4":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":96},"end":{"line":131,"column":96}},{"start":{"line":131,"column":96},"end":{"line":131,"column":96}}]},"5":{"line":144,"type":"if","locations":[{"start":{"line":144,"column":8},"end":{"line":144,"column":8}},{"start":{"line":144,"column":8},"end":{"line":144,"column":8}}]},"6":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":8},"end":{"line":145,"column":8}},{"start":{"line":145,"column":8},"end":{"line":145,"column":8}}]},"7":{"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}}]},"8":{"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}}]}}}, +"contracts/modules/lite/CCTCMTATBasePolicyEngine.sol":{"l":{"51":55,"72":55,"95":55,"98":55,"101":55,"104":55,"107":55,"108":55,"111":55,"121":55,"132":0,"146":233,"147":233,"148":88,"150":145,"163":35,"164":35,"165":12,"167":23,"189":1016,"190":998,"199":6},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/CCTCMTATBasePolicyEngine.sol","s":{"1":55,"2":55,"3":55,"4":55,"5":55,"6":55,"7":55,"8":55,"9":55,"10":55,"11":0,"12":233,"13":233,"14":88,"15":145,"16":35,"17":35,"18":12,"19":23,"20":1016,"21":998,"22":6},"b":{"1":[55,2],"2":[55,0],"3":[55,0],"4":[55,0],"5":[0,0],"6":[88,145],"7":[12,23],"8":[0,0],"9":[99,6],"10":[37,3],"11":[78,9],"12":[922,76],"13":[3,0]},"f":{"1":55,"2":55,"3":55,"4":55,"5":0,"6":233,"7":35,"8":0,"9":99,"10":37,"11":78,"12":1016,"13":6},"fnMap":{"1":{"name":"initialize","line":50,"loc":{"start":{"line":43,"column":4},"end":{"line":59,"column":4}}},"2":{"name":"_initialize","line":71,"loc":{"start":{"line":64,"column":4},"end":{"line":80,"column":4}}},"3":{"name":"__CMTAT_init","line":92,"loc":{"start":{"line":85,"column":4},"end":{"line":112,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":119,"loc":{"start":{"line":117,"column":4},"end":{"line":122,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":131,"loc":{"start":{"line":127,"column":4},"end":{"line":133,"column":4}}},"6":{"name":"canTransfer","line":141,"loc":{"start":{"line":141,"column":4},"end":{"line":152,"column":4}}},"7":{"name":"canTransferFrom","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":169,"column":4}}},"8":{"name":"_authorizeAttachPolicyEngine","line":171,"loc":{"start":{"line":171,"column":4},"end":{"line":171,"column":107}}},"9":{"name":"_authorizePause","line":177,"loc":{"start":{"line":177,"column":4},"end":{"line":177,"column":93}}},"10":{"name":"_authorizeDeactivate","line":178,"loc":{"start":{"line":178,"column":4},"end":{"line":178,"column":105}}},"11":{"name":"_authorizeFreeze","line":180,"loc":{"start":{"line":180,"column":4},"end":{"line":180,"column":102}}},"12":{"name":"_checkTransferred","line":183,"loc":{"start":{"line":183,"column":4},"end":{"line":194,"column":4}}},"13":{"name":"supportsInterface","line":196,"loc":{"start":{"line":196,"column":4},"end":{"line":202,"column":4}}}},"statementMap":{"1":{"start":{"line":51,"column":8},"end":{"line":51,"column":2308}},"2":{"start":{"line":72,"column":8},"end":{"line":72,"column":2936}},"3":{"start":{"line":95,"column":8},"end":{"line":95,"column":33}},"4":{"start":{"line":98,"column":8},"end":{"line":98,"column":32}},"5":{"start":{"line":101,"column":8},"end":{"line":101,"column":60}},"6":{"start":{"line":104,"column":8},"end":{"line":104,"column":97}},"7":{"start":{"line":107,"column":8},"end":{"line":107,"column":61}},"8":{"start":{"line":108,"column":8},"end":{"line":108,"column":61}},"9":{"start":{"line":111,"column":8},"end":{"line":111,"column":58}},"10":{"start":{"line":121,"column":8},"end":{"line":121,"column":77}},"11":{"start":{"line":132,"column":8},"end":{"line":132,"column":97}},"12":{"start":{"line":146,"column":8},"end":{"line":146,"column":90}},"13":{"start":{"line":147,"column":8},"end":{"line":147,"column":5666}},"14":{"start":{"line":148,"column":12},"end":{"line":148,"column":24}},"15":{"start":{"line":150,"column":12},"end":{"line":150,"column":76}},"16":{"start":{"line":163,"column":8},"end":{"line":163,"column":90}},"17":{"start":{"line":164,"column":8},"end":{"line":164,"column":6185}},"18":{"start":{"line":165,"column":12},"end":{"line":165,"column":24}},"19":{"start":{"line":167,"column":12},"end":{"line":167,"column":89}},"20":{"start":{"line":189,"column":8},"end":{"line":189,"column":66}},"21":{"start":{"line":190,"column":8},"end":{"line":190,"column":7298}},"22":{"start":{"line":199,"column":8},"end":{"line":199,"column":7697}}},"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":71,"type":"if","locations":[{"start":{"line":71,"column":23},"end":{"line":71,"column":23}},{"start":{"line":71,"column":23},"end":{"line":71,"column":23}}]},"3":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":23},"end":{"line":92,"column":23}},{"start":{"line":92,"column":23},"end":{"line":92,"column":23}}]},"4":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":23},"end":{"line":119,"column":23}},{"start":{"line":119,"column":23},"end":{"line":119,"column":23}}]},"5":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":23},"end":{"line":131,"column":23}},{"start":{"line":131,"column":23},"end":{"line":131,"column":23}}]},"6":{"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}}]},"7":{"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}}]},"8":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":77},"end":{"line":171,"column":77}},{"start":{"line":171,"column":77},"end":{"line":171,"column":77}}]},"9":{"line":177,"type":"if","locations":[{"start":{"line":177,"column":70},"end":{"line":177,"column":70}},{"start":{"line":177,"column":70},"end":{"line":177,"column":70}}]},"10":{"line":178,"type":"if","locations":[{"start":{"line":178,"column":75},"end":{"line":178,"column":75}},{"start":{"line":178,"column":75},"end":{"line":178,"column":75}}]},"11":{"line":180,"type":"if","locations":[{"start":{"line":180,"column":77},"end":{"line":180,"column":77}},{"start":{"line":180,"column":77},"end":{"line":180,"column":77}}]},"12":{"line":190,"type":"if","locations":[{"start":{"line":190,"column":8},"end":{"line":190,"column":8}},{"start":{"line":190,"column":8},"end":{"line":190,"column":8}}]},"13":{"line":200,"type":"cond-expr","locations":[{"start":{"line":200,"column":12},"end":{"line":200,"column":64}},{"start":{"line":201,"column":12},"end":{"line":201,"column":72}}]}}}, +"contracts/modules/lite/PolicyValidationModuleERC1404.sol":{"l":{"45":9,"46":2,"48":1,"50":1,"52":1,"54":2,"56":1,"58":1,"75":6,"76":6,"77":5,"79":1,"89":3,"90":1,"92":2,"93":2,"94":1,"96":1,"113":7,"114":1,"116":1,"118":1,"120":2,"122":2},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/PolicyValidationModuleERC1404.sol","s":{"1":9,"2":2,"3":7,"4":1,"5":6,"6":1,"7":5,"8":1,"9":4,"10":2,"11":2,"12":1,"13":1,"14":6,"15":6,"16":5,"17":1,"18":3,"19":1,"20":2,"21":2,"22":1,"23":1,"24":7,"25":1,"26":6,"27":1,"28":5,"29":1,"30":4,"31":2,"32":2},"b":{"1":[2,7],"2":[1,6],"3":[1,5],"4":[1,4],"5":[2,2],"6":[1,1],"7":[5,1],"8":[1,2],"9":[1,1],"10":[1,6],"11":[1,5],"12":[1,4],"13":[2,2]},"f":{"1":9,"2":6,"3":3,"4":7},"fnMap":{"1":{"name":"messageForTransferRestriction","line":42,"loc":{"start":{"line":42,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"detectTransferRestriction","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":81,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":99,"column":4}}},"4":{"name":"_detectTransferRestriction","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":124,"column":4}}}},"statementMap":{"1":{"start":{"line":45,"column":8},"end":{"line":45,"column":1876}},"2":{"start":{"line":46,"column":12},"end":{"line":46,"column":35}},"3":{"start":{"line":47,"column":15},"end":{"line":47,"column":2007}},"4":{"start":{"line":48,"column":12},"end":{"line":48,"column":48}},"5":{"start":{"line":49,"column":15},"end":{"line":49,"column":2164}},"6":{"start":{"line":50,"column":12},"end":{"line":50,"column":53}},"7":{"start":{"line":51,"column":15},"end":{"line":51,"column":2331}},"8":{"start":{"line":52,"column":12},"end":{"line":52,"column":53}},"9":{"start":{"line":53,"column":15},"end":{"line":53,"column":2498}},"10":{"start":{"line":54,"column":12},"end":{"line":54,"column":51}},"11":{"start":{"line":55,"column":15},"end":{"line":55,"column":2661}},"12":{"start":{"line":56,"column":12},"end":{"line":56,"column":56}},"13":{"start":{"line":58,"column":12},"end":{"line":58,"column":36}},"14":{"start":{"line":75,"column":8},"end":{"line":75,"column":70}},"15":{"start":{"line":76,"column":8},"end":{"line":76,"column":3513}},"16":{"start":{"line":77,"column":12},"end":{"line":77,"column":29}},"17":{"start":{"line":79,"column":12},"end":{"line":79,"column":71}},"18":{"start":{"line":89,"column":8},"end":{"line":89,"column":3940}},"19":{"start":{"line":90,"column":12},"end":{"line":90,"column":92}},"20":{"start":{"line":92,"column":12},"end":{"line":92,"column":74}},"21":{"start":{"line":93,"column":12},"end":{"line":93,"column":4168}},"22":{"start":{"line":94,"column":16},"end":{"line":94,"column":33}},"23":{"start":{"line":96,"column":16},"end":{"line":96,"column":75}},"24":{"start":{"line":113,"column":8},"end":{"line":113,"column":4844}},"25":{"start":{"line":114,"column":12},"end":{"line":114,"column":89}},"26":{"start":{"line":115,"column":15},"end":{"line":115,"column":4971}},"27":{"start":{"line":116,"column":12},"end":{"line":116,"column":84}},"28":{"start":{"line":117,"column":15},"end":{"line":117,"column":5088}},"29":{"start":{"line":118,"column":12},"end":{"line":118,"column":89}},"30":{"start":{"line":119,"column":15},"end":{"line":119,"column":5216}},"31":{"start":{"line":120,"column":12},"end":{"line":120,"column":87}},"32":{"start":{"line":122,"column":12},"end":{"line":122,"column":71}}},"branchMap":{"1":{"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}}]},"2":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":15},"end":{"line":47,"column":15}},{"start":{"line":47,"column":15},"end":{"line":47,"column":15}}]},"3":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":15},"end":{"line":49,"column":15}},{"start":{"line":49,"column":15},"end":{"line":49,"column":15}}]},"4":{"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}}]},"5":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":15},"end":{"line":53,"column":15}},{"start":{"line":53,"column":15},"end":{"line":53,"column":15}}]},"6":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":15},"end":{"line":55,"column":15}},{"start":{"line":55,"column":15},"end":{"line":55,"column":15}}]},"7":{"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}}]},"8":{"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}}]},"9":{"line":93,"type":"if","locations":[{"start":{"line":93,"column":12},"end":{"line":93,"column":12}},{"start":{"line":93,"column":12},"end":{"line":93,"column":12}}]},"10":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":8},"end":{"line":113,"column":8}},{"start":{"line":113,"column":8},"end":{"line":113,"column":8}}]},"11":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":15},"end":{"line":115,"column":15}},{"start":{"line":115,"column":15},"end":{"line":115,"column":15}}]},"12":{"line":117,"type":"if","locations":[{"start":{"line":117,"column":15},"end":{"line":117,"column":15}},{"start":{"line":117,"column":15},"end":{"line":117,"column":15}}]},"13":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":15},"end":{"line":119,"column":15}},{"start":{"line":119,"column":15},"end":{"line":119,"column":15}}]}}}, +"contracts/modules/lite/ValidationModulePolicyEngine.sol":{"l":{"25":145,"38":23,"46":145,"47":39,"49":106,"59":23,"60":12,"62":11,"72":11,"80":106,"84":118,"85":118,"86":117,"87":117,"92":111,"94":6,"97":1,"108":1001,"109":932,"110":932,"111":931,"112":931,"115":924,"116":2,"119":925},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/ValidationModulePolicyEngine.sol","s":{"1":145,"2":23,"3":145,"4":39,"5":106,"6":23,"7":12,"8":11,"9":11,"10":106,"11":118,"12":118,"13":117,"14":117,"15":111,"16":6,"17":1,"18":1001,"19":932,"20":932,"21":931,"22":931,"23":924,"24":2,"25":925},"b":{"1":[39,106],"2":[12,11],"3":[117,1],"4":[931,1],"5":[2,922]},"f":{"1":145,"2":23,"3":145,"4":23,"5":11,"6":106,"7":118,"8":1001},"fnMap":{"1":{"name":"canTransfer","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"canTransferFrom","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":39,"column":4}}},"3":{"name":"_canTransfer","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"4":{"name":"_canTransferFrom","line":53,"loc":{"start":{"line":53,"column":4},"end":{"line":64,"column":4}}},"5":{"name":"_canTransferFromWithPolicyEngine","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":73,"column":4}}},"6":{"name":"_canTransferWithPolicyEngine","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":81,"column":4}}},"7":{"name":"_tryCheckPolicies","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":99,"column":4}}},"8":{"name":"_transferred","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":120,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":44}},"2":{"start":{"line":38,"column":8},"end":{"line":38,"column":57}},"3":{"start":{"line":46,"column":8},"end":{"line":46,"column":1819}},"4":{"start":{"line":47,"column":12},"end":{"line":47,"column":24}},"5":{"start":{"line":49,"column":12},"end":{"line":49,"column":64}},"6":{"start":{"line":59,"column":8},"end":{"line":59,"column":2176}},"7":{"start":{"line":60,"column":12},"end":{"line":60,"column":24}},"8":{"start":{"line":62,"column":12},"end":{"line":62,"column":77}},"9":{"start":{"line":72,"column":8},"end":{"line":72,"column":100}},"10":{"start":{"line":80,"column":8},"end":{"line":80,"column":87}},"11":{"start":{"line":84,"column":8},"end":{"line":84,"column":70}},"12":{"start":{"line":85,"column":8},"end":{"line":85,"column":3118}},"13":{"start":{"line":86,"column":12},"end":{"line":86,"column":47}},"14":{"start":{"line":87,"column":12},"end":{"line":87,"column":3227}},"15":{"start":{"line":92,"column":16},"end":{"line":92,"column":27}},"16":{"start":{"line":94,"column":16},"end":{"line":94,"column":28}},"17":{"start":{"line":97,"column":12},"end":{"line":97,"column":23}},"18":{"start":{"line":108,"column":8},"end":{"line":108,"column":62}},"19":{"start":{"line":109,"column":8},"end":{"line":109,"column":70}},"20":{"start":{"line":110,"column":8},"end":{"line":110,"column":3919}},"21":{"start":{"line":111,"column":12},"end":{"line":111,"column":47}},"22":{"start":{"line":112,"column":12},"end":{"line":112,"column":4028}},"23":{"start":{"line":115,"column":12},"end":{"line":115,"column":4193}},"24":{"start":{"line":116,"column":16},"end":{"line":116,"column":29}},"25":{"start":{"line":119,"column":8},"end":{"line":119,"column":19}}},"branchMap":{"1":{"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}}]},"2":{"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}}]},"3":{"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}}]},"4":{"line":110,"type":"if","locations":[{"start":{"line":110,"column":8},"end":{"line":110,"column":8}},{"start":{"line":110,"column":8},"end":{"line":110,"column":8}}]},"5":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":12},"end":{"line":115,"column":12}},{"start":{"line":115,"column":12},"end":{"line":115,"column":12}}]}}}, +"contracts/modules/standard/CCTCommon.sol":{"l":{"57":12,"75":12,"96":12,"99":12,"102":12,"105":12,"107":12,"110":12,"113":12,"114":12,"124":12,"134":12,"142":12,"148":12,"163":48,"173":12,"184":9,"191":13,"198":10,"204":9,"217":376,"227":48,"238":0,"328":478},"path":"/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/standard/CCTCommon.sol","s":{"1":12,"2":12,"3":12,"4":12,"5":12,"6":12,"7":12,"8":12,"9":12,"10":12,"11":12,"12":12,"13":12,"14":12,"15":48,"16":12,"17":9,"18":13,"19":10,"20":9,"21":376,"22":48,"23":0,"24":478},"b":{"1":[12,2],"2":[12,0],"3":[12,0],"4":[12,0],"5":[12,0],"6":[12,0],"7":[48,0],"8":[12,0],"9":[3,3],"10":[3,3],"11":[3,3],"12":[352,24],"13":[33,15],"14":[63,3],"15":[3,3],"16":[48,12],"17":[12,12],"18":[12,3],"19":[3,3],"20":[15,6],"21":[3,3],"22":[3,3]},"f":{"1":12,"2":12,"3":12,"4":12,"5":12,"6":12,"7":48,"8":12,"9":3,"10":9,"11":13,"12":10,"13":9,"14":376,"15":48,"16":0,"17":3,"18":352,"19":33,"20":63,"21":3,"22":48,"23":12,"24":12,"25":3,"26":15,"27":3,"28":3,"29":478},"fnMap":{"1":{"name":"initialize","line":56,"loc":{"start":{"line":49,"column":4},"end":{"line":65,"column":4}}},"2":{"name":"_initialize","line":74,"loc":{"start":{"line":67,"column":4},"end":{"line":83,"column":4}}},"3":{"name":"__CMTAT_init","line":95,"loc":{"start":{"line":88,"column":4},"end":{"line":115,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":122,"loc":{"start":{"line":120,"column":4},"end":{"line":125,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":133,"loc":{"start":{"line":130,"column":4},"end":{"line":135,"column":4}}},"6":{"name":"__CMTAT_commonModules_init_unchained","line":140,"loc":{"start":{"line":137,"column":4},"end":{"line":153,"column":4}}},"7":{"name":"transfer","line":162,"loc":{"start":{"line":159,"column":4},"end":{"line":164,"column":4}}},"8":{"name":"transferFrom","line":172,"loc":{"start":{"line":168,"column":4},"end":{"line":174,"column":4}}},"9":{"name":"_authorizeAttachPolicyEngine","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":176,"column":88}}},"10":{"name":"decimals","line":183,"loc":{"start":{"line":183,"column":4},"end":{"line":185,"column":4}}},"11":{"name":"name","line":190,"loc":{"start":{"line":190,"column":4},"end":{"line":192,"column":4}}},"12":{"name":"symbol","line":197,"loc":{"start":{"line":197,"column":4},"end":{"line":199,"column":4}}},"13":{"name":"supportsInterface","line":201,"loc":{"start":{"line":201,"column":4},"end":{"line":207,"column":4}}},"14":{"name":"_mintOverride","line":213,"loc":{"start":{"line":213,"column":4},"end":{"line":218,"column":4}}},"15":{"name":"_burnOverride","line":223,"loc":{"start":{"line":223,"column":4},"end":{"line":228,"column":4}}},"16":{"name":"_minterTransferOverride","line":233,"loc":{"start":{"line":233,"column":4},"end":{"line":239,"column":4}}},"17":{"name":"_authorizeERC20AttributeManagement","line":247,"loc":{"start":{"line":247,"column":4},"end":{"line":247,"column":104}}},"18":{"name":"_authorizeMint","line":253,"loc":{"start":{"line":253,"column":4},"end":{"line":253,"column":84}}},"19":{"name":"_authorizeBurn","line":259,"loc":{"start":{"line":259,"column":4},"end":{"line":259,"column":84}}},"20":{"name":"_authorizeDocumentManagement","line":265,"loc":{"start":{"line":265,"column":4},"end":{"line":265,"column":103}}},"21":{"name":"_authorizeExtraInfoManagement","line":271,"loc":{"start":{"line":271,"column":4},"end":{"line":271,"column":106}}},"22":{"name":"_authorizeERC20Enforcer","line":277,"loc":{"start":{"line":277,"column":4},"end":{"line":277,"column":100}}},"23":{"name":"_authorizeForcedTransfer","line":283,"loc":{"start":{"line":283,"column":4},"end":{"line":283,"column":101}}},"24":{"name":"_authorizeSnapshots","line":289,"loc":{"start":{"line":289,"column":4},"end":{"line":289,"column":94}}},"25":{"name":"_authorizeCCIPSetAdmin","line":295,"loc":{"start":{"line":295,"column":4},"end":{"line":295,"column":87}}},"26":{"name":"_checkTokenBridge","line":306,"loc":{"start":{"line":306,"column":4},"end":{"line":306,"column":107}}},"27":{"name":"_authorizeBurnFrom","line":313,"loc":{"start":{"line":313,"column":4},"end":{"line":313,"column":94}}},"28":{"name":"_authorizeSelfBurn","line":320,"loc":{"start":{"line":320,"column":4},"end":{"line":320,"column":94}}},"29":{"name":"_update","line":323,"loc":{"start":{"line":323,"column":4},"end":{"line":329,"column":4}}}},"statementMap":{"1":{"start":{"line":57,"column":8},"end":{"line":57,"column":2294}},"2":{"start":{"line":75,"column":8},"end":{"line":75,"column":2857}},"3":{"start":{"line":96,"column":8},"end":{"line":96,"column":38}},"4":{"start":{"line":99,"column":8},"end":{"line":99,"column":33}},"5":{"start":{"line":102,"column":8},"end":{"line":102,"column":32}},"6":{"start":{"line":105,"column":8},"end":{"line":105,"column":60}},"7":{"start":{"line":107,"column":8},"end":{"line":107,"column":57}},"8":{"start":{"line":110,"column":8},"end":{"line":110,"column":84}},"9":{"start":{"line":113,"column":8},"end":{"line":113,"column":61}},"10":{"start":{"line":114,"column":8},"end":{"line":114,"column":61}},"11":{"start":{"line":124,"column":8},"end":{"line":124,"column":77}},"12":{"start":{"line":134,"column":8},"end":{"line":134,"column":90}},"13":{"start":{"line":142,"column":8},"end":{"line":142,"column":5290}},"14":{"start":{"line":148,"column":8},"end":{"line":148,"column":5489}},"15":{"start":{"line":163,"column":8},"end":{"line":163,"column":50}},"16":{"start":{"line":173,"column":8},"end":{"line":173,"column":60}},"17":{"start":{"line":184,"column":8},"end":{"line":184,"column":41}},"18":{"start":{"line":191,"column":8},"end":{"line":191,"column":37}},"19":{"start":{"line":198,"column":8},"end":{"line":198,"column":39}},"20":{"start":{"line":204,"column":8},"end":{"line":204,"column":7490}},"21":{"start":{"line":217,"column":8},"end":{"line":217,"column":52}},"22":{"start":{"line":227,"column":8},"end":{"line":227,"column":52}},"23":{"start":{"line":238,"column":8},"end":{"line":238,"column":63}},"24":{"start":{"line":328,"column":8},"end":{"line":328,"column":56}}},"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":74,"type":"if","locations":[{"start":{"line":74,"column":23},"end":{"line":74,"column":23}},{"start":{"line":74,"column":23},"end":{"line":74,"column":23}}]},"3":{"line":95,"type":"if","locations":[{"start":{"line":95,"column":23},"end":{"line":95,"column":23}},{"start":{"line":95,"column":23},"end":{"line":95,"column":23}}]},"4":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":23},"end":{"line":122,"column":23}},{"start":{"line":122,"column":23},"end":{"line":122,"column":23}}]},"5":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":23},"end":{"line":133,"column":23}},{"start":{"line":133,"column":23},"end":{"line":133,"column":23}}]},"6":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":23},"end":{"line":140,"column":23}},{"start":{"line":140,"column":23},"end":{"line":140,"column":23}}]},"7":{"line":162,"type":"if","locations":[{"start":{"line":162,"column":65},"end":{"line":162,"column":65}},{"start":{"line":162,"column":65},"end":{"line":162,"column":65}}]},"8":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":65},"end":{"line":172,"column":65}},{"start":{"line":172,"column":65},"end":{"line":172,"column":65}}]},"9":{"line":176,"type":"if","locations":[{"start":{"line":176,"column":77},"end":{"line":176,"column":77}},{"start":{"line":176,"column":77},"end":{"line":176,"column":77}}]},"10":{"line":205,"type":"cond-expr","locations":[{"start":{"line":205,"column":12},"end":{"line":205,"column":64}},{"start":{"line":206,"column":12},"end":{"line":206,"column":73}}]},"11":{"line":247,"type":"if","locations":[{"start":{"line":247,"column":93},"end":{"line":247,"column":93}},{"start":{"line":247,"column":93},"end":{"line":247,"column":93}}]},"12":{"line":253,"type":"if","locations":[{"start":{"line":253,"column":73},"end":{"line":253,"column":73}},{"start":{"line":253,"column":73},"end":{"line":253,"column":73}}]},"13":{"line":259,"type":"if","locations":[{"start":{"line":259,"column":73},"end":{"line":259,"column":73}},{"start":{"line":259,"column":73},"end":{"line":259,"column":73}}]},"14":{"line":265,"type":"if","locations":[{"start":{"line":265,"column":92},"end":{"line":265,"column":92}},{"start":{"line":265,"column":92},"end":{"line":265,"column":92}}]},"15":{"line":271,"type":"if","locations":[{"start":{"line":271,"column":95},"end":{"line":271,"column":95}},{"start":{"line":271,"column":95},"end":{"line":271,"column":95}}]},"16":{"line":277,"type":"if","locations":[{"start":{"line":277,"column":89},"end":{"line":277,"column":89}},{"start":{"line":277,"column":89},"end":{"line":277,"column":89}}]},"17":{"line":283,"type":"if","locations":[{"start":{"line":283,"column":90},"end":{"line":283,"column":90}},{"start":{"line":283,"column":90},"end":{"line":283,"column":90}}]},"18":{"line":289,"type":"if","locations":[{"start":{"line":289,"column":83},"end":{"line":289,"column":83}},{"start":{"line":289,"column":83},"end":{"line":289,"column":83}}]},"19":{"line":295,"type":"if","locations":[{"start":{"line":295,"column":76},"end":{"line":295,"column":76}},{"start":{"line":295,"column":76},"end":{"line":295,"column":76}}]},"20":{"line":306,"type":"if","locations":[{"start":{"line":306,"column":96},"end":{"line":306,"column":96}},{"start":{"line":306,"column":96},"end":{"line":306,"column":96}}]},"21":{"line":313,"type":"if","locations":[{"start":{"line":313,"column":83},"end":{"line":313,"column":83}},{"start":{"line":313,"column":83},"end":{"line":313,"column":83}}]},"22":{"line":320,"type":"if","locations":[{"start":{"line":320,"column":83},"end":{"line":320,"column":83}},{"start":{"line":320,"column":83},"end":{"line":320,"column":83}}]}}}} diff --git a/doc/coverage/coverage.json b/doc/coverage/coverage.json new file mode 100644 index 0000000..bf75ba1 --- /dev/null +++ b/doc/coverage/coverage.json @@ -0,0 +1 @@ +{"contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol":{"l":{"34":47},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol","s":{"1":47},"b":{},"f":{"1":47},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":42,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1480}}},"branchMap":{}},"contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol":{"l":{"16":1},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol","s":{"1":1},"b":{},"f":{"1":1},"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/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol":{"l":{"19":1},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol","s":{"1":1},"b":{"1":[2,1]},"f":{"1":1,"2":2},"fnMap":{"1":{"name":"constructor","line":17,"loc":{"start":{"line":17,"column":4},"end":{"line":20,"column":4}}},"2":{"name":"_authorizeUpgrade","line":27,"loc":{"start":{"line":25,"column":4},"end":{"line":27,"column":79}}}},"statementMap":{"1":{"start":{"line":19,"column":8},"end":{"line":19,"column":29}}},"branchMap":{"1":{"line":27,"type":"if","locations":[{"start":{"line":27,"column":49},"end":{"line":27,"column":49}},{"start":{"line":27,"column":49},"end":{"line":27,"column":49}}]}}},"contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol":{"l":{"34":8},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol","s":{"1":8},"b":{},"f":{"1":8},"fnMap":{"1":{"name":"constructor","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":42,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":1416}}},"branchMap":{}},"contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol":{"l":{"16":1},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol","s":{"1":1},"b":{},"f":{"1":1},"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/standard/ComplianceTokenCMTATUUPSUpgradeable.sol":{"l":{"17":1},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol","s":{"1":1},"b":{"1":[2,1]},"f":{"1":1,"2":2},"fnMap":{"1":{"name":"constructor","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":18,"column":4}}},"2":{"name":"_authorizeUpgrade","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":23,"column":112}}}},"statementMap":{"1":{"start":{"line":17,"column":8},"end":{"line":17,"column":29}}},"branchMap":{"1":{"line":23,"type":"if","locations":[{"start":{"line":23,"column":101},"end":{"line":23,"column":101}},{"start":{"line":23,"column":101},"end":{"line":23,"column":101}}]}}},"contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol":{"l":{"31":34,"32":34,"33":34,"34":34,"36":34,"37":30,"38":30,"39":30,"41":4,"42":4,"44":0,"47":34,"48":34,"49":34,"50":34,"51":34,"53":34},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol","s":{"1":34,"2":34,"3":34,"4":34,"5":34,"6":4,"7":34,"8":34},"b":{"1":[30,4],"2":[4,0]},"f":{"1":34},"fnMap":{"1":{"name":"extract","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":54,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":23}},"2":{"start":{"line":32,"column":8},"end":{"line":32,"column":20}},"3":{"start":{"line":33,"column":8},"end":{"line":33,"column":18}},"4":{"start":{"line":34,"column":8},"end":{"line":34,"column":22}},"5":{"start":{"line":36,"column":8},"end":{"line":36,"column":1498}},"6":{"start":{"line":40,"column":15},"end":{"line":40,"column":1711}},"7":{"start":{"line":47,"column":8},"end":{"line":47,"column":82}},"8":{"start":{"line":53,"column":8},"end":{"line":53,"column":21}}},"branchMap":{"1":{"line":36,"type":"if","locations":[{"start":{"line":36,"column":8},"end":{"line":36,"column":8}},{"start":{"line":36,"column":8},"end":{"line":36,"column":8}}]},"2":{"line":40,"type":"if","locations":[{"start":{"line":40,"column":15},"end":{"line":40,"column":15}},{"start":{"line":40,"column":15},"end":{"line":40,"column":15}}]}}},"contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol":{"l":{"38":69,"49":33,"50":30,"51":30,"52":30,"53":37,"54":37,"64":2,"65":2,"66":2,"67":2,"68":2,"69":2,"71":2,"78":1,"85":1,"101":35,"102":35,"104":35,"106":33,"107":33,"108":33,"109":33,"111":33,"112":35,"113":35,"114":13,"115":13,"120":2,"121":2,"122":2,"124":2,"125":2,"126":2,"127":1,"128":1,"133":21},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol","s":{"1":33,"2":30,"3":30,"4":30,"5":37,"6":37,"7":2,"8":2,"9":2,"10":2,"11":2,"12":2,"13":1,"14":1,"15":35,"16":35,"17":35,"18":33,"19":33,"20":33,"21":33,"22":33,"23":35,"24":35,"25":13,"26":2,"27":2,"28":2,"29":2,"30":2,"31":2,"32":1,"33":21},"b":{"1":[33,0],"2":[30,3],"3":[37,0],"4":[2,1],"5":[2,0],"6":[33,2],"7":[13,22],"8":[1,1]},"f":{"1":69,"2":33,"3":2,"4":1,"5":1,"6":35},"fnMap":{"1":{"name":"_getStorage","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":41,"column":4}}},"2":{"name":"configure","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":57,"column":4}}},"3":{"name":"setRules","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":72,"column":4}}},"4":{"name":"rules","line":77,"loc":{"start":{"line":77,"column":4},"end":{"line":79,"column":4}}},"5":{"name":"rulesCount","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":86,"column":4}}},"6":{"name":"run","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":134,"column":4}}}},"statementMap":{"1":{"start":{"line":49,"column":8},"end":{"line":49,"column":2016}},"2":{"start":{"line":50,"column":12},"end":{"line":50,"column":76}},"3":{"start":{"line":51,"column":12},"end":{"line":51,"column":63}},"4":{"start":{"line":52,"column":12},"end":{"line":52,"column":2204}},"5":{"start":{"line":53,"column":16},"end":{"line":53,"column":81}},"6":{"start":{"line":54,"column":16},"end":{"line":54,"column":48}},"7":{"start":{"line":64,"column":8},"end":{"line":64,"column":59}},"8":{"start":{"line":65,"column":8},"end":{"line":65,"column":46}},"9":{"start":{"line":67,"column":8},"end":{"line":67,"column":2745}},"10":{"start":{"line":68,"column":12},"end":{"line":68,"column":83}},"11":{"start":{"line":69,"column":12},"end":{"line":69,"column":34}},"12":{"start":{"line":71,"column":8},"end":{"line":71,"column":55}},"13":{"start":{"line":78,"column":8},"end":{"line":78,"column":34}},"14":{"start":{"line":85,"column":8},"end":{"line":85,"column":41}},"15":{"start":{"line":101,"column":8},"end":{"line":101,"column":59}},"16":{"start":{"line":102,"column":8},"end":{"line":102,"column":36}},"17":{"start":{"line":104,"column":8},"end":{"line":104,"column":3910}},"18":{"start":{"line":106,"column":12},"end":{"line":106,"column":66}},"19":{"start":{"line":107,"column":12},"end":{"line":107,"column":63}},"20":{"start":{"line":108,"column":12},"end":{"line":108,"column":61}},"21":{"start":{"line":109,"column":12},"end":{"line":109,"column":65}},"22":{"start":{"line":111,"column":12},"end":{"line":111,"column":4298}},"23":{"start":{"line":112,"column":16},"end":{"line":112,"column":96}},"24":{"start":{"line":113,"column":16},"end":{"line":113,"column":4452}},"25":{"start":{"line":114,"column":20},"end":{"line":114,"column":90}},"26":{"start":{"line":120,"column":12},"end":{"line":120,"column":63}},"27":{"start":{"line":121,"column":12},"end":{"line":121,"column":61}},"28":{"start":{"line":122,"column":12},"end":{"line":122,"column":65}},"29":{"start":{"line":124,"column":12},"end":{"line":124,"column":4945}},"30":{"start":{"line":125,"column":16},"end":{"line":125,"column":83}},"31":{"start":{"line":126,"column":16},"end":{"line":126,"column":5086}},"32":{"start":{"line":127,"column":20},"end":{"line":127,"column":90}},"33":{"start":{"line":133,"column":8},"end":{"line":133,"column":50}}},"branchMap":{"1":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":68},"end":{"line":48,"column":68}},{"start":{"line":48,"column":68},"end":{"line":48,"column":68}}]},"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":53,"type":"if","locations":[{"start":{"line":53,"column":16},"end":{"line":53,"column":16}},{"start":{"line":53,"column":16},"end":{"line":53,"column":16}}]},"4":{"line":63,"type":"if","locations":[{"start":{"line":63,"column":56},"end":{"line":63,"column":56}},{"start":{"line":63,"column":56},"end":{"line":63,"column":56}}]},"5":{"line":68,"type":"if","locations":[{"start":{"line":68,"column":12},"end":{"line":68,"column":12}},{"start":{"line":68,"column":12},"end":{"line":68,"column":12}}]},"6":{"line":104,"type":"if","locations":[{"start":{"line":104,"column":8},"end":{"line":104,"column":8}},{"start":{"line":104,"column":8},"end":{"line":104,"column":8}}]},"7":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":16},"end":{"line":113,"column":16}},{"start":{"line":113,"column":16},"end":{"line":113,"column":16}}]},"8":{"line":126,"type":"if","locations":[{"start":{"line":126,"column":16},"end":{"line":126,"column":16}},{"start":{"line":126,"column":16},"end":{"line":126,"column":16}}]}}},"contracts/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol":{"l":{"16":1,"20":0,"24":8,"28":1,"29":1,"30":1,"35":5,"45":0,"51":0,"61":0,"67":0,"81":7,"87":1,"91":1,"95":1,"101":1,"117":1,"126":3},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol","s":{"1":0,"2":1,"3":1,"4":0,"5":0,"6":0,"7":0,"8":7,"9":1,"10":1,"11":3},"b":{"1":[1,0],"2":[7,0],"3":[1,1],"4":[1,1],"5":[1,0],"6":[1,0]},"f":{"1":1,"2":0,"3":8,"4":1,"5":5,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":7,"21":1,"22":1,"23":1,"24":1,"25":1,"26":0,"27":0,"28":0,"29":0,"30":1,"31":3},"fnMap":{"1":{"name":"setDetachShouldRevert","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":17,"column":4}}},"2":{"name":"typeAndVersion","line":19,"loc":{"start":{"line":19,"column":4},"end":{"line":21,"column":4}}},"3":{"name":"attach","line":23,"loc":{"start":{"line":23,"column":4},"end":{"line":25,"column":4}}},"4":{"name":"detach","line":27,"loc":{"start":{"line":27,"column":4},"end":{"line":32,"column":4}}},"5":{"name":"run","line":34,"loc":{"start":{"line":34,"column":4},"end":{"line":36,"column":4}}},"6":{"name":"check","line":38,"loc":{"start":{"line":38,"column":4},"end":{"line":38,"column":61}}},"7":{"name":"setExtractor","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":40,"column":67}}},"8":{"name":"setExtractors","line":42,"loc":{"start":{"line":42,"column":4},"end":{"line":42,"column":79}}},"9":{"name":"getExtractor","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":46,"column":4}}},"10":{"name":"setPolicyMapper","line":48,"loc":{"start":{"line":48,"column":4},"end":{"line":48,"column":71}}},"11":{"name":"getPolicyMapper","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":52,"column":4}}},"12":{"name":"addPolicy","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":54,"column":93}}},"13":{"name":"addPolicyAt","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":56,"column":104}}},"14":{"name":"removePolicy","line":58,"loc":{"start":{"line":58,"column":4},"end":{"line":58,"column":76}}},"15":{"name":"getPolicies","line":60,"loc":{"start":{"line":60,"column":4},"end":{"line":62,"column":4}}},"16":{"name":"setPolicyConfiguration","line":64,"loc":{"start":{"line":64,"column":4},"end":{"line":64,"column":102}}},"17":{"name":"getPolicyConfigVersion","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":68,"column":4}}},"18":{"name":"setDefaultPolicyAllow","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":70,"column":65}}},"19":{"name":"setTargetDefaultPolicyAllow","line":72,"loc":{"start":{"line":72,"column":4},"end":{"line":72,"column":80}}},"20":{"name":"initialize","line":80,"loc":{"start":{"line":80,"column":4},"end":{"line":82,"column":4}}},"21":{"name":"_authorizeAttachPolicyEngine","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":84,"column":75}}},"22":{"name":"guardedRun","line":86,"loc":{"start":{"line":86,"column":4},"end":{"line":88,"column":4}}},"23":{"name":"guardedRunWithContext","line":90,"loc":{"start":{"line":90,"column":4},"end":{"line":92,"column":4}}},"24":{"name":"guardedRunAndRevert","line":94,"loc":{"start":{"line":94,"column":4},"end":{"line":96,"column":4}}},"25":{"name":"initializeWithPolicyEngine","line":100,"loc":{"start":{"line":100,"column":4},"end":{"line":102,"column":4}}},"26":{"name":"_authorizeAttachPolicyEngine","line":104,"loc":{"start":{"line":104,"column":4},"end":{"line":104,"column":75}}},"27":{"name":"_authorizePause","line":106,"loc":{"start":{"line":106,"column":4},"end":{"line":106,"column":55}}},"28":{"name":"_authorizeDeactivate","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":108,"column":60}}},"29":{"name":"_authorizeFreeze","line":110,"loc":{"start":{"line":110,"column":4},"end":{"line":110,"column":56}}},"30":{"name":"exposedTryCheckPolicies","line":112,"loc":{"start":{"line":112,"column":4},"end":{"line":118,"column":4}}},"31":{"name":"exposedTransferred","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":127,"column":4}}}},"statementMap":{"1":{"start":{"line":20,"column":8},"end":{"line":20,"column":39}},"2":{"start":{"line":29,"column":8},"end":{"line":29,"column":987}},"3":{"start":{"line":30,"column":12},"end":{"line":30,"column":52}},"4":{"start":{"line":45,"column":8},"end":{"line":45,"column":25}},"5":{"start":{"line":51,"column":8},"end":{"line":51,"column":25}},"6":{"start":{"line":61,"column":8},"end":{"line":61,"column":31}},"7":{"start":{"line":67,"column":8},"end":{"line":67,"column":16}},"8":{"start":{"line":81,"column":8},"end":{"line":81,"column":43}},"9":{"start":{"line":101,"column":8},"end":{"line":101,"column":43}},"10":{"start":{"line":117,"column":8},"end":{"line":117,"column":56}},"11":{"start":{"line":126,"column":8},"end":{"line":126,"column":53}}},"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":80,"type":"if","locations":[{"start":{"line":80,"column":55},"end":{"line":80,"column":55}},{"start":{"line":80,"column":55},"end":{"line":80,"column":55}}]},"3":{"line":86,"type":"if","locations":[{"start":{"line":86,"column":35},"end":{"line":86,"column":35}},{"start":{"line":86,"column":35},"end":{"line":86,"column":35}}]},"4":{"line":90,"type":"if","locations":[{"start":{"line":90,"column":68},"end":{"line":90,"column":68}},{"start":{"line":90,"column":68},"end":{"line":90,"column":68}}]},"5":{"line":94,"type":"if","locations":[{"start":{"line":94,"column":44},"end":{"line":94,"column":44}},{"start":{"line":94,"column":44},"end":{"line":94,"column":44}}]},"6":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":71},"end":{"line":100,"column":71}},{"start":{"line":100,"column":71},"end":{"line":100,"column":71}}]}}},"contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol":{"l":{"21":26,"29":25,"38":23,"42":0,"51":0,"64":0,"68":0,"72":8,"88":3,"89":3,"93":14,"94":14,"95":12,"100":3,"108":12,"109":10,"110":6,"119":12,"123":0,"132":0,"145":0,"149":0,"153":6,"154":4,"155":0},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol","s":{"1":25,"2":23,"3":0,"4":0,"5":0,"6":0,"7":8,"8":3,"9":14,"10":12,"11":2,"12":10,"13":4,"14":6,"15":12,"16":0,"17":0,"18":0,"19":0,"20":6,"21":2,"22":4,"23":4,"24":0},"b":{"1":[8,17],"2":[8,0],"3":[3,0],"4":[3,0],"5":[2,10],"6":[4,6],"7":[0,0],"8":[2,4],"9":[4,0]},"f":{"1":26,"2":25,"3":23,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":8,"11":3,"12":14,"13":3,"14":12,"15":12,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":6},"fnMap":{"1":{"name":"constructor","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":22,"column":4}}},"2":{"name":"detectTransferRestriction","line":24,"loc":{"start":{"line":24,"column":4},"end":{"line":30,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":39,"column":4}}},"4":{"name":"canTransfer","line":41,"loc":{"start":{"line":41,"column":4},"end":{"line":43,"column":4}}},"5":{"name":"canTransferFrom","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":52,"column":4}}},"6":{"name":"transferred","line":54,"loc":{"start":{"line":54,"column":4},"end":{"line":54,"column":108}}},"7":{"name":"transferred","line":56,"loc":{"start":{"line":56,"column":4},"end":{"line":61,"column":30}}},"8":{"name":"supportsInterface","line":63,"loc":{"start":{"line":63,"column":4},"end":{"line":65,"column":4}}},"9":{"name":"canReturnTransferRestrictionCode","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":69,"column":4}}},"10":{"name":"messageForTransferRestriction","line":71,"loc":{"start":{"line":71,"column":4},"end":{"line":73,"column":4}}},"11":{"name":"onlyOwner","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":90,"column":4}}},"12":{"name":"constructor","line":92,"loc":{"start":{"line":92,"column":4},"end":{"line":97,"column":4}}},"13":{"name":"setRestricted","line":99,"loc":{"start":{"line":99,"column":4},"end":{"line":101,"column":4}}},"14":{"name":"detectTransferRestriction","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":111,"column":4}}},"15":{"name":"detectTransferRestrictionFrom","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":120,"column":4}}},"16":{"name":"canTransfer","line":122,"loc":{"start":{"line":122,"column":4},"end":{"line":124,"column":4}}},"17":{"name":"canTransferFrom","line":126,"loc":{"start":{"line":126,"column":4},"end":{"line":133,"column":4}}},"18":{"name":"transferred","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":135,"column":108}}},"19":{"name":"transferred","line":137,"loc":{"start":{"line":137,"column":4},"end":{"line":142,"column":30}}},"20":{"name":"supportsInterface","line":144,"loc":{"start":{"line":144,"column":4},"end":{"line":146,"column":4}}},"21":{"name":"canReturnTransferRestrictionCode","line":148,"loc":{"start":{"line":148,"column":4},"end":{"line":150,"column":4}}},"22":{"name":"messageForTransferRestriction","line":152,"loc":{"start":{"line":152,"column":4},"end":{"line":156,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":91}},"2":{"start":{"line":38,"column":8},"end":{"line":38,"column":58}},"3":{"start":{"line":42,"column":8},"end":{"line":42,"column":63}},"4":{"start":{"line":51,"column":8},"end":{"line":51,"column":44}},"5":{"start":{"line":64,"column":8},"end":{"line":64,"column":53}},"6":{"start":{"line":68,"column":8},"end":{"line":68,"column":38}},"7":{"start":{"line":72,"column":8},"end":{"line":72,"column":82}},"8":{"start":{"line":88,"column":8},"end":{"line":88,"column":49}},"9":{"start":{"line":94,"column":8},"end":{"line":94,"column":2793}},"10":{"start":{"line":108,"column":8},"end":{"line":108,"column":52}},"11":{"start":{"line":108,"column":30},"end":{"line":108,"column":52}},"12":{"start":{"line":109,"column":8},"end":{"line":109,"column":48}},"13":{"start":{"line":109,"column":28},"end":{"line":109,"column":48}},"14":{"start":{"line":110,"column":8},"end":{"line":110,"column":52}},"15":{"start":{"line":119,"column":8},"end":{"line":119,"column":58}},"16":{"start":{"line":123,"column":8},"end":{"line":123,"column":63}},"17":{"start":{"line":132,"column":8},"end":{"line":132,"column":44}},"18":{"start":{"line":145,"column":8},"end":{"line":145,"column":53}},"19":{"start":{"line":149,"column":8},"end":{"line":149,"column":63}},"20":{"start":{"line":153,"column":8},"end":{"line":153,"column":66}},"21":{"start":{"line":153,"column":37},"end":{"line":153,"column":66}},"22":{"start":{"line":154,"column":8},"end":{"line":154,"column":67}},"23":{"start":{"line":154,"column":35},"end":{"line":154,"column":67}},"24":{"start":{"line":155,"column":8},"end":{"line":155,"column":29}}},"branchMap":{"1":{"line":29,"type":"if","locations":[{"start":{"line":29,"column":36},"end":{"line":29,"column":50}},{"start":{"line":29,"column":54},"end":{"line":29,"column":90}}]},"2":{"line":72,"type":"if","locations":[{"start":{"line":72,"column":41},"end":{"line":72,"column":64}},{"start":{"line":72,"column":68},"end":{"line":72,"column":81}}]},"3":{"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}}]},"4":{"line":99,"type":"if","locations":[{"start":{"line":99,"column":66},"end":{"line":99,"column":66}},{"start":{"line":99,"column":66},"end":{"line":99,"column":66}}]},"5":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":8},"end":{"line":108,"column":8}},{"start":{"line":108,"column":8},"end":{"line":108,"column":8}}]},"6":{"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}}]},"7":{"line":149,"type":"cond-expr","locations":[{"start":{"line":149,"column":15},"end":{"line":149,"column":37}},{"start":{"line":149,"column":42},"end":{"line":149,"column":62}}]},"8":{"line":153,"type":"if","locations":[{"start":{"line":153,"column":8},"end":{"line":153,"column":8}},{"start":{"line":153,"column":8},"end":{"line":153,"column":8}}]},"9":{"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}}]}}},"contracts/modules/chainlink-ace/modified/MintBurnExtractor.sol":{"l":{"34":4,"35":4,"37":4,"38":2,"40":1,"41":1,"43":1,"46":3,"47":3,"48":3,"49":3},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/chainlink-ace/modified/MintBurnExtractor.sol","s":{"1":4,"2":4,"3":4,"4":2,"5":3,"6":3},"b":{"1":[2,2],"2":[1,1],"3":[1,1]},"f":{"1":4},"fnMap":{"1":{"name":"extract","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":50,"column":4}}}},"statementMap":{"1":{"start":{"line":34,"column":8},"end":{"line":34,"column":23}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":22}},"3":{"start":{"line":37,"column":8},"end":{"line":37,"column":1615}},"4":{"start":{"line":39,"column":15},"end":{"line":39,"column":1791}},"5":{"start":{"line":46,"column":8},"end":{"line":46,"column":82}},"6":{"start":{"line":49,"column":8},"end":{"line":49,"column":21}}},"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":37,"type":"cond-expr","locations":[{"start":{"line":37,"column":12},"end":{"line":37,"column":44}},{"start":{"line":37,"column":49},"end":{"line":37,"column":86}}]},"3":{"line":39,"type":"if","locations":[{"start":{"line":39,"column":15},"end":{"line":39,"column":15}},{"start":{"line":39,"column":15},"end":{"line":39,"column":15}}]}}},"contracts/modules/chainlink-ace/modified/PolicyProtectedUpgradeable.sol":{"l":{"32":4374,"38":8,"39":8,"43":71,"52":703,"53":1,"55":702,"56":702,"59":612,"60":593,"61":1,"70":2,"71":1,"73":1,"76":1,"83":7,"84":4,"88":75,"89":74,"90":4,"93":1,"96":74,"97":74,"98":74,"103":1054,"108":3,"113":1752,"118":4,"127":11},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/chainlink-ace/modified/PolicyProtectedUpgradeable.sol","s":{"1":8,"2":8,"3":71,"4":703,"5":702,"6":702,"7":593,"8":1,"9":2,"10":1,"11":7,"12":4,"13":75,"14":74,"15":4,"16":1,"17":74,"18":74,"19":1054,"20":1752,"21":11},"b":{"1":[8,0],"2":[71,0],"3":[1,702],"4":[1,592],"5":[1,1],"6":[74,1],"7":[4,70],"8":[4,0]},"f":{"1":4374,"2":8,"3":71,"4":703,"5":2,"6":7,"7":75,"8":1054,"9":3,"10":1752,"11":4,"12":11},"fnMap":{"1":{"name":"_policyProtectedStorage","line":30,"loc":{"start":{"line":30,"column":4},"end":{"line":35,"column":4}}},"2":{"name":"__PolicyProtected_init","line":37,"loc":{"start":{"line":37,"column":4},"end":{"line":40,"column":4}}},"3":{"name":"__PolicyProtected_init_unchained","line":42,"loc":{"start":{"line":42,"column":4},"end":{"line":44,"column":4}}},"4":{"name":"runPolicy","line":51,"loc":{"start":{"line":51,"column":4},"end":{"line":63,"column":4}}},"5":{"name":"runPolicyWithContext","line":69,"loc":{"start":{"line":69,"column":4},"end":{"line":77,"column":4}}},"6":{"name":"attachPolicyEngine","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":85,"column":4}}},"7":{"name":"_attachPolicyEngine","line":87,"loc":{"start":{"line":87,"column":4},"end":{"line":99,"column":4}}},"8":{"name":"getPolicyEngine","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":104,"column":4}}},"9":{"name":"setContext","line":107,"loc":{"start":{"line":107,"column":4},"end":{"line":109,"column":4}}},"10":{"name":"getContext","line":112,"loc":{"start":{"line":112,"column":4},"end":{"line":114,"column":4}}},"11":{"name":"clearContext","line":117,"loc":{"start":{"line":117,"column":4},"end":{"line":119,"column":4}}},"12":{"name":"supportsInterface","line":124,"loc":{"start":{"line":124,"column":4},"end":{"line":128,"column":4}}}},"statementMap":{"1":{"start":{"line":38,"column":8},"end":{"line":38,"column":22}},"2":{"start":{"line":39,"column":8},"end":{"line":39,"column":53}},"3":{"start":{"line":43,"column":8},"end":{"line":43,"column":40}},"4":{"start":{"line":52,"column":8},"end":{"line":52,"column":2588}},"5":{"start":{"line":55,"column":8},"end":{"line":55,"column":43}},"6":{"start":{"line":56,"column":8},"end":{"line":56,"column":2778}},"7":{"start":{"line":60,"column":8},"end":{"line":60,"column":2965}},"8":{"start":{"line":61,"column":12},"end":{"line":61,"column":25}},"9":{"start":{"line":70,"column":8},"end":{"line":70,"column":3303}},"10":{"start":{"line":73,"column":8},"end":{"line":73,"column":3448}},"11":{"start":{"line":83,"column":8},"end":{"line":83,"column":49}},"12":{"start":{"line":84,"column":8},"end":{"line":84,"column":40}},"13":{"start":{"line":88,"column":8},"end":{"line":88,"column":75}},"14":{"start":{"line":89,"column":8},"end":{"line":89,"column":4090}},"15":{"start":{"line":90,"column":12},"end":{"line":90,"column":4175}},"16":{"start":{"line":93,"column":16},"end":{"line":93,"column":102}},"17":{"start":{"line":97,"column":8},"end":{"line":97,"column":43}},"18":{"start":{"line":98,"column":8},"end":{"line":98,"column":47}},"19":{"start":{"line":103,"column":8},"end":{"line":103,"column":62}},"20":{"start":{"line":113,"column":8},"end":{"line":113,"column":66}},"21":{"start":{"line":127,"column":8},"end":{"line":127,"column":104}}},"branchMap":{"1":{"line":37,"type":"if","locations":[{"start":{"line":37,"column":67},"end":{"line":37,"column":67}},{"start":{"line":37,"column":67},"end":{"line":37,"column":67}}]},"2":{"line":42,"type":"if","locations":[{"start":{"line":42,"column":77},"end":{"line":42,"column":77}},{"start":{"line":42,"column":77},"end":{"line":42,"column":77}}]},"3":{"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}}]},"4":{"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}}]},"5":{"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}}]},"6":{"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}}]},"7":{"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}}]},"8":{"line":127,"type":"cond-expr","locations":[{"start":{"line":127,"column":15},"end":{"line":127,"column":63}},{"start":{"line":127,"column":68},"end":{"line":127,"column":103}}]}}},"contracts/modules/demo/DemoImports.sol":{"l":{},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/demo/DemoImports.sol","s":{},"b":{},"f":{},"fnMap":{},"statementMap":{},"branchMap":{}},"contracts/modules/lite/CCTCMTATBaseERC1404.sol":{"l":{"31":10,"35":1,"37":9,"49":233,"61":35,"72":8,"73":8,"74":1,"75":1,"76":1,"79":7,"85":6},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/lite/CCTCMTATBaseERC1404.sol","s":{"1":10,"2":1,"3":9,"4":233,"5":35,"6":8,"7":8,"8":1,"9":1,"10":1,"11":7,"12":6},"b":{"1":[1,9],"2":[1,7],"3":[1,0]},"f":{"1":10,"2":233,"3":35,"4":8,"5":6},"fnMap":{"1":{"name":"messageForTransferRestriction","line":28,"loc":{"start":{"line":28,"column":4},"end":{"line":39,"column":4}}},"2":{"name":"canTransfer","line":44,"loc":{"start":{"line":44,"column":4},"end":{"line":50,"column":4}}},"3":{"name":"canTransferFrom","line":55,"loc":{"start":{"line":55,"column":4},"end":{"line":62,"column":4}}},"4":{"name":"_detectTransferRestriction","line":67,"loc":{"start":{"line":67,"column":4},"end":{"line":80,"column":4}}},"5":{"name":"supportsInterface","line":82,"loc":{"start":{"line":82,"column":4},"end":{"line":86,"column":4}}}},"statementMap":{"1":{"start":{"line":31,"column":8},"end":{"line":31,"column":1405}},"2":{"start":{"line":35,"column":12},"end":{"line":35,"column":74}},"3":{"start":{"line":37,"column":12},"end":{"line":37,"column":95}},"4":{"start":{"line":49,"column":8},"end":{"line":49,"column":68}},"5":{"start":{"line":61,"column":8},"end":{"line":61,"column":81}},"6":{"start":{"line":72,"column":8},"end":{"line":72,"column":80}},"7":{"start":{"line":73,"column":8},"end":{"line":73,"column":2947}},"8":{"start":{"line":74,"column":12},"end":{"line":74,"column":88}},"9":{"start":{"line":75,"column":12},"end":{"line":75,"column":3082}},"10":{"start":{"line":76,"column":16},"end":{"line":76,"column":114}},"11":{"start":{"line":79,"column":8},"end":{"line":79,"column":88}},"12":{"start":{"line":85,"column":8},"end":{"line":85,"column":70}}},"branchMap":{"1":{"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}}]},"2":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":8},"end":{"line":73,"column":8}},{"start":{"line":73,"column":8},"end":{"line":73,"column":8}}]},"3":{"line":75,"type":"if","locations":[{"start":{"line":75,"column":12},"end":{"line":75,"column":12}},{"start":{"line":75,"column":12},"end":{"line":75,"column":12}}]}}},"contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol":{"l":{"29":119,"35":81,"45":29,"54":731,"55":716,"65":144,"66":120,"77":27,"78":18,"85":3,"92":10,"99":10,"106":12,"132":39,"167":939},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol","s":{"1":119,"2":81,"3":29,"4":731,"5":716,"6":144,"7":120,"8":27,"9":18,"10":3,"11":10,"12":10,"13":12,"14":39,"15":939},"b":{"1":[119,3],"2":[6,3],"3":[9,3],"4":[39,12],"5":[15,3],"6":[9,6],"7":[18,6],"8":[12,6]},"f":{"1":119,"2":81,"3":29,"4":731,"5":144,"6":27,"7":3,"8":10,"9":10,"10":12,"11":9,"12":39,"13":9,"14":12,"15":939},"fnMap":{"1":{"name":"approve","line":28,"loc":{"start":{"line":25,"column":4},"end":{"line":30,"column":4}}},"2":{"name":"transfer","line":31,"loc":{"start":{"line":31,"column":4},"end":{"line":36,"column":4}}},"3":{"name":"transferFrom","line":40,"loc":{"start":{"line":40,"column":4},"end":{"line":46,"column":4}}},"4":{"name":"_mintOverride","line":50,"loc":{"start":{"line":50,"column":4},"end":{"line":56,"column":4}}},"5":{"name":"_burnOverride","line":61,"loc":{"start":{"line":61,"column":4},"end":{"line":67,"column":4}}},"6":{"name":"_minterTransferOverride","line":72,"loc":{"start":{"line":72,"column":4},"end":{"line":79,"column":4}}},"7":{"name":"decimals","line":84,"loc":{"start":{"line":84,"column":4},"end":{"line":86,"column":4}}},"8":{"name":"name","line":91,"loc":{"start":{"line":91,"column":4},"end":{"line":93,"column":4}}},"9":{"name":"symbol","line":98,"loc":{"start":{"line":98,"column":4},"end":{"line":100,"column":4}}},"10":{"name":"supportsInterface","line":103,"loc":{"start":{"line":103,"column":4},"end":{"line":109,"column":4}}},"11":{"name":"_authorizeCCIPSetAdmin","line":120,"loc":{"start":{"line":120,"column":4},"end":{"line":120,"column":106}}},"12":{"name":"_checkTokenBridge","line":131,"loc":{"start":{"line":131,"column":4},"end":{"line":133,"column":4}}},"13":{"name":"_authorizeBurnFrom","line":145,"loc":{"start":{"line":140,"column":4},"end":{"line":146,"column":5}}},"14":{"name":"_authorizeSelfBurn","line":158,"loc":{"start":{"line":153,"column":4},"end":{"line":159,"column":5}}},"15":{"name":"_update","line":162,"loc":{"start":{"line":162,"column":4},"end":{"line":168,"column":4}}}},"statementMap":{"1":{"start":{"line":29,"column":8},"end":{"line":29,"column":55}},"2":{"start":{"line":35,"column":8},"end":{"line":35,"column":50}},"3":{"start":{"line":45,"column":8},"end":{"line":45,"column":60}},"4":{"start":{"line":54,"column":8},"end":{"line":54,"column":64}},"5":{"start":{"line":55,"column":8},"end":{"line":55,"column":60}},"6":{"start":{"line":65,"column":8},"end":{"line":65,"column":64}},"7":{"start":{"line":66,"column":8},"end":{"line":66,"column":60}},"8":{"start":{"line":77,"column":8},"end":{"line":77,"column":53}},"9":{"start":{"line":78,"column":8},"end":{"line":78,"column":71}},"10":{"start":{"line":85,"column":8},"end":{"line":85,"column":41}},"11":{"start":{"line":92,"column":8},"end":{"line":92,"column":37}},"12":{"start":{"line":99,"column":8},"end":{"line":99,"column":39}},"13":{"start":{"line":106,"column":8},"end":{"line":106,"column":3715}},"14":{"start":{"line":132,"column":8},"end":{"line":132,"column":68}},"15":{"start":{"line":167,"column":8},"end":{"line":167,"column":56}}},"branchMap":{"1":{"line":28,"type":"if","locations":[{"start":{"line":28,"column":48},"end":{"line":28,"column":48}},{"start":{"line":28,"column":48},"end":{"line":28,"column":48}}]},"2":{"line":107,"type":"cond-expr","locations":[{"start":{"line":107,"column":12},"end":{"line":107,"column":64}},{"start":{"line":108,"column":12},"end":{"line":108,"column":62}}]},"3":{"line":120,"type":"if","locations":[{"start":{"line":120,"column":76},"end":{"line":120,"column":76}},{"start":{"line":120,"column":76},"end":{"line":120,"column":76}}]},"4":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":96},"end":{"line":131,"column":96}},{"start":{"line":131,"column":96},"end":{"line":131,"column":96}}]},"5":{"line":144,"type":"if","locations":[{"start":{"line":144,"column":8},"end":{"line":144,"column":8}},{"start":{"line":144,"column":8},"end":{"line":144,"column":8}}]},"6":{"line":145,"type":"if","locations":[{"start":{"line":145,"column":8},"end":{"line":145,"column":8}},{"start":{"line":145,"column":8},"end":{"line":145,"column":8}}]},"7":{"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}}]},"8":{"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}}]}}},"contracts/modules/lite/CCTCMTATBasePolicyEngine.sol":{"l":{"51":51,"72":51,"95":51,"98":51,"101":51,"104":51,"107":51,"108":51,"111":51,"121":51,"132":0,"146":233,"147":233,"148":88,"150":145,"163":35,"164":35,"165":12,"167":23,"189":1012,"190":994,"199":6},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/lite/CCTCMTATBasePolicyEngine.sol","s":{"1":51,"2":51,"3":51,"4":51,"5":51,"6":51,"7":51,"8":51,"9":51,"10":51,"11":0,"12":233,"13":233,"14":88,"15":145,"16":35,"17":35,"18":12,"19":23,"20":1012,"21":994,"22":6},"b":{"1":[51,2],"2":[51,0],"3":[51,0],"4":[51,0],"5":[0,0],"6":[88,145],"7":[12,23],"8":[0,0],"9":[99,6],"10":[37,3],"11":[78,9],"12":[918,76],"13":[3,0]},"f":{"1":51,"2":51,"3":51,"4":51,"5":0,"6":233,"7":35,"8":0,"9":99,"10":37,"11":78,"12":1012,"13":6},"fnMap":{"1":{"name":"initialize","line":50,"loc":{"start":{"line":43,"column":4},"end":{"line":59,"column":4}}},"2":{"name":"_initialize","line":71,"loc":{"start":{"line":64,"column":4},"end":{"line":80,"column":4}}},"3":{"name":"__CMTAT_init","line":92,"loc":{"start":{"line":85,"column":4},"end":{"line":112,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":119,"loc":{"start":{"line":117,"column":4},"end":{"line":122,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":131,"loc":{"start":{"line":127,"column":4},"end":{"line":133,"column":4}}},"6":{"name":"canTransfer","line":141,"loc":{"start":{"line":141,"column":4},"end":{"line":152,"column":4}}},"7":{"name":"canTransferFrom","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":169,"column":4}}},"8":{"name":"_authorizeAttachPolicyEngine","line":171,"loc":{"start":{"line":171,"column":4},"end":{"line":171,"column":107}}},"9":{"name":"_authorizePause","line":177,"loc":{"start":{"line":177,"column":4},"end":{"line":177,"column":93}}},"10":{"name":"_authorizeDeactivate","line":178,"loc":{"start":{"line":178,"column":4},"end":{"line":178,"column":105}}},"11":{"name":"_authorizeFreeze","line":180,"loc":{"start":{"line":180,"column":4},"end":{"line":180,"column":102}}},"12":{"name":"_checkTransferred","line":183,"loc":{"start":{"line":183,"column":4},"end":{"line":194,"column":4}}},"13":{"name":"supportsInterface","line":196,"loc":{"start":{"line":196,"column":4},"end":{"line":202,"column":4}}}},"statementMap":{"1":{"start":{"line":51,"column":8},"end":{"line":51,"column":2292}},"2":{"start":{"line":72,"column":8},"end":{"line":72,"column":2920}},"3":{"start":{"line":95,"column":8},"end":{"line":95,"column":33}},"4":{"start":{"line":98,"column":8},"end":{"line":98,"column":32}},"5":{"start":{"line":101,"column":8},"end":{"line":101,"column":60}},"6":{"start":{"line":104,"column":8},"end":{"line":104,"column":97}},"7":{"start":{"line":107,"column":8},"end":{"line":107,"column":61}},"8":{"start":{"line":108,"column":8},"end":{"line":108,"column":61}},"9":{"start":{"line":111,"column":8},"end":{"line":111,"column":54}},"10":{"start":{"line":121,"column":8},"end":{"line":121,"column":77}},"11":{"start":{"line":132,"column":8},"end":{"line":132,"column":97}},"12":{"start":{"line":146,"column":8},"end":{"line":146,"column":90}},"13":{"start":{"line":147,"column":8},"end":{"line":147,"column":5646}},"14":{"start":{"line":148,"column":12},"end":{"line":148,"column":24}},"15":{"start":{"line":150,"column":12},"end":{"line":150,"column":76}},"16":{"start":{"line":163,"column":8},"end":{"line":163,"column":90}},"17":{"start":{"line":164,"column":8},"end":{"line":164,"column":6165}},"18":{"start":{"line":165,"column":12},"end":{"line":165,"column":24}},"19":{"start":{"line":167,"column":12},"end":{"line":167,"column":89}},"20":{"start":{"line":189,"column":8},"end":{"line":189,"column":66}},"21":{"start":{"line":190,"column":8},"end":{"line":190,"column":7278}},"22":{"start":{"line":199,"column":8},"end":{"line":199,"column":7669}}},"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":71,"type":"if","locations":[{"start":{"line":71,"column":23},"end":{"line":71,"column":23}},{"start":{"line":71,"column":23},"end":{"line":71,"column":23}}]},"3":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":23},"end":{"line":92,"column":23}},{"start":{"line":92,"column":23},"end":{"line":92,"column":23}}]},"4":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":23},"end":{"line":119,"column":23}},{"start":{"line":119,"column":23},"end":{"line":119,"column":23}}]},"5":{"line":131,"type":"if","locations":[{"start":{"line":131,"column":23},"end":{"line":131,"column":23}},{"start":{"line":131,"column":23},"end":{"line":131,"column":23}}]},"6":{"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}}]},"7":{"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}}]},"8":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":77},"end":{"line":171,"column":77}},{"start":{"line":171,"column":77},"end":{"line":171,"column":77}}]},"9":{"line":177,"type":"if","locations":[{"start":{"line":177,"column":70},"end":{"line":177,"column":70}},{"start":{"line":177,"column":70},"end":{"line":177,"column":70}}]},"10":{"line":178,"type":"if","locations":[{"start":{"line":178,"column":75},"end":{"line":178,"column":75}},{"start":{"line":178,"column":75},"end":{"line":178,"column":75}}]},"11":{"line":180,"type":"if","locations":[{"start":{"line":180,"column":77},"end":{"line":180,"column":77}},{"start":{"line":180,"column":77},"end":{"line":180,"column":77}}]},"12":{"line":190,"type":"if","locations":[{"start":{"line":190,"column":8},"end":{"line":190,"column":8}},{"start":{"line":190,"column":8},"end":{"line":190,"column":8}}]},"13":{"line":200,"type":"cond-expr","locations":[{"start":{"line":200,"column":12},"end":{"line":200,"column":64}},{"start":{"line":201,"column":12},"end":{"line":201,"column":68}}]}}},"contracts/modules/lite/PolicyValidationModuleERC1404.sol":{"l":{"45":9,"46":2,"48":1,"50":1,"52":1,"54":2,"56":1,"58":1,"75":6,"76":6,"77":5,"79":1,"89":3,"90":1,"92":2,"93":2,"94":1,"96":1,"113":7,"114":1,"116":1,"118":1,"120":2,"122":2},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/lite/PolicyValidationModuleERC1404.sol","s":{"1":9,"2":2,"3":7,"4":1,"5":6,"6":1,"7":5,"8":1,"9":4,"10":2,"11":2,"12":1,"13":1,"14":6,"15":6,"16":5,"17":1,"18":3,"19":1,"20":2,"21":2,"22":1,"23":1,"24":7,"25":1,"26":6,"27":1,"28":5,"29":1,"30":4,"31":2,"32":2},"b":{"1":[2,7],"2":[1,6],"3":[1,5],"4":[1,4],"5":[2,2],"6":[1,1],"7":[5,1],"8":[1,2],"9":[1,1],"10":[1,6],"11":[1,5],"12":[1,4],"13":[2,2]},"f":{"1":9,"2":6,"3":3,"4":7},"fnMap":{"1":{"name":"messageForTransferRestriction","line":42,"loc":{"start":{"line":42,"column":4},"end":{"line":60,"column":4}}},"2":{"name":"detectTransferRestriction","line":70,"loc":{"start":{"line":70,"column":4},"end":{"line":81,"column":4}}},"3":{"name":"detectTransferRestrictionFrom","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":99,"column":4}}},"4":{"name":"_detectTransferRestriction","line":108,"loc":{"start":{"line":108,"column":4},"end":{"line":124,"column":4}}}},"statementMap":{"1":{"start":{"line":45,"column":8},"end":{"line":45,"column":1876}},"2":{"start":{"line":46,"column":12},"end":{"line":46,"column":35}},"3":{"start":{"line":47,"column":15},"end":{"line":47,"column":2007}},"4":{"start":{"line":48,"column":12},"end":{"line":48,"column":48}},"5":{"start":{"line":49,"column":15},"end":{"line":49,"column":2164}},"6":{"start":{"line":50,"column":12},"end":{"line":50,"column":53}},"7":{"start":{"line":51,"column":15},"end":{"line":51,"column":2331}},"8":{"start":{"line":52,"column":12},"end":{"line":52,"column":53}},"9":{"start":{"line":53,"column":15},"end":{"line":53,"column":2498}},"10":{"start":{"line":54,"column":12},"end":{"line":54,"column":51}},"11":{"start":{"line":55,"column":15},"end":{"line":55,"column":2661}},"12":{"start":{"line":56,"column":12},"end":{"line":56,"column":56}},"13":{"start":{"line":58,"column":12},"end":{"line":58,"column":36}},"14":{"start":{"line":75,"column":8},"end":{"line":75,"column":70}},"15":{"start":{"line":76,"column":8},"end":{"line":76,"column":3513}},"16":{"start":{"line":77,"column":12},"end":{"line":77,"column":29}},"17":{"start":{"line":79,"column":12},"end":{"line":79,"column":71}},"18":{"start":{"line":89,"column":8},"end":{"line":89,"column":3940}},"19":{"start":{"line":90,"column":12},"end":{"line":90,"column":92}},"20":{"start":{"line":92,"column":12},"end":{"line":92,"column":74}},"21":{"start":{"line":93,"column":12},"end":{"line":93,"column":4168}},"22":{"start":{"line":94,"column":16},"end":{"line":94,"column":33}},"23":{"start":{"line":96,"column":16},"end":{"line":96,"column":75}},"24":{"start":{"line":113,"column":8},"end":{"line":113,"column":4844}},"25":{"start":{"line":114,"column":12},"end":{"line":114,"column":89}},"26":{"start":{"line":115,"column":15},"end":{"line":115,"column":4971}},"27":{"start":{"line":116,"column":12},"end":{"line":116,"column":84}},"28":{"start":{"line":117,"column":15},"end":{"line":117,"column":5088}},"29":{"start":{"line":118,"column":12},"end":{"line":118,"column":89}},"30":{"start":{"line":119,"column":15},"end":{"line":119,"column":5216}},"31":{"start":{"line":120,"column":12},"end":{"line":120,"column":87}},"32":{"start":{"line":122,"column":12},"end":{"line":122,"column":71}}},"branchMap":{"1":{"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}}]},"2":{"line":47,"type":"if","locations":[{"start":{"line":47,"column":15},"end":{"line":47,"column":15}},{"start":{"line":47,"column":15},"end":{"line":47,"column":15}}]},"3":{"line":49,"type":"if","locations":[{"start":{"line":49,"column":15},"end":{"line":49,"column":15}},{"start":{"line":49,"column":15},"end":{"line":49,"column":15}}]},"4":{"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}}]},"5":{"line":53,"type":"if","locations":[{"start":{"line":53,"column":15},"end":{"line":53,"column":15}},{"start":{"line":53,"column":15},"end":{"line":53,"column":15}}]},"6":{"line":55,"type":"if","locations":[{"start":{"line":55,"column":15},"end":{"line":55,"column":15}},{"start":{"line":55,"column":15},"end":{"line":55,"column":15}}]},"7":{"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}}]},"8":{"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}}]},"9":{"line":93,"type":"if","locations":[{"start":{"line":93,"column":12},"end":{"line":93,"column":12}},{"start":{"line":93,"column":12},"end":{"line":93,"column":12}}]},"10":{"line":113,"type":"if","locations":[{"start":{"line":113,"column":8},"end":{"line":113,"column":8}},{"start":{"line":113,"column":8},"end":{"line":113,"column":8}}]},"11":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":15},"end":{"line":115,"column":15}},{"start":{"line":115,"column":15},"end":{"line":115,"column":15}}]},"12":{"line":117,"type":"if","locations":[{"start":{"line":117,"column":15},"end":{"line":117,"column":15}},{"start":{"line":117,"column":15},"end":{"line":117,"column":15}}]},"13":{"line":119,"type":"if","locations":[{"start":{"line":119,"column":15},"end":{"line":119,"column":15}},{"start":{"line":119,"column":15},"end":{"line":119,"column":15}}]}}},"contracts/modules/lite/ValidationModulePolicyEngine.sol":{"l":{"25":145,"38":23,"46":145,"47":39,"49":106,"59":23,"60":12,"62":11,"72":11,"80":106,"84":118,"85":118,"86":117,"87":117,"92":111,"94":6,"97":1,"108":997,"109":928,"110":928,"111":927,"112":927,"115":920,"116":2,"119":921},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/lite/ValidationModulePolicyEngine.sol","s":{"1":145,"2":23,"3":145,"4":39,"5":106,"6":23,"7":12,"8":11,"9":11,"10":106,"11":118,"12":118,"13":117,"14":117,"15":111,"16":6,"17":1,"18":997,"19":928,"20":928,"21":927,"22":927,"23":920,"24":2,"25":921},"b":{"1":[39,106],"2":[12,11],"3":[117,1],"4":[927,1],"5":[2,918]},"f":{"1":145,"2":23,"3":145,"4":23,"5":11,"6":106,"7":118,"8":997},"fnMap":{"1":{"name":"canTransfer","line":20,"loc":{"start":{"line":20,"column":4},"end":{"line":26,"column":4}}},"2":{"name":"canTransferFrom","line":32,"loc":{"start":{"line":32,"column":4},"end":{"line":39,"column":4}}},"3":{"name":"_canTransfer","line":45,"loc":{"start":{"line":45,"column":4},"end":{"line":51,"column":4}}},"4":{"name":"_canTransferFrom","line":53,"loc":{"start":{"line":53,"column":4},"end":{"line":64,"column":4}}},"5":{"name":"_canTransferFromWithPolicyEngine","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":73,"column":4}}},"6":{"name":"_canTransferWithPolicyEngine","line":75,"loc":{"start":{"line":75,"column":4},"end":{"line":81,"column":4}}},"7":{"name":"_tryCheckPolicies","line":83,"loc":{"start":{"line":83,"column":4},"end":{"line":99,"column":4}}},"8":{"name":"_transferred","line":102,"loc":{"start":{"line":102,"column":4},"end":{"line":120,"column":4}}}},"statementMap":{"1":{"start":{"line":25,"column":8},"end":{"line":25,"column":44}},"2":{"start":{"line":38,"column":8},"end":{"line":38,"column":57}},"3":{"start":{"line":46,"column":8},"end":{"line":46,"column":1793}},"4":{"start":{"line":47,"column":12},"end":{"line":47,"column":24}},"5":{"start":{"line":49,"column":12},"end":{"line":49,"column":64}},"6":{"start":{"line":59,"column":8},"end":{"line":59,"column":2150}},"7":{"start":{"line":60,"column":12},"end":{"line":60,"column":24}},"8":{"start":{"line":62,"column":12},"end":{"line":62,"column":77}},"9":{"start":{"line":72,"column":8},"end":{"line":72,"column":100}},"10":{"start":{"line":80,"column":8},"end":{"line":80,"column":87}},"11":{"start":{"line":84,"column":8},"end":{"line":84,"column":70}},"12":{"start":{"line":85,"column":8},"end":{"line":85,"column":3092}},"13":{"start":{"line":86,"column":12},"end":{"line":86,"column":47}},"14":{"start":{"line":87,"column":12},"end":{"line":87,"column":3201}},"15":{"start":{"line":92,"column":16},"end":{"line":92,"column":27}},"16":{"start":{"line":94,"column":16},"end":{"line":94,"column":28}},"17":{"start":{"line":97,"column":12},"end":{"line":97,"column":23}},"18":{"start":{"line":108,"column":8},"end":{"line":108,"column":62}},"19":{"start":{"line":109,"column":8},"end":{"line":109,"column":70}},"20":{"start":{"line":110,"column":8},"end":{"line":110,"column":3893}},"21":{"start":{"line":111,"column":12},"end":{"line":111,"column":47}},"22":{"start":{"line":112,"column":12},"end":{"line":112,"column":4002}},"23":{"start":{"line":115,"column":12},"end":{"line":115,"column":4167}},"24":{"start":{"line":116,"column":16},"end":{"line":116,"column":29}},"25":{"start":{"line":119,"column":8},"end":{"line":119,"column":19}}},"branchMap":{"1":{"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}}]},"2":{"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}}]},"3":{"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}}]},"4":{"line":110,"type":"if","locations":[{"start":{"line":110,"column":8},"end":{"line":110,"column":8}},{"start":{"line":110,"column":8},"end":{"line":110,"column":8}}]},"5":{"line":115,"type":"if","locations":[{"start":{"line":115,"column":12},"end":{"line":115,"column":12}},{"start":{"line":115,"column":12},"end":{"line":115,"column":12}}]}}},"contracts/modules/standard/CCTCommon.sol":{"l":{"57":12,"75":12,"96":12,"99":12,"102":12,"105":12,"107":12,"110":12,"113":12,"114":12,"124":12,"134":12,"142":12,"148":12,"163":48,"173":12,"184":9,"191":13,"198":10,"204":9,"217":376,"227":48,"238":0,"328":478},"path":"/home/ryan/Pictures/dev/CMTAT-ACE/contracts/modules/standard/CCTCommon.sol","s":{"1":12,"2":12,"3":12,"4":12,"5":12,"6":12,"7":12,"8":12,"9":12,"10":12,"11":12,"12":12,"13":12,"14":12,"15":48,"16":12,"17":9,"18":13,"19":10,"20":9,"21":376,"22":48,"23":0,"24":478},"b":{"1":[12,2],"2":[12,0],"3":[12,0],"4":[12,0],"5":[12,0],"6":[12,0],"7":[48,0],"8":[12,0],"9":[3,3],"10":[3,3],"11":[3,3],"12":[352,24],"13":[33,15],"14":[63,3],"15":[3,3],"16":[48,12],"17":[12,12],"18":[12,3],"19":[3,3],"20":[15,6],"21":[3,3],"22":[3,3]},"f":{"1":12,"2":12,"3":12,"4":12,"5":12,"6":12,"7":48,"8":12,"9":3,"10":9,"11":13,"12":10,"13":9,"14":376,"15":48,"16":0,"17":3,"18":352,"19":33,"20":63,"21":3,"22":48,"23":12,"24":12,"25":3,"26":15,"27":3,"28":3,"29":478},"fnMap":{"1":{"name":"initialize","line":56,"loc":{"start":{"line":49,"column":4},"end":{"line":65,"column":4}}},"2":{"name":"_initialize","line":74,"loc":{"start":{"line":67,"column":4},"end":{"line":83,"column":4}}},"3":{"name":"__CMTAT_init","line":95,"loc":{"start":{"line":88,"column":4},"end":{"line":115,"column":4}}},"4":{"name":"__CMTAT_openzeppelin_init_unchained","line":122,"loc":{"start":{"line":120,"column":4},"end":{"line":125,"column":4}}},"5":{"name":"__CMTAT_modules_init_unchained","line":133,"loc":{"start":{"line":130,"column":4},"end":{"line":135,"column":4}}},"6":{"name":"__CMTAT_commonModules_init_unchained","line":140,"loc":{"start":{"line":137,"column":4},"end":{"line":153,"column":4}}},"7":{"name":"transfer","line":162,"loc":{"start":{"line":159,"column":4},"end":{"line":164,"column":4}}},"8":{"name":"transferFrom","line":172,"loc":{"start":{"line":168,"column":4},"end":{"line":174,"column":4}}},"9":{"name":"_authorizeAttachPolicyEngine","line":176,"loc":{"start":{"line":176,"column":4},"end":{"line":176,"column":88}}},"10":{"name":"decimals","line":183,"loc":{"start":{"line":183,"column":4},"end":{"line":185,"column":4}}},"11":{"name":"name","line":190,"loc":{"start":{"line":190,"column":4},"end":{"line":192,"column":4}}},"12":{"name":"symbol","line":197,"loc":{"start":{"line":197,"column":4},"end":{"line":199,"column":4}}},"13":{"name":"supportsInterface","line":201,"loc":{"start":{"line":201,"column":4},"end":{"line":207,"column":4}}},"14":{"name":"_mintOverride","line":213,"loc":{"start":{"line":213,"column":4},"end":{"line":218,"column":4}}},"15":{"name":"_burnOverride","line":223,"loc":{"start":{"line":223,"column":4},"end":{"line":228,"column":4}}},"16":{"name":"_minterTransferOverride","line":233,"loc":{"start":{"line":233,"column":4},"end":{"line":239,"column":4}}},"17":{"name":"_authorizeERC20AttributeManagement","line":247,"loc":{"start":{"line":247,"column":4},"end":{"line":247,"column":104}}},"18":{"name":"_authorizeMint","line":253,"loc":{"start":{"line":253,"column":4},"end":{"line":253,"column":84}}},"19":{"name":"_authorizeBurn","line":259,"loc":{"start":{"line":259,"column":4},"end":{"line":259,"column":84}}},"20":{"name":"_authorizeDocumentManagement","line":265,"loc":{"start":{"line":265,"column":4},"end":{"line":265,"column":103}}},"21":{"name":"_authorizeExtraInfoManagement","line":271,"loc":{"start":{"line":271,"column":4},"end":{"line":271,"column":106}}},"22":{"name":"_authorizeERC20Enforcer","line":277,"loc":{"start":{"line":277,"column":4},"end":{"line":277,"column":100}}},"23":{"name":"_authorizeForcedTransfer","line":283,"loc":{"start":{"line":283,"column":4},"end":{"line":283,"column":101}}},"24":{"name":"_authorizeSnapshots","line":289,"loc":{"start":{"line":289,"column":4},"end":{"line":289,"column":94}}},"25":{"name":"_authorizeCCIPSetAdmin","line":295,"loc":{"start":{"line":295,"column":4},"end":{"line":295,"column":87}}},"26":{"name":"_checkTokenBridge","line":306,"loc":{"start":{"line":306,"column":4},"end":{"line":306,"column":107}}},"27":{"name":"_authorizeBurnFrom","line":313,"loc":{"start":{"line":313,"column":4},"end":{"line":313,"column":94}}},"28":{"name":"_authorizeSelfBurn","line":320,"loc":{"start":{"line":320,"column":4},"end":{"line":320,"column":94}}},"29":{"name":"_update","line":323,"loc":{"start":{"line":323,"column":4},"end":{"line":329,"column":4}}}},"statementMap":{"1":{"start":{"line":57,"column":8},"end":{"line":57,"column":2274}},"2":{"start":{"line":75,"column":8},"end":{"line":75,"column":2837}},"3":{"start":{"line":96,"column":8},"end":{"line":96,"column":38}},"4":{"start":{"line":99,"column":8},"end":{"line":99,"column":33}},"5":{"start":{"line":102,"column":8},"end":{"line":102,"column":32}},"6":{"start":{"line":105,"column":8},"end":{"line":105,"column":60}},"7":{"start":{"line":107,"column":8},"end":{"line":107,"column":53}},"8":{"start":{"line":110,"column":8},"end":{"line":110,"column":84}},"9":{"start":{"line":113,"column":8},"end":{"line":113,"column":61}},"10":{"start":{"line":114,"column":8},"end":{"line":114,"column":61}},"11":{"start":{"line":124,"column":8},"end":{"line":124,"column":77}},"12":{"start":{"line":134,"column":8},"end":{"line":134,"column":90}},"13":{"start":{"line":142,"column":8},"end":{"line":142,"column":5266}},"14":{"start":{"line":148,"column":8},"end":{"line":148,"column":5465}},"15":{"start":{"line":163,"column":8},"end":{"line":163,"column":50}},"16":{"start":{"line":173,"column":8},"end":{"line":173,"column":60}},"17":{"start":{"line":184,"column":8},"end":{"line":184,"column":41}},"18":{"start":{"line":191,"column":8},"end":{"line":191,"column":37}},"19":{"start":{"line":198,"column":8},"end":{"line":198,"column":39}},"20":{"start":{"line":204,"column":8},"end":{"line":204,"column":7458}},"21":{"start":{"line":217,"column":8},"end":{"line":217,"column":52}},"22":{"start":{"line":227,"column":8},"end":{"line":227,"column":52}},"23":{"start":{"line":238,"column":8},"end":{"line":238,"column":63}},"24":{"start":{"line":328,"column":8},"end":{"line":328,"column":56}}},"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":74,"type":"if","locations":[{"start":{"line":74,"column":23},"end":{"line":74,"column":23}},{"start":{"line":74,"column":23},"end":{"line":74,"column":23}}]},"3":{"line":95,"type":"if","locations":[{"start":{"line":95,"column":23},"end":{"line":95,"column":23}},{"start":{"line":95,"column":23},"end":{"line":95,"column":23}}]},"4":{"line":122,"type":"if","locations":[{"start":{"line":122,"column":23},"end":{"line":122,"column":23}},{"start":{"line":122,"column":23},"end":{"line":122,"column":23}}]},"5":{"line":133,"type":"if","locations":[{"start":{"line":133,"column":23},"end":{"line":133,"column":23}},{"start":{"line":133,"column":23},"end":{"line":133,"column":23}}]},"6":{"line":140,"type":"if","locations":[{"start":{"line":140,"column":23},"end":{"line":140,"column":23}},{"start":{"line":140,"column":23},"end":{"line":140,"column":23}}]},"7":{"line":162,"type":"if","locations":[{"start":{"line":162,"column":65},"end":{"line":162,"column":65}},{"start":{"line":162,"column":65},"end":{"line":162,"column":65}}]},"8":{"line":172,"type":"if","locations":[{"start":{"line":172,"column":65},"end":{"line":172,"column":65}},{"start":{"line":172,"column":65},"end":{"line":172,"column":65}}]},"9":{"line":176,"type":"if","locations":[{"start":{"line":176,"column":77},"end":{"line":176,"column":77}},{"start":{"line":176,"column":77},"end":{"line":176,"column":77}}]},"10":{"line":205,"type":"cond-expr","locations":[{"start":{"line":205,"column":12},"end":{"line":205,"column":64}},{"start":{"line":206,"column":12},"end":{"line":206,"column":69}}]},"11":{"line":247,"type":"if","locations":[{"start":{"line":247,"column":93},"end":{"line":247,"column":93}},{"start":{"line":247,"column":93},"end":{"line":247,"column":93}}]},"12":{"line":253,"type":"if","locations":[{"start":{"line":253,"column":73},"end":{"line":253,"column":73}},{"start":{"line":253,"column":73},"end":{"line":253,"column":73}}]},"13":{"line":259,"type":"if","locations":[{"start":{"line":259,"column":73},"end":{"line":259,"column":73}},{"start":{"line":259,"column":73},"end":{"line":259,"column":73}}]},"14":{"line":265,"type":"if","locations":[{"start":{"line":265,"column":92},"end":{"line":265,"column":92}},{"start":{"line":265,"column":92},"end":{"line":265,"column":92}}]},"15":{"line":271,"type":"if","locations":[{"start":{"line":271,"column":95},"end":{"line":271,"column":95}},{"start":{"line":271,"column":95},"end":{"line":271,"column":95}}]},"16":{"line":277,"type":"if","locations":[{"start":{"line":277,"column":89},"end":{"line":277,"column":89}},{"start":{"line":277,"column":89},"end":{"line":277,"column":89}}]},"17":{"line":283,"type":"if","locations":[{"start":{"line":283,"column":90},"end":{"line":283,"column":90}},{"start":{"line":283,"column":90},"end":{"line":283,"column":90}}]},"18":{"line":289,"type":"if","locations":[{"start":{"line":289,"column":83},"end":{"line":289,"column":83}},{"start":{"line":289,"column":83},"end":{"line":289,"column":83}}]},"19":{"line":295,"type":"if","locations":[{"start":{"line":295,"column":76},"end":{"line":295,"column":76}},{"start":{"line":295,"column":76},"end":{"line":295,"column":76}}]},"20":{"line":306,"type":"if","locations":[{"start":{"line":306,"column":96},"end":{"line":306,"column":96}},{"start":{"line":306,"column":96},"end":{"line":306,"column":96}}]},"21":{"line":313,"type":"if","locations":[{"start":{"line":313,"column":83},"end":{"line":313,"column":83}},{"start":{"line":313,"column":83},"end":{"line":313,"column":83}}]},"22":{"line":320,"type":"if","locations":[{"start":{"line":320,"column":83},"end":{"line":320,"column":83}},{"start":{"line":320,"column":83},"end":{"line":320,"column":83}}]}}}} \ No newline at end of file diff --git a/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol.html b/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol.html new file mode 100644 index 0000000..7c0ca34 --- /dev/null +++ b/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol.html @@ -0,0 +1,194 @@ + + + + Code coverage report for deployment/lite/ComplianceTokenCMTATLiteStandalone.sol + + + + + + + +
+
+

+ all files / deployment/lite/ ComplianceTokenCMTATLiteStandalone.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 +40 +41 +42 +43 +44  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +51× +  +  +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol";
+import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol";
+import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol";
+import {IERC1643} from "CMTAT/interfaces/tokenization/draft-IERC1643.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATLite
+ * @author Chainlink
+ * @notice Standalone Compliance Token contract with Chainlink ACE policy validation on CMTA transfers
+ */
+contract ComplianceTokenCMTATLiteStandalone is CCTCMTATBaseERC20CrossChain {
+    /**
+     * @notice Contract version for standalone deployment
+     * @param admin address of the admin of contract (Access Control)
+     * @param ERC20Attributes_ ERC20 name, symbol and decimals
+     * @param extraInformationAttributes_ tokenId, terms, information
+     * @param policyEngine_ address of the policy engine
+     * @param snapshotEngine_ address of the snapshot engine
+     * @param documentEngine_ address of the document engine
+     */
+    constructor(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) {
+        // Initialize the contract to avoid front-running
+        initialize(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine_,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol.html b/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol.html new file mode 100644 index 0000000..ce8322d --- /dev/null +++ b/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol.html @@ -0,0 +1,149 @@ + + + + Code coverage report for deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol + + + + + + + +
+
+

+ all files / deployment/lite/ ComplianceTokenCMTATLiteUUPSUpgradeable.sol +

+
+
+ 100% + Statements + 1/1 +
+
+ 100% + Branches + 2/2 +
+
+ 100% + Functions + 2/2 +
+
+ 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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
+import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATLiteUUPSUpgradeable
+ * @author Chainlink
+ * @notice UUPS upgradeable lite ComplianceToken contract with Chainlink ACE policy validation on CMTA transfers
+ */
+contract ComplianceTokenCMTATLiteUUPSUpgradeable is CCTCMTATBaseERC20CrossChain, UUPSUpgradeable {
+    bytes32 public constant PROXY_UPGRADE_ROLE = keccak256("PROXY_UPGRADE_ROLE");
+ 
+    /// @custom:oz-upgrades-unsafe-allow constructor
+    constructor() {
+        // Disable the possibility to initialize the implementation
+        _disableInitializers();
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    function _authorizeUpgrade(
+        address newImplementation
+    ) internal virtual override(UUPSUpgradeable) onlyRole(PROXY_UPGRADE_ROLE) {}
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol.html b/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol.html new file mode 100644 index 0000000..eec4f7a --- /dev/null +++ b/doc/coverage/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol.html @@ -0,0 +1,119 @@ + + + + Code coverage report for deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol + + + + + + + +
+
+

+ all files / deployment/lite/ ComplianceTokenCMTATLiteUpgradeable.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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATLite
+ * @author Chainlink
+ * @notice Standalone upgradeable lite Compliance Token contract with Chainlink ACE policy validation on CMTA transfers
+ */
+contract ComplianceTokenCMTATLiteUpgradeable is CCTCMTATBaseERC20CrossChain {
+    /// @custom:oz-upgrades-unsafe-allow constructor
+    constructor() {
+        // Disable the possibility to initialize the implementation
+        _disableInitializers();
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/deployment/lite/index.html b/doc/coverage/deployment/lite/index.html new file mode 100644 index 0000000..f9c1e77 --- /dev/null +++ b/doc/coverage/deployment/lite/index.html @@ -0,0 +1,119 @@ + + + + Code coverage report for deployment/lite/ + + + + + + + +
+
+

+ all files deployment/lite/ +

+
+
+ 100% + Statements + 3/3 +
+
+ 100% + Branches + 2/2 +
+
+ 100% + Functions + 4/4 +
+
+ 100% + Lines + 3/3 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
ComplianceTokenCMTATLiteStandalone.sol
100%1/1100%0/0100%1/1100%1/1
ComplianceTokenCMTATLiteUUPSUpgradeable.sol
100%1/1100%2/2100%2/2100%1/1
ComplianceTokenCMTATLiteUpgradeable.sol
100%1/1100%0/0100%1/1100%1/1
+
+
+ + + + + + + diff --git a/doc/coverage/deployment/standard/ComplianceTokenCMTATStandalone.sol.html b/doc/coverage/deployment/standard/ComplianceTokenCMTATStandalone.sol.html new file mode 100644 index 0000000..b9e2df3 --- /dev/null +++ b/doc/coverage/deployment/standard/ComplianceTokenCMTATStandalone.sol.html @@ -0,0 +1,194 @@ + + + + Code coverage report for deployment/standard/ComplianceTokenCMTATStandalone.sol + + + + + + + +
+
+

+ all files / deployment/standard/ ComplianceTokenCMTATStandalone.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 +40 +41 +42 +43 +44  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCommon} from "../../modules/standard/CCTCommon.sol";
+import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol";
+import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol";
+import {IERC1643} from "CMTAT/interfaces/engine/IDocumentEngine.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATStandalone
+ * @author Chainlink
+ * @notice Standalone ComplianceToken contract with Chainlink ACE policy validation on state-changing operations
+ */
+contract ComplianceTokenCMTATStandalone is CCTCommon {
+    /**
+     * @notice Contract version for standalone deployment
+     * @param admin_ address of the admin/owner
+     * @param ERC20Attributes_ ERC20 name, symbol and decimals
+     * @param extraInformationAttributes_ tokenId, terms, information
+     * @param policyEngine_ address of the policy engine
+     * @param snapshotEngine_ address of the snapshot engine
+     * @param documentEngine_ address of the document engine
+     */
+    constructor(
+        address admin_,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) {
+        // Initialize the contract to avoid front-running
+        initialize(
+            admin_,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine_,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol.html b/doc/coverage/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol.html new file mode 100644 index 0000000..74ea59b --- /dev/null +++ b/doc/coverage/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol.html @@ -0,0 +1,137 @@ + + + + Code coverage report for deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol + + + + + + + +
+
+

+ all files / deployment/standard/ ComplianceTokenCMTATUUPSUpgradeable.sol +

+
+
+ 100% + Statements + 1/1 +
+
+ 100% + Branches + 2/2 +
+
+ 100% + Functions + 2/2 +
+
+ 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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
+import {CCTCommon} from "../../modules/standard/CCTCommon.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATUUPSUpgradeable
+ * @author Chainlink
+ * @notice UUPS upgradeable ComplianceToken contract with Chainlink ACE policy validation on state-changing operations
+ */
+contract ComplianceTokenCMTATUUPSUpgradeable is CCTCommon, UUPSUpgradeable {
+    /// @custom:oz-upgrades-unsafe-allow constructor
+    constructor() {
+        // Disable the possibility to initialize the implementation
+        _disableInitializers();
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyOwner {}
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/deployment/standard/ComplianceTokenCMTATUpgradeable.sol.html b/doc/coverage/deployment/standard/ComplianceTokenCMTATUpgradeable.sol.html new file mode 100644 index 0000000..6160346 --- /dev/null +++ b/doc/coverage/deployment/standard/ComplianceTokenCMTATUpgradeable.sol.html @@ -0,0 +1,119 @@ + + + + Code coverage report for deployment/standard/ComplianceTokenCMTATUpgradeable.sol + + + + + + + +
+
+

+ all files / deployment/standard/ ComplianceTokenCMTATUpgradeable.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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCommon} from "../../modules/standard/CCTCommon.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATUpgradeable
+ * @author Chainlink
+ * @notice Upgradeable ComplianceToken contract with Chainlink ACE policy validation on state-changing operations
+ */
+contract ComplianceTokenCMTATUpgradeable is CCTCommon {
+    /// @custom:oz-upgrades-unsafe-allow constructor
+    constructor() {
+        // Disable the possibility to initialize the implementation
+        _disableInitializers();
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/deployment/standard/index.html b/doc/coverage/deployment/standard/index.html new file mode 100644 index 0000000..9ba79e6 --- /dev/null +++ b/doc/coverage/deployment/standard/index.html @@ -0,0 +1,119 @@ + + + + Code coverage report for deployment/standard/ + + + + + + + +
+
+

+ all files deployment/standard/ +

+
+
+ 100% + Statements + 3/3 +
+
+ 100% + Branches + 2/2 +
+
+ 100% + Functions + 4/4 +
+
+ 100% + Lines + 3/3 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
ComplianceTokenCMTATStandalone.sol
100%1/1100%0/0100%1/1100%1/1
ComplianceTokenCMTATUUPSUpgradeable.sol
100%1/1100%2/2100%2/2100%1/1
ComplianceTokenCMTATUpgradeable.sol
100%1/1100%0/0100%1/1100%1/1
+
+
+ + + + + + + diff --git a/doc/coverage/index.html b/doc/coverage/index.html new file mode 100644 index 0000000..510b328 --- /dev/null +++ b/doc/coverage/index.html @@ -0,0 +1,158 @@ + + + + Code coverage report for All files + + + + + + + +
+
+

+ / +

+
+
+ 94.71% + Statements + 197/208 +
+
+ 85.39% + Branches + 152/178 +
+
+ 86.61% + Functions + 97/112 +
+
+ 94.55% + Lines + 208/220 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
deployment/lite/
100%3/3100%2/2100%4/4100%3/3
deployment/standard/
100%3/3100%2/2100%4/4100%3/3
modules/chainlink-ace/custom/
100%48/4885.71%24/28100%8/898.51%66/67
modules/chainlink-ace/mocks/
62.5%15/2466.67%12/1845.45%10/2264%16/25
modules/lite/
99.06%105/10689.29%75/8495.56%43/4598.98%97/98
modules/standard/
95.83%23/2484.09%37/4496.55%28/2995.83%23/24
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/base.css b/doc/coverage/lcov-report/base.css new file mode 100644 index 0000000..29737bc --- /dev/null +++ b/doc/coverage/lcov-report/base.css @@ -0,0 +1,213 @@ +body, html { + margin:0; padding: 0; + height: 100%; +} +body { + font-family: Helvetica Neue, Helvetica, Arial; + font-size: 14px; + color:#333; +} +.small { font-size: 12px; } +*, *:after, *:before { + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + box-sizing:border-box; + } +h1 { font-size: 20px; margin: 0;} +h2 { font-size: 14px; } +pre { + font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; + margin: 0; + padding: 0; + -moz-tab-size: 2; + -o-tab-size: 2; + tab-size: 2; +} +a { color:#0074D9; text-decoration:none; } +a:hover { text-decoration:underline; } +.strong { font-weight: bold; } +.space-top1 { padding: 10px 0 0 0; } +.pad2y { padding: 20px 0; } +.pad1y { padding: 10px 0; } +.pad2x { padding: 0 20px; } +.pad2 { padding: 20px; } +.pad1 { padding: 10px; } +.space-left2 { padding-left:55px; } +.space-right2 { padding-right:20px; } +.center { text-align:center; } +.clearfix { display:block; } +.clearfix:after { + content:''; + display:block; + height:0; + clear:both; + visibility:hidden; + } +.fl { float: left; } +@media only screen and (max-width:640px) { + .col3 { width:100%; max-width:100%; } + .hide-mobile { display:none!important; } +} + +.quiet { + color: #7f7f7f; + color: rgba(0,0,0,0.5); +} +.quiet a { opacity: 0.7; } + +.fraction { + font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; + font-size: 10px; + color: #555; + background: #E8E8E8; + padding: 4px 5px; + border-radius: 3px; + vertical-align: middle; +} + +div.path a:link, div.path a:visited { color: #333; } +table.coverage { + border-collapse: collapse; + margin: 10px 0 0 0; + padding: 0; +} + +table.coverage td { + margin: 0; + padding: 0; + vertical-align: top; +} +table.coverage td.line-count { + text-align: right; + padding: 0 5px 0 20px; +} +table.coverage td.line-coverage { + text-align: right; + padding-right: 10px; + min-width:20px; +} + +table.coverage td span.cline-any { + display: inline-block; + padding: 0 5px; + width: 100%; +} +.missing-if-branch { + display: inline-block; + margin-right: 5px; + border-radius: 3px; + position: relative; + padding: 0 4px; + background: #333; + color: yellow; +} + +.skip-if-branch { + display: none; + margin-right: 10px; + position: relative; + padding: 0 4px; + background: #ccc; + color: white; +} +.missing-if-branch .typ, .skip-if-branch .typ { + color: inherit !important; +} +.coverage-summary { + border-collapse: collapse; + width: 100%; +} +.coverage-summary tr { border-bottom: 1px solid #bbb; } +.keyline-all { border: 1px solid #ddd; } +.coverage-summary td, .coverage-summary th { padding: 10px; } +.coverage-summary tbody { border: 1px solid #bbb; } +.coverage-summary td { border-right: 1px solid #bbb; } +.coverage-summary td:last-child { border-right: none; } +.coverage-summary th { + text-align: left; + font-weight: normal; + white-space: nowrap; +} +.coverage-summary th.file { border-right: none !important; } +.coverage-summary th.pct { } +.coverage-summary th.pic, +.coverage-summary th.abs, +.coverage-summary td.pct, +.coverage-summary td.abs { text-align: right; } +.coverage-summary td.file { white-space: nowrap; } +.coverage-summary td.pic { min-width: 120px !important; } +.coverage-summary tfoot td { } + +.coverage-summary .sorter { + height: 10px; + width: 7px; + display: inline-block; + margin-left: 0.5em; + background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; +} +.coverage-summary .sorted .sorter { + background-position: 0 -20px; +} +.coverage-summary .sorted-desc .sorter { + background-position: 0 -10px; +} +.status-line { height: 10px; } +/* dark red */ +.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } +.low .chart { border:1px solid #C21F39 } +/* medium red */ +.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } +/* light red */ +.low, .cline-no { background:#FCE1E5 } +/* light green */ +.high, .cline-yes { background:rgb(230,245,208) } +/* medium green */ +.cstat-yes { background:rgb(161,215,106) } +/* dark green */ +.status-line.high, .high .cover-fill { background:rgb(77,146,33) } +.high .chart { border:1px solid rgb(77,146,33) } +/* dark yellow (gold) */ +.medium .chart { border:1px solid #f9cd0b; } +.status-line.medium, .medium .cover-fill { background: #f9cd0b; } +/* light yellow */ +.medium { background: #fff4c2; } +/* light gray */ +span.cline-neutral { background: #eaeaea; } + +.cbranch-no { background: yellow !important; color: #111; } + +.cstat-skip { background: #ddd; color: #111; } +.fstat-skip { background: #ddd; color: #111 !important; } +.cbranch-skip { background: #ddd !important; color: #111; } + + +.cover-fill, .cover-empty { + display:inline-block; + height: 12px; +} +.chart { + line-height: 0; +} +.cover-empty { + background: white; +} +.cover-full { + border-right: none !important; +} +pre.prettyprint { + border: none !important; + padding: 0 !important; + margin: 0 !important; +} +.com { color: #999 !important; } +.ignore-none { color: #999; font-weight: normal; } + +.wrapper { + min-height: 100%; + height: auto !important; + height: 100%; + margin: 0 auto -48px; +} +.footer, .push { + height: 48px; +} diff --git a/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol.html b/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol.html new file mode 100644 index 0000000..7c0ca34 --- /dev/null +++ b/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol.html @@ -0,0 +1,194 @@ + + + + Code coverage report for deployment/lite/ComplianceTokenCMTATLiteStandalone.sol + + + + + + + +
+
+

+ all files / deployment/lite/ ComplianceTokenCMTATLiteStandalone.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 +40 +41 +42 +43 +44  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +51× +  +  +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol";
+import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol";
+import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol";
+import {IERC1643} from "CMTAT/interfaces/tokenization/draft-IERC1643.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATLite
+ * @author Chainlink
+ * @notice Standalone Compliance Token contract with Chainlink ACE policy validation on CMTA transfers
+ */
+contract ComplianceTokenCMTATLiteStandalone is CCTCMTATBaseERC20CrossChain {
+    /**
+     * @notice Contract version for standalone deployment
+     * @param admin address of the admin of contract (Access Control)
+     * @param ERC20Attributes_ ERC20 name, symbol and decimals
+     * @param extraInformationAttributes_ tokenId, terms, information
+     * @param policyEngine_ address of the policy engine
+     * @param snapshotEngine_ address of the snapshot engine
+     * @param documentEngine_ address of the document engine
+     */
+    constructor(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) {
+        // Initialize the contract to avoid front-running
+        initialize(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine_,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol.html b/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol.html new file mode 100644 index 0000000..ce8322d --- /dev/null +++ b/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol.html @@ -0,0 +1,149 @@ + + + + Code coverage report for deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol + + + + + + + +
+
+

+ all files / deployment/lite/ ComplianceTokenCMTATLiteUUPSUpgradeable.sol +

+
+
+ 100% + Statements + 1/1 +
+
+ 100% + Branches + 2/2 +
+
+ 100% + Functions + 2/2 +
+
+ 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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
+import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATLiteUUPSUpgradeable
+ * @author Chainlink
+ * @notice UUPS upgradeable lite ComplianceToken contract with Chainlink ACE policy validation on CMTA transfers
+ */
+contract ComplianceTokenCMTATLiteUUPSUpgradeable is CCTCMTATBaseERC20CrossChain, UUPSUpgradeable {
+    bytes32 public constant PROXY_UPGRADE_ROLE = keccak256("PROXY_UPGRADE_ROLE");
+ 
+    /// @custom:oz-upgrades-unsafe-allow constructor
+    constructor() {
+        // Disable the possibility to initialize the implementation
+        _disableInitializers();
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    function _authorizeUpgrade(
+        address newImplementation
+    ) internal virtual override(UUPSUpgradeable) onlyRole(PROXY_UPGRADE_ROLE) {}
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol.html b/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol.html new file mode 100644 index 0000000..eec4f7a --- /dev/null +++ b/doc/coverage/lcov-report/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol.html @@ -0,0 +1,119 @@ + + + + Code coverage report for deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol + + + + + + + +
+
+

+ all files / deployment/lite/ ComplianceTokenCMTATLiteUpgradeable.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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCMTATBaseERC20CrossChain} from "../../modules/lite/CCTCMTATBaseERC20CrossChain.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATLite
+ * @author Chainlink
+ * @notice Standalone upgradeable lite Compliance Token contract with Chainlink ACE policy validation on CMTA transfers
+ */
+contract ComplianceTokenCMTATLiteUpgradeable is CCTCMTATBaseERC20CrossChain {
+    /// @custom:oz-upgrades-unsafe-allow constructor
+    constructor() {
+        // Disable the possibility to initialize the implementation
+        _disableInitializers();
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/deployment/lite/index.html b/doc/coverage/lcov-report/deployment/lite/index.html new file mode 100644 index 0000000..f9c1e77 --- /dev/null +++ b/doc/coverage/lcov-report/deployment/lite/index.html @@ -0,0 +1,119 @@ + + + + Code coverage report for deployment/lite/ + + + + + + + +
+
+

+ all files deployment/lite/ +

+
+
+ 100% + Statements + 3/3 +
+
+ 100% + Branches + 2/2 +
+
+ 100% + Functions + 4/4 +
+
+ 100% + Lines + 3/3 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
ComplianceTokenCMTATLiteStandalone.sol
100%1/1100%0/0100%1/1100%1/1
ComplianceTokenCMTATLiteUUPSUpgradeable.sol
100%1/1100%2/2100%2/2100%1/1
ComplianceTokenCMTATLiteUpgradeable.sol
100%1/1100%0/0100%1/1100%1/1
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATStandalone.sol.html b/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATStandalone.sol.html new file mode 100644 index 0000000..b9e2df3 --- /dev/null +++ b/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATStandalone.sol.html @@ -0,0 +1,194 @@ + + + + Code coverage report for deployment/standard/ComplianceTokenCMTATStandalone.sol + + + + + + + +
+
+

+ all files / deployment/standard/ ComplianceTokenCMTATStandalone.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 +40 +41 +42 +43 +44  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCommon} from "../../modules/standard/CCTCommon.sol";
+import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol";
+import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol";
+import {IERC1643} from "CMTAT/interfaces/engine/IDocumentEngine.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATStandalone
+ * @author Chainlink
+ * @notice Standalone ComplianceToken contract with Chainlink ACE policy validation on state-changing operations
+ */
+contract ComplianceTokenCMTATStandalone is CCTCommon {
+    /**
+     * @notice Contract version for standalone deployment
+     * @param admin_ address of the admin/owner
+     * @param ERC20Attributes_ ERC20 name, symbol and decimals
+     * @param extraInformationAttributes_ tokenId, terms, information
+     * @param policyEngine_ address of the policy engine
+     * @param snapshotEngine_ address of the snapshot engine
+     * @param documentEngine_ address of the document engine
+     */
+    constructor(
+        address admin_,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) {
+        // Initialize the contract to avoid front-running
+        initialize(
+            admin_,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine_,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol.html b/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol.html new file mode 100644 index 0000000..74ea59b --- /dev/null +++ b/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol.html @@ -0,0 +1,137 @@ + + + + Code coverage report for deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol + + + + + + + +
+
+

+ all files / deployment/standard/ ComplianceTokenCMTATUUPSUpgradeable.sol +

+
+
+ 100% + Statements + 1/1 +
+
+ 100% + Branches + 2/2 +
+
+ 100% + Functions + 2/2 +
+
+ 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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {UUPSUpgradeable} from "@openzeppelin/contracts/proxy/utils/UUPSUpgradeable.sol";
+import {CCTCommon} from "../../modules/standard/CCTCommon.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATUUPSUpgradeable
+ * @author Chainlink
+ * @notice UUPS upgradeable ComplianceToken contract with Chainlink ACE policy validation on state-changing operations
+ */
+contract ComplianceTokenCMTATUUPSUpgradeable is CCTCommon, UUPSUpgradeable {
+    /// @custom:oz-upgrades-unsafe-allow constructor
+    constructor() {
+        // Disable the possibility to initialize the implementation
+        _disableInitializers();
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    function _authorizeUpgrade(address newImplementation) internal virtual override(UUPSUpgradeable) onlyOwner {}
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATUpgradeable.sol.html b/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATUpgradeable.sol.html new file mode 100644 index 0000000..6160346 --- /dev/null +++ b/doc/coverage/lcov-report/deployment/standard/ComplianceTokenCMTATUpgradeable.sol.html @@ -0,0 +1,119 @@ + + + + Code coverage report for deployment/standard/ComplianceTokenCMTATUpgradeable.sol + + + + + + + +
+
+

+ all files / deployment/standard/ ComplianceTokenCMTATUpgradeable.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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCommon} from "../../modules/standard/CCTCommon.sol";
+ 
+/**
+ * @title ComplianceTokenCMTATUpgradeable
+ * @author Chainlink
+ * @notice Upgradeable ComplianceToken contract with Chainlink ACE policy validation on state-changing operations
+ */
+contract ComplianceTokenCMTATUpgradeable is CCTCommon {
+    /// @custom:oz-upgrades-unsafe-allow constructor
+    constructor() {
+        // Disable the possibility to initialize the implementation
+        _disableInitializers();
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/deployment/standard/index.html b/doc/coverage/lcov-report/deployment/standard/index.html new file mode 100644 index 0000000..9ba79e6 --- /dev/null +++ b/doc/coverage/lcov-report/deployment/standard/index.html @@ -0,0 +1,119 @@ + + + + Code coverage report for deployment/standard/ + + + + + + + +
+
+

+ all files deployment/standard/ +

+
+
+ 100% + Statements + 3/3 +
+
+ 100% + Branches + 2/2 +
+
+ 100% + Functions + 4/4 +
+
+ 100% + Lines + 3/3 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
ComplianceTokenCMTATStandalone.sol
100%1/1100%0/0100%1/1100%1/1
ComplianceTokenCMTATUUPSUpgradeable.sol
100%1/1100%2/2100%2/2100%1/1
ComplianceTokenCMTATUpgradeable.sol
100%1/1100%0/0100%1/1100%1/1
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/index.html b/doc/coverage/lcov-report/index.html new file mode 100644 index 0000000..510b328 --- /dev/null +++ b/doc/coverage/lcov-report/index.html @@ -0,0 +1,158 @@ + + + + Code coverage report for All files + + + + + + + +
+
+

+ / +

+
+
+ 94.71% + Statements + 197/208 +
+
+ 85.39% + Branches + 152/178 +
+
+ 86.61% + Functions + 97/112 +
+
+ 94.55% + Lines + 208/220 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
deployment/lite/
100%3/3100%2/2100%4/4100%3/3
deployment/standard/
100%3/3100%2/2100%4/4100%3/3
modules/chainlink-ace/custom/
100%48/4885.71%24/28100%8/898.51%66/67
modules/chainlink-ace/mocks/
62.5%15/2466.67%12/1845.45%10/2264%16/25
modules/lite/
99.06%105/10689.29%75/8495.56%43/4598.98%97/98
modules/standard/
95.83%23/2484.09%37/4496.55%28/2995.83%23/24
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol.html b/doc/coverage/lcov-report/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol.html new file mode 100644 index 0000000..06a67f6 --- /dev/null +++ b/doc/coverage/lcov-report/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol.html @@ -0,0 +1,230 @@ + + + + Code coverage report for modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/custom/ ERC20TransferFromExtractor.sol +

+
+
+ 100% + Statements + 8/8 +
+
+ 75% + Branches + 3/4 +
+
+ 100% + Functions + 1/1 +
+
+ 94.12% + Lines + 16/17 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +34× +34× +34× +34× +  +34× +30× +30× +30× +  + + +  +  +  +  +34× +34× +34× +34× +34× +  +34× +  +  + 
// SPDX-License-Identifier: BUSL-1.1
+pragma solidity ^0.8.20;
+ 
+import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+ 
+/**
+ * @title ERC20TransferFromExtractor
+ * @notice Extends the standard ERC20TransferExtractor by also extracting the
+ *         spender address, enabling policies to validate transferFrom approvals.
+ * @dev Handles:
+ *      - transfer(address to, uint256 amount):
+ *          spender = sender, from = sender, to = decoded, amount = decoded
+ *      - transferFrom(address from, address to, uint256 amount):
+ *          spender = sender, from = decoded, to = decoded, amount = decoded
+ *
+ *      Returns 4 parameters: [spender, from, to, amount]
+ */
+contract ERC20TransferFromExtractor is IExtractor {
+    string public constant override typeAndVersion = "ERC20TransferFromExtractor 1.0.0";
+ 
+    bytes32 public constant PARAM_SPENDER = keccak256("spender");
+    bytes32 public constant PARAM_FROM = keccak256("from");
+    bytes32 public constant PARAM_TO = keccak256("to");
+    bytes32 public constant PARAM_AMOUNT = keccak256("amount");
+ 
+    function extract(
+        IPolicyEngine.Payload calldata payload
+    ) external pure override returns (IPolicyEngine.Parameter[] memory) {
+        address spender;
+        address from;
+        address to;
+        uint256 amount;
+ 
+        if (payload.selector == IERC20.transfer.selector) {
+            spender = payload.sender;
+            from = payload.sender;
+            (to, amount) = abi.decode(payload.data, (address, uint256));
+        } else Eif (payload.selector == IERC20.transferFrom.selector) {
+            spender = payload.sender;
+            (from, to, amount) = abi.decode(payload.data, (address, address, uint256));
+        } else {
+            revert IPolicyEngine.UnsupportedSelector(payload.selector);
+        }
+ 
+        IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](4);
+        result[0] = IPolicyEngine.Parameter(PARAM_SPENDER, abi.encode(spender));
+        result[1] = IPolicyEngine.Parameter(PARAM_FROM, abi.encode(from));
+        result[2] = IPolicyEngine.Parameter(PARAM_TO, abi.encode(to));
+        result[3] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
+ 
+        return result;
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/chainlink-ace/custom/MintBurnExtractor.sol.html b/doc/coverage/lcov-report/modules/chainlink-ace/custom/MintBurnExtractor.sol.html new file mode 100644 index 0000000..19d9657 --- /dev/null +++ b/doc/coverage/lcov-report/modules/chainlink-ace/custom/MintBurnExtractor.sol.html @@ -0,0 +1,218 @@ + + + + Code coverage report for modules/chainlink-ace/custom/MintBurnExtractor.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/custom/ MintBurnExtractor.sol +

+
+
+ 100% + Statements + 6/6 +
+
+ 100% + Branches + 6/6 +
+
+ 100% + Functions + 1/1 +
+
+ 100% + Lines + 11/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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  + + +  + + +  + +  +  + + + + +  +  + 
// SPDX-License-Identifier: BUSL-1.1
+pragma solidity ^0.8.20;
+ 
+import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+ 
+/**
+ * @title MintBurnExtractor
+ * @notice Extracts parameters from CMTAT mint and burn function calls.
+ * @dev Mirrors ComplianceTokenMintBurnExtractor from @chainlink/ace but avoids
+ *      the cross-package relative import of ComplianceTokenERC20 which is
+ *      incompatible with Hardhat's module resolution. Selectors are inlined.
+ *      Handles:
+ *        - mint(address account, uint256 amount)       → 0x40c10f19
+ *        - burnFrom(address account, uint256 amount)   → 0x79cc6790
+ *        - burn(uint256 amount)                        → 0x42966c68
+ */
+contract MintBurnExtractor is IExtractor {
+    string public constant override typeAndVersion = "MintBurnExtractor 1.0.0";
+ 
+    bytes32 public constant PARAM_ACCOUNT = keccak256("account");
+    bytes32 public constant PARAM_AMOUNT = keccak256("amount");
+ 
+    // mint(address,uint256)
+    bytes4 private constant MINT_SELECTOR = bytes4(keccak256("mint(address,uint256)"));
+    // burnFrom(address,uint256)
+    bytes4 private constant BURN_FROM_SELECTOR = bytes4(keccak256("burnFrom(address,uint256)"));
+    // burn(uint256)
+    bytes4 private constant BURN_SELECTOR = bytes4(keccak256("burn(uint256)"));
+ 
+    function extract(
+        IPolicyEngine.Payload calldata payload
+    ) external pure override returns (IPolicyEngine.Parameter[] memory) {
+        address account;
+        uint256 amount;
+ 
+        if (payload.selector == MINT_SELECTOR || payload.selector == BURN_FROM_SELECTOR) {
+            (account, amount) = abi.decode(payload.data, (address, uint256));
+        } else if (payload.selector == BURN_SELECTOR) {
+            account = payload.sender;
+            (amount) = abi.decode(payload.data, (uint256));
+        } else {
+            revert IPolicyEngine.UnsupportedSelector(payload.selector);
+        }
+ 
+        IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](2);
+        result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account));
+        result[1] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
+        return result;
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/chainlink-ace/custom/TransferValidationPolicy.sol.html b/doc/coverage/lcov-report/modules/chainlink-ace/custom/TransferValidationPolicy.sol.html new file mode 100644 index 0000000..d77d463 --- /dev/null +++ b/doc/coverage/lcov-report/modules/chainlink-ace/custom/TransferValidationPolicy.sol.html @@ -0,0 +1,488 @@ + + + + Code coverage report for modules/chainlink-ace/custom/TransferValidationPolicy.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/custom/ TransferValidationPolicy.sol +

+
+
+ 100% + Statements + 34/34 +
+
+ 83.33% + Branches + 15/18 +
+
+ 100% + Functions + 6/6 +
+
+ 100% + Lines + 39/39 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +77× +  +  +  +  +  +  +  +  +  +  +37× +34× +34× +34× +41× +41× +  +  +  +  +  +  +  +  +  + + + + + + +  + +  +  +  +  +  +  + +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +39× +39× +  +39× + +  +  +35× +  +33× +33× +33× +33× +  +33× +35× +35× +13× +13× +  +  +  +  + + + +  + + + + + +  +  +  +  +21× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {Policy} from "@chainlink/policy-management/core/Policy.sol";
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+import {IRule} from "CMTAT/mocks/RuleEngine/interfaces/IRule.sol";
+ 
+/**
+ * @title TransferValidationPolicy
+ * @notice A policy that validates ERC-20 transfers by running an array of IRule
+ *         contracts, mimicking CMTAT's _canTransferWithRuleEngine() behavior.
+ * @dev Works with both ERC20TransferExtractor (3 params) and
+ *      ERC20TransferFromExtractor (4 params):
+ *
+ *      3 parameters: [from, to, amount]
+ *        → uses detectTransferRestriction(from, to, amount)
+ *
+ *      4 parameters: [spender, from, to, amount]
+ *        → uses detectTransferRestrictionFrom(spender, from, to, amount)
+ *
+ *      Each IRule is checked in order. If any rule returns a non-zero code
+ *      the policy reverts with PolicyRejected containing the rule's message.
+ */
+contract TransferValidationPolicy is Policy {
+    error InvalidParametersLength(uint256 length);
+ 
+    string public constant override typeAndVersion = "TransferValidationPolicy 1.0.0";
+    event RulesUpdated(uint256 previousCount, uint256 newCount);
+ 
+    /// @custom:storage-location erc7201:cmta.TransferValidationPolicy
+    struct TransferValidationStorage {
+        IRule[] rules;
+    }
+ 
+    // keccak256(abi.encode(uint256(keccak256("cmta.TransferValidationPolicy")) - 1)) & ~bytes32(uint256(0xff))
+    bytes32 private constant STORAGE_LOCATION = 0xd90ded5881f9295c61e86b2e3b551acbb5fe06f9f79d0cec87ddc5bb60d48e00;
+ 
+    function _getStorage() private pure returns (TransferValidationStorage storage $) {
+        assembly {
+            $.slot := STORAGE_LOCATION
+        }
+    }
+ 
+    /**
+     * @inheritdoc Policy
+     * @dev Decodes an array of IRule addresses to set as initial rules.
+     *      Pass empty bytes if no initial rules are needed.
+     */
+    function configure(bytes calldata parameters) internal override EonlyInitializing {
+        if (parameters.length > 0) {
+            address[] memory ruleAddrs = abi.decode(parameters, (address[]));
+            TransferValidationStorage storage $ = _getStorage();
+            for (uint256 i = 0; i < ruleAddrs.length; ++i) {
+                Erequire(ruleAddrs[i] != address(0), "Rule address cannot be zero");
+                $.rules.push(IRule(ruleAddrs[i]));
+            }
+        }
+    }
+ 
+    /**
+     * @notice Replaces all rules with a new set.
+     * @param rules_ The new array of IRule contracts.
+     */
+    function setRules(IRule[] calldata rules_) external onlyOwner {
+        TransferValidationStorage storage $ = _getStorage();
+        uint256 previousCount = $.rules.length;
+        delete $.rules;
+        for (uint256 i = 0; i < rules_.length; ++i) {
+            Erequire(address(rules_[i]) != address(0), "Rule address cannot be zero");
+            $.rules.push(rules_[i]);
+        }
+        emit RulesUpdated(previousCount, rules_.length);
+    }
+ 
+    /**
+     * @notice Returns the current rules.
+     */
+    function rules() external view returns (IRule[] memory) {
+        return _getStorage().rules;
+    }
+ 
+    /**
+     * @notice Returns the number of rules.
+     */
+    function rulesCount() external view returns (uint256) {
+        return _getStorage().rules.length;
+    }
+ 
+    /**
+     * @inheritdoc Policy
+     * @dev Supports both 3-param (transfer) and 4-param (transferFrom) layouts.
+     *      With 4 parameters, uses detectTransferRestrictionFrom to also validate
+     *      the spender.
+     */
+    function run(
+        address /* caller */,
+        address /* subject */,
+        bytes4 /* selector */,
+        bytes[] calldata parameters,
+        bytes calldata /* context */
+    ) public view override returns (IPolicyEngine.PolicyResult) {
+        TransferValidationStorage storage $ = _getStorage();
+        uint256 len = $.rules.length;
+ 
+        if (parameters.length != 3 && parameters.length != 4) {
+            revert InvalidParametersLength(parameters.length);
+        }
+ 
+        if (parameters.length == 4) {
+            // ERC20TransferFromExtractor layout: [spender, from, to, amount]
+            address spender = abi.decode(parameters[0], (address));
+            address from = abi.decode(parameters[1], (address));
+            address to = abi.decode(parameters[2], (address));
+            uint256 amount = abi.decode(parameters[3], (uint256));
+ 
+            for (uint256 i = 0; i < len; ++i) {
+                uint8 code = $.rules[i].detectTransferRestrictionFrom(spender, from, to, amount);
+                if (code != 0) {
+                    string memory message = $.rules[i].messageForTransferRestriction(code);
+                    revert IPolicyEngine.PolicyRejected(message);
+                }
+            }
+        } else {
+            // ERC20TransferExtractor layout: [from, to, amount]
+            address from = abi.decode(parameters[0], (address));
+            address to = abi.decode(parameters[1], (address));
+            uint256 amount = abi.decode(parameters[2], (uint256));
+ 
+            for (uint256 i = 0; i < len; ++i) {
+                uint8 code = $.rules[i].detectTransferRestriction(from, to, amount);
+                if (code != 0) {
+                    string memory message = $.rules[i].messageForTransferRestriction(code);
+                    revert IPolicyEngine.PolicyRejected(message);
+                }
+            }
+        }
+ 
+        return IPolicyEngine.PolicyResult.Continue;
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/chainlink-ace/custom/index.html b/doc/coverage/lcov-report/modules/chainlink-ace/custom/index.html new file mode 100644 index 0000000..0c49bff --- /dev/null +++ b/doc/coverage/lcov-report/modules/chainlink-ace/custom/index.html @@ -0,0 +1,119 @@ + + + + Code coverage report for modules/chainlink-ace/custom/ + + + + + + + +
+
+

+ all files modules/chainlink-ace/custom/ +

+
+
+ 100% + Statements + 48/48 +
+
+ 85.71% + Branches + 24/28 +
+
+ 100% + Functions + 8/8 +
+
+ 98.51% + Lines + 66/67 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
ERC20TransferFromExtractor.sol
100%8/875%3/4100%1/194.12%16/17
MintBurnExtractor.sol
100%6/6100%6/6100%1/1100%11/11
TransferValidationPolicy.sol
100%34/3483.33%15/18100%6/6100%39/39
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol.html b/doc/coverage/lcov-report/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol.html new file mode 100644 index 0000000..db0ea57 --- /dev/null +++ b/doc/coverage/lcov-report/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol.html @@ -0,0 +1,374 @@ + + + + Code coverage report for modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/mocks/ PolicyProtectedUpgradeableMocks.sol +

+
+
+ 30% + Statements + 3/10 +
+
+ 25% + Branches + 1/4 +
+
+ 18.52% + Functions + 5/27 +
+
+ 35.71% + Lines + 5/14 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  + +  + 
// SPDX-License-Identifier: BUSL-1.1
+pragma solidity ^0.8.20;
+ 
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+import {ValidationModulePolicyEngine} from "../../lite/ValidationModulePolicyEngine.sol";
+ 
+contract MockPolicyEngine is IPolicyEngine {
+    Payload public lastPayload;
+    uint256 public attachCalls;
+    uint256 public detachCalls;
+    bool public detachShouldRevert;
+ 
+    function setDetachShouldRevert(bool value) external {
+        detachShouldRevert = value;
+    }
+ 
+    function typeAndVersion() external pure override returns (string memory) {
+        return "MockPolicyEngine 1.0.0";
+    }
+ 
+    function attach() external override {
+        attachCalls++;
+    }
+ 
+    function detach() external override {
+        detachCalls++;
+        if (detachShouldRevert) {
+            revert("MockPolicyEngine: detach failed");
+        }
+    }
+ 
+    function run(Payload calldata payload) external override {
+        lastPayload = payload;
+    }
+ 
+    function check(Payload calldata) external pure override {}
+ 
+    function setExtractor(bytes4, address) external pure override {}
+ 
+    function setExtractors(bytes4[] calldata, address) external pure override {}
+ 
+    function getExtractor(bytes4) external pure override returns (address) {
+        return address(0);
+    }
+ 
+    function setPolicyMapper(address, address) external pure override {}
+ 
+    function getPolicyMapper(address) external pure override returns (address) {
+        return address(0);
+    }
+ 
+    function addPolicy(address, bytes4, address, bytes32[] calldata) external pure override {}
+ 
+    function addPolicyAt(address, bytes4, address, bytes32[] calldata, uint256) external pure override {}
+ 
+    function removePolicy(address, bytes4, address) external pure override {}
+ 
+    function getPolicies(address, bytes4) external pure override returns (address[] memory) {
+        return new address[](0);
+    }
+ 
+    function setPolicyConfiguration(address, uint256, bytes4, bytes calldata) external pure override {}
+ 
+    function getPolicyConfigVersion(address) external pure override returns (uint256) {
+        return 0;
+    }
+ 
+    function upgradePolicy(address, address, bytes calldata) external pure override {}
+ 
+    function setDefaultPolicyAllow(bool) external pure override {}
+ 
+    function setTargetDefaultPolicyAllow(address, bool) external pure override {}
+}
+ 
+contract ValidationModulePolicyEngineHarness is ValidationModulePolicyEngine {
+    function initializeWithPolicyEngine(address policyEngine) external Einitializer {
+        __PolicyProtectedBase_init(policyEngine);
+    }
+ 
+    function _authorizeAttachPolicyEngine(address) internal pure override {}
+ 
+    function _authorizePause() internal pure override {}
+ 
+    function _authorizeDeactivate() internal pure override {}
+ 
+    function _authorizeFreeze() internal pure override {}
+ 
+    function exposedTryCheckPolicies(
+        bytes4 selector,
+        address sender,
+        bytes calldata data
+    ) external view returns (bool) {
+        return _tryCheckPolicies(selector, sender, data);
+    }
+ 
+    function exposedTransferred(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) external returns (bool) {
+        return _transferred(spender, from, to, value);
+    }
+}
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/chainlink-ace/mocks/TransferRuleMocks.sol.html b/doc/coverage/lcov-report/modules/chainlink-ace/mocks/TransferRuleMocks.sol.html new file mode 100644 index 0000000..d47d98b --- /dev/null +++ b/doc/coverage/lcov-report/modules/chainlink-ace/mocks/TransferRuleMocks.sol.html @@ -0,0 +1,536 @@ + + + + Code coverage report for modules/chainlink-ace/mocks/TransferRuleMocks.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/mocks/ TransferRuleMocks.sol +

+
+
+ 62.5% + Statements + 15/24 +
+
+ 66.67% + Branches + 12/18 +
+
+ 45.45% + Functions + 10/22 +
+
+ 64% + Lines + 16/25 +
+
+
+
+

+
+
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 +156 +157 +158  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +30× +  +  +  +  +  +  +  +25× +  +  +  +  +  +  +  +  +23× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  +  +  +14× +14× +12× +  +  +  +  + +  +  +  +  +  +  +  +12× +10× + +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {IRule} from "../../../../submodules/RuleEngine/src/interfaces/IRule.sol";
+ 
+/**
+ * @dev WARNING: Mock rule contracts for tests/examples only.
+ *      Not designed, reviewed, or hardened for production deployments.
+ */
+ 
+/**
+ * @title MaxAmountRule
+ * @notice Rejects transfers where the amount exceeds a configurable maximum.
+ */
+contract MaxAmountRule is IRule {
+    uint256 public immutable maxAmount;
+    uint8 constant AMOUNT_TOO_HIGH = 13;
+ 
+    constructor(uint256 maxAmount_) {
+        maxAmount = maxAmount_;
+    }
+ 
+    function detectTransferRestriction(
+        address /* from */,
+        address /* to */,
+        uint256 amount
+    ) public view override returns (uint8) {
+        return amount > maxAmount ? AMOUNT_TOO_HIGH : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+    }
+ 
+    function detectTransferRestrictionFrom(
+        address /* spender */,
+        address from,
+        address to,
+        uint256 amount
+    ) public view override returns (uint8) {
+        return detectTransferRestriction(from, to, amount);
+    }
+ 
+    function canTransfer(address from, address to, uint256 amount) public view override returns (bool) {
+        return detectTransferRestriction(from, to, amount) == 0;
+    }
+ 
+     function canTransferFrom(
+        address /* spender */,
+        address from,
+        address to,
+        uint256 amount
+    ) external view override returns (bool) {
+        return canTransfer(from, to, amount);
+    }
+ 
+    function transferred(address /* from */, address /* to */, uint256 /* value */) external pure override {}
+ 
+    function transferred(
+        address /* spender */,
+        address /* from */,
+        address /* to */,
+        uint256 /* value */
+    ) external pure override {}
+ 
+    function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
+        return interfaceId == type(IRule).interfaceId;
+    }
+ 
+    function canReturnTransferRestrictionCode(uint8 code) public pure override returns (bool) {
+        return code == AMOUNT_TOO_HIGH;
+    }
+ 
+    function messageForTransferRestriction(uint8 code) external pure override returns (string memory) {
+        return code == AMOUNT_TOO_HIGH ? "Amount exceeds maximum" : E"Unknown code";
+    }
+}
+ 
+/**
+ * @title RestrictedAddressRule
+ * @notice Rejects transfers involving addresses on a restricted list.
+ */
+contract RestrictedAddressRule is IRule {
+    uint8 constant FROM_RESTRICTED = 14;
+    uint8 constant TO_RESTRICTED = 15;
+ 
+    mapping(address => bool) public restricted;
+    address public immutable owner;
+ 
+    modifier onlyOwner() {
+        Erequire(msg.sender == owner, "only owner");
+        _;
+    }
+ 
+    constructor(address[] memory restricted_) {
+        owner = msg.sender;
+        for (uint256 i = 0; i < restricted_.length; ++i) {
+            restricted[restricted_[i]] = true;
+        }
+    }
+ 
+    function setRestricted(address account, bool status) external EonlyOwner {
+        restricted[account] = status;
+    }
+ 
+    function detectTransferRestriction(
+        address from,
+        address to,
+        uint256 /* amount */
+    ) public view override returns (uint8) {
+        if (restricted[from]) return FROM_RESTRICTED;
+        if (restricted[to]) return TO_RESTRICTED;
+        return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+    }
+ 
+    function detectTransferRestrictionFrom(
+        address /* spender */,
+        address from,
+        address to,
+        uint256 amount
+    ) public view override returns (uint8) {
+        return detectTransferRestriction(from, to, amount);
+    }
+ 
+    function canTransfer(address from, address to, uint256 amount) public view override returns (bool) {
+        return detectTransferRestriction(from, to, amount) == 0;
+    }
+ 
+    function canTransferFrom(
+        address /* spender */,
+        address from,
+        address to,
+        uint256 amount
+    ) external view override returns (bool) {
+        return canTransfer(from, to, amount);
+    }
+ 
+    function transferred(address /* from */, address /* to */, uint256 /* value */) external pure override {}
+ 
+    function transferred(
+        address /* spender */,
+        address /* from */,
+        address /* to */,
+        uint256 /* value */
+    ) external pure override {}
+ 
+    function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
+        return interfaceId == type(IRule).interfaceId;
+    }
+ 
+    function canReturnTransferRestrictionCode(uint8 code) public pure override returns (bool) {
+        return code == FROM_RESTRICTED || code == TO_RESTRICTED;
+    }
+ 
+    function messageForTransferRestriction(uint8 code) external pure override returns (string memory) {
+        if (code == FROM_RESTRICTED) return "Sender is restricted";
+        Eif (code == TO_RESTRICTED) return "Recipient is restricted";
+        return "Unknown code";
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/chainlink-ace/mocks/index.html b/doc/coverage/lcov-report/modules/chainlink-ace/mocks/index.html new file mode 100644 index 0000000..43b901a --- /dev/null +++ b/doc/coverage/lcov-report/modules/chainlink-ace/mocks/index.html @@ -0,0 +1,93 @@ + + + + Code coverage report for modules/chainlink-ace/mocks/ + + + + + + + +
+
+

+ all files modules/chainlink-ace/mocks/ +

+
+
+ 62.5% + Statements + 15/24 +
+
+ 66.67% + Branches + 12/18 +
+
+ 45.45% + Functions + 10/22 +
+
+ 64% + Lines + 16/25 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
TransferRuleMocks.sol
62.5%15/2466.67%12/1845.45%10/2264%16/25
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/lite/CCTCMTATBaseERC1404.sol.html b/doc/coverage/lcov-report/modules/lite/CCTCMTATBaseERC1404.sol.html new file mode 100644 index 0000000..44fc278 --- /dev/null +++ b/doc/coverage/lcov-report/modules/lite/CCTCMTATBaseERC1404.sol.html @@ -0,0 +1,323 @@ + + + + Code coverage report for modules/lite/CCTCMTATBaseERC1404.sol + + + + + + + +
+
+

+ all files / modules/lite/ CCTCMTATBaseERC1404.sol +

+
+
+ 100% + Statements + 12/12 +
+
+ 83.33% + Branches + 5/6 +
+
+ 100% + Functions + 5/5 +
+
+ 100% + Lines + 12/12 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +10× +  +  +  + +  + +  +  +  +  +  +  +  +  +  +  +  +233× +  +  +  +  +  +  +  +  +  +  +  +35× +  +  +  +  +  +  +  +  +  +  + + + + + +  +  + +  +  +  +  +  + +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCMTATBasePolicyEngine} from "./CCTCMTATBasePolicyEngine.sol";
+import {PolicyValidationModuleERC1404, IERC1404, IERC1404Extend} from "./PolicyValidationModuleERC1404.sol";
+import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {
+    ERC20EnforcementModule,
+    ERC20EnforcementModuleInternal
+} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol";
+ 
+abstract contract CCTCMTATBaseERC1404 is CCTCMTATBasePolicyEngine, PolicyValidationModuleERC1404 {
+    /**
+     * @dev ERC20EnforcementModule error text
+     */
+    string internal constant TEXT_TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE =
+        "AddrFrom:insufficientActiveBalance";
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+ 
+    /**
+     * @inheritdoc PolicyValidationModuleERC1404
+     */
+    function messageForTransferRestriction(
+        uint8 restrictionCode
+    ) public view virtual override(PolicyValidationModuleERC1404) returns (string memory message) {
+        if (
+            restrictionCode ==
+            uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE)
+        ) {
+            return TEXT_TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE;
+        } else {
+            return PolicyValidationModuleERC1404.messageForTransferRestriction(restrictionCode);
+        }
+    }
+ 
+    /**
+     * @inheritdoc CCTCMTATBasePolicyEngine
+     */
+    function canTransfer(
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(CCTCMTATBasePolicyEngine, ValidationModuleCore) returns (bool) {
+        return CCTCMTATBasePolicyEngine.canTransfer(from, to, value);
+    }
+ 
+    /**
+     * @inheritdoc CCTCMTATBasePolicyEngine
+     */
+    function canTransferFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(CCTCMTATBasePolicyEngine, ValidationModuleCore) returns (bool) {
+        return CCTCMTATBasePolicyEngine.canTransferFrom(spender, from, to, value);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    function _detectTransferRestriction(
+        address from,
+        address to,
+        uint256 value
+    ) internal view virtual override(PolicyValidationModuleERC1404) returns (uint8 code) {
+        uint256 frozenTokensLocal = ERC20EnforcementModule.getFrozenTokens(from);
+        if (frozenTokensLocal > 0) {
+            uint256 activeBalance = ERC20Upgradeable.balanceOf(from) - frozenTokensLocal;
+            Eif (value > activeBalance) {
+                return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE);
+            }
+        }
+        return PolicyValidationModuleERC1404._detectTransferRestriction(from, to, value);
+    }
+ 
+    function supportsInterface(
+        bytes4 interfaceId
+    ) public view virtual override(CCTCMTATBasePolicyEngine) returns (bool) {
+        return CCTCMTATBasePolicyEngine.supportsInterface(interfaceId);
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/lite/CCTCMTATBaseERC20CrossChain.sol.html b/doc/coverage/lcov-report/modules/lite/CCTCMTATBaseERC20CrossChain.sol.html new file mode 100644 index 0000000..ce0c13d --- /dev/null +++ b/doc/coverage/lcov-report/modules/lite/CCTCMTATBaseERC20CrossChain.sol.html @@ -0,0 +1,572 @@ + + + + Code coverage report for modules/lite/CCTCMTATBaseERC20CrossChain.sol + + + + + + + +
+
+

+ all files / modules/lite/ CCTCMTATBaseERC20CrossChain.sol +

+
+
+ 100% + Statements + 15/15 +
+
+ 100% + Branches + 16/16 +
+
+ 100% + Functions + 15/15 +
+
+ 100% + Lines + 15/15 +
+
+
+
+

+
+
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 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +119× +  +  +  +  +  +81× +  +  +  +  +  +  +  +  +  +29× +  +  +  +  +  +  +  +  +735× +720× +  +  +  +  +  +  +  +  +  +144× +120× +  +  +  +  +  +  +  +  +  +  +27× +18× +  +  +  +  +  +  + +  +  +  +  +  +  +10× +  +  +  +  +  +  +10× +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +39× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +943× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {ERC20CrossChainModule} from "CMTAT/modules/wrapper/options/ERC20CrossChainModule.sol";
+import {CCIPModule} from "CMTAT/modules/wrapper/options/CCIPModule.sol";
+import {CCTCMTATBaseERC1404} from "./CCTCMTATBaseERC1404.sol";
+import {CMTATBaseCommon} from "CMTAT/modules/0_CMTATBaseCommon.sol";
+import {
+    ERC20MintModule,
+    ERC20MintModuleInternal
+} from "CMTAT/modules/wrapper/core/ERC20MintModule.sol";
+import {
+    ERC20BurnModule,
+    ERC20BurnModuleInternal
+} from "CMTAT/modules/wrapper/core/ERC20BurnModule.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
+ 
+abstract contract CCTCMTATBaseERC20CrossChain is ERC20CrossChainModule, CCIPModule, CCTCMTATBaseERC1404 {
+    /* ============  State Functions ============ */
+    /**
+     * @dev revert if the contract is in pause state
+     */
+    function approve(
+        address spender,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) {
+        return ERC20Upgradeable.approve(spender, value);
+    }
+    function transfer(
+        address to,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (bool) {
+        return CMTATBaseCommon.transfer(to, value);
+    }
+    /*
+     * @inheritdoc ERC20BaseModule
+     */
+    function transferFrom(
+        address from,
+        address to,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (bool) {
+        return CMTATBaseCommon.transferFrom(from, to, value);
+    }
+    /**
+     * @dev Check if the mint is valid
+     */
+    function _mintOverride(
+        address account,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
+        _checkTransferred(address(0), address(0), account, value);
+        ERC20MintModuleInternal._mintOverride(account, value);
+    }
+ 
+    /**
+     * @dev Check if the burn is valid
+     */
+    function _burnOverride(
+        address account,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) {
+        _checkTransferred(address(0), account, address(0), value);
+        ERC20BurnModuleInternal._burnOverride(account, value);
+    }
+ 
+    /**
+     * @dev Check if a minter transfer is valid
+     */
+    function _minterTransferOverride(
+        address from,
+        address to,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
+        _checkTransferred(address(0), from, to, value);
+        ERC20MintModuleInternal._minterTransferOverride(from, to, value);
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function decimals() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (uint8) {
+        return CMTATBaseCommon.decimals();
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function name() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) {
+        return CMTATBaseCommon.name();
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function symbol() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) {
+        return CMTATBaseCommon.symbol();
+    }
+ 
+    /* ============ View functions ============ */
+    function supportsInterface(
+        bytes4 _interfaceId
+    ) public view virtual override(ERC20CrossChainModule, CCTCMTATBaseERC1404) returns (bool) {
+        return
+            ERC20CrossChainModule.supportsInterface(_interfaceId) ||
+            CCTCMTATBaseERC1404.supportsInterface(_interfaceId);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ==== Access Control ==== */
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DEFAULT_ADMIN_ROLE`.
+     */
+    function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {}
+ 
+    /**
+     * @dev
+     * A cross-chain bridge could call the OpenZeppelin function `renounceRole` to lose their privileges (CROSS_CHAIN_ROLE)
+     * While it is not intended,this has no other effect than depriving the bridge of burn/mint tokens
+     * An attacker could use this to disrupt minting/burning if they can get the bridge to execute calls.
+     * However, in this case, the bridge should still be considered compromised and not used again.
+     * @custom:access-control
+     * - the caller must have the `CROSS_CHAIN_ROLE`.
+     */
+    function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule) whenNotPaused {
+        AccessControlUpgradeable._checkRole(CROSS_CHAIN_ROLE, caller);
+    }
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `BURNER_FROM_ROLE`.
+     * - We don't allow token holder to burn their own tokens if they don't have this role.
+     */
+    function _authorizeBurnFrom()
+        internal
+        virtual
+        override(ERC20CrossChainModule)
+        onlyRole(BURNER_FROM_ROLE)
+        whenNotPaused
+    {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `BURNER_SELF_ROLE`.
+     * - We don't allow token holder to burn their own tokens if they don't have this role.
+     */
+    function _authorizeSelfBurn()
+        internal
+        virtual
+        override(ERC20CrossChainModule)
+        onlyRole(BURNER_SELF_ROLE)
+        whenNotPaused
+    {}
+ 
+    /* ==== ERC-20 OpenZeppelin ==== */
+    function _update(
+        address from,
+        address to,
+        uint256 amount
+    ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) {
+        return CMTATBaseCommon._update(from, to, amount);
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/lite/CCTCMTATBasePolicyEngine.sol.html b/doc/coverage/lcov-report/modules/lite/CCTCMTATBasePolicyEngine.sol.html new file mode 100644 index 0000000..f2e3cf8 --- /dev/null +++ b/doc/coverage/lcov-report/modules/lite/CCTCMTATBasePolicyEngine.sol.html @@ -0,0 +1,674 @@ + + + + Code coverage report for modules/lite/CCTCMTATBasePolicyEngine.sol + + + + + + + +
+
+

+ all files / modules/lite/ CCTCMTATBasePolicyEngine.sol +

+
+
+ 95.45% + Statements + 21/22 +
+
+ 69.23% + Branches + 18/26 +
+
+ 84.62% + Functions + 11/13 +
+
+ 95.45% + Lines + 21/22 +
+
+
+
+

+
+
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 +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 +203 +204  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +55× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +55× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +55× +  +  +55× +  +  +55× +  +  +55× +  +  +55× +55× +  +  +55× +  +  +  +  +  +  +  +  +  +55× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +233× +233× +88× +  +145× +  +  +  +  +  +  +  +  +  +  +  +  +35× +35× +12× +  +23× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1016× +998× +  +  +  +  +  +  +  +  + +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {
+    CMTATBaseCommon,
+    CMTATBaseAccessControl
+} from "CMTAT/modules/1_CMTATBaseAccessControl.sol";
+import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol";
+import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol";
+import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol";
+import {IERC1643} from "CMTAT/interfaces/tokenization/draft-IERC1643.sol";
+import {ValidationModulePolicyEngine} from "./ValidationModulePolicyEngine.sol";
+import {PauseModule} from "CMTAT/modules/wrapper/core/PauseModule.sol";
+import {EnforcementModule} from "CMTAT/modules/wrapper/core/EnforcementModule.sol";
+import {IERC7943FungibleTransferError} from "CMTAT/interfaces/tokenization/draft-IERC7943.sol";
+// Extensions
+import {
+    ERC20EnforcementModule,
+    ERC20EnforcementModuleInternal
+} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol";
+ 
+abstract contract CCTCMTATBasePolicyEngine is
+    CMTATBaseAccessControl,
+    ValidationModulePolicyEngine,
+    IERC7943FungibleTransferError
+{
+    /*//////////////////////////////////////////////////////////////
+                         INITIALIZER FUNCTION
+    //////////////////////////////////////////////////////////////*/
+    /**
+     * @notice
+     * initialize the proxy contract
+     * The calls to this function will revert if the contract was deployed without a proxy
+     * @param admin address of the admin of contract (Access Control)
+     * @param ERC20Attributes_ ERC20 name, symbol and decimals
+     * @param extraInformationAttributes_ tokenId, terms, information
+     * @param policyEngine_ address of the policy engine
+     * @dev
+     * If you override the public function initialize,
+     * call inside directly the internal function, not the public one which is protected by the initializer modifier
+     */
+    function initialize(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) public virtual initializer {
+        _initialize(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine_,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+ 
+    /**
+     * @dev don't call the initializer modifer
+     */
+    function _initialize(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) internal virtual EonlyInitializing {
+        __CMTAT_init(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine_,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+ 
+    /**
+     * @dev calls the different initialize functions from the different modules
+     */
+    function __CMTAT_init(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) internal virtual EonlyInitializing {
+        /* OpenZeppelin library */
+        // OZ init_unchained functions are called firstly due to inheritance
+        __Context_init_unchained();
+ 
+        // AccessControlUpgradeable inherits from ERC165Upgradeable
+        __ERC165_init_unchained();
+ 
+        // Openzeppelin
+        __CMTAT_openzeppelin_init_unchained(ERC20Attributes_);
+ 
+        /* Wrapper modules */
+        __CMTAT_commonModules_init_unchained(admin, ERC20Attributes_, extraInformationAttributes_);
+ 
+        /* Engine modules */
+        __SnapshotEngineModule_init_unchained(snapshotEngine_);
+        __DocumentEngineModule_init_unchained(documentEngine_);
+ 
+        /* Chainlink-ACE policy module */
+        __PolicyProtectedBase_init_unchained(policyEngine_);
+    }
+ 
+    /*
+     * @dev OpenZeppelin
+     */
+    function __CMTAT_openzeppelin_init_unchained(
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_
+    ) internal virtual EonlyInitializing {
+        // Note that the Openzeppelin functions name() and symbol() are overriden in ERC20BaseModule
+        __ERC20_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol);
+    }
+ 
+    /*
+     * @dev CMTAT wrapper modules
+     */
+    function __CMTAT_modules_init_unchained(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_
+    ) internal virtual onlyInitializing {
+        __CMTAT_commonModules_init_unchained(admin, ERC20Attributes_, extraInformationAttributes_);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /**
+     * @inheritdoc ValidationModulePolicyEngine
+     */
+    function canTransfer(
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(ValidationModulePolicyEngine) returns (bool) {
+        (bool isValid, ) = ERC20EnforcementModuleInternal._checkActiveBalance(from, value);
+        if (!isValid) {
+            return false;
+        } else {
+            return ValidationModulePolicyEngine.canTransfer(from, to, value);
+        }
+    }
+ 
+    /**
+     * @inheritdoc ValidationModulePolicyEngine
+     */
+    function canTransferFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(ValidationModulePolicyEngine) returns (bool) {
+        (bool isValid, ) = ERC20EnforcementModuleInternal._checkActiveBalance(from, value);
+        if (!isValid) {
+            return false;
+        } else {
+            return ValidationModulePolicyEngine.canTransferFrom(spender, from, to, value);
+        }
+    }
+ 
+    function _authorizeAttachPolicyEngine(address) internal virtual override onlyRole(DEFAULT_ADMIN_ROLE) {}
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ==== Access Control ==== */
+    function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE) {}
+    function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE) {}
+ 
+    function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE) {}
+ 
+    /* ==== Transfer/mint/burn restriction ==== */
+    function _checkTransferred(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon) {
+        CMTATBaseCommon._checkTransferred(spender, from, to, value);
+        require(
+            ValidationModulePolicyEngine._transferred(spender, from, to, value),
+            ERC7943CannotTransfer(from, to, value)
+        );
+    }
+ 
+    function supportsInterface(
+        bytes4 interfaceId
+    ) public view virtual override(CMTATBaseAccessControl, PolicyProtectedBaseUpgradeable) returns (bool) {
+        return
+            CMTATBaseAccessControl.supportsInterface(interfaceId) ||
+            PolicyProtectedBaseUpgradeable.supportsInterface(interfaceId);
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/lite/PolicyValidationModuleERC1404.sol.html b/doc/coverage/lcov-report/modules/lite/PolicyValidationModuleERC1404.sol.html new file mode 100644 index 0000000..55557a8 --- /dev/null +++ b/doc/coverage/lcov-report/modules/lite/PolicyValidationModuleERC1404.sol.html @@ -0,0 +1,440 @@ + + + + Code coverage report for modules/lite/PolicyValidationModuleERC1404.sol + + + + + + + +
+
+

+ all files / modules/lite/ PolicyValidationModuleERC1404.sol +

+
+
+ 100% + Statements + 32/32 +
+
+ 100% + Branches + 26/26 +
+
+ 100% + Functions + 4/4 +
+
+ 100% + Lines + 24/24 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  + +  + +  + +  + +  + +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + + +  + +  +  +  +  +  +  +  +  +  + + +  + + + +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  + +  + +  + +  + +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+/* ==== Tokenization === */
+import {IERC1404, IERC1404Extend} from "CMTAT/interfaces/tokenization/draft-IERC1404.sol";
+import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol";
+ 
+/**
+ * @dev Validation module (ERC-1404)
+ *
+ * Useful to restrict and validate transfers
+ */
+abstract contract PolicyValidationModuleERC1404 is ValidationModuleCore, IERC1404Extend {
+    /* ============ State Variables ============ */
+    string constant TEXT_TRANSFER_OK = "NoRestriction";
+    string constant TEXT_UNKNOWN_CODE = "UnknownCode";
+ 
+    /* EnforcementModule */
+    string internal constant TEXT_TRANSFER_REJECTED_FROM_FROZEN = "AddrFromIsFrozen";
+ 
+    string internal constant TEXT_TRANSFER_REJECTED_TO_FROZEN = "AddrToIsFrozen";
+ 
+    string internal constant TEXT_TRANSFER_REJECTED_SPENDER_FROZEN = "AddrSpenderIsFrozen";
+ 
+    /* PauseModule */
+    string internal constant TEXT_TRANSFER_REJECTED_PAUSED = "EnforcedPause";
+ 
+    /* Contract deactivated */
+    string internal constant TEXT_TRANSFER_REJECTED_DEACTIVATED = "ContractDeactivated";
+ 
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /**
+     * @notice returns the human readable explanation
+     * corresponding to the error code returned by detectTransferRestriction
+     * @param restrictionCode The error code returned by detectTransferRestriction
+     * @return message The human readable explanation corresponding to the error code returned by detectTransferRestriction
+     * @dev see {ERC-1404}
+     */
+    function messageForTransferRestriction(
+        uint8 restrictionCode
+    ) public view virtual override(IERC1404) returns (string memory message) {
+        if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) {
+            return TEXT_TRANSFER_OK;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED)) {
+            return TEXT_TRANSFER_REJECTED_PAUSED;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_DEACTIVATED)) {
+            return TEXT_TRANSFER_REJECTED_DEACTIVATED;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN)) {
+            return TEXT_TRANSFER_REJECTED_FROM_FROZEN;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN)) {
+            return TEXT_TRANSFER_REJECTED_TO_FROZEN;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN)) {
+            return TEXT_TRANSFER_REJECTED_SPENDER_FROZEN;
+        } else {
+            return TEXT_UNKNOWN_CODE;
+        }
+    }
+ 
+    /**
+     * @notice check if value token can be transferred from `from` to `to`
+     * @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}
+     */
+    function detectTransferRestriction(
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(IERC1404) returns (uint8 code) {
+        uint8 codeReturn = _detectTransferRestriction(from, to, value);
+        if (codeReturn != uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) {
+            return codeReturn;
+        } else {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
+        }
+    }
+ 
+    function detectTransferRestrictionFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(IERC1404Extend) returns (uint8 code) {
+        if (isFrozen(spender)) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN);
+        } else {
+            uint8 codeReturn = _detectTransferRestriction(from, to, value);
+            if (codeReturn != uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) {
+                return codeReturn;
+            } else {
+                return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
+            }
+        }
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+ 
+    /**
+     * @dev override this function to add further restriction
+     */
+    function _detectTransferRestriction(
+        address from,
+        address to,
+        uint256 /* value */
+    ) internal view virtual returns (uint8 code) {
+        if (deactivated()) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_DEACTIVATED);
+        } else if (paused()) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED);
+        } else if (isFrozen(from)) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN);
+        } else if (isFrozen(to)) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN);
+        } else {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
+        }
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/lite/ValidationModulePolicyEngine.sol.html b/doc/coverage/lcov-report/modules/lite/ValidationModulePolicyEngine.sol.html new file mode 100644 index 0000000..f44f4d0 --- /dev/null +++ b/doc/coverage/lcov-report/modules/lite/ValidationModulePolicyEngine.sol.html @@ -0,0 +1,428 @@ + + + + Code coverage report for modules/lite/ValidationModulePolicyEngine.sol + + + + + + + +
+
+

+ all files / modules/lite/ ValidationModulePolicyEngine.sol +

+
+
+ 100% + Statements + 25/25 +
+
+ 100% + Branches + 10/10 +
+
+ 100% + Functions + 8/8 +
+
+ 100% + Lines + 25/25 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +145× +  +  +  +  +  +  +  +  +  +  +  +  +23× +  +  +  +  +  +  +  +145× +39× +  +106× +  +  +  +  +  +  +  +  +  +23× +12× +  +11× +  +  +  +  +  +  +  +  +  +11× +  +  +  +  +  +  +  +106× +  +  +  +118× +118× +117× +117× +  +  +  +  +111× +  + +  +  + +  +  +  +  +  +  +  +  +  +  +1001× +932× +932× +931× +931× +  +  +924× + +  +  +925× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol";
+import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol";
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+ 
+abstract contract ValidationModulePolicyEngine is ValidationModuleCore, PolicyProtectedBaseUpgradeable {
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+ 
+    /* ============ View functions ============ */
+    /**
+     * @inheritdoc ValidationModuleCore
+     * @dev call the policy engine if set
+     */
+    function canTransfer(
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(ValidationModuleCore) returns (bool) {
+        return _canTransfer(from, to, value);
+    }
+ 
+    /**
+     * @inheritdoc ValidationModuleCore
+     * @dev call the policy engine if set
+     */
+    function canTransferFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(ValidationModuleCore) returns (bool) {
+        return _canTransferFrom(spender, from, to, value);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============ View functions ============ */
+    function _canTransfer(address from, address to, uint256 value) internal view virtual returns (bool) {
+        if (!ValidationModuleCore.canTransfer(from, to, value)) {
+            return false;
+        } else {
+            return _canTransferWithPolicyEngine(from, to, value);
+        }
+    }
+ 
+    function _canTransferFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) internal view virtual returns (bool) {
+        if (!ValidationModuleCore.canTransferFrom(spender, from, to, value)) {
+            return false;
+        } else {
+            return _canTransferFromWithPolicyEngine(spender, from, to, value);
+        }
+    }
+ 
+    function _canTransferFromWithPolicyEngine(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) internal view virtual returns (bool) {
+        return _tryCheckPolicies(IERC20.transferFrom.selector, spender, abi.encode(from, to, value));
+    }
+ 
+    function _canTransferWithPolicyEngine(
+        address from,
+        address to,
+        uint256 value
+    ) internal view virtual returns (bool) {
+        return _tryCheckPolicies(IERC20.transfer.selector, from, abi.encode(to, value));
+    }
+ 
+    function _tryCheckPolicies(bytes4 selector, address sender, bytes memory data) internal view returns (bool) {
+        IPolicyEngine policyEngine_ = IPolicyEngine(getPolicyEngine());
+        if (address(policyEngine_) != address(0)) {
+            bytes memory context = getContext();
+            try
+                policyEngine_.check(
+                    IPolicyEngine.Payload({selector: selector, sender: sender, data: data, context: context})
+                )
+            {
+                return true;
+            } catch {
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+ 
+    /* ============ State functions ============ */
+    function _transferred(
+        address spender,
+        address from,
+        address to,
+        uint256 /* value */
+    ) internal virtual returns (bool) {
+        _canTransferGenericByModuleAndRevert(spender, from, to);
+        IPolicyEngine policyEngine_ = IPolicyEngine(getPolicyEngine());
+        if (address(policyEngine_) != address(0)) {
+            bytes memory context = getContext();
+            policyEngine_.run(
+                IPolicyEngine.Payload({selector: msg.sig, sender: _msgSender(), data: msg.data[4:], context: context})
+            );
+            if (context.length > 0) {
+                clearContext();
+            }
+        }
+        return true;
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/lite/index.html b/doc/coverage/lcov-report/modules/lite/index.html new file mode 100644 index 0000000..b286953 --- /dev/null +++ b/doc/coverage/lcov-report/modules/lite/index.html @@ -0,0 +1,145 @@ + + + + Code coverage report for modules/lite/ + + + + + + + +
+
+

+ all files modules/lite/ +

+
+
+ 99.06% + Statements + 105/106 +
+
+ 89.29% + Branches + 75/84 +
+
+ 95.56% + Functions + 43/45 +
+
+ 98.98% + Lines + 97/98 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
CCTCMTATBaseERC1404.sol
100%12/1283.33%5/6100%5/5100%12/12
CCTCMTATBaseERC20CrossChain.sol
100%15/15100%16/16100%15/15100%15/15
CCTCMTATBasePolicyEngine.sol
95.45%21/2269.23%18/2684.62%11/1395.45%21/22
PolicyValidationModuleERC1404.sol
100%32/32100%26/26100%4/4100%24/24
ValidationModulePolicyEngine.sol
100%25/25100%10/10100%8/8100%25/25
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/standard/CCTCommon.sol.html b/doc/coverage/lcov-report/modules/standard/CCTCommon.sol.html new file mode 100644 index 0000000..4d8a056 --- /dev/null +++ b/doc/coverage/lcov-report/modules/standard/CCTCommon.sol.html @@ -0,0 +1,1055 @@ + + + + Code coverage report for modules/standard/CCTCommon.sol + + + + + + + +
+
+

+ all files / modules/standard/ CCTCommon.sol +

+
+
+ 95.83% + Statements + 23/24 +
+
+ 84.09% + Branches + 37/44 +
+
+ 96.55% + Functions + 28/29 +
+
+ 95.83% + Lines + 23/24 +
+
+
+
+

+
+
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 +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 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +12× +  +  +12× +  +  +12× +  +  +12× +  +12× +  +  +12× +  +  +12× +12× +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +12× +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +48× +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +13× +  +  +  +  +  +  +10× +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +376× +  +  +  +  +  +  +  +  +  +48× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +478× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+/* ==== OpenZeppelin === */
+import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
+ 
+/* ==== CMTAT === */
+import {CMTATBaseCommon} from "CMTAT/modules/0_CMTATBaseCommon.sol";
+/* = Base = */
+/* = Core = */
+import {
+    ERC20BurnModule,
+    ERC20BurnModuleInternal
+} from "CMTAT/modules/wrapper/core/ERC20BurnModule.sol";
+import {
+    ERC20MintModule,
+    ERC20MintModuleInternal
+} from "CMTAT/modules/wrapper/core/ERC20MintModule.sol";
+import {ERC20BaseModule} from "CMTAT/modules/wrapper/core/ERC20BaseModule.sol";
+/* = Option & Extension = */
+import {ERC20CrossChainModule} from "CMTAT/modules/wrapper/options/ERC20CrossChainModule.sol";
+import {CCIPModule} from "CMTAT/modules/wrapper/options/CCIPModule.sol";
+import {ExtraInformationModule} from "CMTAT/modules/wrapper/extensions/ExtraInformationModule.sol";
+import {
+    ERC20EnforcementModule,
+    ERC20EnforcementModuleInternal
+} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol";
+import {
+    DocumentEngineModule,
+    IERC1643
+} from "CMTAT/modules/wrapper/extensions/DocumentEngineModule.sol";
+import {SnapshotEngineModule} from "CMTAT/modules/wrapper/extensions/SnapshotEngineModule.sol";
+/* = Interface = */
+import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol";
+import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol";
+/* ==== Chainlink ACE === */
+import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol";
+ 
+abstract contract CCTCommon is
+    OwnableUpgradeable,
+    ERC20CrossChainModule,
+    PolicyProtectedBaseUpgradeable,
+    CMTATBaseCommon,
+    CCIPModule
+{
+    function initialize(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) public virtual initializer {
+        _initialize(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+ 
+    function _initialize(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) internal virtual EonlyInitializing {
+        __CMTAT_init(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+ 
+    /**
+     * @dev calls the different initialize functions from the different modules
+     */
+    function __CMTAT_init(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory ExtraInformationAttributes_,
+        address policyEngine,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) internal virtual EonlyInitializing {
+        __Ownable_init_unchained(admin);
+        /* OpenZeppelin library */
+        // OZ init_unchained functions are called firstly due to inheritance
+        __Context_init_unchained();
+ 
+        // AccessControlUpgradeable inherits from ERC165Upgradeable
+        __ERC165_init_unchained();
+ 
+        // Openzeppelin
+        __CMTAT_openzeppelin_init_unchained(ERC20Attributes_);
+ 
+        __PolicyProtectedBase_init_unchained(policyEngine);
+ 
+        /* Wrapper modules */
+        __CMTAT_modules_init_unchained(ERC20Attributes_, ExtraInformationAttributes_);
+ 
+        /* Engine modules */
+        __SnapshotEngineModule_init_unchained(snapshotEngine_);
+        __DocumentEngineModule_init_unchained(documentEngine_);
+    }
+ 
+    /*
+     * @dev OpenZeppelin
+     */
+    function __CMTAT_openzeppelin_init_unchained(
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_
+    ) internal virtual EonlyInitializing {
+        // Note that the Openzeppelin functions name() and symbol() are overriden in ERC20BaseModule
+        __ERC20_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol);
+    }
+ 
+    /*
+     * @dev CMTAT wrapper modules
+     */
+    function __CMTAT_modules_init_unchained(
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_
+    ) internal virtual EonlyInitializing {
+        __CMTAT_commonModules_init_unchained(ERC20Attributes_, extraInformationAttributes_);
+    }
+ 
+    function __CMTAT_commonModules_init_unchained(
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory ExtraInformationModuleAttributes_
+    ) internal virtual EonlyInitializing {
+        // Core
+        __ERC20BaseModule_init_unchained(
+            ERC20Attributes_.decimalsIrrevocable,
+            ERC20Attributes_.name,
+            ERC20Attributes_.symbol
+        );
+        /* Extensions */
+        __ExtraInformationModule_init_unchained(
+            ExtraInformationModuleAttributes_.tokenId,
+            ExtraInformationModuleAttributes_.terms,
+            ExtraInformationModuleAttributes_.information
+        );
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                        PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============  State Functions ============ */
+    function transfer(
+        address to,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) ErunPolicy returns (bool) {
+        return CMTATBaseCommon.transfer(to, value);
+    }
+    /*
+     * @inheritdoc ERC20BaseModule
+     */
+    function transferFrom(
+        address from,
+        address to,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) ErunPolicy returns (bool) {
+        return CMTATBaseCommon.transferFrom(from, to, value);
+    }
+ 
+    function _authorizeAttachPolicyEngine(address) internal virtual override onlyOwner {}
+ 
+    /* ============ View functions ============ */
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function decimals() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (uint8) {
+        return CMTATBaseCommon.decimals();
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function name() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) {
+        return CMTATBaseCommon.name();
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function symbol() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) {
+        return CMTATBaseCommon.symbol();
+    }
+ 
+    function supportsInterface(
+        bytes4 _interfaceId
+    ) public view virtual override(IERC165, ERC20CrossChainModule, PolicyProtectedBaseUpgradeable) returns (bool) {
+        return
+            ERC20CrossChainModule.supportsInterface(_interfaceId) ||
+            PolicyProtectedBaseUpgradeable.supportsInterface(_interfaceId);
+    }
+ 
+    /* ==== Mint and Burn Operations ==== */
+    /**
+     * @dev Check if the mint is valid
+     */
+    function _mintOverride(
+        address account,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
+        CMTATBaseCommon._mintOverride(account, value);
+    }
+ 
+    /**
+     * @dev Check if the burn is valid
+     */
+    function _burnOverride(
+        address account,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) {
+        CMTATBaseCommon._burnOverride(account, value);
+    }
+ 
+    /**
+     * @dev Check if a minter transfer is valid
+     */
+    function _minterTransferOverride(
+        address from,
+        address to,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
+        CMTATBaseCommon._minterTransferOverride(from, to, value);
+    }
+ 
+    /* ==== Access Control Functions ==== */
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DEFAULT_ADMIN_ROLE`.
+     */
+    function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `MINTER_ROLE`.
+     */
+    function _authorizeMint() internal virtual override(ERC20MintModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - The caller must have the `BURNER_ROLE`.
+     */
+    function _authorizeBurn() internal virtual override(ERC20BurnModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DOCUMENT_ROLE`.
+     */
+    function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `EXTRA_INFORMATION_ROLE`.
+     */
+    function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `ERC20ENFORCER_ROLE`.
+     */
+    function _authorizeERC20Enforcer() internal virtual override(ERC20EnforcementModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DEFAULT_ADMIN_ROLE`.
+     */
+    function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `SNAPSHOOTER_ROLE`.
+     */
+    function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DEFAULT_ADMIN_ROLE`.
+     */
+    function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) runPolicy {}
+ 
+    /**
+     * @dev
+     * A cross-chain bridge could call the OpenZeppelin function `renounceRole` to lose their privileges (CROSS_CHAIN_ROLE)
+     * While it is not intended,this has no other effect than depriving the bridge of burn/mint tokens
+     * An attacker could use this to disrupt minting/burning if they can get the bridge to execute calls.
+     * However, in this case, the bridge should still be considered compromised and not used again.
+     * @custom:access-control
+     * - the caller must have the `CROSS_CHAIN_ROLE`.
+     */
+    function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `BURNER_FROM_ROLE`.
+     * - We don't allow token holder to burn their own tokens if they don't have this role.
+     */
+    function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `BURNER_ROLE`.
+     * - We don't allow token holder to burn their own tokens if they don't have this role.
+     */
+    function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) runPolicy {}
+ 
+    /* ==== ERC-20 OpenZeppelin ==== */
+    function _update(
+        address from,
+        address to,
+        uint256 amount
+    ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) {
+        return CMTATBaseCommon._update(from, to, amount);
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/modules/standard/index.html b/doc/coverage/lcov-report/modules/standard/index.html new file mode 100644 index 0000000..de598aa --- /dev/null +++ b/doc/coverage/lcov-report/modules/standard/index.html @@ -0,0 +1,93 @@ + + + + Code coverage report for modules/standard/ + + + + + + + +
+
+

+ all files modules/standard/ +

+
+
+ 95.83% + Statements + 23/24 +
+
+ 84.09% + Branches + 37/44 +
+
+ 96.55% + Functions + 28/29 +
+
+ 95.83% + Lines + 23/24 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
CCTCommon.sol
95.83%23/2484.09%37/4496.55%28/2995.83%23/24
+
+
+ + + + + + + diff --git a/doc/coverage/lcov-report/prettify.css b/doc/coverage/lcov-report/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/doc/coverage/lcov-report/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/doc/coverage/lcov-report/prettify.js b/doc/coverage/lcov-report/prettify.js new file mode 100644 index 0000000..ef51e03 --- /dev/null +++ b/doc/coverage/lcov-report/prettify.js @@ -0,0 +1 @@ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/doc/coverage/lcov-report/sort-arrow-sprite.png b/doc/coverage/lcov-report/sort-arrow-sprite.png new file mode 100644 index 0000000..03f704a Binary files /dev/null and b/doc/coverage/lcov-report/sort-arrow-sprite.png differ diff --git a/doc/coverage/lcov-report/sorter.js b/doc/coverage/lcov-report/sorter.js new file mode 100644 index 0000000..6c5034e --- /dev/null +++ b/doc/coverage/lcov-report/sorter.js @@ -0,0 +1,158 @@ +var addSorting = (function () { + "use strict"; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { return document.querySelector('.coverage-summary'); } + // returns the thead element of the summary table + function getTableHeader() { return getTable().querySelector('thead tr'); } + // returns the tbody element of the summary table + function getTableBody() { return getTable().querySelector('tbody'); } + // returns the th element for nth column + function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function (a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function (a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function () { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i =0 ; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function () { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(cols); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/doc/coverage/lcov.info b/doc/coverage/lcov.info new file mode 100644 index 0000000..9bd74b1 --- /dev/null +++ b/doc/coverage/lcov.info @@ -0,0 +1,766 @@ +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/lite/ComplianceTokenCMTATLiteStandalone.sol +FN:25,constructor +FNF:1 +FNH:1 +FNDA:51,constructor +DA:34,51 +LF:1 +LH:1 +BRF:0 +BRH:0 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/lite/ComplianceTokenCMTATLiteUpgradeable.sol +FN:14,constructor +FNF:1 +FNH:1 +FNDA:1,constructor +DA:16,1 +LF:1 +LH:1 +BRF:0 +BRH:0 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/lite/ComplianceTokenCMTATLiteUUPSUpgradeable.sol +FN:17,constructor +FN:27,_authorizeUpgrade +FNF:2 +FNH:2 +FNDA:1,constructor +FNDA:2,_authorizeUpgrade +DA:19,1 +LF:1 +LH:1 +BRDA:27,1,0,2 +BRDA:27,1,1,1 +BRF:2 +BRH:2 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/standard/ComplianceTokenCMTATStandalone.sol +FN:25,constructor +FNF:1 +FNH:1 +FNDA:8,constructor +DA:34,8 +LF:1 +LH:1 +BRF:0 +BRH:0 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/standard/ComplianceTokenCMTATUpgradeable.sol +FN:14,constructor +FNF:1 +FNH:1 +FNDA:1,constructor +DA:16,1 +LF:1 +LH:1 +BRF:0 +BRH:0 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/deployment/standard/ComplianceTokenCMTATUUPSUpgradeable.sol +FN:15,constructor +FN:23,_authorizeUpgrade +FNF:2 +FNH:2 +FNDA:1,constructor +FNDA:2,_authorizeUpgrade +DA:17,1 +LF:1 +LH:1 +BRDA:23,1,0,2 +BRDA:23,1,1,1 +BRF:2 +BRH:2 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol +FN:28,extract +FNF:1 +FNH:1 +FNDA:34,extract +DA:31,34 +DA:32,34 +DA:33,34 +DA:34,34 +DA:36,34 +DA:37,30 +DA:38,30 +DA:39,30 +DA:41,4 +DA:42,4 +DA:44,0 +DA:47,34 +DA:48,34 +DA:49,34 +DA:50,34 +DA:51,34 +DA:53,34 +LF:17 +LH:16 +BRDA:36,1,0,30 +BRDA:36,1,1,4 +BRDA:40,2,0,4 +BRDA:40,2,1,0 +BRF:4 +BRH:3 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/chainlink-ace/custom/MintBurnExtractor.sol +FN:31,extract +FNF:1 +FNH:1 +FNDA:4,extract +DA:34,4 +DA:35,4 +DA:37,4 +DA:38,2 +DA:40,1 +DA:41,1 +DA:43,1 +DA:46,3 +DA:47,3 +DA:48,3 +DA:49,3 +LF:11 +LH:11 +BRDA:37,1,0,2 +BRDA:37,1,1,2 +BRDA:37,2,0,1 +BRDA:37,2,1,1 +BRDA:39,3,0,1 +BRDA:39,3,1,1 +BRF:6 +BRH:6 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/chainlink-ace/custom/TransferValidationPolicy.sol +FN:39,_getStorage +FN:50,configure +FN:65,setRules +FN:79,rules +FN:86,rulesCount +FN:96,run +FNF:6 +FNH:6 +FNDA:77,_getStorage +FNDA:37,configure +FNDA:2,setRules +FNDA:1,rules +FNDA:1,rulesCount +FNDA:39,run +DA:40,77 +DA:51,37 +DA:52,34 +DA:53,34 +DA:54,34 +DA:55,41 +DA:56,41 +DA:66,2 +DA:67,2 +DA:68,2 +DA:69,2 +DA:70,2 +DA:71,2 +DA:73,2 +DA:80,1 +DA:87,1 +DA:103,39 +DA:104,39 +DA:106,39 +DA:107,4 +DA:110,35 +DA:112,33 +DA:113,33 +DA:114,33 +DA:115,33 +DA:117,33 +DA:118,35 +DA:119,35 +DA:120,13 +DA:121,13 +DA:126,2 +DA:127,2 +DA:128,2 +DA:130,2 +DA:131,2 +DA:132,2 +DA:133,1 +DA:134,1 +DA:139,21 +LF:39 +LH:39 +BRDA:50,1,0,37 +BRDA:50,1,1,0 +BRDA:51,2,0,34 +BRDA:51,2,1,3 +BRDA:55,3,0,41 +BRDA:55,3,1,0 +BRDA:65,4,0,2 +BRDA:65,4,1,1 +BRDA:70,5,0,2 +BRDA:70,5,1,0 +BRDA:106,6,0,4 +BRDA:106,6,1,35 +BRDA:110,7,0,33 +BRDA:110,7,1,2 +BRDA:119,8,0,13 +BRDA:119,8,1,22 +BRDA:132,9,0,1 +BRDA:132,9,1,1 +BRF:18 +BRH:15 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/chainlink-ace/mocks/TransferRuleMocks.sol +FN:20,constructor +FN:24,detectTransferRestriction +FN:32,detectTransferRestrictionFrom +FN:41,canTransfer +FN:45,canTransferFrom +FN:54,transferred +FN:56,transferred +FN:63,supportsInterface +FN:67,canReturnTransferRestrictionCode +FN:71,messageForTransferRestriction +FN:87,onlyOwner +FN:92,constructor +FN:99,setRestricted +FN:103,detectTransferRestriction +FN:113,detectTransferRestrictionFrom +FN:122,canTransfer +FN:126,canTransferFrom +FN:135,transferred +FN:137,transferred +FN:144,supportsInterface +FN:148,canReturnTransferRestrictionCode +FN:152,messageForTransferRestriction +FNF:22 +FNH:10 +FNDA:30,constructor +FNDA:25,detectTransferRestriction +FNDA:23,detectTransferRestrictionFrom +FNDA:0,canTransfer +FNDA:0,canTransferFrom +FNDA:0,transferred +FNDA:0,transferred +FNDA:0,supportsInterface +FNDA:0,canReturnTransferRestrictionCode +FNDA:8,messageForTransferRestriction +FNDA:3,onlyOwner +FNDA:14,constructor +FNDA:3,setRestricted +FNDA:12,detectTransferRestriction +FNDA:12,detectTransferRestrictionFrom +FNDA:0,canTransfer +FNDA:0,canTransferFrom +FNDA:0,transferred +FNDA:0,transferred +FNDA:0,supportsInterface +FNDA:0,canReturnTransferRestrictionCode +FNDA:6,messageForTransferRestriction +DA:21,30 +DA:29,25 +DA:38,23 +DA:42,0 +DA:51,0 +DA:64,0 +DA:68,0 +DA:72,8 +DA:88,3 +DA:89,3 +DA:93,14 +DA:94,14 +DA:95,12 +DA:100,3 +DA:108,12 +DA:109,10 +DA:110,6 +DA:119,12 +DA:123,0 +DA:132,0 +DA:145,0 +DA:149,0 +DA:153,6 +DA:154,4 +DA:155,0 +LF:25 +LH:16 +BRDA:29,1,0,8 +BRDA:29,1,1,17 +BRDA:72,2,0,8 +BRDA:72,2,1,0 +BRDA:88,3,0,3 +BRDA:88,3,1,0 +BRDA:99,4,0,3 +BRDA:99,4,1,0 +BRDA:108,5,0,2 +BRDA:108,5,1,10 +BRDA:109,6,0,4 +BRDA:109,6,1,6 +BRDA:149,7,0,0 +BRDA:149,7,1,0 +BRDA:153,8,0,2 +BRDA:153,8,1,4 +BRDA:154,9,0,4 +BRDA:154,9,1,0 +BRF:18 +BRH:12 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/CCTCMTATBaseERC1404.sol +FN:27,messageForTransferRestriction +FN:43,canTransfer +FN:54,canTransferFrom +FN:66,_detectTransferRestriction +FN:81,supportsInterface +FNF:5 +FNH:5 +FNDA:10,messageForTransferRestriction +FNDA:233,canTransfer +FNDA:35,canTransferFrom +FNDA:8,_detectTransferRestriction +FNDA:6,supportsInterface +DA:30,10 +DA:34,1 +DA:36,9 +DA:48,233 +DA:60,35 +DA:71,8 +DA:72,8 +DA:73,1 +DA:74,1 +DA:75,1 +DA:78,7 +DA:84,6 +LF:12 +LH:12 +BRDA:30,1,0,1 +BRDA:30,1,1,9 +BRDA:72,2,0,1 +BRDA:72,2,1,7 +BRDA:74,3,0,1 +BRDA:74,3,1,0 +BRF:6 +BRH:5 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/CCTCMTATBaseERC20CrossChain.sol +FN:28,approve +FN:31,transfer +FN:40,transferFrom +FN:50,_mintOverride +FN:61,_burnOverride +FN:72,_minterTransferOverride +FN:84,decimals +FN:91,name +FN:98,symbol +FN:103,supportsInterface +FN:120,_authorizeCCIPSetAdmin +FN:131,_checkTokenBridge +FN:145,_authorizeBurnFrom +FN:158,_authorizeSelfBurn +FN:162,_update +FNF:15 +FNH:15 +FNDA:119,approve +FNDA:81,transfer +FNDA:29,transferFrom +FNDA:735,_mintOverride +FNDA:144,_burnOverride +FNDA:27,_minterTransferOverride +FNDA:3,decimals +FNDA:10,name +FNDA:10,symbol +FNDA:12,supportsInterface +FNDA:9,_authorizeCCIPSetAdmin +FNDA:39,_checkTokenBridge +FNDA:9,_authorizeBurnFrom +FNDA:12,_authorizeSelfBurn +FNDA:943,_update +DA:29,119 +DA:35,81 +DA:45,29 +DA:54,735 +DA:55,720 +DA:65,144 +DA:66,120 +DA:77,27 +DA:78,18 +DA:85,3 +DA:92,10 +DA:99,10 +DA:106,12 +DA:132,39 +DA:167,943 +LF:15 +LH:15 +BRDA:28,1,0,119 +BRDA:28,1,1,3 +BRDA:107,2,0,6 +BRDA:107,2,1,3 +BRDA:120,3,0,9 +BRDA:120,3,1,3 +BRDA:131,4,0,39 +BRDA:131,4,1,12 +BRDA:144,5,0,15 +BRDA:144,5,1,3 +BRDA:145,6,0,9 +BRDA:145,6,1,6 +BRDA:157,7,0,18 +BRDA:157,7,1,6 +BRDA:158,8,0,12 +BRDA:158,8,1,6 +BRF:16 +BRH:16 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/CCTCMTATBasePolicyEngine.sol +FN:50,initialize +FN:71,_initialize +FN:92,__CMTAT_init +FN:119,__CMTAT_openzeppelin_init_unchained +FN:131,__CMTAT_modules_init_unchained +FN:141,canTransfer +FN:157,canTransferFrom +FN:171,_authorizeAttachPolicyEngine +FN:177,_authorizePause +FN:178,_authorizeDeactivate +FN:180,_authorizeFreeze +FN:183,_checkTransferred +FN:196,supportsInterface +FNF:13 +FNH:11 +FNDA:55,initialize +FNDA:55,_initialize +FNDA:55,__CMTAT_init +FNDA:55,__CMTAT_openzeppelin_init_unchained +FNDA:0,__CMTAT_modules_init_unchained +FNDA:233,canTransfer +FNDA:35,canTransferFrom +FNDA:0,_authorizeAttachPolicyEngine +FNDA:99,_authorizePause +FNDA:37,_authorizeDeactivate +FNDA:78,_authorizeFreeze +FNDA:1016,_checkTransferred +FNDA:6,supportsInterface +DA:51,55 +DA:72,55 +DA:95,55 +DA:98,55 +DA:101,55 +DA:104,55 +DA:107,55 +DA:108,55 +DA:111,55 +DA:121,55 +DA:132,0 +DA:146,233 +DA:147,233 +DA:148,88 +DA:150,145 +DA:163,35 +DA:164,35 +DA:165,12 +DA:167,23 +DA:189,1016 +DA:190,998 +DA:199,6 +LF:22 +LH:21 +BRDA:50,1,0,55 +BRDA:50,1,1,2 +BRDA:71,2,0,55 +BRDA:71,2,1,0 +BRDA:92,3,0,55 +BRDA:92,3,1,0 +BRDA:119,4,0,55 +BRDA:119,4,1,0 +BRDA:131,5,0,0 +BRDA:131,5,1,0 +BRDA:147,6,0,88 +BRDA:147,6,1,145 +BRDA:164,7,0,12 +BRDA:164,7,1,23 +BRDA:171,8,0,0 +BRDA:171,8,1,0 +BRDA:177,9,0,99 +BRDA:177,9,1,6 +BRDA:178,10,0,37 +BRDA:178,10,1,3 +BRDA:180,11,0,78 +BRDA:180,11,1,9 +BRDA:190,12,0,922 +BRDA:190,12,1,76 +BRDA:200,13,0,3 +BRDA:200,13,1,0 +BRF:26 +BRH:18 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/PolicyValidationModuleERC1404.sol +FN:42,messageForTransferRestriction +FN:70,detectTransferRestriction +FN:83,detectTransferRestrictionFrom +FN:108,_detectTransferRestriction +FNF:4 +FNH:4 +FNDA:9,messageForTransferRestriction +FNDA:6,detectTransferRestriction +FNDA:3,detectTransferRestrictionFrom +FNDA:7,_detectTransferRestriction +DA:45,9 +DA:46,2 +DA:48,1 +DA:50,1 +DA:52,1 +DA:54,2 +DA:56,1 +DA:58,1 +DA:75,6 +DA:76,6 +DA:77,5 +DA:79,1 +DA:89,3 +DA:90,1 +DA:92,2 +DA:93,2 +DA:94,1 +DA:96,1 +DA:113,7 +DA:114,1 +DA:116,1 +DA:118,1 +DA:120,2 +DA:122,2 +LF:24 +LH:24 +BRDA:45,1,0,2 +BRDA:45,1,1,7 +BRDA:47,2,0,1 +BRDA:47,2,1,6 +BRDA:49,3,0,1 +BRDA:49,3,1,5 +BRDA:51,4,0,1 +BRDA:51,4,1,4 +BRDA:53,5,0,2 +BRDA:53,5,1,2 +BRDA:55,6,0,1 +BRDA:55,6,1,1 +BRDA:76,7,0,5 +BRDA:76,7,1,1 +BRDA:89,8,0,1 +BRDA:89,8,1,2 +BRDA:93,9,0,1 +BRDA:93,9,1,1 +BRDA:113,10,0,1 +BRDA:113,10,1,6 +BRDA:115,11,0,1 +BRDA:115,11,1,5 +BRDA:117,12,0,1 +BRDA:117,12,1,4 +BRDA:119,13,0,2 +BRDA:119,13,1,2 +BRF:26 +BRH:26 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/lite/ValidationModulePolicyEngine.sol +FN:20,canTransfer +FN:32,canTransferFrom +FN:45,_canTransfer +FN:53,_canTransferFrom +FN:66,_canTransferFromWithPolicyEngine +FN:75,_canTransferWithPolicyEngine +FN:83,_tryCheckPolicies +FN:102,_transferred +FNF:8 +FNH:8 +FNDA:145,canTransfer +FNDA:23,canTransferFrom +FNDA:145,_canTransfer +FNDA:23,_canTransferFrom +FNDA:11,_canTransferFromWithPolicyEngine +FNDA:106,_canTransferWithPolicyEngine +FNDA:118,_tryCheckPolicies +FNDA:1001,_transferred +DA:25,145 +DA:38,23 +DA:46,145 +DA:47,39 +DA:49,106 +DA:59,23 +DA:60,12 +DA:62,11 +DA:72,11 +DA:80,106 +DA:84,118 +DA:85,118 +DA:86,117 +DA:87,117 +DA:92,111 +DA:94,6 +DA:97,1 +DA:108,1001 +DA:109,932 +DA:110,932 +DA:111,931 +DA:112,931 +DA:115,924 +DA:116,2 +DA:119,925 +LF:25 +LH:25 +BRDA:46,1,0,39 +BRDA:46,1,1,106 +BRDA:59,2,0,12 +BRDA:59,2,1,11 +BRDA:85,3,0,117 +BRDA:85,3,1,1 +BRDA:110,4,0,931 +BRDA:110,4,1,1 +BRDA:115,5,0,2 +BRDA:115,5,1,922 +BRF:10 +BRH:10 +end_of_record +TN: +SF:/Users/mark/dev/bcm/bcm-solutions/accounts/cmta/contracts/modules/standard/CCTCommon.sol +FN:56,initialize +FN:74,_initialize +FN:95,__CMTAT_init +FN:122,__CMTAT_openzeppelin_init_unchained +FN:133,__CMTAT_modules_init_unchained +FN:140,__CMTAT_commonModules_init_unchained +FN:162,transfer +FN:172,transferFrom +FN:176,_authorizeAttachPolicyEngine +FN:183,decimals +FN:190,name +FN:197,symbol +FN:201,supportsInterface +FN:213,_mintOverride +FN:223,_burnOverride +FN:233,_minterTransferOverride +FN:247,_authorizeERC20AttributeManagement +FN:253,_authorizeMint +FN:259,_authorizeBurn +FN:265,_authorizeDocumentManagement +FN:271,_authorizeExtraInfoManagement +FN:277,_authorizeERC20Enforcer +FN:283,_authorizeForcedTransfer +FN:289,_authorizeSnapshots +FN:295,_authorizeCCIPSetAdmin +FN:306,_checkTokenBridge +FN:313,_authorizeBurnFrom +FN:320,_authorizeSelfBurn +FN:323,_update +FNF:29 +FNH:28 +FNDA:12,initialize +FNDA:12,_initialize +FNDA:12,__CMTAT_init +FNDA:12,__CMTAT_openzeppelin_init_unchained +FNDA:12,__CMTAT_modules_init_unchained +FNDA:12,__CMTAT_commonModules_init_unchained +FNDA:48,transfer +FNDA:12,transferFrom +FNDA:3,_authorizeAttachPolicyEngine +FNDA:9,decimals +FNDA:13,name +FNDA:10,symbol +FNDA:9,supportsInterface +FNDA:376,_mintOverride +FNDA:48,_burnOverride +FNDA:0,_minterTransferOverride +FNDA:3,_authorizeERC20AttributeManagement +FNDA:352,_authorizeMint +FNDA:33,_authorizeBurn +FNDA:63,_authorizeDocumentManagement +FNDA:3,_authorizeExtraInfoManagement +FNDA:48,_authorizeERC20Enforcer +FNDA:12,_authorizeForcedTransfer +FNDA:12,_authorizeSnapshots +FNDA:3,_authorizeCCIPSetAdmin +FNDA:15,_checkTokenBridge +FNDA:3,_authorizeBurnFrom +FNDA:3,_authorizeSelfBurn +FNDA:478,_update +DA:57,12 +DA:75,12 +DA:96,12 +DA:99,12 +DA:102,12 +DA:105,12 +DA:107,12 +DA:110,12 +DA:113,12 +DA:114,12 +DA:124,12 +DA:134,12 +DA:142,12 +DA:148,12 +DA:163,48 +DA:173,12 +DA:184,9 +DA:191,13 +DA:198,10 +DA:204,9 +DA:217,376 +DA:227,48 +DA:238,0 +DA:328,478 +LF:24 +LH:23 +BRDA:56,1,0,12 +BRDA:56,1,1,2 +BRDA:74,2,0,12 +BRDA:74,2,1,0 +BRDA:95,3,0,12 +BRDA:95,3,1,0 +BRDA:122,4,0,12 +BRDA:122,4,1,0 +BRDA:133,5,0,12 +BRDA:133,5,1,0 +BRDA:140,6,0,12 +BRDA:140,6,1,0 +BRDA:162,7,0,48 +BRDA:162,7,1,0 +BRDA:172,8,0,12 +BRDA:172,8,1,0 +BRDA:176,9,0,3 +BRDA:176,9,1,3 +BRDA:205,10,0,3 +BRDA:205,10,1,3 +BRDA:247,11,0,3 +BRDA:247,11,1,3 +BRDA:253,12,0,352 +BRDA:253,12,1,24 +BRDA:259,13,0,33 +BRDA:259,13,1,15 +BRDA:265,14,0,63 +BRDA:265,14,1,3 +BRDA:271,15,0,3 +BRDA:271,15,1,3 +BRDA:277,16,0,48 +BRDA:277,16,1,12 +BRDA:283,17,0,12 +BRDA:283,17,1,12 +BRDA:289,18,0,12 +BRDA:289,18,1,3 +BRDA:295,19,0,3 +BRDA:295,19,1,3 +BRDA:306,20,0,15 +BRDA:306,20,1,6 +BRDA:313,21,0,3 +BRDA:313,21,1,3 +BRDA:320,22,0,3 +BRDA:320,22,1,3 +BRF:44 +BRH:37 +end_of_record diff --git a/doc/coverage/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol.html b/doc/coverage/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol.html new file mode 100644 index 0000000..06a67f6 --- /dev/null +++ b/doc/coverage/modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol.html @@ -0,0 +1,230 @@ + + + + Code coverage report for modules/chainlink-ace/custom/ERC20TransferFromExtractor.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/custom/ ERC20TransferFromExtractor.sol +

+
+
+ 100% + Statements + 8/8 +
+
+ 75% + Branches + 3/4 +
+
+ 100% + Functions + 1/1 +
+
+ 94.12% + Lines + 16/17 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +34× +34× +34× +34× +  +34× +30× +30× +30× +  + + +  +  +  +  +34× +34× +34× +34× +34× +  +34× +  +  + 
// SPDX-License-Identifier: BUSL-1.1
+pragma solidity ^0.8.20;
+ 
+import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+ 
+/**
+ * @title ERC20TransferFromExtractor
+ * @notice Extends the standard ERC20TransferExtractor by also extracting the
+ *         spender address, enabling policies to validate transferFrom approvals.
+ * @dev Handles:
+ *      - transfer(address to, uint256 amount):
+ *          spender = sender, from = sender, to = decoded, amount = decoded
+ *      - transferFrom(address from, address to, uint256 amount):
+ *          spender = sender, from = decoded, to = decoded, amount = decoded
+ *
+ *      Returns 4 parameters: [spender, from, to, amount]
+ */
+contract ERC20TransferFromExtractor is IExtractor {
+    string public constant override typeAndVersion = "ERC20TransferFromExtractor 1.0.0";
+ 
+    bytes32 public constant PARAM_SPENDER = keccak256("spender");
+    bytes32 public constant PARAM_FROM = keccak256("from");
+    bytes32 public constant PARAM_TO = keccak256("to");
+    bytes32 public constant PARAM_AMOUNT = keccak256("amount");
+ 
+    function extract(
+        IPolicyEngine.Payload calldata payload
+    ) external pure override returns (IPolicyEngine.Parameter[] memory) {
+        address spender;
+        address from;
+        address to;
+        uint256 amount;
+ 
+        if (payload.selector == IERC20.transfer.selector) {
+            spender = payload.sender;
+            from = payload.sender;
+            (to, amount) = abi.decode(payload.data, (address, uint256));
+        } else Eif (payload.selector == IERC20.transferFrom.selector) {
+            spender = payload.sender;
+            (from, to, amount) = abi.decode(payload.data, (address, address, uint256));
+        } else {
+            revert IPolicyEngine.UnsupportedSelector(payload.selector);
+        }
+ 
+        IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](4);
+        result[0] = IPolicyEngine.Parameter(PARAM_SPENDER, abi.encode(spender));
+        result[1] = IPolicyEngine.Parameter(PARAM_FROM, abi.encode(from));
+        result[2] = IPolicyEngine.Parameter(PARAM_TO, abi.encode(to));
+        result[3] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
+ 
+        return result;
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/chainlink-ace/custom/MintBurnExtractor.sol.html b/doc/coverage/modules/chainlink-ace/custom/MintBurnExtractor.sol.html new file mode 100644 index 0000000..19d9657 --- /dev/null +++ b/doc/coverage/modules/chainlink-ace/custom/MintBurnExtractor.sol.html @@ -0,0 +1,218 @@ + + + + Code coverage report for modules/chainlink-ace/custom/MintBurnExtractor.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/custom/ MintBurnExtractor.sol +

+
+
+ 100% + Statements + 6/6 +
+
+ 100% + Branches + 6/6 +
+
+ 100% + Functions + 1/1 +
+
+ 100% + Lines + 11/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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  + + +  + + +  + +  +  + + + + +  +  + 
// SPDX-License-Identifier: BUSL-1.1
+pragma solidity ^0.8.20;
+ 
+import {IExtractor} from "@chainlink/policy-management/interfaces/IExtractor.sol";
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+ 
+/**
+ * @title MintBurnExtractor
+ * @notice Extracts parameters from CMTAT mint and burn function calls.
+ * @dev Mirrors ComplianceTokenMintBurnExtractor from @chainlink/ace but avoids
+ *      the cross-package relative import of ComplianceTokenERC20 which is
+ *      incompatible with Hardhat's module resolution. Selectors are inlined.
+ *      Handles:
+ *        - mint(address account, uint256 amount)       → 0x40c10f19
+ *        - burnFrom(address account, uint256 amount)   → 0x79cc6790
+ *        - burn(uint256 amount)                        → 0x42966c68
+ */
+contract MintBurnExtractor is IExtractor {
+    string public constant override typeAndVersion = "MintBurnExtractor 1.0.0";
+ 
+    bytes32 public constant PARAM_ACCOUNT = keccak256("account");
+    bytes32 public constant PARAM_AMOUNT = keccak256("amount");
+ 
+    // mint(address,uint256)
+    bytes4 private constant MINT_SELECTOR = bytes4(keccak256("mint(address,uint256)"));
+    // burnFrom(address,uint256)
+    bytes4 private constant BURN_FROM_SELECTOR = bytes4(keccak256("burnFrom(address,uint256)"));
+    // burn(uint256)
+    bytes4 private constant BURN_SELECTOR = bytes4(keccak256("burn(uint256)"));
+ 
+    function extract(
+        IPolicyEngine.Payload calldata payload
+    ) external pure override returns (IPolicyEngine.Parameter[] memory) {
+        address account;
+        uint256 amount;
+ 
+        if (payload.selector == MINT_SELECTOR || payload.selector == BURN_FROM_SELECTOR) {
+            (account, amount) = abi.decode(payload.data, (address, uint256));
+        } else if (payload.selector == BURN_SELECTOR) {
+            account = payload.sender;
+            (amount) = abi.decode(payload.data, (uint256));
+        } else {
+            revert IPolicyEngine.UnsupportedSelector(payload.selector);
+        }
+ 
+        IPolicyEngine.Parameter[] memory result = new IPolicyEngine.Parameter[](2);
+        result[0] = IPolicyEngine.Parameter(PARAM_ACCOUNT, abi.encode(account));
+        result[1] = IPolicyEngine.Parameter(PARAM_AMOUNT, abi.encode(amount));
+        return result;
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/chainlink-ace/custom/TransferValidationPolicy.sol.html b/doc/coverage/modules/chainlink-ace/custom/TransferValidationPolicy.sol.html new file mode 100644 index 0000000..d77d463 --- /dev/null +++ b/doc/coverage/modules/chainlink-ace/custom/TransferValidationPolicy.sol.html @@ -0,0 +1,488 @@ + + + + Code coverage report for modules/chainlink-ace/custom/TransferValidationPolicy.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/custom/ TransferValidationPolicy.sol +

+
+
+ 100% + Statements + 34/34 +
+
+ 83.33% + Branches + 15/18 +
+
+ 100% + Functions + 6/6 +
+
+ 100% + Lines + 39/39 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +77× +  +  +  +  +  +  +  +  +  +  +37× +34× +34× +34× +41× +41× +  +  +  +  +  +  +  +  +  + + + + + + +  + +  +  +  +  +  +  + +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +39× +39× +  +39× + +  +  +35× +  +33× +33× +33× +33× +  +33× +35× +35× +13× +13× +  +  +  +  + + + +  + + + + + +  +  +  +  +21× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {Policy} from "@chainlink/policy-management/core/Policy.sol";
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+import {IRule} from "CMTAT/mocks/RuleEngine/interfaces/IRule.sol";
+ 
+/**
+ * @title TransferValidationPolicy
+ * @notice A policy that validates ERC-20 transfers by running an array of IRule
+ *         contracts, mimicking CMTAT's _canTransferWithRuleEngine() behavior.
+ * @dev Works with both ERC20TransferExtractor (3 params) and
+ *      ERC20TransferFromExtractor (4 params):
+ *
+ *      3 parameters: [from, to, amount]
+ *        → uses detectTransferRestriction(from, to, amount)
+ *
+ *      4 parameters: [spender, from, to, amount]
+ *        → uses detectTransferRestrictionFrom(spender, from, to, amount)
+ *
+ *      Each IRule is checked in order. If any rule returns a non-zero code
+ *      the policy reverts with PolicyRejected containing the rule's message.
+ */
+contract TransferValidationPolicy is Policy {
+    error InvalidParametersLength(uint256 length);
+ 
+    string public constant override typeAndVersion = "TransferValidationPolicy 1.0.0";
+    event RulesUpdated(uint256 previousCount, uint256 newCount);
+ 
+    /// @custom:storage-location erc7201:cmta.TransferValidationPolicy
+    struct TransferValidationStorage {
+        IRule[] rules;
+    }
+ 
+    // keccak256(abi.encode(uint256(keccak256("cmta.TransferValidationPolicy")) - 1)) & ~bytes32(uint256(0xff))
+    bytes32 private constant STORAGE_LOCATION = 0xd90ded5881f9295c61e86b2e3b551acbb5fe06f9f79d0cec87ddc5bb60d48e00;
+ 
+    function _getStorage() private pure returns (TransferValidationStorage storage $) {
+        assembly {
+            $.slot := STORAGE_LOCATION
+        }
+    }
+ 
+    /**
+     * @inheritdoc Policy
+     * @dev Decodes an array of IRule addresses to set as initial rules.
+     *      Pass empty bytes if no initial rules are needed.
+     */
+    function configure(bytes calldata parameters) internal override EonlyInitializing {
+        if (parameters.length > 0) {
+            address[] memory ruleAddrs = abi.decode(parameters, (address[]));
+            TransferValidationStorage storage $ = _getStorage();
+            for (uint256 i = 0; i < ruleAddrs.length; ++i) {
+                Erequire(ruleAddrs[i] != address(0), "Rule address cannot be zero");
+                $.rules.push(IRule(ruleAddrs[i]));
+            }
+        }
+    }
+ 
+    /**
+     * @notice Replaces all rules with a new set.
+     * @param rules_ The new array of IRule contracts.
+     */
+    function setRules(IRule[] calldata rules_) external onlyOwner {
+        TransferValidationStorage storage $ = _getStorage();
+        uint256 previousCount = $.rules.length;
+        delete $.rules;
+        for (uint256 i = 0; i < rules_.length; ++i) {
+            Erequire(address(rules_[i]) != address(0), "Rule address cannot be zero");
+            $.rules.push(rules_[i]);
+        }
+        emit RulesUpdated(previousCount, rules_.length);
+    }
+ 
+    /**
+     * @notice Returns the current rules.
+     */
+    function rules() external view returns (IRule[] memory) {
+        return _getStorage().rules;
+    }
+ 
+    /**
+     * @notice Returns the number of rules.
+     */
+    function rulesCount() external view returns (uint256) {
+        return _getStorage().rules.length;
+    }
+ 
+    /**
+     * @inheritdoc Policy
+     * @dev Supports both 3-param (transfer) and 4-param (transferFrom) layouts.
+     *      With 4 parameters, uses detectTransferRestrictionFrom to also validate
+     *      the spender.
+     */
+    function run(
+        address /* caller */,
+        address /* subject */,
+        bytes4 /* selector */,
+        bytes[] calldata parameters,
+        bytes calldata /* context */
+    ) public view override returns (IPolicyEngine.PolicyResult) {
+        TransferValidationStorage storage $ = _getStorage();
+        uint256 len = $.rules.length;
+ 
+        if (parameters.length != 3 && parameters.length != 4) {
+            revert InvalidParametersLength(parameters.length);
+        }
+ 
+        if (parameters.length == 4) {
+            // ERC20TransferFromExtractor layout: [spender, from, to, amount]
+            address spender = abi.decode(parameters[0], (address));
+            address from = abi.decode(parameters[1], (address));
+            address to = abi.decode(parameters[2], (address));
+            uint256 amount = abi.decode(parameters[3], (uint256));
+ 
+            for (uint256 i = 0; i < len; ++i) {
+                uint8 code = $.rules[i].detectTransferRestrictionFrom(spender, from, to, amount);
+                if (code != 0) {
+                    string memory message = $.rules[i].messageForTransferRestriction(code);
+                    revert IPolicyEngine.PolicyRejected(message);
+                }
+            }
+        } else {
+            // ERC20TransferExtractor layout: [from, to, amount]
+            address from = abi.decode(parameters[0], (address));
+            address to = abi.decode(parameters[1], (address));
+            uint256 amount = abi.decode(parameters[2], (uint256));
+ 
+            for (uint256 i = 0; i < len; ++i) {
+                uint8 code = $.rules[i].detectTransferRestriction(from, to, amount);
+                if (code != 0) {
+                    string memory message = $.rules[i].messageForTransferRestriction(code);
+                    revert IPolicyEngine.PolicyRejected(message);
+                }
+            }
+        }
+ 
+        return IPolicyEngine.PolicyResult.Continue;
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/chainlink-ace/custom/index.html b/doc/coverage/modules/chainlink-ace/custom/index.html new file mode 100644 index 0000000..0c49bff --- /dev/null +++ b/doc/coverage/modules/chainlink-ace/custom/index.html @@ -0,0 +1,119 @@ + + + + Code coverage report for modules/chainlink-ace/custom/ + + + + + + + +
+
+

+ all files modules/chainlink-ace/custom/ +

+
+
+ 100% + Statements + 48/48 +
+
+ 85.71% + Branches + 24/28 +
+
+ 100% + Functions + 8/8 +
+
+ 98.51% + Lines + 66/67 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
ERC20TransferFromExtractor.sol
100%8/875%3/4100%1/194.12%16/17
MintBurnExtractor.sol
100%6/6100%6/6100%1/1100%11/11
TransferValidationPolicy.sol
100%34/3483.33%15/18100%6/6100%39/39
+
+
+ + + + + + + diff --git a/doc/coverage/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol.html b/doc/coverage/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol.html new file mode 100644 index 0000000..db0ea57 --- /dev/null +++ b/doc/coverage/modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol.html @@ -0,0 +1,374 @@ + + + + Code coverage report for modules/chainlink-ace/mocks/PolicyProtectedUpgradeableMocks.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/mocks/ PolicyProtectedUpgradeableMocks.sol +

+
+
+ 30% + Statements + 3/10 +
+
+ 25% + Branches + 1/4 +
+
+ 18.52% + Functions + 5/27 +
+
+ 35.71% + Lines + 5/14 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  + +  + 
// SPDX-License-Identifier: BUSL-1.1
+pragma solidity ^0.8.20;
+ 
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+import {ValidationModulePolicyEngine} from "../../lite/ValidationModulePolicyEngine.sol";
+ 
+contract MockPolicyEngine is IPolicyEngine {
+    Payload public lastPayload;
+    uint256 public attachCalls;
+    uint256 public detachCalls;
+    bool public detachShouldRevert;
+ 
+    function setDetachShouldRevert(bool value) external {
+        detachShouldRevert = value;
+    }
+ 
+    function typeAndVersion() external pure override returns (string memory) {
+        return "MockPolicyEngine 1.0.0";
+    }
+ 
+    function attach() external override {
+        attachCalls++;
+    }
+ 
+    function detach() external override {
+        detachCalls++;
+        if (detachShouldRevert) {
+            revert("MockPolicyEngine: detach failed");
+        }
+    }
+ 
+    function run(Payload calldata payload) external override {
+        lastPayload = payload;
+    }
+ 
+    function check(Payload calldata) external pure override {}
+ 
+    function setExtractor(bytes4, address) external pure override {}
+ 
+    function setExtractors(bytes4[] calldata, address) external pure override {}
+ 
+    function getExtractor(bytes4) external pure override returns (address) {
+        return address(0);
+    }
+ 
+    function setPolicyMapper(address, address) external pure override {}
+ 
+    function getPolicyMapper(address) external pure override returns (address) {
+        return address(0);
+    }
+ 
+    function addPolicy(address, bytes4, address, bytes32[] calldata) external pure override {}
+ 
+    function addPolicyAt(address, bytes4, address, bytes32[] calldata, uint256) external pure override {}
+ 
+    function removePolicy(address, bytes4, address) external pure override {}
+ 
+    function getPolicies(address, bytes4) external pure override returns (address[] memory) {
+        return new address[](0);
+    }
+ 
+    function setPolicyConfiguration(address, uint256, bytes4, bytes calldata) external pure override {}
+ 
+    function getPolicyConfigVersion(address) external pure override returns (uint256) {
+        return 0;
+    }
+ 
+    function upgradePolicy(address, address, bytes calldata) external pure override {}
+ 
+    function setDefaultPolicyAllow(bool) external pure override {}
+ 
+    function setTargetDefaultPolicyAllow(address, bool) external pure override {}
+}
+ 
+contract ValidationModulePolicyEngineHarness is ValidationModulePolicyEngine {
+    function initializeWithPolicyEngine(address policyEngine) external Einitializer {
+        __PolicyProtectedBase_init(policyEngine);
+    }
+ 
+    function _authorizeAttachPolicyEngine(address) internal pure override {}
+ 
+    function _authorizePause() internal pure override {}
+ 
+    function _authorizeDeactivate() internal pure override {}
+ 
+    function _authorizeFreeze() internal pure override {}
+ 
+    function exposedTryCheckPolicies(
+        bytes4 selector,
+        address sender,
+        bytes calldata data
+    ) external view returns (bool) {
+        return _tryCheckPolicies(selector, sender, data);
+    }
+ 
+    function exposedTransferred(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) external returns (bool) {
+        return _transferred(spender, from, to, value);
+    }
+}
+
+
+ + + + + + + diff --git a/doc/coverage/modules/chainlink-ace/mocks/TransferRuleMocks.sol.html b/doc/coverage/modules/chainlink-ace/mocks/TransferRuleMocks.sol.html new file mode 100644 index 0000000..d47d98b --- /dev/null +++ b/doc/coverage/modules/chainlink-ace/mocks/TransferRuleMocks.sol.html @@ -0,0 +1,536 @@ + + + + Code coverage report for modules/chainlink-ace/mocks/TransferRuleMocks.sol + + + + + + + +
+
+

+ all files / modules/chainlink-ace/mocks/ TransferRuleMocks.sol +

+
+
+ 62.5% + Statements + 15/24 +
+
+ 66.67% + Branches + 12/18 +
+
+ 45.45% + Functions + 10/22 +
+
+ 64% + Lines + 16/25 +
+
+
+
+

+
+
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 +156 +157 +158  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +30× +  +  +  +  +  +  +  +25× +  +  +  +  +  +  +  +  +23× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  +  +  +14× +14× +12× +  +  +  +  + +  +  +  +  +  +  +  +12× +10× + +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {IRule} from "../../../../submodules/RuleEngine/src/interfaces/IRule.sol";
+ 
+/**
+ * @dev WARNING: Mock rule contracts for tests/examples only.
+ *      Not designed, reviewed, or hardened for production deployments.
+ */
+ 
+/**
+ * @title MaxAmountRule
+ * @notice Rejects transfers where the amount exceeds a configurable maximum.
+ */
+contract MaxAmountRule is IRule {
+    uint256 public immutable maxAmount;
+    uint8 constant AMOUNT_TOO_HIGH = 13;
+ 
+    constructor(uint256 maxAmount_) {
+        maxAmount = maxAmount_;
+    }
+ 
+    function detectTransferRestriction(
+        address /* from */,
+        address /* to */,
+        uint256 amount
+    ) public view override returns (uint8) {
+        return amount > maxAmount ? AMOUNT_TOO_HIGH : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+    }
+ 
+    function detectTransferRestrictionFrom(
+        address /* spender */,
+        address from,
+        address to,
+        uint256 amount
+    ) public view override returns (uint8) {
+        return detectTransferRestriction(from, to, amount);
+    }
+ 
+    function canTransfer(address from, address to, uint256 amount) public view override returns (bool) {
+        return detectTransferRestriction(from, to, amount) == 0;
+    }
+ 
+     function canTransferFrom(
+        address /* spender */,
+        address from,
+        address to,
+        uint256 amount
+    ) external view override returns (bool) {
+        return canTransfer(from, to, amount);
+    }
+ 
+    function transferred(address /* from */, address /* to */, uint256 /* value */) external pure override {}
+ 
+    function transferred(
+        address /* spender */,
+        address /* from */,
+        address /* to */,
+        uint256 /* value */
+    ) external pure override {}
+ 
+    function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
+        return interfaceId == type(IRule).interfaceId;
+    }
+ 
+    function canReturnTransferRestrictionCode(uint8 code) public pure override returns (bool) {
+        return code == AMOUNT_TOO_HIGH;
+    }
+ 
+    function messageForTransferRestriction(uint8 code) external pure override returns (string memory) {
+        return code == AMOUNT_TOO_HIGH ? "Amount exceeds maximum" : E"Unknown code";
+    }
+}
+ 
+/**
+ * @title RestrictedAddressRule
+ * @notice Rejects transfers involving addresses on a restricted list.
+ */
+contract RestrictedAddressRule is IRule {
+    uint8 constant FROM_RESTRICTED = 14;
+    uint8 constant TO_RESTRICTED = 15;
+ 
+    mapping(address => bool) public restricted;
+    address public immutable owner;
+ 
+    modifier onlyOwner() {
+        Erequire(msg.sender == owner, "only owner");
+        _;
+    }
+ 
+    constructor(address[] memory restricted_) {
+        owner = msg.sender;
+        for (uint256 i = 0; i < restricted_.length; ++i) {
+            restricted[restricted_[i]] = true;
+        }
+    }
+ 
+    function setRestricted(address account, bool status) external EonlyOwner {
+        restricted[account] = status;
+    }
+ 
+    function detectTransferRestriction(
+        address from,
+        address to,
+        uint256 /* amount */
+    ) public view override returns (uint8) {
+        if (restricted[from]) return FROM_RESTRICTED;
+        if (restricted[to]) return TO_RESTRICTED;
+        return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+    }
+ 
+    function detectTransferRestrictionFrom(
+        address /* spender */,
+        address from,
+        address to,
+        uint256 amount
+    ) public view override returns (uint8) {
+        return detectTransferRestriction(from, to, amount);
+    }
+ 
+    function canTransfer(address from, address to, uint256 amount) public view override returns (bool) {
+        return detectTransferRestriction(from, to, amount) == 0;
+    }
+ 
+    function canTransferFrom(
+        address /* spender */,
+        address from,
+        address to,
+        uint256 amount
+    ) external view override returns (bool) {
+        return canTransfer(from, to, amount);
+    }
+ 
+    function transferred(address /* from */, address /* to */, uint256 /* value */) external pure override {}
+ 
+    function transferred(
+        address /* spender */,
+        address /* from */,
+        address /* to */,
+        uint256 /* value */
+    ) external pure override {}
+ 
+    function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
+        return interfaceId == type(IRule).interfaceId;
+    }
+ 
+    function canReturnTransferRestrictionCode(uint8 code) public pure override returns (bool) {
+        return code == FROM_RESTRICTED || code == TO_RESTRICTED;
+    }
+ 
+    function messageForTransferRestriction(uint8 code) external pure override returns (string memory) {
+        if (code == FROM_RESTRICTED) return "Sender is restricted";
+        Eif (code == TO_RESTRICTED) return "Recipient is restricted";
+        return "Unknown code";
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/chainlink-ace/mocks/index.html b/doc/coverage/modules/chainlink-ace/mocks/index.html new file mode 100644 index 0000000..43b901a --- /dev/null +++ b/doc/coverage/modules/chainlink-ace/mocks/index.html @@ -0,0 +1,93 @@ + + + + Code coverage report for modules/chainlink-ace/mocks/ + + + + + + + +
+
+

+ all files modules/chainlink-ace/mocks/ +

+
+
+ 62.5% + Statements + 15/24 +
+
+ 66.67% + Branches + 12/18 +
+
+ 45.45% + Functions + 10/22 +
+
+ 64% + Lines + 16/25 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
TransferRuleMocks.sol
62.5%15/2466.67%12/1845.45%10/2264%16/25
+
+
+ + + + + + + diff --git a/doc/coverage/modules/lite/CCTCMTATBaseERC1404.sol.html b/doc/coverage/modules/lite/CCTCMTATBaseERC1404.sol.html new file mode 100644 index 0000000..44fc278 --- /dev/null +++ b/doc/coverage/modules/lite/CCTCMTATBaseERC1404.sol.html @@ -0,0 +1,323 @@ + + + + Code coverage report for modules/lite/CCTCMTATBaseERC1404.sol + + + + + + + +
+
+

+ all files / modules/lite/ CCTCMTATBaseERC1404.sol +

+
+
+ 100% + Statements + 12/12 +
+
+ 83.33% + Branches + 5/6 +
+
+ 100% + Functions + 5/5 +
+
+ 100% + Lines + 12/12 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +10× +  +  +  + +  + +  +  +  +  +  +  +  +  +  +  +  +233× +  +  +  +  +  +  +  +  +  +  +  +35× +  +  +  +  +  +  +  +  +  +  + + + + + +  +  + +  +  +  +  +  + +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {CCTCMTATBasePolicyEngine} from "./CCTCMTATBasePolicyEngine.sol";
+import {PolicyValidationModuleERC1404, IERC1404, IERC1404Extend} from "./PolicyValidationModuleERC1404.sol";
+import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {
+    ERC20EnforcementModule,
+    ERC20EnforcementModuleInternal
+} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol";
+ 
+abstract contract CCTCMTATBaseERC1404 is CCTCMTATBasePolicyEngine, PolicyValidationModuleERC1404 {
+    /**
+     * @dev ERC20EnforcementModule error text
+     */
+    string internal constant TEXT_TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE =
+        "AddrFrom:insufficientActiveBalance";
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+ 
+    /**
+     * @inheritdoc PolicyValidationModuleERC1404
+     */
+    function messageForTransferRestriction(
+        uint8 restrictionCode
+    ) public view virtual override(PolicyValidationModuleERC1404) returns (string memory message) {
+        if (
+            restrictionCode ==
+            uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE)
+        ) {
+            return TEXT_TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE;
+        } else {
+            return PolicyValidationModuleERC1404.messageForTransferRestriction(restrictionCode);
+        }
+    }
+ 
+    /**
+     * @inheritdoc CCTCMTATBasePolicyEngine
+     */
+    function canTransfer(
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(CCTCMTATBasePolicyEngine, ValidationModuleCore) returns (bool) {
+        return CCTCMTATBasePolicyEngine.canTransfer(from, to, value);
+    }
+ 
+    /**
+     * @inheritdoc CCTCMTATBasePolicyEngine
+     */
+    function canTransferFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(CCTCMTATBasePolicyEngine, ValidationModuleCore) returns (bool) {
+        return CCTCMTATBasePolicyEngine.canTransferFrom(spender, from, to, value);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    function _detectTransferRestriction(
+        address from,
+        address to,
+        uint256 value
+    ) internal view virtual override(PolicyValidationModuleERC1404) returns (uint8 code) {
+        uint256 frozenTokensLocal = ERC20EnforcementModule.getFrozenTokens(from);
+        if (frozenTokensLocal > 0) {
+            uint256 activeBalance = ERC20Upgradeable.balanceOf(from) - frozenTokensLocal;
+            Eif (value > activeBalance) {
+                return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_INSUFFICIENT_ACTIVE_BALANCE);
+            }
+        }
+        return PolicyValidationModuleERC1404._detectTransferRestriction(from, to, value);
+    }
+ 
+    function supportsInterface(
+        bytes4 interfaceId
+    ) public view virtual override(CCTCMTATBasePolicyEngine) returns (bool) {
+        return CCTCMTATBasePolicyEngine.supportsInterface(interfaceId);
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/lite/CCTCMTATBaseERC20CrossChain.sol.html b/doc/coverage/modules/lite/CCTCMTATBaseERC20CrossChain.sol.html new file mode 100644 index 0000000..ce0c13d --- /dev/null +++ b/doc/coverage/modules/lite/CCTCMTATBaseERC20CrossChain.sol.html @@ -0,0 +1,572 @@ + + + + Code coverage report for modules/lite/CCTCMTATBaseERC20CrossChain.sol + + + + + + + +
+
+

+ all files / modules/lite/ CCTCMTATBaseERC20CrossChain.sol +

+
+
+ 100% + Statements + 15/15 +
+
+ 100% + Branches + 16/16 +
+
+ 100% + Functions + 15/15 +
+
+ 100% + Lines + 15/15 +
+
+
+
+

+
+
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 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +119× +  +  +  +  +  +81× +  +  +  +  +  +  +  +  +  +29× +  +  +  +  +  +  +  +  +735× +720× +  +  +  +  +  +  +  +  +  +144× +120× +  +  +  +  +  +  +  +  +  +  +27× +18× +  +  +  +  +  +  + +  +  +  +  +  +  +10× +  +  +  +  +  +  +10× +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +39× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +943× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {ERC20CrossChainModule} from "CMTAT/modules/wrapper/options/ERC20CrossChainModule.sol";
+import {CCIPModule} from "CMTAT/modules/wrapper/options/CCIPModule.sol";
+import {CCTCMTATBaseERC1404} from "./CCTCMTATBaseERC1404.sol";
+import {CMTATBaseCommon} from "CMTAT/modules/0_CMTATBaseCommon.sol";
+import {
+    ERC20MintModule,
+    ERC20MintModuleInternal
+} from "CMTAT/modules/wrapper/core/ERC20MintModule.sol";
+import {
+    ERC20BurnModule,
+    ERC20BurnModuleInternal
+} from "CMTAT/modules/wrapper/core/ERC20BurnModule.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {AccessControlUpgradeable} from "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
+ 
+abstract contract CCTCMTATBaseERC20CrossChain is ERC20CrossChainModule, CCIPModule, CCTCMTATBaseERC1404 {
+    /* ============  State Functions ============ */
+    /**
+     * @dev revert if the contract is in pause state
+     */
+    function approve(
+        address spender,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable) whenNotPaused returns (bool) {
+        return ERC20Upgradeable.approve(spender, value);
+    }
+    function transfer(
+        address to,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (bool) {
+        return CMTATBaseCommon.transfer(to, value);
+    }
+    /*
+     * @inheritdoc ERC20BaseModule
+     */
+    function transferFrom(
+        address from,
+        address to,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (bool) {
+        return CMTATBaseCommon.transferFrom(from, to, value);
+    }
+    /**
+     * @dev Check if the mint is valid
+     */
+    function _mintOverride(
+        address account,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
+        _checkTransferred(address(0), address(0), account, value);
+        ERC20MintModuleInternal._mintOverride(account, value);
+    }
+ 
+    /**
+     * @dev Check if the burn is valid
+     */
+    function _burnOverride(
+        address account,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) {
+        _checkTransferred(address(0), account, address(0), value);
+        ERC20BurnModuleInternal._burnOverride(account, value);
+    }
+ 
+    /**
+     * @dev Check if a minter transfer is valid
+     */
+    function _minterTransferOverride(
+        address from,
+        address to,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
+        _checkTransferred(address(0), from, to, value);
+        ERC20MintModuleInternal._minterTransferOverride(from, to, value);
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function decimals() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (uint8) {
+        return CMTATBaseCommon.decimals();
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function name() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) {
+        return CMTATBaseCommon.name();
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function symbol() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) {
+        return CMTATBaseCommon.symbol();
+    }
+ 
+    /* ============ View functions ============ */
+    function supportsInterface(
+        bytes4 _interfaceId
+    ) public view virtual override(ERC20CrossChainModule, CCTCMTATBaseERC1404) returns (bool) {
+        return
+            ERC20CrossChainModule.supportsInterface(_interfaceId) ||
+            CCTCMTATBaseERC1404.supportsInterface(_interfaceId);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ==== Access Control ==== */
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DEFAULT_ADMIN_ROLE`.
+     */
+    function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) onlyRole(DEFAULT_ADMIN_ROLE) {}
+ 
+    /**
+     * @dev
+     * A cross-chain bridge could call the OpenZeppelin function `renounceRole` to lose their privileges (CROSS_CHAIN_ROLE)
+     * While it is not intended,this has no other effect than depriving the bridge of burn/mint tokens
+     * An attacker could use this to disrupt minting/burning if they can get the bridge to execute calls.
+     * However, in this case, the bridge should still be considered compromised and not used again.
+     * @custom:access-control
+     * - the caller must have the `CROSS_CHAIN_ROLE`.
+     */
+    function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule) whenNotPaused {
+        AccessControlUpgradeable._checkRole(CROSS_CHAIN_ROLE, caller);
+    }
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `BURNER_FROM_ROLE`.
+     * - We don't allow token holder to burn their own tokens if they don't have this role.
+     */
+    function _authorizeBurnFrom()
+        internal
+        virtual
+        override(ERC20CrossChainModule)
+        onlyRole(BURNER_FROM_ROLE)
+        whenNotPaused
+    {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `BURNER_SELF_ROLE`.
+     * - We don't allow token holder to burn their own tokens if they don't have this role.
+     */
+    function _authorizeSelfBurn()
+        internal
+        virtual
+        override(ERC20CrossChainModule)
+        onlyRole(BURNER_SELF_ROLE)
+        whenNotPaused
+    {}
+ 
+    /* ==== ERC-20 OpenZeppelin ==== */
+    function _update(
+        address from,
+        address to,
+        uint256 amount
+    ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) {
+        return CMTATBaseCommon._update(from, to, amount);
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/lite/CCTCMTATBasePolicyEngine.sol.html b/doc/coverage/modules/lite/CCTCMTATBasePolicyEngine.sol.html new file mode 100644 index 0000000..f2e3cf8 --- /dev/null +++ b/doc/coverage/modules/lite/CCTCMTATBasePolicyEngine.sol.html @@ -0,0 +1,674 @@ + + + + Code coverage report for modules/lite/CCTCMTATBasePolicyEngine.sol + + + + + + + +
+
+

+ all files / modules/lite/ CCTCMTATBasePolicyEngine.sol +

+
+
+ 95.45% + Statements + 21/22 +
+
+ 69.23% + Branches + 18/26 +
+
+ 84.62% + Functions + 11/13 +
+
+ 95.45% + Lines + 21/22 +
+
+
+
+

+
+
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 +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 +203 +204  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +55× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +55× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +55× +  +  +55× +  +  +55× +  +  +55× +  +  +55× +55× +  +  +55× +  +  +  +  +  +  +  +  +  +55× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +233× +233× +88× +  +145× +  +  +  +  +  +  +  +  +  +  +  +  +35× +35× +12× +  +23× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1016× +998× +  +  +  +  +  +  +  +  + +  +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {
+    CMTATBaseCommon,
+    CMTATBaseAccessControl
+} from "CMTAT/modules/1_CMTATBaseAccessControl.sol";
+import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol";
+import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol";
+import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol";
+import {IERC1643} from "CMTAT/interfaces/tokenization/draft-IERC1643.sol";
+import {ValidationModulePolicyEngine} from "./ValidationModulePolicyEngine.sol";
+import {PauseModule} from "CMTAT/modules/wrapper/core/PauseModule.sol";
+import {EnforcementModule} from "CMTAT/modules/wrapper/core/EnforcementModule.sol";
+import {IERC7943FungibleTransferError} from "CMTAT/interfaces/tokenization/draft-IERC7943.sol";
+// Extensions
+import {
+    ERC20EnforcementModule,
+    ERC20EnforcementModuleInternal
+} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol";
+ 
+abstract contract CCTCMTATBasePolicyEngine is
+    CMTATBaseAccessControl,
+    ValidationModulePolicyEngine,
+    IERC7943FungibleTransferError
+{
+    /*//////////////////////////////////////////////////////////////
+                         INITIALIZER FUNCTION
+    //////////////////////////////////////////////////////////////*/
+    /**
+     * @notice
+     * initialize the proxy contract
+     * The calls to this function will revert if the contract was deployed without a proxy
+     * @param admin address of the admin of contract (Access Control)
+     * @param ERC20Attributes_ ERC20 name, symbol and decimals
+     * @param extraInformationAttributes_ tokenId, terms, information
+     * @param policyEngine_ address of the policy engine
+     * @dev
+     * If you override the public function initialize,
+     * call inside directly the internal function, not the public one which is protected by the initializer modifier
+     */
+    function initialize(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) public virtual initializer {
+        _initialize(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine_,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+ 
+    /**
+     * @dev don't call the initializer modifer
+     */
+    function _initialize(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) internal virtual EonlyInitializing {
+        __CMTAT_init(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine_,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+ 
+    /**
+     * @dev calls the different initialize functions from the different modules
+     */
+    function __CMTAT_init(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine_,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) internal virtual EonlyInitializing {
+        /* OpenZeppelin library */
+        // OZ init_unchained functions are called firstly due to inheritance
+        __Context_init_unchained();
+ 
+        // AccessControlUpgradeable inherits from ERC165Upgradeable
+        __ERC165_init_unchained();
+ 
+        // Openzeppelin
+        __CMTAT_openzeppelin_init_unchained(ERC20Attributes_);
+ 
+        /* Wrapper modules */
+        __CMTAT_commonModules_init_unchained(admin, ERC20Attributes_, extraInformationAttributes_);
+ 
+        /* Engine modules */
+        __SnapshotEngineModule_init_unchained(snapshotEngine_);
+        __DocumentEngineModule_init_unchained(documentEngine_);
+ 
+        /* Chainlink-ACE policy module */
+        __PolicyProtectedBase_init_unchained(policyEngine_);
+    }
+ 
+    /*
+     * @dev OpenZeppelin
+     */
+    function __CMTAT_openzeppelin_init_unchained(
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_
+    ) internal virtual EonlyInitializing {
+        // Note that the Openzeppelin functions name() and symbol() are overriden in ERC20BaseModule
+        __ERC20_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol);
+    }
+ 
+    /*
+     * @dev CMTAT wrapper modules
+     */
+    function __CMTAT_modules_init_unchained(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_
+    ) internal virtual onlyInitializing {
+        __CMTAT_commonModules_init_unchained(admin, ERC20Attributes_, extraInformationAttributes_);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /**
+     * @inheritdoc ValidationModulePolicyEngine
+     */
+    function canTransfer(
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(ValidationModulePolicyEngine) returns (bool) {
+        (bool isValid, ) = ERC20EnforcementModuleInternal._checkActiveBalance(from, value);
+        if (!isValid) {
+            return false;
+        } else {
+            return ValidationModulePolicyEngine.canTransfer(from, to, value);
+        }
+    }
+ 
+    /**
+     * @inheritdoc ValidationModulePolicyEngine
+     */
+    function canTransferFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(ValidationModulePolicyEngine) returns (bool) {
+        (bool isValid, ) = ERC20EnforcementModuleInternal._checkActiveBalance(from, value);
+        if (!isValid) {
+            return false;
+        } else {
+            return ValidationModulePolicyEngine.canTransferFrom(spender, from, to, value);
+        }
+    }
+ 
+    function _authorizeAttachPolicyEngine(address) internal virtual override onlyRole(DEFAULT_ADMIN_ROLE) {}
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ==== Access Control ==== */
+    function _authorizePause() internal virtual override(PauseModule) onlyRole(PAUSER_ROLE) {}
+    function _authorizeDeactivate() internal virtual override(PauseModule) onlyRole(DEFAULT_ADMIN_ROLE) {}
+ 
+    function _authorizeFreeze() internal virtual override(EnforcementModule) onlyRole(ENFORCER_ROLE) {}
+ 
+    /* ==== Transfer/mint/burn restriction ==== */
+    function _checkTransferred(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon) {
+        CMTATBaseCommon._checkTransferred(spender, from, to, value);
+        require(
+            ValidationModulePolicyEngine._transferred(spender, from, to, value),
+            ERC7943CannotTransfer(from, to, value)
+        );
+    }
+ 
+    function supportsInterface(
+        bytes4 interfaceId
+    ) public view virtual override(CMTATBaseAccessControl, PolicyProtectedBaseUpgradeable) returns (bool) {
+        return
+            CMTATBaseAccessControl.supportsInterface(interfaceId) ||
+            PolicyProtectedBaseUpgradeable.supportsInterface(interfaceId);
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/lite/PolicyValidationModuleERC1404.sol.html b/doc/coverage/modules/lite/PolicyValidationModuleERC1404.sol.html new file mode 100644 index 0000000..55557a8 --- /dev/null +++ b/doc/coverage/modules/lite/PolicyValidationModuleERC1404.sol.html @@ -0,0 +1,440 @@ + + + + Code coverage report for modules/lite/PolicyValidationModuleERC1404.sol + + + + + + + +
+
+

+ all files / modules/lite/ PolicyValidationModuleERC1404.sol +

+
+
+ 100% + Statements + 32/32 +
+
+ 100% + Branches + 26/26 +
+
+ 100% + Functions + 4/4 +
+
+ 100% + Lines + 24/24 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  + +  + +  + +  + +  + +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + + +  + +  +  +  +  +  +  +  +  +  + + +  + + + +  + +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  + + +  + +  + +  + +  + +  +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+/* ==== Tokenization === */
+import {IERC1404, IERC1404Extend} from "CMTAT/interfaces/tokenization/draft-IERC1404.sol";
+import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol";
+ 
+/**
+ * @dev Validation module (ERC-1404)
+ *
+ * Useful to restrict and validate transfers
+ */
+abstract contract PolicyValidationModuleERC1404 is ValidationModuleCore, IERC1404Extend {
+    /* ============ State Variables ============ */
+    string constant TEXT_TRANSFER_OK = "NoRestriction";
+    string constant TEXT_UNKNOWN_CODE = "UnknownCode";
+ 
+    /* EnforcementModule */
+    string internal constant TEXT_TRANSFER_REJECTED_FROM_FROZEN = "AddrFromIsFrozen";
+ 
+    string internal constant TEXT_TRANSFER_REJECTED_TO_FROZEN = "AddrToIsFrozen";
+ 
+    string internal constant TEXT_TRANSFER_REJECTED_SPENDER_FROZEN = "AddrSpenderIsFrozen";
+ 
+    /* PauseModule */
+    string internal constant TEXT_TRANSFER_REJECTED_PAUSED = "EnforcedPause";
+ 
+    /* Contract deactivated */
+    string internal constant TEXT_TRANSFER_REJECTED_DEACTIVATED = "ContractDeactivated";
+ 
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /**
+     * @notice returns the human readable explanation
+     * corresponding to the error code returned by detectTransferRestriction
+     * @param restrictionCode The error code returned by detectTransferRestriction
+     * @return message The human readable explanation corresponding to the error code returned by detectTransferRestriction
+     * @dev see {ERC-1404}
+     */
+    function messageForTransferRestriction(
+        uint8 restrictionCode
+    ) public view virtual override(IERC1404) returns (string memory message) {
+        if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) {
+            return TEXT_TRANSFER_OK;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED)) {
+            return TEXT_TRANSFER_REJECTED_PAUSED;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_DEACTIVATED)) {
+            return TEXT_TRANSFER_REJECTED_DEACTIVATED;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN)) {
+            return TEXT_TRANSFER_REJECTED_FROM_FROZEN;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN)) {
+            return TEXT_TRANSFER_REJECTED_TO_FROZEN;
+        } else if (restrictionCode == uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN)) {
+            return TEXT_TRANSFER_REJECTED_SPENDER_FROZEN;
+        } else {
+            return TEXT_UNKNOWN_CODE;
+        }
+    }
+ 
+    /**
+     * @notice check if value token can be transferred from `from` to `to`
+     * @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}
+     */
+    function detectTransferRestriction(
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(IERC1404) returns (uint8 code) {
+        uint8 codeReturn = _detectTransferRestriction(from, to, value);
+        if (codeReturn != uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) {
+            return codeReturn;
+        } else {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
+        }
+    }
+ 
+    function detectTransferRestrictionFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(IERC1404Extend) returns (uint8 code) {
+        if (isFrozen(spender)) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_SPENDER_FROZEN);
+        } else {
+            uint8 codeReturn = _detectTransferRestriction(from, to, value);
+            if (codeReturn != uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK)) {
+                return codeReturn;
+            } else {
+                return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
+            }
+        }
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+ 
+    /**
+     * @dev override this function to add further restriction
+     */
+    function _detectTransferRestriction(
+        address from,
+        address to,
+        uint256 /* value */
+    ) internal view virtual returns (uint8 code) {
+        if (deactivated()) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_DEACTIVATED);
+        } else if (paused()) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_PAUSED);
+        } else if (isFrozen(from)) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_FROM_FROZEN);
+        } else if (isFrozen(to)) {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_REJECTED_TO_FROZEN);
+        } else {
+            return uint8(IERC1404Extend.REJECTED_CODE_BASE.TRANSFER_OK);
+        }
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/lite/ValidationModulePolicyEngine.sol.html b/doc/coverage/modules/lite/ValidationModulePolicyEngine.sol.html new file mode 100644 index 0000000..f44f4d0 --- /dev/null +++ b/doc/coverage/modules/lite/ValidationModulePolicyEngine.sol.html @@ -0,0 +1,428 @@ + + + + Code coverage report for modules/lite/ValidationModulePolicyEngine.sol + + + + + + + +
+
+

+ all files / modules/lite/ ValidationModulePolicyEngine.sol +

+
+
+ 100% + Statements + 25/25 +
+
+ 100% + Branches + 10/10 +
+
+ 100% + Functions + 8/8 +
+
+ 100% + Lines + 25/25 +
+
+
+
+

+
+
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  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +145× +  +  +  +  +  +  +  +  +  +  +  +  +23× +  +  +  +  +  +  +  +145× +39× +  +106× +  +  +  +  +  +  +  +  +  +23× +12× +  +11× +  +  +  +  +  +  +  +  +  +11× +  +  +  +  +  +  +  +106× +  +  +  +118× +118× +117× +117× +  +  +  +  +111× +  + +  +  + +  +  +  +  +  +  +  +  +  +  +1001× +932× +932× +931× +931× +  +  +924× + +  +  +925× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+import {ValidationModuleCore} from "CMTAT/modules/wrapper/core/ValidationModuleCore.sol";
+import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol";
+import {IPolicyEngine} from "@chainlink/policy-management/interfaces/IPolicyEngine.sol";
+import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
+ 
+abstract contract ValidationModulePolicyEngine is ValidationModuleCore, PolicyProtectedBaseUpgradeable {
+    /*//////////////////////////////////////////////////////////////
+                            PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+ 
+    /* ============ View functions ============ */
+    /**
+     * @inheritdoc ValidationModuleCore
+     * @dev call the policy engine if set
+     */
+    function canTransfer(
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(ValidationModuleCore) returns (bool) {
+        return _canTransfer(from, to, value);
+    }
+ 
+    /**
+     * @inheritdoc ValidationModuleCore
+     * @dev call the policy engine if set
+     */
+    function canTransferFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) public view virtual override(ValidationModuleCore) returns (bool) {
+        return _canTransferFrom(spender, from, to, value);
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                            INTERNAL/PRIVATE FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============ View functions ============ */
+    function _canTransfer(address from, address to, uint256 value) internal view virtual returns (bool) {
+        if (!ValidationModuleCore.canTransfer(from, to, value)) {
+            return false;
+        } else {
+            return _canTransferWithPolicyEngine(from, to, value);
+        }
+    }
+ 
+    function _canTransferFrom(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) internal view virtual returns (bool) {
+        if (!ValidationModuleCore.canTransferFrom(spender, from, to, value)) {
+            return false;
+        } else {
+            return _canTransferFromWithPolicyEngine(spender, from, to, value);
+        }
+    }
+ 
+    function _canTransferFromWithPolicyEngine(
+        address spender,
+        address from,
+        address to,
+        uint256 value
+    ) internal view virtual returns (bool) {
+        return _tryCheckPolicies(IERC20.transferFrom.selector, spender, abi.encode(from, to, value));
+    }
+ 
+    function _canTransferWithPolicyEngine(
+        address from,
+        address to,
+        uint256 value
+    ) internal view virtual returns (bool) {
+        return _tryCheckPolicies(IERC20.transfer.selector, from, abi.encode(to, value));
+    }
+ 
+    function _tryCheckPolicies(bytes4 selector, address sender, bytes memory data) internal view returns (bool) {
+        IPolicyEngine policyEngine_ = IPolicyEngine(getPolicyEngine());
+        if (address(policyEngine_) != address(0)) {
+            bytes memory context = getContext();
+            try
+                policyEngine_.check(
+                    IPolicyEngine.Payload({selector: selector, sender: sender, data: data, context: context})
+                )
+            {
+                return true;
+            } catch {
+                return false;
+            }
+        } else {
+            return true;
+        }
+    }
+ 
+    /* ============ State functions ============ */
+    function _transferred(
+        address spender,
+        address from,
+        address to,
+        uint256 /* value */
+    ) internal virtual returns (bool) {
+        _canTransferGenericByModuleAndRevert(spender, from, to);
+        IPolicyEngine policyEngine_ = IPolicyEngine(getPolicyEngine());
+        if (address(policyEngine_) != address(0)) {
+            bytes memory context = getContext();
+            policyEngine_.run(
+                IPolicyEngine.Payload({selector: msg.sig, sender: _msgSender(), data: msg.data[4:], context: context})
+            );
+            if (context.length > 0) {
+                clearContext();
+            }
+        }
+        return true;
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/lite/index.html b/doc/coverage/modules/lite/index.html new file mode 100644 index 0000000..b286953 --- /dev/null +++ b/doc/coverage/modules/lite/index.html @@ -0,0 +1,145 @@ + + + + Code coverage report for modules/lite/ + + + + + + + +
+
+

+ all files modules/lite/ +

+
+
+ 99.06% + Statements + 105/106 +
+
+ 89.29% + Branches + 75/84 +
+
+ 95.56% + Functions + 43/45 +
+
+ 98.98% + Lines + 97/98 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
CCTCMTATBaseERC1404.sol
100%12/1283.33%5/6100%5/5100%12/12
CCTCMTATBaseERC20CrossChain.sol
100%15/15100%16/16100%15/15100%15/15
CCTCMTATBasePolicyEngine.sol
95.45%21/2269.23%18/2684.62%11/1395.45%21/22
PolicyValidationModuleERC1404.sol
100%32/32100%26/26100%4/4100%24/24
ValidationModulePolicyEngine.sol
100%25/25100%10/10100%8/8100%25/25
+
+
+ + + + + + + diff --git a/doc/coverage/modules/standard/CCTCommon.sol.html b/doc/coverage/modules/standard/CCTCommon.sol.html new file mode 100644 index 0000000..4d8a056 --- /dev/null +++ b/doc/coverage/modules/standard/CCTCommon.sol.html @@ -0,0 +1,1055 @@ + + + + Code coverage report for modules/standard/CCTCommon.sol + + + + + + + +
+
+

+ all files / modules/standard/ CCTCommon.sol +

+
+
+ 95.83% + Statements + 23/24 +
+
+ 84.09% + Branches + 37/44 +
+
+ 96.55% + Functions + 28/29 +
+
+ 95.83% + Lines + 23/24 +
+
+
+
+

+
+
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 +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 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327 +328 +329 +330 +331  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +12× +  +  +12× +  +  +12× +  +  +12× +  +12× +  +  +12× +  +  +12× +12× +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +12× +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +48× +  +  +  +  +  +  +  +  +  +12× +  +  +  +  +  +  +  +  +  +  + +  +  +  +  +  +  +13× +  +  +  +  +  +  +10× +  +  +  +  +  + +  +  +  +  +  +  +  +  +  +  +  +  +376× +  +  +  +  +  +  +  +  +  +48× +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +478× +  +  + 
// SPDX-License-Identifier: MPL-2.0
+ 
+pragma solidity ^0.8.20;
+ 
+/* ==== OpenZeppelin === */
+import {IERC165} from "@openzeppelin/contracts/interfaces/IERC165.sol";
+import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
+import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
+ 
+/* ==== CMTAT === */
+import {CMTATBaseCommon} from "CMTAT/modules/0_CMTATBaseCommon.sol";
+/* = Base = */
+/* = Core = */
+import {
+    ERC20BurnModule,
+    ERC20BurnModuleInternal
+} from "CMTAT/modules/wrapper/core/ERC20BurnModule.sol";
+import {
+    ERC20MintModule,
+    ERC20MintModuleInternal
+} from "CMTAT/modules/wrapper/core/ERC20MintModule.sol";
+import {ERC20BaseModule} from "CMTAT/modules/wrapper/core/ERC20BaseModule.sol";
+/* = Option & Extension = */
+import {ERC20CrossChainModule} from "CMTAT/modules/wrapper/options/ERC20CrossChainModule.sol";
+import {CCIPModule} from "CMTAT/modules/wrapper/options/CCIPModule.sol";
+import {ExtraInformationModule} from "CMTAT/modules/wrapper/extensions/ExtraInformationModule.sol";
+import {
+    ERC20EnforcementModule,
+    ERC20EnforcementModuleInternal
+} from "CMTAT/modules/wrapper/extensions/ERC20EnforcementModule.sol";
+import {
+    DocumentEngineModule,
+    IERC1643
+} from "CMTAT/modules/wrapper/extensions/DocumentEngineModule.sol";
+import {SnapshotEngineModule} from "CMTAT/modules/wrapper/extensions/SnapshotEngineModule.sol";
+/* = Interface = */
+import {ICMTATConstructor} from "CMTAT/interfaces/technical/ICMTATConstructor.sol";
+import {ISnapshotEngine} from "CMTAT/interfaces/engine/ISnapshotEngine.sol";
+/* ==== Chainlink ACE === */
+import {PolicyProtectedBaseUpgradeable} from "@chainlink/policy-management/core/PolicyProtectedBaseUpgradeable.sol";
+ 
+abstract contract CCTCommon is
+    OwnableUpgradeable,
+    ERC20CrossChainModule,
+    PolicyProtectedBaseUpgradeable,
+    CMTATBaseCommon,
+    CCIPModule
+{
+    function initialize(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) public virtual initializer {
+        _initialize(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+ 
+    function _initialize(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_,
+        address policyEngine,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) internal virtual EonlyInitializing {
+        __CMTAT_init(
+            admin,
+            ERC20Attributes_,
+            extraInformationAttributes_,
+            policyEngine,
+            snapshotEngine_,
+            documentEngine_
+        );
+    }
+ 
+    /**
+     * @dev calls the different initialize functions from the different modules
+     */
+    function __CMTAT_init(
+        address admin,
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory ExtraInformationAttributes_,
+        address policyEngine,
+        ISnapshotEngine snapshotEngine_,
+        IERC1643 documentEngine_
+    ) internal virtual EonlyInitializing {
+        __Ownable_init_unchained(admin);
+        /* OpenZeppelin library */
+        // OZ init_unchained functions are called firstly due to inheritance
+        __Context_init_unchained();
+ 
+        // AccessControlUpgradeable inherits from ERC165Upgradeable
+        __ERC165_init_unchained();
+ 
+        // Openzeppelin
+        __CMTAT_openzeppelin_init_unchained(ERC20Attributes_);
+ 
+        __PolicyProtectedBase_init_unchained(policyEngine);
+ 
+        /* Wrapper modules */
+        __CMTAT_modules_init_unchained(ERC20Attributes_, ExtraInformationAttributes_);
+ 
+        /* Engine modules */
+        __SnapshotEngineModule_init_unchained(snapshotEngine_);
+        __DocumentEngineModule_init_unchained(documentEngine_);
+    }
+ 
+    /*
+     * @dev OpenZeppelin
+     */
+    function __CMTAT_openzeppelin_init_unchained(
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_
+    ) internal virtual EonlyInitializing {
+        // Note that the Openzeppelin functions name() and symbol() are overriden in ERC20BaseModule
+        __ERC20_init_unchained(ERC20Attributes_.name, ERC20Attributes_.symbol);
+    }
+ 
+    /*
+     * @dev CMTAT wrapper modules
+     */
+    function __CMTAT_modules_init_unchained(
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory extraInformationAttributes_
+    ) internal virtual EonlyInitializing {
+        __CMTAT_commonModules_init_unchained(ERC20Attributes_, extraInformationAttributes_);
+    }
+ 
+    function __CMTAT_commonModules_init_unchained(
+        ICMTATConstructor.ERC20Attributes memory ERC20Attributes_,
+        ICMTATConstructor.ExtraInformationAttributes memory ExtraInformationModuleAttributes_
+    ) internal virtual EonlyInitializing {
+        // Core
+        __ERC20BaseModule_init_unchained(
+            ERC20Attributes_.decimalsIrrevocable,
+            ERC20Attributes_.name,
+            ERC20Attributes_.symbol
+        );
+        /* Extensions */
+        __ExtraInformationModule_init_unchained(
+            ExtraInformationModuleAttributes_.tokenId,
+            ExtraInformationModuleAttributes_.terms,
+            ExtraInformationModuleAttributes_.information
+        );
+    }
+ 
+    /*//////////////////////////////////////////////////////////////
+                        PUBLIC/EXTERNAL FUNCTIONS
+    //////////////////////////////////////////////////////////////*/
+    /* ============  State Functions ============ */
+    function transfer(
+        address to,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) ErunPolicy returns (bool) {
+        return CMTATBaseCommon.transfer(to, value);
+    }
+    /*
+     * @inheritdoc ERC20BaseModule
+     */
+    function transferFrom(
+        address from,
+        address to,
+        uint256 value
+    ) public virtual override(ERC20Upgradeable, CMTATBaseCommon) ErunPolicy returns (bool) {
+        return CMTATBaseCommon.transferFrom(from, to, value);
+    }
+ 
+    function _authorizeAttachPolicyEngine(address) internal virtual override onlyOwner {}
+ 
+    /* ============ View functions ============ */
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function decimals() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (uint8) {
+        return CMTATBaseCommon.decimals();
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function name() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) {
+        return CMTATBaseCommon.name();
+    }
+ 
+    /**
+     * @inheritdoc CMTATBaseCommon
+     */
+    function symbol() public view virtual override(ERC20Upgradeable, CMTATBaseCommon) returns (string memory) {
+        return CMTATBaseCommon.symbol();
+    }
+ 
+    function supportsInterface(
+        bytes4 _interfaceId
+    ) public view virtual override(IERC165, ERC20CrossChainModule, PolicyProtectedBaseUpgradeable) returns (bool) {
+        return
+            ERC20CrossChainModule.supportsInterface(_interfaceId) ||
+            PolicyProtectedBaseUpgradeable.supportsInterface(_interfaceId);
+    }
+ 
+    /* ==== Mint and Burn Operations ==== */
+    /**
+     * @dev Check if the mint is valid
+     */
+    function _mintOverride(
+        address account,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
+        CMTATBaseCommon._mintOverride(account, value);
+    }
+ 
+    /**
+     * @dev Check if the burn is valid
+     */
+    function _burnOverride(
+        address account,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20BurnModuleInternal) {
+        CMTATBaseCommon._burnOverride(account, value);
+    }
+ 
+    /**
+     * @dev Check if a minter transfer is valid
+     */
+    function _minterTransferOverride(
+        address from,
+        address to,
+        uint256 value
+    ) internal virtual override(CMTATBaseCommon, ERC20MintModuleInternal) {
+        CMTATBaseCommon._minterTransferOverride(from, to, value);
+    }
+ 
+    /* ==== Access Control Functions ==== */
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DEFAULT_ADMIN_ROLE`.
+     */
+    function _authorizeERC20AttributeManagement() internal virtual override(ERC20BaseModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `MINTER_ROLE`.
+     */
+    function _authorizeMint() internal virtual override(ERC20MintModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - The caller must have the `BURNER_ROLE`.
+     */
+    function _authorizeBurn() internal virtual override(ERC20BurnModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DOCUMENT_ROLE`.
+     */
+    function _authorizeDocumentManagement() internal virtual override(DocumentEngineModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `EXTRA_INFORMATION_ROLE`.
+     */
+    function _authorizeExtraInfoManagement() internal virtual override(ExtraInformationModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `ERC20ENFORCER_ROLE`.
+     */
+    function _authorizeERC20Enforcer() internal virtual override(ERC20EnforcementModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DEFAULT_ADMIN_ROLE`.
+     */
+    function _authorizeForcedTransfer() internal virtual override(ERC20EnforcementModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `SNAPSHOOTER_ROLE`.
+     */
+    function _authorizeSnapshots() internal virtual override(SnapshotEngineModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `DEFAULT_ADMIN_ROLE`.
+     */
+    function _authorizeCCIPSetAdmin() internal virtual override(CCIPModule) runPolicy {}
+ 
+    /**
+     * @dev
+     * A cross-chain bridge could call the OpenZeppelin function `renounceRole` to lose their privileges (CROSS_CHAIN_ROLE)
+     * While it is not intended,this has no other effect than depriving the bridge of burn/mint tokens
+     * An attacker could use this to disrupt minting/burning if they can get the bridge to execute calls.
+     * However, in this case, the bridge should still be considered compromised and not used again.
+     * @custom:access-control
+     * - the caller must have the `CROSS_CHAIN_ROLE`.
+     */
+    function _checkTokenBridge(address caller) internal virtual override(ERC20CrossChainModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `BURNER_FROM_ROLE`.
+     * - We don't allow token holder to burn their own tokens if they don't have this role.
+     */
+    function _authorizeBurnFrom() internal virtual override(ERC20CrossChainModule) runPolicy {}
+ 
+    /**
+     * @custom:access-control
+     * - the caller must have the `BURNER_ROLE`.
+     * - We don't allow token holder to burn their own tokens if they don't have this role.
+     */
+    function _authorizeSelfBurn() internal virtual override(ERC20CrossChainModule) runPolicy {}
+ 
+    /* ==== ERC-20 OpenZeppelin ==== */
+    function _update(
+        address from,
+        address to,
+        uint256 amount
+    ) internal virtual override(ERC20Upgradeable, CMTATBaseCommon) {
+        return CMTATBaseCommon._update(from, to, amount);
+    }
+}
+ 
+
+
+ + + + + + + diff --git a/doc/coverage/modules/standard/index.html b/doc/coverage/modules/standard/index.html new file mode 100644 index 0000000..de598aa --- /dev/null +++ b/doc/coverage/modules/standard/index.html @@ -0,0 +1,93 @@ + + + + Code coverage report for modules/standard/ + + + + + + + +
+
+

+ all files modules/standard/ +

+
+
+ 95.83% + Statements + 23/24 +
+
+ 84.09% + Branches + 37/44 +
+
+ 96.55% + Functions + 28/29 +
+
+ 95.83% + Lines + 23/24 +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
CCTCommon.sol
95.83%23/2484.09%37/4496.55%28/2995.83%23/24
+
+
+ + + + + + + diff --git a/doc/coverage/prettify.css b/doc/coverage/prettify.css new file mode 100644 index 0000000..b317a7c --- /dev/null +++ b/doc/coverage/prettify.css @@ -0,0 +1 @@ +.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/doc/coverage/prettify.js b/doc/coverage/prettify.js new file mode 100644 index 0000000..ef51e03 --- /dev/null +++ b/doc/coverage/prettify.js @@ -0,0 +1 @@ +window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/doc/coverage/sort-arrow-sprite.png b/doc/coverage/sort-arrow-sprite.png new file mode 100644 index 0000000..03f704a Binary files /dev/null and b/doc/coverage/sort-arrow-sprite.png differ diff --git a/doc/coverage/sorter.js b/doc/coverage/sorter.js new file mode 100644 index 0000000..6c5034e --- /dev/null +++ b/doc/coverage/sorter.js @@ -0,0 +1,158 @@ +var addSorting = (function () { + "use strict"; + var cols, + currentSort = { + index: 0, + desc: false + }; + + // returns the summary table element + function getTable() { return document.querySelector('.coverage-summary'); } + // returns the thead element of the summary table + function getTableHeader() { return getTable().querySelector('thead tr'); } + // returns the tbody element of the summary table + function getTableBody() { return getTable().querySelector('tbody'); } + // returns the th element for nth column + function getNthColumn(n) { return getTableHeader().querySelectorAll('th')[n]; } + + // loads all columns + function loadColumns() { + var colNodes = getTableHeader().querySelectorAll('th'), + colNode, + cols = [], + col, + i; + + for (i = 0; i < colNodes.length; i += 1) { + colNode = colNodes[i]; + col = { + key: colNode.getAttribute('data-col'), + sortable: !colNode.getAttribute('data-nosort'), + type: colNode.getAttribute('data-type') || 'string' + }; + cols.push(col); + if (col.sortable) { + col.defaultDescSort = col.type === 'number'; + colNode.innerHTML = colNode.innerHTML + ''; + } + } + return cols; + } + // attaches a data attribute to every tr element with an object + // of data values keyed by column name + function loadRowData(tableRow) { + var tableCols = tableRow.querySelectorAll('td'), + colNode, + col, + data = {}, + i, + val; + for (i = 0; i < tableCols.length; i += 1) { + colNode = tableCols[i]; + col = cols[i]; + val = colNode.getAttribute('data-value'); + if (col.type === 'number') { + val = Number(val); + } + data[col.key] = val; + } + return data; + } + // loads all row data + function loadData() { + var rows = getTableBody().querySelectorAll('tr'), + i; + + for (i = 0; i < rows.length; i += 1) { + rows[i].data = loadRowData(rows[i]); + } + } + // sorts the table using the data for the ith column + function sortByIndex(index, desc) { + var key = cols[index].key, + sorter = function (a, b) { + a = a.data[key]; + b = b.data[key]; + return a < b ? -1 : a > b ? 1 : 0; + }, + finalSorter = sorter, + tableBody = document.querySelector('.coverage-summary tbody'), + rowNodes = tableBody.querySelectorAll('tr'), + rows = [], + i; + + if (desc) { + finalSorter = function (a, b) { + return -1 * sorter(a, b); + }; + } + + for (i = 0; i < rowNodes.length; i += 1) { + rows.push(rowNodes[i]); + tableBody.removeChild(rowNodes[i]); + } + + rows.sort(finalSorter); + + for (i = 0; i < rows.length; i += 1) { + tableBody.appendChild(rows[i]); + } + } + // removes sort indicators for current column being sorted + function removeSortIndicators() { + var col = getNthColumn(currentSort.index), + cls = col.className; + + cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); + col.className = cls; + } + // adds sort indicators for current column being sorted + function addSortIndicators() { + getNthColumn(currentSort.index).className += currentSort.desc ? ' sorted-desc' : ' sorted'; + } + // adds event listeners for all sorter widgets + function enableUI() { + var i, + el, + ithSorter = function ithSorter(i) { + var col = cols[i]; + + return function () { + var desc = col.defaultDescSort; + + if (currentSort.index === i) { + desc = !currentSort.desc; + } + sortByIndex(i, desc); + removeSortIndicators(); + currentSort.index = i; + currentSort.desc = desc; + addSortIndicators(); + }; + }; + for (i =0 ; i < cols.length; i += 1) { + if (cols[i].sortable) { + // add the click event handler on the th so users + // dont have to click on those tiny arrows + el = getNthColumn(i).querySelector('.sorter').parentElement; + if (el.addEventListener) { + el.addEventListener('click', ithSorter(i)); + } else { + el.attachEvent('onclick', ithSorter(i)); + } + } + } + } + // adds sorting functionality to the UI + return function () { + if (!getTable()) { + return; + } + cols = loadColumns(); + loadData(cols); + addSortIndicators(); + enableUI(); + }; +})(); + +window.addEventListener('load', addSorting); diff --git a/doc/script/convert_links_for_pdf.sh b/doc/script/convert_links_for_pdf.sh new file mode 100755 index 0000000..2f4d392 --- /dev/null +++ b/doc/script/convert_links_for_pdf.sh @@ -0,0 +1,47 @@ +#!/bin/bash + +# Script to replace relative markdown links with GitHub links for PDF generation +# Preserves image links (they render in PDF) and external links + +set -e + +if [ -z "$1" ]; then + echo "Usage: $0 [input-file] [output-file]" + echo "" + echo "Example:" + echo " $0 https://github.com/CMTA/CMTAT/blob/v3.0.0" + echo " $0 https://github.com/CMTA/CMTAT/blob/v3.0.0 README.md README_UPDATE.md" + exit 1 +fi + +GITHUB_LINK="${1%/}" # Remove trailing slash if present +INPUT_FILE="${2:-../../README.md}" +OUTPUT_FILE="${3:-README_UPDATE.md}" + +if [ ! -f "$INPUT_FILE" ]; then + echo "Error: Input file '$INPUT_FILE' not found" + exit 1 +fi + +# Create a temporary file +TMP_FILE=$(mktemp) +cp "$INPUT_FILE" "$TMP_FILE" + +# Use a placeholder to avoid sed escaping issues +PLACEHOLDER="__GITHUB_LINK__" + +# Step 1: Convert ALL relative links [text](./...) to placeholder +sed -i -E "s|\[([^]]+)\]\(\./([^)]+)\)|[\1]($PLACEHOLDER/\2)|g" "$TMP_FILE" + +# Step 2: Restore image links back to relative (images render inline in PDF) +for ext in png jpg jpeg gif svg ico webp bmp tiff; do + sed -i -E "s|\[([^]]+)\]\($PLACEHOLDER/([^)]+\.$ext)\)|[\1](./\2)|gi" "$TMP_FILE" +done + +# Step 3: Replace placeholder with actual GitHub link +sed -i "s|$PLACEHOLDER|$GITHUB_LINK|g" "$TMP_FILE" + +mv "$TMP_FILE" "$OUTPUT_FILE" + +echo "Created '$OUTPUT_FILE' with GitHub links pointing to:" +echo " $GITHUB_LINK" diff --git a/doc/script/script_surya_graph.sh b/doc/script/script_surya_graph.sh new file mode 100755 index 0000000..31a1cef --- /dev/null +++ b/doc/script/script_surya_graph.sh @@ -0,0 +1,18 @@ +#/bin/bash +cd '../../' +DIR=$(pwd) +DIR_OUT=${DIR}/docOut/surya_graph +if ! [ -d "$DIR_OUT" ]; then + mkdir -p ./docOut/surya_graph +fi +cd './src' +DIR=$(pwd) +for i in $(find $DIR -type f); +do + #echo $i + filename=${i##*/} + ext=${i##*.} + if [[ $ext == 'sol' ]]; then + npx surya graph $i | dot -Tpng > ../docOut/surya_graph/surya_graph_$filename.png; + fi +done; \ No newline at end of file diff --git a/doc/script/script_surya_inheritance.sh b/doc/script/script_surya_inheritance.sh new file mode 100755 index 0000000..e4b8ca7 --- /dev/null +++ b/doc/script/script_surya_inheritance.sh @@ -0,0 +1,17 @@ +#/bin/bash +cd '../../' +DIR=$(pwd) +DIR_OUT=${DIR}/docOut/inheritance +if ! [ -d "$DIR_OUT" ]; then + mkdir -p ./docOut/surya_inheritance +fi +cd './src' +DIR=$(pwd) +for i in $(find $dir -type f); +do + filename=${i##*/} + ext=${i##*.} + if [[ $ext == 'sol' ]]; then + npx surya inheritance $i | dot -Tpng > ../docOut/surya_inheritance/surya_inheritance_$filename.png; + fi +done; \ No newline at end of file diff --git a/doc/script/script_surya_report.sh b/doc/script/script_surya_report.sh new file mode 100755 index 0000000..84769c9 --- /dev/null +++ b/doc/script/script_surya_report.sh @@ -0,0 +1,17 @@ +#/bin/bash +cd '../../' +DIR=$(pwd) +DIR_OUT=${DIR}/docOut/surya_report +if ! [ -d "$DIR_OUT" ]; then + mkdir ./docOut/surya_report +fi +cd './src' +DIR=$(pwd) +for i in $(find $dir -type f); +do + filename=${i##*/} + ext=${i##*.} + if [[ $ext == 'sol' ]]; then + npx surya mdreport ../docOut/surya_report/surya_report_$filename.md $i; + fi +done; \ No newline at end of file diff --git a/eslint.config.js b/eslint.config.js new file mode 100644 index 0000000..f4b002e --- /dev/null +++ b/eslint.config.js @@ -0,0 +1,54 @@ +const js = require('@eslint/js'); +const prettier = require('eslint-config-prettier'); + +module.exports = [ + { + ignores: [ + 'node_modules/**', + 'submodules/**', + 'artifacts/**', + 'cache_hardhat/**', + 'typechain-types/**', + 'cct/**', + 'doc/**', + ], + }, + js.configs.recommended, + prettier, + { + files: ['test/**/*.js'], + languageOptions: { + globals: { + before: 'readonly', + after: 'readonly', + beforeEach: 'readonly', + afterEach: 'readonly', + describe: 'readonly', + it: 'readonly', + context: 'readonly', + }, + }, + }, + { + languageOptions: { + ecmaVersion: 'latest', + sourceType: 'commonjs', + globals: { + require: 'readonly', + module: 'readonly', + exports: 'readonly', + __dirname: 'readonly', + __filename: 'readonly', + process: 'readonly', + Buffer: 'readonly', + setTimeout: 'readonly', + clearTimeout: 'readonly', + console: 'readonly', + ethers: 'readonly', + }, + }, + rules: { + 'no-unused-vars': ['warn', { argsIgnorePattern: '^_' }], + }, + }, +]; diff --git a/foundry.toml b/foundry.toml new file mode 100644 index 0000000..c59b4e5 --- /dev/null +++ b/foundry.toml @@ -0,0 +1,8 @@ +[profile.default] +src = "contracts" +remappings = [ + "@chainlink/policy-management/=node_modules/@chainlink/ace/packages/policy-management/src/", + "@chainlink/cross-chain-identity/=node_modules/@chainlink/ace/packages/cross-chain-identity/src/", + "@chainlink/contracts/=node_modules/@chainlink/contracts/", + "CMTAT/=submodules/CMTAT/contracts/", +] diff --git a/hardhat.config.js b/hardhat.config.js new file mode 100644 index 0000000..0a94789 --- /dev/null +++ b/hardhat.config.js @@ -0,0 +1,52 @@ +require('@nomicfoundation/hardhat-foundry'); +require('@nomicfoundation/hardhat-chai-matchers'); +require('@openzeppelin/hardhat-upgrades'); +require('hardhat-dependency-compiler'); +require('solidity-coverage'); + +const { silenceWarnings } = require('@openzeppelin/upgrades-core'); +silenceWarnings(); + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: { + compilers: [ + { + version: '0.8.30', + settings: { + optimizer: { + enabled: true, + runs: 50, + }, + evmVersion: 'prague', + }, + }, + { + version: '0.8.26', + settings: { + optimizer: { + enabled: true, + runs: 50, + }, + evmVersion: 'cancun', + }, + }, + ], + }, + paths: { + sources: './contracts', + tests: './test', + }, + dependencyCompiler: { + paths: [ + '@chainlink/contracts/src/v0.8/tests/MockV3Aggregator.sol', + '@chainlink/policy-management/core/PolicyEngine.sol', + '@chainlink/policy-management/policies/PausePolicy.sol', + '@chainlink/policy-management/policies/RoleBasedAccessControlPolicy.sol', + '@chainlink/policy-management/policies/SecureMintPolicy.sol', + '@chainlink/policy-management/extractors/ERC20TransferExtractor.sol', + 'CMTAT/mocks/SnapshotEngineMock.sol', + 'CMTAT/mocks/DocumentEngineMock.sol', + ], + }, +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..a10865d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,10672 @@ +{ + "name": "cmtat-ace", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cmtat-ace", + "version": "1.0.0", + "devDependencies": { + "@chainlink/ace": "1.1.1", + "@chainlink/contracts": "1.3.0", + "@eslint/js": "^10.0.1", + "@nomicfoundation/hardhat-chai-matchers": "^2.1.0", + "@nomicfoundation/hardhat-foundry": "^1.2.1", + "@nomicfoundation/hardhat-network-helpers": "^1.1.2", + "@openzeppelin/contracts": "5.6.1", + "@openzeppelin/contracts-upgradeable": "5.6.1", + "@openzeppelin/hardhat-upgrades": "^3.2.0", + "@openzeppelin/upgrades-core": "^1.44.1", + "eslint": "^10.4.1", + "eslint-config-prettier": "^10.1.8", + "hardhat": "^2.28.0", + "hardhat-contract-sizer": "^2.10.0", + "hardhat-dependency-compiler": "^1.2.1", + "hardhat-gas-reporter": "^1.0.9", + "prettier": "^3.8.4", + "prettier-plugin-solidity": "^2.3.1", + "solidity-coverage": "^0.8.17", + "surya": "^0.4.13" + } + }, + "node_modules/@adraffy/ens-normalize": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", + "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", + "dev": true, + "peer": true + }, + "node_modules/@arbitrum/nitro-contracts": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@arbitrum/nitro-contracts/-/nitro-contracts-1.1.1.tgz", + "integrity": "sha512-4Tyk3XVHz+bm8UujUC78LYSw3xAxyYvBCxfEX4z3qE4/ww7Qck/rmce5gbHMzQjArEAzAP2YSfYIFuIFuRXtfg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@offchainlabs/upgrade-executor": "1.1.0-beta.0", + "@openzeppelin/contracts": "4.5.0", + "@openzeppelin/contracts-upgradeable": "4.5.2", + "patch-package": "^6.4.7" + } + }, + "node_modules/@arbitrum/nitro-contracts/node_modules/@openzeppelin/contracts": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.5.0.tgz", + "integrity": "sha512-fdkzKPYMjrRiPK6K4y64e6GzULR7R7RwxSigHS8DDp7aWDeoReqsQI+cxHV1UuhAqX69L1lAaWDxenfP+xiqzA==", + "dev": true + }, + "node_modules/@arbitrum/nitro-contracts/node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.5.2.tgz", + "integrity": "sha512-xgWZYaPlrEOQo3cBj97Ufiuv79SPd8Brh4GcFYhPgb6WvAq4ppz8dWKL6h+jLAK01rUqMRp/TS9AdXgAeNvCLA==", + "dev": true + }, + "node_modules/@arbitrum/token-bridge-contracts": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@arbitrum/token-bridge-contracts/-/token-bridge-contracts-1.1.2.tgz", + "integrity": "sha512-k7AZXiB2HFecJ1KfaDBqgOKe3Loo1ttGLC7hUOVB+0YrihIR6cYpJRuqKSKK4YCy+FF21AUDtaG3x57OFM667Q==", + "dev": true, + "dependencies": { + "@arbitrum/nitro-contracts": "^1.0.0-beta.8", + "@offchainlabs/upgrade-executor": "1.1.0-beta.0", + "@openzeppelin/contracts": "4.8.3", + "@openzeppelin/contracts-upgradeable": "4.8.3" + }, + "optionalDependencies": { + "@openzeppelin/upgrades-core": "^1.24.1" + } + }, + "node_modules/@arbitrum/token-bridge-contracts/node_modules/@openzeppelin/contracts": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.8.3.tgz", + "integrity": "sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg==", + "dev": true + }, + "node_modules/@arbitrum/token-bridge-contracts/node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.3.tgz", + "integrity": "sha512-SXDRl7HKpl2WDoJpn7CK/M9U4Z8gNXDHHChAKh0Iz+Wew3wu6CmFYBeie3je8V0GSXZAIYYwUktSrnW/kwVPtg==", + "dev": true + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-lambda": { + "version": "3.1045.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.1045.0.tgz", + "integrity": "sha512-9EDPinh03XanJQssTBdTY+9E7PkyQ0NLLJiaOAM71/g4DI+0OZboGqhX7KKizwUGqKkj0paKEAwgWaMLgEkQFQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/credential-provider-node": "^3.972.39", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.38", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.24", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/eventstream-serde-browser": "^4.2.14", + "@smithy/eventstream-serde-config-resolver": "^4.3.14", + "@smithy/eventstream-serde-node": "^4.2.14", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "@smithy/util-waiter": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.974.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.8.tgz", + "integrity": "sha512-njR2qoG6ZuB0kvAS2FyICsFZJ6gmCcf2X/7JcD14sUvGDm26wiZ5BrA6LOiUxKFEF+IVe7kdroxyE00YlkiYsw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/xml-builder": "^3.972.22", + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.34", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.34.tgz", + "integrity": "sha512-XT0jtf8Fw9JE6ppsQeoNnZRiG+jqRixMT1v1ZR17G60UvVdsQmTG8nbEyHuEPfMxDXEhfdARaM/XiEhca4lGHQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.36", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.36.tgz", + "integrity": "sha512-DPoGWfy7J7RKxvbf5kOKIGQkD2ek3dbKgzKIGrnLuvZBz5myU+Im/H6pmc14QcnFbqHMqxvtWSgRDSJW3qXLQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/types": "^3.973.8", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-stream": "^4.5.25", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.972.38", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.38.tgz", + "integrity": "sha512-oDzUBu2MGJFgoar05sPMCwSrhw44ASyccrHzj66vO69OZqi7I6hZZxXfuPLC8OCzW7C+sU+bI73XHij41yekgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/credential-provider-env": "^3.972.34", + "@aws-sdk/credential-provider-http": "^3.972.36", + "@aws-sdk/credential-provider-login": "^3.972.38", + "@aws-sdk/credential-provider-process": "^3.972.34", + "@aws-sdk/credential-provider-sso": "^3.972.38", + "@aws-sdk/credential-provider-web-identity": "^3.972.38", + "@aws-sdk/nested-clients": "^3.997.6", + "@aws-sdk/types": "^3.973.8", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.38", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.38.tgz", + "integrity": "sha512-g1NosS8qe4OF++G2UFCM5ovSkgipC7YYor5KCWatG0UoMSO5YFj9C8muePlyVmOBV/WTI16Jo3/s1NUo/o1Bww==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/nested-clients": "^3.997.6", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.39", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.39.tgz", + "integrity": "sha512-HEswDQyxUtadoZ/bJsPPENHg7R0Lzym5LuMksJeHvqhCOpP+rtkDLKI4/ZChH4w3cf5kG8n6bZuI8PzajoiqMg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.34", + "@aws-sdk/credential-provider-http": "^3.972.36", + "@aws-sdk/credential-provider-ini": "^3.972.38", + "@aws-sdk/credential-provider-process": "^3.972.34", + "@aws-sdk/credential-provider-sso": "^3.972.38", + "@aws-sdk/credential-provider-web-identity": "^3.972.38", + "@aws-sdk/types": "^3.973.8", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.34", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.34.tgz", + "integrity": "sha512-T3IFs4EVmVi1dVN5RciFnklCANSzvrQd/VuHY9ThHSQmYkTogjcGkoJEr+oNUPQZnso52183088NqysMPji1/Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.972.38", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.38.tgz", + "integrity": "sha512-5ZxG+t0+3Q3QPh8KEjX6syskhgNf7I0MN7oGioTf6Lm1NTjfP7sIcYGNsthXC2qR8vcD3edNZwCr2ovfSSWuRA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/nested-clients": "^3.997.6", + "@aws-sdk/token-providers": "3.1041.0", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.38", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.38.tgz", + "integrity": "sha512-lYHFF30DGI20jZcYX8cm6Ns0V7f1dDN6g/MBDLTyD/5iw+bXs3yBr2iAiHDkx4RFU5JgsnZvCHYKiRVPRdmOgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/nested-clients": "^3.997.6", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.10.tgz", + "integrity": "sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.10.tgz", + "integrity": "sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.11.tgz", + "integrity": "sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.972.37", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.37.tgz", + "integrity": "sha512-Km7M+i8DrLArVzrid1gfxeGhYHBd3uxvE77g0s5a52zPSVosxzQBnJ0gwWb6NIp/DOk8gsBMhi7V+cpJG0ndTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-arn-parser": "^3.972.3", + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.972.38", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.38.tgz", + "integrity": "sha512-iz+B29TXcAZsJpwB+AwG/TTGA5l/VnmMZ2UxtiySOZjI6gCdmviXPwdgzcmuazMy16rXoPY4mYCGe7zdNKfx5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@smithy/core": "^3.23.17", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-retry": "^4.3.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.997.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.6.tgz", + "integrity": "sha512-WBDnqatJl+kGObpfmfSxqnXeYTu3Me8wx8WCtvoxX3pfWrrTv8I4WTMSSs7PZqcRcVh8WeUKMgGFjMG+52SR1w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/middleware-host-header": "^3.972.10", + "@aws-sdk/middleware-logger": "^3.972.10", + "@aws-sdk/middleware-recursion-detection": "^3.972.11", + "@aws-sdk/middleware-user-agent": "^3.972.38", + "@aws-sdk/region-config-resolver": "^3.972.13", + "@aws-sdk/signature-v4-multi-region": "^3.996.25", + "@aws-sdk/types": "^3.973.8", + "@aws-sdk/util-endpoints": "^3.996.8", + "@aws-sdk/util-user-agent-browser": "^3.972.10", + "@aws-sdk/util-user-agent-node": "^3.973.24", + "@smithy/config-resolver": "^4.4.17", + "@smithy/core": "^3.23.17", + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/hash-node": "^4.2.14", + "@smithy/invalid-dependency": "^4.2.14", + "@smithy/middleware-content-length": "^4.2.14", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-retry": "^4.5.7", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/protocol-http": "^5.3.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-body-length-node": "^4.2.3", + "@smithy/util-defaults-mode-browser": "^4.3.49", + "@smithy/util-defaults-mode-node": "^4.2.54", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.13.tgz", + "integrity": "sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/config-resolver": "^4.4.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.996.25", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.25.tgz", + "integrity": "sha512-+CMIt3e1VzlklAECmG+DtP1sV8iKq25FuA0OKpnJ4KA0kxUtd7CgClY7/RU6VzJBQwbN4EJ9Ue6plvqx1qGadw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "^3.972.37", + "@aws-sdk/types": "^3.973.8", + "@smithy/protocol-http": "^5.3.14", + "@smithy/signature-v4": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.1041.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1041.0.tgz", + "integrity": "sha512-Th7kPI6YPtvJUcdznooXJMy+9rQWjmEF81LxaJssngBzuysK4a/x+l8kjm1zb7nYsUPbndnBdUnwng/3PLvtGw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.974.8", + "@aws-sdk/nested-clients": "^3.997.6", + "@aws-sdk/types": "^3.973.8", + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.973.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.8.tgz", + "integrity": "sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.972.3", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.972.3.tgz", + "integrity": "sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.996.8", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.8.tgz", + "integrity": "sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-endpoints": "^3.4.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", + "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.10.tgz", + "integrity": "sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.8", + "@smithy/types": "^4.14.1", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.973.24", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.24.tgz", + "integrity": "sha512-ZWwlkjcIp7cEL8ZfTpTAPNkwx25p7xol0xlKoWVVf22+nsjwmLcHYtTPjIV1cSpmB/b6DaK4cb1fSkvCXHgRdw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "^3.972.38", + "@aws-sdk/types": "^3.973.8", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/util-utf8-browser": { + "version": "3.259.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-utf8-browser/-/util-utf8-browser-3.259.0.tgz", + "integrity": "sha512-UvFa/vR+e19XookZF8RzFZBrw2EUkQWxiBW0yYQAhvk3C+QVGl0H3ouca8LDBlBfQKXwmW3huo/59H8rwb1wJw==", + "dev": true, + "dependencies": { + "tslib": "^2.3.1" + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.22", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.22.tgz", + "integrity": "sha512-PMYKKtJd70IsSG0yHrdAbxBr+ZWBKLvzFZfD3/urxgf6hXVMzuU5M+3MJ5G67RpOmLBu1fAUN65SbWuKUCOlAA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@nodable/entities": "2.1.0", + "@smithy/types": "^4.14.1", + "fast-xml-parser": "5.7.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", + "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bytecodealliance/preview2-shim": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.0.tgz", + "integrity": "sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ==", + "dev": true + }, + "node_modules/@chainlink/ace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@chainlink/ace/-/ace-1.1.1.tgz", + "integrity": "sha512-SgfFFUn3PQ2MkHP8811UP2GEZ30bxtSdbQbm9z1VEejOitZW6PW63cjWhgwHChZnwiVhc+EQSrJtSW6zFjEbPQ==", + "dev": true, + "license": "BUSL-1.1" + }, + "node_modules/@chainlink/contracts": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@chainlink/contracts/-/contracts-1.3.0.tgz", + "integrity": "sha512-Vk93nijTC5iRFW/L6FKUzeMuJy7k5dNzAtqlHpdreqtzL7efO/qXbYCkqjJFNXGurfOXVehHlehFoH4tWvSbfw==", + "dev": true, + "dependencies": { + "@arbitrum/nitro-contracts": "1.1.1", + "@arbitrum/token-bridge-contracts": "1.1.2", + "@changesets/changelog-github": "^0.5.0", + "@changesets/cli": "~2.27.8", + "@eth-optimism/contracts": "0.6.0", + "@openzeppelin/contracts": "4.9.3", + "@openzeppelin/contracts-upgradeable": "4.9.3", + "@scroll-tech/contracts": "0.1.0", + "@zksync/contracts": "git+https://github.com/matter-labs/era-contracts.git#446d391d34bdb48255d5f8fef8a8248925fc98b9", + "semver": "^7.6.3" + }, + "engines": { + "node": ">=18", + "pnpm": ">=9" + } + }, + "node_modules/@chainlink/contracts/node_modules/@eth-optimism/contracts": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eth-optimism/contracts/-/contracts-0.6.0.tgz", + "integrity": "sha512-vQ04wfG9kMf1Fwy3FEMqH2QZbgS0gldKhcBeBUPfO8zu68L61VI97UDXmsMQXzTsEAxK8HnokW3/gosl4/NW3w==", + "dev": true, + "dependencies": { + "@eth-optimism/core-utils": "0.12.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/abstract-signer": "^5.7.0" + }, + "peerDependencies": { + "ethers": "^5" + } + }, + "node_modules/@chainlink/contracts/node_modules/@openzeppelin/contracts": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.9.3.tgz", + "integrity": "sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==", + "dev": true + }, + "node_modules/@chainlink/contracts/node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.9.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz", + "integrity": "sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A==", + "dev": true + }, + "node_modules/@chainlink/contracts/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/@changesets/apply-release-plan": { + "version": "7.0.14", + "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.14.tgz", + "integrity": "sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==", + "dev": true, + "dependencies": { + "@changesets/config": "^3.1.2", + "@changesets/get-version-range-type": "^0.4.0", + "@changesets/git": "^3.0.4", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "detect-indent": "^6.0.0", + "fs-extra": "^7.0.1", + "lodash.startcase": "^4.4.0", + "outdent": "^0.5.0", + "prettier": "^2.7.1", + "resolve-from": "^5.0.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/apply-release-plan/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@changesets/assemble-release-plan": { + "version": "6.0.9", + "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.9.tgz", + "integrity": "sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.3", + "@changesets/should-skip-package": "^0.1.2", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/changelog-git": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz", + "integrity": "sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.1.0" + } + }, + "node_modules/@changesets/changelog-github": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@changesets/changelog-github/-/changelog-github-0.5.2.tgz", + "integrity": "sha512-HeGeDl8HaIGj9fQHo/tv5XKQ2SNEi9+9yl1Bss1jttPqeiASRXhfi0A2wv8yFKCp07kR1gpOI5ge6+CWNm1jPw==", + "dev": true, + "dependencies": { + "@changesets/get-github-info": "^0.7.0", + "@changesets/types": "^6.1.0", + "dotenv": "^8.1.0" + } + }, + "node_modules/@changesets/cli": { + "version": "2.27.12", + "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.27.12.tgz", + "integrity": "sha512-9o3fOfHYOvBnyEn0mcahB7wzaA3P4bGJf8PNqGit5PKaMEFdsRixik+txkrJWd2VX+O6wRFXpxQL8j/1ANKE9g==", + "dev": true, + "dependencies": { + "@changesets/apply-release-plan": "^7.0.8", + "@changesets/assemble-release-plan": "^6.0.5", + "@changesets/changelog-git": "^0.2.0", + "@changesets/config": "^3.0.5", + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.2", + "@changesets/get-release-plan": "^4.0.6", + "@changesets/git": "^3.0.2", + "@changesets/logger": "^0.1.1", + "@changesets/pre": "^2.0.1", + "@changesets/read": "^0.6.2", + "@changesets/should-skip-package": "^0.1.1", + "@changesets/types": "^6.0.0", + "@changesets/write": "^0.3.2", + "@manypkg/get-packages": "^1.1.3", + "ansi-colors": "^4.1.3", + "ci-info": "^3.7.0", + "enquirer": "^2.4.1", + "external-editor": "^3.1.0", + "fs-extra": "^7.0.1", + "mri": "^1.2.0", + "p-limit": "^2.2.0", + "package-manager-detector": "^0.2.0", + "picocolors": "^1.1.0", + "resolve-from": "^5.0.0", + "semver": "^7.5.3", + "spawndamnit": "^3.0.1", + "term-size": "^2.1.0" + }, + "bin": { + "changeset": "bin.js" + } + }, + "node_modules/@changesets/config": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.1.2.tgz", + "integrity": "sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/get-dependents-graph": "^2.1.3", + "@changesets/logger": "^0.1.1", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1", + "micromatch": "^4.0.8" + } + }, + "node_modules/@changesets/errors": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", + "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", + "dev": true, + "dependencies": { + "extendable-error": "^0.1.5" + } + }, + "node_modules/@changesets/get-dependents-graph": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.3.tgz", + "integrity": "sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "picocolors": "^1.1.0", + "semver": "^7.5.3" + } + }, + "node_modules/@changesets/get-github-info": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@changesets/get-github-info/-/get-github-info-0.7.0.tgz", + "integrity": "sha512-+i67Bmhfj9V4KfDeS1+Tz3iF32btKZB2AAx+cYMqDSRFP7r3/ZdGbjCo+c6qkyViN9ygDuBjzageuPGJtKGe5A==", + "dev": true, + "dependencies": { + "dataloader": "^1.4.0", + "node-fetch": "^2.5.0" + } + }, + "node_modules/@changesets/get-release-plan": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.14.tgz", + "integrity": "sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==", + "dev": true, + "dependencies": { + "@changesets/assemble-release-plan": "^6.0.9", + "@changesets/config": "^3.1.2", + "@changesets/pre": "^2.0.2", + "@changesets/read": "^0.6.6", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/get-version-range-type": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", + "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", + "dev": true + }, + "node_modules/@changesets/git": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz", + "integrity": "sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.2.0", + "@manypkg/get-packages": "^1.1.3", + "is-subdir": "^1.1.1", + "micromatch": "^4.0.8", + "spawndamnit": "^3.0.1" + } + }, + "node_modules/@changesets/logger": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", + "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", + "dev": true, + "dependencies": { + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/parse": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.2.tgz", + "integrity": "sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.1.0", + "js-yaml": "^4.1.1" + } + }, + "node_modules/@changesets/pre": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz", + "integrity": "sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==", + "dev": true, + "dependencies": { + "@changesets/errors": "^0.2.0", + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3", + "fs-extra": "^7.0.1" + } + }, + "node_modules/@changesets/read": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.6.tgz", + "integrity": "sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==", + "dev": true, + "dependencies": { + "@changesets/git": "^3.0.4", + "@changesets/logger": "^0.1.1", + "@changesets/parse": "^0.4.2", + "@changesets/types": "^6.1.0", + "fs-extra": "^7.0.1", + "p-filter": "^2.1.0", + "picocolors": "^1.1.0" + } + }, + "node_modules/@changesets/should-skip-package": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz", + "integrity": "sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.1.0", + "@manypkg/get-packages": "^1.1.3" + } + }, + "node_modules/@changesets/types": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz", + "integrity": "sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==", + "dev": true + }, + "node_modules/@changesets/write": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.3.2.tgz", + "integrity": "sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==", + "dev": true, + "dependencies": { + "@changesets/types": "^6.0.0", + "fs-extra": "^7.0.1", + "human-id": "^1.0.2", + "prettier": "^2.7.1" + } + }, + "node_modules/@changesets/write/node_modules/prettier": { + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.23.5.tgz", + "integrity": "sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^3.0.5", + "debug": "^4.3.1", + "minimatch": "^10.2.4" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.6.0.tgz", + "integrity": "sha512-ii6Bw9jJ2zi2cWA2Z+9/QZ/+3DX6kwaV5Q986D/CdP3Lap3w/pgQZ373FV7byY/i7L4IRH/G43I5dz1ClsCbpA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-1.2.1.tgz", + "integrity": "sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/js": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz", + "integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "eslint": "^10.0.0" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/@eslint/object-schema": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz", + "integrity": "sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", + "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^1.2.1", + "levn": "^0.4.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + } + }, + "node_modules/@eth-optimism/core-utils": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@eth-optimism/core-utils/-/core-utils-0.12.0.tgz", + "integrity": "sha512-qW+7LZYCz7i8dRa7SRlUKIo1VBU8lvN0HeXCxJR+z+xtMzMQpPds20XJNCMclszxYQHkXY00fOT6GvFw9ZL6nw==", + "dev": true, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/abstract-provider": "^5.7.0", + "@ethersproject/address": "^5.7.0", + "@ethersproject/bignumber": "^5.7.0", + "@ethersproject/bytes": "^5.7.0", + "@ethersproject/constants": "^5.7.0", + "@ethersproject/contracts": "^5.7.0", + "@ethersproject/hash": "^5.7.0", + "@ethersproject/keccak256": "^5.7.0", + "@ethersproject/properties": "^5.7.0", + "@ethersproject/providers": "^5.7.0", + "@ethersproject/rlp": "^5.7.0", + "@ethersproject/transactions": "^5.7.0", + "@ethersproject/web": "^5.7.0", + "bufio": "^1.0.7", + "chai": "^4.3.4" + } + }, + "node_modules/@ethereumjs/rlp": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.2.tgz", + "integrity": "sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==", + "dev": true, + "bin": { + "rlp": "bin/rlp.cjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ethereumjs/util": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-9.1.0.tgz", + "integrity": "sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog==", + "dev": true, + "dependencies": { + "@ethereumjs/rlp": "^5.0.2", + "ethereum-cryptography": "^2.2.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/@ethersproject/abi": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", + "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/abstract-provider": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", + "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0" + } + }, + "node_modules/@ethersproject/abstract-signer": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", + "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/@ethersproject/address": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", + "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/rlp": "^5.8.0" + } + }, + "node_modules/@ethersproject/base64": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", + "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0" + } + }, + "node_modules/@ethersproject/basex": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/basex/-/basex-5.8.0.tgz", + "integrity": "sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/properties": "^5.8.0" + } + }, + "node_modules/@ethersproject/bignumber": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", + "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "bn.js": "^5.2.1" + } + }, + "node_modules/@ethersproject/bytes": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", + "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/constants": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", + "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.8.0" + } + }, + "node_modules/@ethersproject/contracts": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/contracts/-/contracts-5.8.0.tgz", + "integrity": "sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "^5.8.0", + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/transactions": "^5.8.0" + } + }, + "node_modules/@ethersproject/hash": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", + "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/hdnode": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/hdnode/-/hdnode-5.8.0.tgz", + "integrity": "sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" + } + }, + "node_modules/@ethersproject/json-wallets": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/json-wallets/-/json-wallets-5.8.0.tgz", + "integrity": "sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/pbkdf2": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "aes-js": "3.0.0", + "scrypt-js": "3.0.1" + } + }, + "node_modules/@ethersproject/json-wallets/node_modules/aes-js": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", + "integrity": "sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==", + "dev": true + }, + "node_modules/@ethersproject/keccak256": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", + "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "js-sha3": "0.8.0" + } + }, + "node_modules/@ethersproject/logger": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", + "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ] + }, + "node_modules/@ethersproject/networks": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", + "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/pbkdf2": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/pbkdf2/-/pbkdf2-5.8.0.tgz", + "integrity": "sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/sha2": "^5.8.0" + } + }, + "node_modules/@ethersproject/properties": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", + "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/providers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/providers/-/providers-5.8.0.tgz", + "integrity": "sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/base64": "^5.8.0", + "@ethersproject/basex": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/networks": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/web": "^5.8.0", + "bech32": "1.1.4", + "ws": "8.18.0" + } + }, + "node_modules/@ethersproject/providers/node_modules/ws": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@ethersproject/random": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/random/-/random-5.8.0.tgz", + "integrity": "sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/rlp": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", + "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/sha2": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/sha2/-/sha2-5.8.0.tgz", + "integrity": "sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/signing-key": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", + "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "bn.js": "^5.2.1", + "elliptic": "6.6.1", + "hash.js": "1.1.7" + } + }, + "node_modules/@ethersproject/solidity": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/solidity/-/solidity-5.8.0.tgz", + "integrity": "sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/sha2": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/strings": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", + "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/transactions": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", + "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/rlp": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0" + } + }, + "node_modules/@ethersproject/units": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.8.0.tgz", + "integrity": "sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/constants": "^5.8.0", + "@ethersproject/logger": "^5.8.0" + } + }, + "node_modules/@ethersproject/wallet": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wallet/-/wallet-5.8.0.tgz", + "integrity": "sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abstract-provider": "^5.8.0", + "@ethersproject/abstract-signer": "^5.8.0", + "@ethersproject/address": "^5.8.0", + "@ethersproject/bignumber": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/hdnode": "^5.8.0", + "@ethersproject/json-wallets": "^5.8.0", + "@ethersproject/keccak256": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/random": "^5.8.0", + "@ethersproject/signing-key": "^5.8.0", + "@ethersproject/transactions": "^5.8.0", + "@ethersproject/wordlists": "^5.8.0" + } + }, + "node_modules/@ethersproject/web": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", + "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/base64": "^5.8.0", + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@ethersproject/wordlists": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/@ethersproject/wordlists/-/wordlists-5.8.0.tgz", + "integrity": "sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/bytes": "^5.8.0", + "@ethersproject/hash": "^5.8.0", + "@ethersproject/logger": "^5.8.0", + "@ethersproject/properties": "^5.8.0", + "@ethersproject/strings": "^5.8.0" + } + }, + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@manypkg/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" + } + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", + "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" + } + }, + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", + "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", + "dev": true + }, + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/@noble/curves": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", + "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "dev": true, + "peer": true, + "dependencies": { + "@noble/hashes": "1.3.2" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/hashes": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", + "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@noble/secp256k1": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", + "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/@nodable/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nomicfoundation/edr": { + "version": "0.12.0-next.23", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.12.0-next.23.tgz", + "integrity": "sha512-F2/6HZh8Q9RsgkOIkRrckldbhPjIZY7d4mT9LYuW68miwGQ5l7CkAgcz9fRRiurA0+YJhtsbx/EyrD9DmX9BOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.23", + "@nomicfoundation/edr-darwin-x64": "0.12.0-next.23", + "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.23", + "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.23", + "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.23", + "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.23", + "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.23" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.12.0-next.23", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.12.0-next.23.tgz", + "integrity": "sha512-Amh7mRoDzZyJJ4efqoePqdoZOzharmSOttZuJDlVE5yy07BoE8hL6ZRpa5fNYn0LCqn/KoWs8OHANWxhKDGhvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.12.0-next.23", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.12.0-next.23.tgz", + "integrity": "sha512-9wn489FIQm7m0UCD+HhktjWx6vskZzeZD9oDc2k9ZvbBzdXwPp5tiDqUBJ+eQpByAzCDfteAJwRn2lQCE0U+Iw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.12.0-next.23", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.12.0-next.23.tgz", + "integrity": "sha512-nlk5EejSzEUfEngv0Jkhqq3/wINIfF2ED9wAofc22w/V1DV99ASh9l3/e/MIHOQFecIZ9MDqt0Em9/oDyB1Uew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.12.0-next.23", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.12.0-next.23.tgz", + "integrity": "sha512-SJuPBp3Rc6vM92UtVTUxZQ/QlLhLfwTftt2XUiYohmGKB3RjGzpgduEFMCA0LEnucUckU6UHrJNFHiDm77C4PQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.12.0-next.23", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.12.0-next.23.tgz", + "integrity": "sha512-NU+Qs3u7Qt6t3bJFdmmjd5CsvgI2bPPzO31KifM2Ez96/jsXYho5debtTQnimlb5NAqiHTSlxjh/F8ROcptmeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.12.0-next.23", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.12.0-next.23.tgz", + "integrity": "sha512-F78fZA2h6/ssiCSZOovlgIu0dUeI7ItKPsDDF3UUlIibef052GCXmliMinC90jVPbrjUADMd1BUwjfI0Z8OllQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.12.0-next.23", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.12.0-next.23.tgz", + "integrity": "sha512-IfJZQJn7d/YyqhmguBIGoCKjE9dKjbu6V6iNEPApfwf5JyyjHYyyfkLU4rf7hygj57bfH4sl1jtQ6r8HnT62lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@nomicfoundation/hardhat-chai-matchers": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.1.2.tgz", + "integrity": "sha512-NlUlde/ycXw2bLzA2gWjjbxQaD9xIRbAF30nsoEprAWzH8dXEI1ILZUKZMyux9n9iygEXTzN0SDVjE6zWDZi9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/chai-as-promised": "^7.1.3", + "chai-as-promised": "^7.1.1", + "deep-eql": "^4.0.1", + "ordinal": "^1.0.3" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.1.0", + "chai": "^4.2.0", + "ethers": "^6.14.0", + "hardhat": "^2.26.0" + } + }, + "node_modules/@nomicfoundation/hardhat-ethers": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.1.3.tgz", + "integrity": "sha512-208JcDeVIl+7Wu3MhFUUtiA8TJ7r2Rn3Wr+lSx9PfsDTKkbsAsWPY6N6wQ4mtzDv0/pB9nIbJhkjoHe1EsgNsA==", + "dev": true, + "peer": true, + "dependencies": { + "debug": "^4.1.1", + "lodash.isequal": "^4.5.0" + }, + "peerDependencies": { + "ethers": "^6.14.0", + "hardhat": "^2.28.0" + } + }, + "node_modules/@nomicfoundation/hardhat-foundry": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-foundry/-/hardhat-foundry-1.2.1.tgz", + "integrity": "sha512-pH1KeyI0sysgi7I7uQKPLXWl895EkuS6V41rSi820Ipqp/FScIwDh27RbevgC9zJ4ufSsSz34njm9cvRMGMNVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.1.0" + }, + "peerDependencies": { + "hardhat": "^2.26.0" + } + }, + "node_modules/@nomicfoundation/hardhat-network-helpers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.1.2.tgz", + "integrity": "sha512-p7HaUVDbLj7ikFivQVNhnfMHUBgiHYMwQWvGn9AriieuopGOELIrwj2KjyM2a6z70zai5YKO264Vwz+3UFJZPQ==", + "dev": true, + "dependencies": { + "ethereumjs-util": "^7.1.4" + }, + "peerDependencies": { + "hardhat": "^2.26.0" + } + }, + "node_modules/@nomicfoundation/slang": { + "version": "0.18.3", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-0.18.3.tgz", + "integrity": "sha512-YqAWgckqbHM0/CZxi9Nlf4hjk9wUNLC9ngWCWBiqMxPIZmzsVKYuChdlrfeBPQyvQQBoOhbx+7C1005kLVQDZQ==", + "dev": true, + "dependencies": { + "@bytecodealliance/preview2-shim": "0.17.0" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", + "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "dev": true, + "engines": { + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", + "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", + "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", + "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", + "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", + "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", + "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", + "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", + "dev": true, + "optional": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@offchainlabs/upgrade-executor": { + "version": "1.1.0-beta.0", + "resolved": "https://registry.npmjs.org/@offchainlabs/upgrade-executor/-/upgrade-executor-1.1.0-beta.0.tgz", + "integrity": "sha512-mpn6PHjH/KDDjNX0pXHEKdyv8m6DVGQiI2nGzQn0JbM1nOSHJpWx6fvfjtH7YxHJ6zBZTcsKkqGkFKDtCfoSLw==", + "dev": true, + "dependencies": { + "@openzeppelin/contracts": "4.7.3", + "@openzeppelin/contracts-upgradeable": "4.7.3" + } + }, + "node_modules/@offchainlabs/upgrade-executor/node_modules/@openzeppelin/contracts": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-4.7.3.tgz", + "integrity": "sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==", + "dev": true + }, + "node_modules/@offchainlabs/upgrade-executor/node_modules/@openzeppelin/contracts-upgradeable": { + "version": "4.7.3", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.7.3.tgz", + "integrity": "sha512-+wuegAMaLcZnLCJIvrVUDzA9z/Wp93f0Dla/4jJvIhijRrPabjQbZe6fWiECLaJyfn5ci9fqf9vTw3xpQOad2A==", + "dev": true + }, + "node_modules/@openzeppelin/contracts": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-5.6.1.tgz", + "integrity": "sha512-Ly6SlsVJ3mj+b18W3R8gNufB7dTICT105fJhodGAGgyC2oqnBAhqSiNDJ8V8DLY05cCz81GLI0CU5vNYA1EC/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@openzeppelin/contracts-upgradeable": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.6.1.tgz", + "integrity": "sha512-n4a/vfRs114lXyUdYg7pyY8LvFKWvCDF5lEcRRAVxap8g6ZEdLqm+9tmt2zTtRHcNMxTYp9y5t6KBof4tHp7Og==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@openzeppelin/contracts": "5.6.1" + } + }, + "node_modules/@openzeppelin/defender-sdk-base-client": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-base-client/-/defender-sdk-base-client-2.7.0.tgz", + "integrity": "sha512-J5IpvbFfdIJM4IadBcXfhCXVdX2yEpaZtRR1ecq87d8CdkmmEpniYfef/yVlG98yekvu125LaIRg0yXQOt9Bdg==", + "dev": true, + "dependencies": { + "@aws-sdk/client-lambda": "^3.563.0", + "amazon-cognito-identity-js": "^6.3.6", + "async-retry": "^1.3.3" + } + }, + "node_modules/@openzeppelin/defender-sdk-deploy-client": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-deploy-client/-/defender-sdk-deploy-client-2.7.0.tgz", + "integrity": "sha512-YOHZmnHmM1y6uSqXWGfk2/5/ae4zZJE6xG92yFEAIOy8vqh1dxznWMsoCcAXRXTCWc8RdCDpFdMfEy4SBTyYtg==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^2.7.0", + "axios": "^1.7.4", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/defender-sdk-network-client": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/@openzeppelin/defender-sdk-network-client/-/defender-sdk-network-client-2.7.0.tgz", + "integrity": "sha512-4CYWPa9+kSjojE5KS7kRmP161qsBATdp97TCrzyDdGoVahj0GyqgafRL9AAjm0eHZOM1c7EIYEpbvYRtFi8vyA==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^2.7.0", + "axios": "^1.7.4", + "lodash": "^4.17.21" + } + }, + "node_modules/@openzeppelin/hardhat-upgrades": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-3.9.1.tgz", + "integrity": "sha512-pSDjlOnIpP+PqaJVe144dK6VVKZw2v6YQusyt0OOLiCsl+WUzfo4D0kylax7zjrOxqy41EK2ipQeIF4T+cCn2A==", + "dev": true, + "dependencies": { + "@openzeppelin/defender-sdk-base-client": "^2.1.0", + "@openzeppelin/defender-sdk-deploy-client": "^2.1.0", + "@openzeppelin/defender-sdk-network-client": "^2.1.0", + "@openzeppelin/upgrades-core": "^1.41.0", + "chalk": "^4.1.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.1.5", + "proper-lockfile": "^4.1.1", + "undici": "^6.11.1" + }, + "bin": { + "migrate-oz-cli-project": "dist/scripts/migrate-oz-cli-project.js" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^3.0.6", + "@nomicfoundation/hardhat-verify": "^2.0.14", + "ethers": "^6.6.0", + "hardhat": "^2.24.1" + }, + "peerDependenciesMeta": { + "@nomicfoundation/hardhat-verify": { + "optional": true + } + } + }, + "node_modules/@openzeppelin/upgrades-core": { + "version": "1.44.2", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.44.2.tgz", + "integrity": "sha512-m6iorjyhPK9ow5/trNs7qsBC/SOzJCO51pvvAF2W9nOiZ1t0RtCd+rlRmRmlWTv4M33V0wzIUeamJ2BPbzgUXA==", + "dev": true, + "dependencies": { + "@nomicfoundation/slang": "^0.18.3", + "bignumber.js": "^9.1.2", + "cbor": "^10.0.0", + "chalk": "^4.1.0", + "compare-versions": "^6.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "minimatch": "^9.0.5", + "minimist": "^1.2.7", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.60" + }, + "bin": { + "openzeppelin-upgrades-core": "dist/cli/cli.js" + } + }, + "node_modules/@scroll-tech/contracts": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@scroll-tech/contracts/-/contracts-0.1.0.tgz", + "integrity": "sha512-aBbDOc3WB/WveZdpJYcrfvMYMz7ZTEiW8M9XMJLba8p9FAR5KGYB/cV+8+EUsq3MKt7C1BfR+WnXoTVdvwIY6w==", + "dev": true + }, + "node_modules/@scure/base": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", + "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "dev": true, + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip32/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "dev": true, + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@scure/bip39/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@sentry/core": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", + "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/core/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@sentry/hub": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", + "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "dev": true, + "dependencies": { + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/hub/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@sentry/minimal": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", + "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/minimal/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@sentry/node": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", + "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "dev": true, + "dependencies": { + "@sentry/core": "5.30.0", + "@sentry/hub": "5.30.0", + "@sentry/tracing": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/node/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@sentry/tracing": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", + "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "dev": true, + "dependencies": { + "@sentry/hub": "5.30.0", + "@sentry/minimal": "5.30.0", + "@sentry/types": "5.30.0", + "@sentry/utils": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/tracing/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@sentry/types": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", + "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils": { + "version": "5.30.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", + "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "dev": true, + "dependencies": { + "@sentry/types": "5.30.0", + "tslib": "^1.9.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@sentry/utils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.17", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.17.tgz", + "integrity": "sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-config-provider": "^4.2.2", + "@smithy/util-endpoints": "^3.4.2", + "@smithy/util-middleware": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.23.17", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.17.tgz", + "integrity": "sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-body-length-browser": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-stream": "^4.5.25", + "@smithy/util-utf8": "^4.2.2", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.14.tgz", + "integrity": "sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.14.tgz", + "integrity": "sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.14.1", + "@smithy/util-hex-encoding": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.14.tgz", + "integrity": "sha512-8IelTCtTctWRbb+0Dcy+C0aICh1qa0qWXqgjcXDmMuCvPJRnv26hiDZoAau2ILOniki65mCPKqOQs/BaWvO4CQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.14.tgz", + "integrity": "sha512-sqHiHpYRYo3FJlaIxD1J8PhbcmJAm7IuM16mVnwSkCToD7g00IBZzKuiLNMGmftULmEUX6/UAz8/NN5uMP8bVA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.14.tgz", + "integrity": "sha512-Ht/8BuGlKfFTy0H3+8eEu0vdpwGztCnaLLXtpXNdQqiR7Hj4vFScU3T436vRAjATglOIPjJXronY+1WxxNLSiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.14.tgz", + "integrity": "sha512-lWyt4T2XQZUZgK3tQ3Wn0w3XBvZsK/vjTuJl6bXbnGZBHH0ZUSONTYiK9TgjTTzU54xQr3DRFwpjmhp0oLm3gg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.17", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.17.tgz", + "integrity": "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.14.tgz", + "integrity": "sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.14.tgz", + "integrity": "sha512-c21qJiTSb25xvvOp+H2TNZzPCngrvl5vIPqPB8zQ/DmJF4QWXO19x1dWfMJZ6wZuuWUPPm0gV8C0cU3+ifcWuw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", + "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.14.tgz", + "integrity": "sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.4.32", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.32.tgz", + "integrity": "sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/middleware-serde": "^4.2.20", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "@smithy/url-parser": "^4.2.14", + "@smithy/util-middleware": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.5.7.tgz", + "integrity": "sha512-bRt6ZImqVSeTk39Nm81K20ObIiAZ3WefY7G6+iz/0tZjs4dgRRjvRX2sgsH+zi6iDCRR/aQvQofLKxxz4rPBZg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/service-error-classification": "^4.3.1", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.6", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.20", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.20.tgz", + "integrity": "sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.14.tgz", + "integrity": "sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.14.tgz", + "integrity": "sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.6.1.tgz", + "integrity": "sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.14.tgz", + "integrity": "sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.14.tgz", + "integrity": "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.14.tgz", + "integrity": "sha512-XYA5Z0IqTeF+5XDdh4BBmSA0HvbgVZIyv4cmOoUheDNR57K1HgBp9ukUMx3Cr3XpDHHpLBnexPE3LAtDsZkj2A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-uri-escape": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.14.tgz", + "integrity": "sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.3.1.tgz", + "integrity": "sha512-aUQuDGh760ts/8MU+APjIZhlLPKhIIfqyzZaJikLEIMrdxFvxuLYD0WxWzaYWpmLbQlXDe9p7EWM3HsBe0K6Gw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.9.tgz", + "integrity": "sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.14.tgz", + "integrity": "sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-uri-escape": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.12.13", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.13.tgz", + "integrity": "sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.17", + "@smithy/middleware-endpoint": "^4.4.32", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-stream": "^4.5.25", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.1.tgz", + "integrity": "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.14.tgz", + "integrity": "sha512-p06BiBigJ8bTA3MgnOfCtDUWnAMY0YfedO/GRpmc7p+wg3KW8vbXy1xwSu5ASy0wV7rRYtlfZOIKH4XqfhjSQQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz", + "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz", + "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz", + "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", + "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", + "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.49", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.49.tgz", + "integrity": "sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.54", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.54.tgz", + "integrity": "sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.4.17", + "@smithy/credential-provider-imds": "^4.2.14", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/property-provider": "^4.2.14", + "@smithy/smithy-client": "^4.12.13", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.4.2.tgz", + "integrity": "sha512-a55Tr+3OKld4TTtnT+RhKOQHyPxm3j/xL4OR83WBUhLJaKDS9dnJ7arRMOp3t31dcLhApwG9bgvrRXBHlLdIkg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", + "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.14.tgz", + "integrity": "sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.3.8.tgz", + "integrity": "sha512-LUIxbTBi+OpvXpg91poGA6BdyoleMDLnfXjVDqyi2RvZmTveY5loE/FgYUBCR5LU2BThW2SoZRh8dTIIy38IPw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^4.3.1", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.25", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.25.tgz", + "integrity": "sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/node-http-handler": "^4.6.1", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", + "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.3.0.tgz", + "integrity": "sha512-JyjYmLAfS+pdxF92o4yLgEoy0zhayKTw73FU1aofLWwLcJw7iSqIY2exGmMTrl/lmZugP5p/zxdFSippJDfKWA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz", + "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@solidity-parser/parser": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.14.5.tgz", + "integrity": "sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==", + "dev": true, + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/@types/bn.js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", + "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, + "node_modules/@types/chai-as-promised": { + "version": "7.1.8", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", + "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", + "dev": true, + "dependencies": { + "@types/chai": "*" + } + }, + "node_modules/@types/concat-stream": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", + "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true + }, + "node_modules/@types/esrecurse": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", + "integrity": "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/form-data": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", + "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "12.20.55", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", + "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", + "dev": true + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "dev": true + }, + "node_modules/@types/secp256k1": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.7.tgz", + "integrity": "sha512-Rcvjl6vARGAKRO6jHeKMatGrvOMGrR/AR11N1x2LqintPCyDZ7NBhrh238Z2VZc7aM7KIwnFpFQ7fnfK4H/9Qw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true + }, + "node_modules/@zksync/contracts": { + "name": "era-contracts", + "version": "0.1.0", + "resolved": "git+ssh://git@github.com/matter-labs/era-contracts.git#446d391d34bdb48255d5f8fef8a8248925fc98b9", + "integrity": "sha512-Uke6C3HTDonp/sqP4SlNxU40YL9TK1ICCubcmEBryGQoZCa0z9oc3GSUZ1WBAHQ9HhLiHnpqpayFNmq9fZkK7Q==", + "dev": true, + "workspaces": { + "packages": [ + "l1-contracts", + "l2-contracts", + "system-contracts", + "gas-bound-caller" + ], + "nohoist": [ + "**/@openzeppelin/**" + ] + } + }, + "node_modules/abbrev": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", + "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", + "dev": true, + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/adm-zip": { + "version": "0.4.16", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", + "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "dev": true, + "engines": { + "node": ">=0.3.0" + } + }, + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", + "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "dev": true, + "peer": true + }, + "node_modules/agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/amazon-cognito-identity-js": { + "version": "6.3.16", + "resolved": "https://registry.npmjs.org/amazon-cognito-identity-js/-/amazon-cognito-identity-js-6.3.16.tgz", + "integrity": "sha512-HPGSBGD6Q36t99puWh0LnptxO/4icnk2kqIQ9cTJ2tFQo5NMUnWQIgtrTAk8nm+caqUbjDzXzG56GBjI2tS6jQ==", + "dev": true, + "dependencies": { + "@aws-crypto/sha256-js": "1.2.2", + "buffer": "4.9.2", + "fast-base64-decode": "^1.0.0", + "isomorphic-unfetch": "^3.0.0", + "js-cookie": "^2.2.1" + } + }, + "node_modules/amazon-cognito-identity-js/node_modules/@aws-crypto/sha256-js": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-1.2.2.tgz", + "integrity": "sha512-Nr1QJIbW/afYYGzYvrF70LtaHrIRtd4TNAglX8BvlfxJLZ45SAmueIKYl5tWoNBPzp65ymXGFK0Bb1vZUpuc9g==", + "dev": true, + "dependencies": { + "@aws-crypto/util": "^1.2.2", + "@aws-sdk/types": "^3.1.0", + "tslib": "^1.11.1" + } + }, + "node_modules/amazon-cognito-identity-js/node_modules/@aws-crypto/util": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-1.2.2.tgz", + "integrity": "sha512-H8PjG5WJ4wz0UXAFXeJjWCW1vkvIJ3qUUD+rGRwJ2/hj+xT58Qle2MTql/2MGzkU+1JLAFuR6aJpLAjHwhmwwg==", + "dev": true, + "dependencies": { + "@aws-sdk/types": "^3.1.0", + "@aws-sdk/util-utf8-browser": "^3.0.0", + "tslib": "^1.11.1" + } + }, + "node_modules/amazon-cognito-identity-js/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "dev": true, + "license": "BSD-3-Clause OR MIT", + "optional": true, + "engines": { + "node": ">=0.4.2" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/antlr4ts": { + "version": "0.5.0-alpha.4", + "resolved": "https://registry.npmjs.org/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz", + "integrity": "sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", + "dev": true + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-retry": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.3.tgz", + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dev": true, + "dependencies": { + "retry": "0.13.1" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/axios": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.16.0.tgz", + "integrity": "sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.16.0", + "form-data": "^4.0.5", + "proxy-from-env": "^2.1.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base-x": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", + "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bech32": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz", + "integrity": "sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==", + "dev": true + }, + "node_modules/better-path-resolve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", + "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "dev": true, + "dependencies": { + "is-windows": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blakejs": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", + "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz", + "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==", + "dev": true, + "license": "MIT" + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/boxen": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", + "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "dev": true, + "dependencies": { + "ansi-align": "^3.0.0", + "camelcase": "^6.2.0", + "chalk": "^4.1.0", + "cli-boxes": "^2.2.1", + "string-width": "^4.2.2", + "type-fest": "^0.20.2", + "widest-line": "^3.1.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/boxen/node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz", + "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "dev": true, + "dependencies": { + "base-x": "^3.0.2" + } + }, + "node_modules/bs58check": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "dev": true, + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/bufio": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bufio/-/bufio-1.2.3.tgz", + "integrity": "sha512-5Tt66bRzYUSlVZatc0E92uDenreJ+DpTBmSAUwL4VSxJn3e6cUyYwx+PoqML0GRZatgA/VX8ybhxItF8InZgqA==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/c3-linearization": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/c3-linearization/-/c3-linearization-0.3.0.tgz", + "integrity": "sha512-eQNsZQhFSJAhrNrITy2FpKh7EHS98q/pniDtQhndWqqsvayiPeqZ9T6I9V9PsHcm0nc+ZYJHKUvI/hh37I33HQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==", + "dev": true + }, + "node_modules/cbor": { + "version": "10.0.11", + "resolved": "https://registry.npmjs.org/cbor/-/cbor-10.0.11.tgz", + "integrity": "sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==", + "dev": true, + "dependencies": { + "nofilter": "^3.0.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/chai": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", + "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.3", + "deep-eql": "^4.1.3", + "get-func-name": "^2.0.2", + "loupe": "^2.3.6", + "pathval": "^1.1.1", + "type-detect": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-as-promised": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", + "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", + "dev": true, + "dependencies": { + "check-error": "^1.0.2" + }, + "peerDependencies": { + "chai": ">= 2.1.2 < 6" + } + }, + "node_modules/chai/node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/check-error": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", + "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/cipher-base": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", + "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cli-boxes": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", + "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-table3": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", + "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + }, + "optionalDependencies": { + "@colors/colors": "1.5.0" + } + }, + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/command-exists": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", + "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "dev": true + }, + "node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/compare-versions": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", + "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/concat-stream/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/concat-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/concat-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/cross-spawn/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/dataloader": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", + "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==", + "dev": true + }, + "node_modules/death": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", + "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", + "dev": true + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", + "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/difflib": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", + "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", + "dev": true, + "dependencies": { + "heap": ">= 0.2.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "8.6.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", + "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/elliptic": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", + "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", + "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/enquirer": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", + "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", + "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^2.7.1", + "estraverse": "^1.9.1", + "esutils": "^2.0.2", + "optionator": "^0.8.1" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=0.12.0" + }, + "optionalDependencies": { + "source-map": "~0.2.0" + } + }, + "node_modules/escodegen/node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/source-map": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", + "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", + "dev": true, + "optional": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/escodegen/node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.5.0.tgz", + "integrity": "sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" + ], + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.6.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.2", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", + "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/eslint/node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eth-gas-reporter": { + "version": "0.2.27", + "resolved": "https://registry.npmjs.org/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz", + "integrity": "sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==", + "dev": true, + "dependencies": { + "@solidity-parser/parser": "^0.14.0", + "axios": "^1.5.1", + "cli-table3": "^0.5.0", + "colors": "1.4.0", + "ethereum-cryptography": "^1.0.3", + "ethers": "^5.7.2", + "fs-readdir-recursive": "^1.1.0", + "lodash": "^4.17.14", + "markdown-table": "^1.1.3", + "mocha": "^10.2.0", + "req-cwd": "^2.0.0", + "sha1": "^1.1.1", + "sync-request": "^6.0.0" + }, + "peerDependencies": { + "@codechecks/client": "^0.1.0" + }, + "peerDependenciesMeta": { + "@codechecks/client": { + "optional": true + } + } + }, + "node_modules/eth-gas-reporter/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/eth-gas-reporter/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/cli-table3": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.5.1.tgz", + "integrity": "sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.0", + "string-width": "^2.1.1" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "colors": "^1.1.2" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/eth-gas-reporter/node_modules/ethers": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-5.8.0.tgz", + "integrity": "sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "dependencies": { + "@ethersproject/abi": "5.8.0", + "@ethersproject/abstract-provider": "5.8.0", + "@ethersproject/abstract-signer": "5.8.0", + "@ethersproject/address": "5.8.0", + "@ethersproject/base64": "5.8.0", + "@ethersproject/basex": "5.8.0", + "@ethersproject/bignumber": "5.8.0", + "@ethersproject/bytes": "5.8.0", + "@ethersproject/constants": "5.8.0", + "@ethersproject/contracts": "5.8.0", + "@ethersproject/hash": "5.8.0", + "@ethersproject/hdnode": "5.8.0", + "@ethersproject/json-wallets": "5.8.0", + "@ethersproject/keccak256": "5.8.0", + "@ethersproject/logger": "5.8.0", + "@ethersproject/networks": "5.8.0", + "@ethersproject/pbkdf2": "5.8.0", + "@ethersproject/properties": "5.8.0", + "@ethersproject/providers": "5.8.0", + "@ethersproject/random": "5.8.0", + "@ethersproject/rlp": "5.8.0", + "@ethersproject/sha2": "5.8.0", + "@ethersproject/signing-key": "5.8.0", + "@ethersproject/solidity": "5.8.0", + "@ethersproject/strings": "5.8.0", + "@ethersproject/transactions": "5.8.0", + "@ethersproject/units": "5.8.0", + "@ethersproject/wallet": "5.8.0", + "@ethersproject/web": "5.8.0", + "@ethersproject/wordlists": "5.8.0" + } + }, + "node_modules/eth-gas-reporter/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eth-gas-reporter/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", + "dev": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ethereum-bloom-filters": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz", + "integrity": "sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.4.0" + } + }, + "node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethereum-cryptography": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", + "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "dev": true, + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, + "node_modules/ethereumjs-util": { + "version": "7.1.5", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", + "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "dev": true, + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/ethers": { + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", + "integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], + "peer": true, + "dependencies": { + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", + "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "dev": true, + "peer": true, + "dependencies": { + "undici-types": "~6.19.2" + } + }, + "node_modules/ethers/node_modules/tslib": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", + "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", + "dev": true, + "peer": true + }, + "node_modules/ethjs-unit": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", + "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "4.11.6", + "number-to-bn": "1.7.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/ethjs-unit/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "license": "MIT" + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/extendable-error": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", + "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", + "dev": true + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-base64-decode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz", + "integrity": "sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==", + "dev": true + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-xml-builder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", + "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "path-expression-matcher": "^1.5.0", + "xml-naming": "^0.1.0" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.7.2.tgz", + "integrity": "sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "@nodable/entities": "^2.1.0", + "fast-xml-builder": "^1.1.5", + "path-expression-matcher": "^1.5.0", + "strnum": "^2.2.3" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-yarn-workspace-root": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz", + "integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==", + "dev": true, + "dependencies": { + "micromatch": "^4.0.2" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", + "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fp-ts": { + "version": "1.19.3", + "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", + "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", + "dev": true + }, + "node_modules/fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", + "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ghost-testrpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", + "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "chalk": "^2.4.2", + "node-emoji": "^1.10.0" + }, + "bin": { + "testrpc-sc": "index.js" + } + }, + "node_modules/ghost-testrpc/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/ghost-testrpc/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/ghost-testrpc/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ghost-testrpc/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, + "node_modules/graphviz": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/graphviz/-/graphviz-0.0.9.tgz", + "integrity": "sha512-SmoY2pOtcikmMCqCSy2NO1YsRfu9OO0wpTlOYW++giGjfX1a6gax/m1Fo8IdUd0/3H15cTOfR1SMKwohj4LKsg==", + "dev": true, + "license": "GPL-3.0", + "dependencies": { + "temp": "~0.4.0" + }, + "engines": { + "node": ">=0.6.8" + } + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hardhat": { + "version": "2.28.6", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.28.6.tgz", + "integrity": "sha512-zQze7qe+8ltwHvhX5NQ8sN1N37WWZGw8L63y+2XcPxGwAjc/SMF829z3NS6o1krX0sryhAsVBK/xrwUqlsot4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethereumjs/util": "^9.1.0", + "@ethersproject/abi": "^5.1.2", + "@nomicfoundation/edr": "0.12.0-next.23", + "@nomicfoundation/solidity-analyzer": "^0.1.0", + "@sentry/node": "^5.18.1", + "adm-zip": "^0.4.16", + "aggregate-error": "^3.0.0", + "ansi-escapes": "^4.3.0", + "boxen": "^5.1.2", + "chokidar": "^4.0.0", + "ci-info": "^2.0.0", + "debug": "^4.1.1", + "enquirer": "^2.3.0", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^1.0.3", + "find-up": "^5.0.0", + "fp-ts": "1.19.3", + "fs-extra": "^7.0.1", + "immutable": "^4.0.0-rc.12", + "io-ts": "1.10.4", + "json-stream-stringify": "^3.1.4", + "keccak": "^3.0.2", + "lodash": "^4.17.11", + "micro-eth-signer": "^0.14.0", + "mnemonist": "^0.38.0", + "mocha": "^10.0.0", + "p-map": "^4.0.0", + "picocolors": "^1.1.0", + "raw-body": "^2.4.1", + "resolve": "1.17.0", + "semver": "^6.3.0", + "solc": "0.8.26", + "source-map-support": "^0.5.13", + "stacktrace-parser": "^0.1.10", + "tinyglobby": "^0.2.6", + "tsort": "0.0.1", + "undici": "^5.14.0", + "uuid": "^8.3.2", + "ws": "^7.4.6" + }, + "bin": { + "hardhat": "internal/cli/bootstrap.js" + }, + "peerDependencies": { + "ts-node": "*", + "typescript": "*" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "node_modules/hardhat-contract-sizer": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/hardhat-contract-sizer/-/hardhat-contract-sizer-2.10.1.tgz", + "integrity": "sha512-/PPQQbUMgW6ERzk8M0/DA8/v2TEM9xRRAnF9qKPNMYF6FX5DFWcnxBsQvtp8uBz+vy7rmLyV9Elti2wmmhgkbg==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "cli-table3": "^0.6.0", + "strip-ansi": "^6.0.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-dependency-compiler": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.2.1.tgz", + "integrity": "sha512-xG5iwbspTtxOEiP5UsPngEYQ1Hg+fjTjliapIjdTQmwGkCPofrsDhQDV2O/dopcYzcR68nTx2X8xTewYHgA2rQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.0" + } + }, + "node_modules/hardhat-gas-reporter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.10.tgz", + "integrity": "sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==", + "dev": true, + "dependencies": { + "array-uniq": "1.0.3", + "eth-gas-reporter": "^0.2.25", + "sha1": "^1.1.1" + }, + "peerDependencies": { + "hardhat": "^2.0.2" + } + }, + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", + "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ] + }, + "node_modules/hardhat/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "dev": true, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", + "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@noble/secp256k1": "~1.7.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", + "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "dependencies": { + "@noble/hashes": "~1.2.0", + "@scure/base": "~1.1.0" + } + }, + "node_modules/hardhat/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", + "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.2.0", + "@noble/secp256k1": "1.7.1", + "@scure/bip32": "1.1.5", + "@scure/bip39": "1.1.1" + } + }, + "node_modules/hardhat/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hardhat/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hardhat/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hardhat/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hardhat/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/hardhat/node_modules/undici": { + "version": "5.29.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", + "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", + "dev": true, + "dependencies": { + "@fastify/busboy": "^2.0.0" + }, + "engines": { + "node": ">=14.0" + } + }, + "node_modules/hardhat/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", + "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hash-base/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hash-base/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/hash-base/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/hasha/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/heap": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", + "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", + "dev": true, + "license": "MIT" + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-basic": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", + "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", + "dev": true, + "dependencies": { + "caseless": "^0.12.0", + "concat-stream": "^1.6.2", + "http-response-object": "^3.0.1", + "parse-cache-control": "^1.0.1" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-response-object": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", + "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", + "dev": true, + "dependencies": { + "@types/node": "^10.0.3" + } + }, + "node_modules/http-response-object/node_modules/@types/node": { + "version": "10.17.60", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", + "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==", + "dev": true + }, + "node_modules/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/human-id": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/human-id/-/human-id-1.0.2.tgz", + "integrity": "sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==", + "dev": true + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immutable": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz", + "integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/io-ts": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", + "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", + "dev": true, + "dependencies": { + "fp-ts": "^1.0.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "dependencies": { + "ci-info": "^2.0.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-ci/node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hex-prefixed": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", + "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-subdir": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", + "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", + "dev": true, + "dependencies": { + "better-path-resolve": "1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/isomorphic-unfetch": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz", + "integrity": "sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==", + "dev": true, + "dependencies": { + "node-fetch": "^2.6.1", + "unfetch": "^4.2.0" + } + }, + "node_modules/js-cookie": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", + "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==", + "dev": true + }, + "node_modules/js-sha3": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stream-stringify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/json-stream-stringify/-/json-stream-stringify-3.1.6.tgz", + "integrity": "sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==", + "dev": true, + "engines": { + "node": ">=7.10.1" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonschema": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", + "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/keccak": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", + "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/klaw-sync": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz", + "integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", + "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", + "dev": true, + "peer": true + }, + "node_modules/lodash.startcase": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", + "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loupe": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", + "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.1" + } + }, + "node_modules/lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", + "dev": true + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/micro-eth-signer": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/micro-eth-signer/-/micro-eth-signer-0.14.0.tgz", + "integrity": "sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==", + "dev": true, + "dependencies": { + "@noble/curves": "~1.8.1", + "@noble/hashes": "~1.7.1", + "micro-packed": "~0.7.2" + } + }, + "node_modules/micro-eth-signer/node_modules/@noble/curves": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", + "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", + "dev": true, + "dependencies": { + "@noble/hashes": "1.7.2" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/micro-eth-signer/node_modules/@noble/hashes": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", + "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", + "dev": true, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/micro-ftch": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", + "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", + "dev": true, + "license": "MIT" + }, + "node_modules/micro-packed": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/micro-packed/-/micro-packed-0.7.3.tgz", + "integrity": "sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==", + "dev": true, + "dependencies": { + "@scure/base": "~1.2.5" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mnemonist": { + "version": "0.38.5", + "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", + "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", + "dev": true, + "dependencies": { + "obliterator": "^2.0.0" + } + }, + "node_modules/mocha": { + "version": "10.8.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", + "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "dev": true, + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/mocha/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", + "dev": true + }, + "node_modules/node-emoji": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", + "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-gyp-build": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", + "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/nofilter": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", + "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", + "dev": true, + "engines": { + "node": ">=12.19" + } + }, + "node_modules/nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-to-bn": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", + "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "4.11.6", + "strip-hex-prefix": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/number-to-bn/node_modules/bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", + "dev": true, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obliterator": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", + "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", + "dev": true + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/open": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/open/-/open-7.4.2.tgz", + "integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0", + "is-wsl": "^2.1.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ordinal": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", + "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", + "dev": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/outdent": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", + "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", + "dev": true + }, + "node_modules/p-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", + "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", + "dev": true, + "dependencies": { + "p-map": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-filter/node_modules/p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/package-manager-detector": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", + "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", + "dev": true, + "dependencies": { + "quansync": "^0.2.7" + } + }, + "node_modules/parse-cache-control": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", + "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==", + "dev": true + }, + "node_modules/patch-package": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz", + "integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==", + "dev": true, + "dependencies": { + "@yarnpkg/lockfile": "^1.1.0", + "chalk": "^4.1.2", + "cross-spawn": "^6.0.5", + "find-yarn-workspace-root": "^2.0.0", + "fs-extra": "^9.0.0", + "is-ci": "^2.0.0", + "klaw-sync": "^6.0.0", + "minimist": "^1.2.6", + "open": "^7.4.2", + "rimraf": "^2.6.3", + "semver": "^5.6.0", + "slash": "^2.0.0", + "tmp": "^0.0.33", + "yaml": "^1.10.2" + }, + "bin": { + "patch-package": "index.js" + }, + "engines": { + "node": ">=10", + "npm": ">5" + } + }, + "node_modules/patch-package/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/patch-package/node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/patch-package/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/patch-package/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/patch-package/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-expression-matcher": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz", + "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==", + "dev": true, + "dependencies": { + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "ripemd160": "^2.0.3", + "safe-buffer": "^5.2.1", + "sha.js": "^2.4.12", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.8.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.4.tgz", + "integrity": "sha512-N2MylSdi48+5N/6S5j+maeHbUSIzzZ5uOcX5Hm4QpV8Dkb1HFjfAKTKX6yNPJQD9AhcT3ifHNB66tWTTJDi11Q==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-solidity": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-2.3.1.tgz", + "integrity": "sha512-71sZM5oqgq6pnTlf+RH23U6Ej710APfCiMWO2Z/pHNjrXyvn9Nr0vTS1AUVaSf4GRW0V6hj6Djt0MyWudJUJbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/slang": "1.3.4", + "@solidity-parser/parser": "^0.20.2", + "semver": "^7.7.4" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "prettier": ">=3.0.0" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/@bytecodealliance/preview2-shim": { + "version": "0.17.8", + "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.8.tgz", + "integrity": "sha512-wS5kg8u0KCML1UeHQPJ1IuOI24x/XLentCzsqPER1+gDNC5Cz2hG4G2blLOZap+3CEGhIhnJ9mmZYj6a2W0Lww==", + "dev": true, + "license": "(Apache-2.0 WITH LLVM-exception)" + }, + "node_modules/prettier-plugin-solidity/node_modules/@nomicfoundation/slang": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-1.3.4.tgz", + "integrity": "sha512-ghzrPSYH1sZO65id6+Bq2Ood87HT54QP3RGC8EkmpcrJ6tT9Ky0RtaJfrzV5G4jpDsnNua6+YEDpzOMori04hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bytecodealliance/preview2-shim": "^0.17.2" + } + }, + "node_modules/prettier-plugin-solidity/node_modules/@solidity-parser/parser": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.20.2.tgz", + "integrity": "sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/promise": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", + "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", + "dev": true, + "dependencies": { + "asap": "~2.0.6" + } + }, + "node_modules/proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + } + }, + "node_modules/proper-lockfile/node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/proxy-from-env": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", + "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/quansync": { + "version": "0.2.11", + "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", + "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/antfu" + }, + { + "type": "individual", + "url": "https://github.com/sponsors/sxzz" + } + ] + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/read-yaml-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", + "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.6.1", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/read-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/read-yaml-file/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/recursive-readdir": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", + "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/recursive-readdir/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/recursive-readdir/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/req-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-cwd/-/req-cwd-2.0.0.tgz", + "integrity": "sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==", + "dev": true, + "dependencies": { + "req-from": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/req-from/-/req-from-2.0.0.tgz", + "integrity": "sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==", + "dev": true, + "dependencies": { + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/req-from/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "dependencies": { + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/rimraf/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/rimraf/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rimraf/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ripemd160": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", + "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", + "dev": true, + "dependencies": { + "hash-base": "^3.1.2", + "inherits": "^2.0.4" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/rlp": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", + "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.0" + }, + "bin": { + "rlp": "bin/rlp" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sc-istanbul": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", + "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "abbrev": "1.0.x", + "async": "1.x", + "escodegen": "1.8.x", + "esprima": "2.7.x", + "glob": "^5.0.15", + "handlebars": "^4.0.1", + "js-yaml": "3.x", + "mkdirp": "0.5.x", + "nopt": "3.x", + "once": "1.x", + "resolve": "1.1.x", + "supports-color": "^3.1.0", + "which": "^1.1.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "istanbul": "lib/cli.js" + } + }, + "node_modules/sc-istanbul/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/sc-istanbul/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/sc-istanbul/node_modules/esprima": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", + "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/sc-istanbul/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sc-istanbul/node_modules/resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sc-istanbul/node_modules/supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/scrypt-js": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", + "dev": true + }, + "node_modules/secp256k1": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz", + "integrity": "sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "elliptic": "^6.5.7", + "node-addon-api": "^5.0.0", + "node-gyp-build": "^4.2.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/secp256k1/node_modules/node-addon-api": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", + "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", + "dev": true, + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sha1": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", + "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", + "dev": true, + "dependencies": { + "charenc": ">= 0.0.1", + "crypt": ">= 0.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/sha1-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/sha1-file/-/sha1-file-2.0.1.tgz", + "integrity": "sha512-L4Kum9Lp8cWqcGKycZcXxR6spUoG4idDIUzAKjPiELnIZWxiFlZ5HFVzFxVxuWuGPsrraeL0JoGk0nFZ7AGFEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasha": "^5.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shelljs": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", + "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "glob": "^7.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + }, + "bin": { + "shjs": "bin/shjs" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/shelljs/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/shelljs/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/shelljs/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/solc": { + "version": "0.8.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.26.tgz", + "integrity": "sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==", + "dev": true, + "dependencies": { + "command-exists": "^1.2.8", + "commander": "^8.1.0", + "follow-redirects": "^1.12.1", + "js-sha3": "0.8.0", + "memorystream": "^0.3.1", + "semver": "^5.5.0", + "tmp": "0.0.33" + }, + "bin": { + "solcjs": "solc.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/solc/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/solidity-ast": { + "version": "0.4.61", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.61.tgz", + "integrity": "sha512-OYBJYcYyG7gLV0VuXl9CUrvgJXjV/v0XnR4+1YomVe3q+QyENQXJJxAEASUz4vN6lMAl+C8RSRSr5MBAz09f6w==", + "dev": true + }, + "node_modules/solidity-coverage": { + "version": "0.8.17", + "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.17.tgz", + "integrity": "sha512-5P8vnB6qVX9tt1MfuONtCTEaEGO/O4WuEidPHIAJjx4sktHHKhO3rFvnE0q8L30nWJPTrcqGQMT7jpE29B2qow==", + "dev": true, + "license": "ISC", + "dependencies": { + "@ethersproject/abi": "^5.0.9", + "@solidity-parser/parser": "^0.20.1", + "chalk": "^2.4.2", + "death": "^1.1.0", + "difflib": "^0.2.4", + "fs-extra": "^8.1.0", + "ghost-testrpc": "^0.0.2", + "global-modules": "^2.0.0", + "globby": "^10.0.1", + "jsonschema": "^1.2.4", + "lodash": "^4.17.21", + "mocha": "^10.2.0", + "node-emoji": "^1.10.0", + "pify": "^4.0.1", + "recursive-readdir": "^2.2.2", + "sc-istanbul": "^0.4.5", + "semver": "^7.3.4", + "shelljs": "^0.8.3", + "web3-utils": "^1.3.6" + }, + "bin": { + "solidity-coverage": "plugins/bin.js" + }, + "peerDependencies": { + "hardhat": "^2.11.0" + } + }, + "node_modules/solidity-coverage/node_modules/@solidity-parser/parser": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.20.2.tgz", + "integrity": "sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==", + "dev": true, + "license": "MIT" + }, + "node_modules/solidity-coverage/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/brace-expansion": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", + "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/solidity-coverage/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/solidity-coverage/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/solidity-coverage/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/solidity-coverage/node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/solidity-coverage/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/solidity-coverage/node_modules/globby": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", + "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/solidity-coverage/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/solidity-coverage/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/solidity-coverage/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spawndamnit": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", + "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.5", + "signal-exit": "^4.0.1" + } + }, + "node_modules/spawndamnit/node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/spawndamnit/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawndamnit/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawndamnit/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/spawndamnit/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/spawndamnit/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/stacktrace-parser": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", + "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", + "dev": true, + "dependencies": { + "type-fest": "^0.7.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stacktrace-parser/node_modules/type-fest": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", + "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-hex-prefix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", + "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-hex-prefixed": "1.0.0" + }, + "engines": { + "node": ">=6.5.0", + "npm": ">=3" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.3.0.tgz", + "integrity": "sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/surya": { + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/surya/-/surya-0.4.13.tgz", + "integrity": "sha512-ff2YmkYu9+u9A1tUv6cEuQDhLw1N+++iI+ZenXyhYR7YmaiQ19h32p2VchBn6zy3JPcfpvBZjf/aEmLbSMW1WA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@solidity-parser/parser": "^0.16.1", + "c3-linearization": "^0.3.0", + "colors": "^1.4.0", + "graphviz": "0.0.9", + "sha1-file": "^2.0.0", + "treeify": "^1.1.0", + "yargs": "^17.0.0" + }, + "bin": { + "surya": "bin/surya" + } + }, + "node_modules/surya/node_modules/@solidity-parser/parser": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.16.2.tgz", + "integrity": "sha512-PI9NfoA3P8XK2VBkK5oIfRgKDsicwDZfkVq9ZTBCQYGOP1N2owgY2dyLGyU5/J/hQs8KRk55kdmvTLjy3Mu3vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "antlr4ts": "^0.5.0-alpha.4" + } + }, + "node_modules/surya/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/surya/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/surya/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/sync-request": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", + "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", + "dev": true, + "dependencies": { + "http-response-object": "^3.0.1", + "sync-rpc": "^1.2.1", + "then-request": "^6.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/sync-rpc": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", + "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", + "dev": true, + "dependencies": { + "get-port": "^3.1.0" + } + }, + "node_modules/temp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.4.0.tgz", + "integrity": "sha512-IsFisGgDKk7qzK9erMIkQe/XwiSUdac7z3wYOsjcLkhPBy3k1SlvLoIh2dAHIlEpgA971CgguMrx9z8fFg7tSA==", + "dev": true, + "engines": [ + "node >=0.4.0" + ] + }, + "node_modules/term-size": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", + "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/then-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", + "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", + "dev": true, + "dependencies": { + "@types/concat-stream": "^1.6.0", + "@types/form-data": "0.0.33", + "@types/node": "^8.0.0", + "@types/qs": "^6.2.31", + "caseless": "~0.12.0", + "concat-stream": "^1.6.0", + "form-data": "^2.2.0", + "http-basic": "^8.1.1", + "http-response-object": "^3.0.1", + "promise": "^8.0.0", + "qs": "^6.4.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/then-request/node_modules/@types/node": { + "version": "8.10.66", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", + "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==", + "dev": true + }, + "node_modules/then-request/node_modules/form-data": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.5.tgz", + "integrity": "sha512-jqdObeR2rxZZbPSGL+3VckHMYtu+f9//KXBsVny6JSX/pa38Fy+bGjuG8eW/H6USNQWhLi8Num++cU2yOCNz4A==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.35", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-buffer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", + "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", + "dev": true, + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-buffer/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/treeify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", + "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true + }, + "node_modules/tsort": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", + "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", + "dev": true + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.25.0.tgz", + "integrity": "sha512-ZgpWDC5gmNiuY9CnLVXEH8rl50xhRCuLNA97fAUnKi8RRuV4E6KG31pDTsLVUKnohJE0I3XDrTeEydAXRw47xg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "node_modules/undici-types": { + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "peer": true + }, + "node_modules/unfetch": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-4.2.0.tgz", + "integrity": "sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==", + "dev": true + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/web3-utils": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", + "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", + "dev": true, + "license": "LGPL-3.0", + "dependencies": { + "@ethereumjs/util": "^8.1.0", + "bn.js": "^5.2.1", + "ethereum-bloom-filters": "^1.0.6", + "ethereum-cryptography": "^2.1.2", + "ethjs-unit": "0.1.6", + "number-to-bn": "1.7.0", + "randombytes": "^2.1.0", + "utf8": "3.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/web3-utils/node_modules/@ethereumjs/rlp": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", + "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", + "dev": true, + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/web3-utils/node_modules/@ethereumjs/util": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", + "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/web3-utils/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/web3-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "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/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "peer": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xml-naming": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", + "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz", + "integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..a66650b --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "cmtat-ace", + "version": "1.0.0", + "description": "", + "scripts": { + "test": "hardhat test", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "format": "prettier --write '**/*.{js,json,md}' 'contracts/**/*.sol'", + "format:check": "prettier --check '**/*.{js,json,md}' 'contracts/**/*.sol'", + "slither": "./scripts/slither.sh" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/CMTA/CMTAT-ACE.git" + }, + "author": "", + "homepage": "https://github.com/CMTA/CMTAT-ACE#readme", + "devDependencies": { + "@chainlink/ace": "1.1.1", + "@chainlink/contracts": "1.3.0", + "@eslint/js": "^10.0.1", + "@nomicfoundation/hardhat-chai-matchers": "^2.1.0", + "@nomicfoundation/hardhat-foundry": "^1.2.1", + "@nomicfoundation/hardhat-network-helpers": "^1.1.2", + "@openzeppelin/contracts": "5.6.1", + "@openzeppelin/contracts-upgradeable": "5.6.1", + "@openzeppelin/hardhat-upgrades": "^3.2.0", + "@openzeppelin/upgrades-core": "^1.44.1", + "eslint": "^10.4.1", + "eslint-config-prettier": "^10.1.8", + "hardhat": "^2.28.0", + "hardhat-contract-sizer": "^2.10.0", + "hardhat-dependency-compiler": "^1.2.1", + "hardhat-gas-reporter": "^1.0.9", + "prettier": "^3.8.4", + "prettier-plugin-solidity": "^2.3.1", + "solidity-coverage": "^0.8.17", + "surya": "^0.4.13" + } +} diff --git a/remappings.txt b/remappings.txt new file mode 100644 index 0000000..12288b4 --- /dev/null +++ b/remappings.txt @@ -0,0 +1,4 @@ +@chainlink/policy-management/=node_modules/@chainlink/ace/packages/policy-management/src/ +@chainlink/cross-chain-identity/=node_modules/@chainlink/ace/packages/cross-chain-identity/src/ +@chainlink/contracts/=node_modules/@chainlink/contracts/ +CMTAT/=submodules/CMTAT/contracts/ diff --git a/scripts/demo.js b/scripts/demo.js new file mode 100644 index 0000000..07c5a34 --- /dev/null +++ b/scripts/demo.js @@ -0,0 +1,562 @@ +/** + * Demo deployment script + * + * Deploys: + * 1. PolicyEngine (proxy) + * 2. ComplianceTokenCMTATStandalone + * 3. PausePolicy (proxy) – added to all external functions + * 4. RoleBasedAccessControlPolicy (proxy) – added to all external functions + * 5. MintBurnExtractor + * 6. SecureMintPolicy (proxy) – added to mint function + * 7. MockV3Aggregator (Hardhat-only reserve price feed for SecureMint) + * 8. ERC20TransferExtractor – set for transfer() + * 9. ERC20TransferFromExtractor – set for transferFrom() + * 10. MaxAmountRule + RestrictedAddressRule (mock IRule contracts) + * 11. TransferValidationPolicy (proxy) – added to transfer() and transferFrom() + * 12. DocumentEngineMock – set on the token + * 13. SnapshotEngineMock – set on the token, used for scheduling snapshots + * + * Script example - do not use it for production + */ +const { ethers, upgrades } = require('hardhat'); +const { ZeroAddress, keccak256, toUtf8Bytes, AbiCoder } = require('ethers'); + +/* ============ Role Constants ============ */ +const MINTER_ROLE = keccak256(toUtf8Bytes('MINTER_ROLE')); +const BURNER_ROLE = keccak256(toUtf8Bytes('BURNER_ROLE')); +const BURNER_FROM_ROLE = keccak256(toUtf8Bytes('BURNER_FROM_ROLE')); +const ENFORCER_ROLE = keccak256(toUtf8Bytes('ENFORCER_ROLE')); +const ERC20ENFORCER_ROLE = keccak256(toUtf8Bytes('ERC20ENFORCER_ROLE')); +const SNAPSHOOTER_ROLE = keccak256(toUtf8Bytes('SNAPSHOOTER_ROLE')); +const DOCUMENT_ROLE = keccak256(toUtf8Bytes('DOCUMENT_ROLE')); +const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; + +/* ============ Helpers ============ */ + +async function deployPolicyEngine(defaultAllow, initialOwner) { + const Factory = await ethers.getContractFactory('PolicyEngine'); + const policyEngine = await upgrades.deployProxy(Factory, [defaultAllow, initialOwner], { + initializer: 'initialize', + unsafeAllow: ['constructor'], + silenceWarnings: true, + }); + await policyEngine.waitForDeployment(); + return policyEngine; +} + +async function deployRBACPolicy(policyEngineAddress, ownerAddress) { + const Factory = await ethers.getContractFactory('RoleBasedAccessControlPolicy'); + const rbacPolicy = await upgrades.deployProxy( + Factory, + [policyEngineAddress, ownerAddress, '0x'], + { + initializer: 'initialize', + unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], + silenceWarnings: true, + }, + ); + await rbacPolicy.waitForDeployment(); + return rbacPolicy; +} + +async function deployPausePolicy(policyEngineAddress, ownerAddress, initiallyPaused = false) { + const abiCoder = AbiCoder.defaultAbiCoder(); + const configParams = abiCoder.encode(['bool'], [initiallyPaused]); + const Factory = await ethers.getContractFactory('PausePolicy'); + const pausePolicy = await upgrades.deployProxy( + Factory, + [policyEngineAddress, ownerAddress, configParams], + { + initializer: 'initialize', + unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], + silenceWarnings: true, + }, + ); + await pausePolicy.waitForDeployment(); + return pausePolicy; +} + +async function deploySecureMintPolicy(policyEngineAddress, ownerAddress, configParams) { + const Factory = await ethers.getContractFactory('SecureMintPolicy'); + const secureMintPolicy = await upgrades.deployProxy( + Factory, + [policyEngineAddress, ownerAddress, configParams], + { + initializer: 'initialize', + unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], + silenceWarnings: true, + }, + ); + await secureMintPolicy.waitForDeployment(); + return secureMintPolicy; +} + +async function deployMockAggregator(decimals, initialAnswer) { + const Factory = await ethers.getContractFactory('MockV3Aggregator'); + const mock = await Factory.deploy(decimals, initialAnswer); + await mock.waitForDeployment(); + return mock; +} + +async function main() { + const network = await ethers.provider.getNetwork(); + const isHardhatNetwork = network.chainId === 31337n; + + const signers = await ethers.getSigners(); + const deployer = signers[0]; + + if (isHardhatNetwork) { + console.log('Hardhat network detected, using account:', deployer.address); + } else { + console.log('Deploying to network:', network.name, 'with account:', deployer.address); + } + + const admin = deployer.address; + const tokenDecimals = 8; + + /* ============================================================ + * 1. Deploy PolicyEngine (defaultAllow = true) + * ============================================================ */ + console.log('\n--- Step 1: Deploy PolicyEngine ---'); + const policyEngine = await deployPolicyEngine(true, admin); + const policyEngineAddress = await policyEngine.getAddress(); + console.log('PolicyEngine deployed to:', policyEngineAddress); + + /* ============================================================ + * 2. Deploy Document & Snapshot Engine Mocks + * ============================================================ */ + console.log('\n--- Step 2: Deploy Document & Snapshot Engine Mocks ---'); + + const DocumentEngineMockFactory = await ethers.getContractFactory('DocumentEngineMock'); + const documentEngineMock = await DocumentEngineMockFactory.deploy(); + await documentEngineMock.waitForDeployment(); + const documentEngineAddress = await documentEngineMock.getAddress(); + console.log('DocumentEngineMock deployed to:', documentEngineAddress); + + // SnapshotEngineMock needs the token address, so deploy with ZeroAddress first, then update after token deploy + const SnapshotEngineMockFactory = await ethers.getContractFactory('SnapshotEngineMock'); + const snapshotEngineMock = await SnapshotEngineMockFactory.deploy(ZeroAddress, admin); + await snapshotEngineMock.waitForDeployment(); + const snapshotEngineAddress = await snapshotEngineMock.getAddress(); + console.log('SnapshotEngineMock deployed to:', snapshotEngineAddress); + + /* ============================================================ + * 3. Deploy ComplianceTokenCMTATStandalone + * ============================================================ */ + console.log('\n--- Step 3: Deploy ComplianceTokenCMTATStandalone ---'); + const ERC20Attributes = { + name: 'Security Token', + symbol: 'ST', + decimalsIrrevocable: tokenDecimals, + }; + const terms = { + name: 'Token Terms v1', + uri: 'https://cmta.ch/standards/cmta-token-cmtat', + documentHash: keccak256(toUtf8Bytes('terms-v1')), + }; + const extraInformationAttributes = { + tokenId: '1234567890', + terms: terms, + information: 'CMTAT smart contract', + }; + + const CMTATFactory = await ethers.getContractFactory('ComplianceTokenCMTATStandalone', deployer); + const cmtat = await CMTATFactory.deploy( + admin, + ERC20Attributes, + extraInformationAttributes, + policyEngineAddress, + snapshotEngineAddress, + documentEngineAddress, + ); + await cmtat.waitForDeployment(); + const cmtatAddress = await cmtat.getAddress(); + console.log('ComplianceTokenCMTATStandalone deployed to:', cmtatAddress); + + // Update SnapshotEngineMock with the actual token address + await snapshotEngineMock.setERC20(cmtatAddress); + console.log('SnapshotEngineMock updated with token address'); + + /* ============================================================ + * 4. Deploy PausePolicy + * ============================================================ */ + console.log('\n--- Step 4: Deploy PausePolicy ---'); + const pausePolicy = await deployPausePolicy(policyEngineAddress, admin, false); + const pausePolicyAddress = await pausePolicy.getAddress(); + console.log('PausePolicy deployed to:', pausePolicyAddress, '(initially unpaused)'); + + /* ============================================================ + * 5. Deploy RoleBasedAccessControlPolicy + * ============================================================ */ + console.log('\n--- Step 5: Deploy RoleBasedAccessControlPolicy ---'); + const rbacPolicy = await deployRBACPolicy(policyEngineAddress, admin); + const rbacPolicyAddress = await rbacPolicy.getAddress(); + console.log('RoleBasedAccessControlPolicy deployed to:', rbacPolicyAddress); + + /* ============================================================ + * 5. Deploy MockV3Aggregator + SecureMintPolicy + * ============================================================ */ + console.log('\n--- Step 5: Deploy SecureMintPolicy ---'); + + // Deploy a mock reserve price feed (Hardhat only) + // Initial answer = 1,000,000 * 10^8 (reserves of 1M tokens with 8 decimals) + const reserveAmount = 1_000_000n * 10n ** BigInt(tokenDecimals); + const mockFeed = await deployMockAggregator(tokenDecimals, reserveAmount); + const mockFeedAddress = await mockFeed.getAddress(); + console.log('MockV3Aggregator (reserve feed) deployed to:', mockFeedAddress); + + // Encode SecureMintPolicy configuration parameters: + // (address reservesFeed, ReserveMarginConfigs(mode, amount), uint256 maxStalenessSeconds, TokenMetadata(tokenAddress, tokenDecimals)) + const abiCoder = AbiCoder.defaultAbiCoder(); + const secureMintConfigParams = abiCoder.encode( + ['address', 'tuple(uint8,uint256)', 'uint256', 'tuple(address,uint8)'], + [ + mockFeedAddress, + [0, 0], // ReserveMarginMode.None, amount=0 + 0, // maxStalenessSeconds=0 (no staleness check for demo) + [cmtatAddress, tokenDecimals], + ], + ); + + const secureMintPolicy = await deploySecureMintPolicy( + policyEngineAddress, + admin, + secureMintConfigParams, + ); + const secureMintPolicyAddress = await secureMintPolicy.getAddress(); + console.log('SecureMintPolicy deployed to:', secureMintPolicyAddress); + + /* ============================================================ + * 7. Deploy MintBurnExtractor + * ============================================================ */ + console.log('\n--- Step 7: Deploy MintBurnExtractor ---'); + const ExtractorFactory = await ethers.getContractFactory('MintBurnExtractor'); + const mintBurnExtractor = await ExtractorFactory.deploy(); + await mintBurnExtractor.waitForDeployment(); + const extractorAddress = await mintBurnExtractor.getAddress(); + console.log('MintBurnExtractor deployed to:', extractorAddress); + + /* ============================================================ + * 8. Collect function selectors + * ============================================================ */ + console.log('\n--- Step 8: Configure PolicyEngine ---'); + + const selectors = { + // Mint / Burn + mint: cmtat.interface.getFunction('mint(address,uint256)').selector, + burn: cmtat.interface.getFunction('burn(address,uint256)').selector, + burnFrom: cmtat.interface.getFunction('burnFrom(address,uint256)').selector, + // Transfers + transfer: cmtat.interface.getFunction('transfer(address,uint256)').selector, + transferFrom: cmtat.interface.getFunction('transferFrom(address,address,uint256)').selector, + // Enforcement + forcedTransfer: cmtat.interface.getFunction('forcedTransfer(address,address,uint256)').selector, + freezePartial: cmtat.interface.getFunction('freezePartialTokens(address,uint256)').selector, + unfreezePartial: cmtat.interface.getFunction('unfreezePartialTokens(address,uint256)').selector, + // Admin + setName: cmtat.interface.getFunction('setName').selector, + setSymbol: cmtat.interface.getFunction('setSymbol').selector, + // Engines + setSnapshotEngine: cmtat.interface.getFunction('setSnapshotEngine').selector, + setDocumentEngine: cmtat.interface.getFunction('setDocumentEngine').selector, + }; + + console.log('Function selectors:'); + for (const [name, sel] of Object.entries(selectors)) { + console.log(` ${name}: ${sel}`); + } + + /* ============================================================ + * 9. Register extractor for mint selector + * ============================================================ */ + console.log('\n--- Step 9: Set extractor for mint selector ---'); + await policyEngine.connect(deployer).setExtractor(selectors.mint, extractorAddress); + console.log('Extractor set for mint selector'); + + /* ============================================================ + * 10. Add PausePolicy to all external functions + * ============================================================ */ + console.log('\n--- Step 10: Add PausePolicy to all functions ---'); + const allSelectors = Object.entries(selectors); + for (const [name, sel] of allSelectors) { + await policyEngine.connect(deployer).addPolicy(cmtatAddress, sel, pausePolicyAddress, []); + console.log(` PausePolicy added for: ${name} (${sel})`); + } + + /* ============================================================ + * 11. Add RBAC policy to all external functions + * ============================================================ */ + console.log('\n--- Step 11: Add RBAC policy to all functions ---'); + for (const [name, sel] of allSelectors) { + await policyEngine.connect(deployer).addPolicy(cmtatAddress, sel, rbacPolicyAddress, []); + console.log(` RBAC policy added for: ${name} (${sel})`); + } + + /* ============================================================ + * 12. Add SecureMint policy to mint function + * ============================================================ */ + console.log('\n--- Step 12: Add SecureMint policy to mint ---'); + // SecureMintPolicy expects 1 parameter: "amount" + // The extractor produces parameters named keccak256("amount") and keccak256("account") + const PARAM_AMOUNT = keccak256(toUtf8Bytes('amount')); + await policyEngine + .connect(deployer) + .addPolicy(cmtatAddress, selectors.mint, secureMintPolicyAddress, [PARAM_AMOUNT]); + console.log('SecureMint policy added for mint selector'); + + /* ============================================================ + * 12b. Deploy ERC20TransferExtractor + ERC20TransferFromExtractor + * ============================================================ */ + console.log('\n--- Step 12b: Deploy Transfer Extractors ---'); + + const ERC20ExtractorFactory = await ethers.getContractFactory('ERC20TransferExtractor'); + const erc20TransferExtractor = await ERC20ExtractorFactory.deploy(); + await erc20TransferExtractor.waitForDeployment(); + const erc20TransferExtractorAddress = await erc20TransferExtractor.getAddress(); + console.log('ERC20TransferExtractor deployed to:', erc20TransferExtractorAddress); + + const ERC20FromExtractorFactory = await ethers.getContractFactory('ERC20TransferFromExtractor'); + const erc20TransferFromExtractor = await ERC20FromExtractorFactory.deploy(); + await erc20TransferFromExtractor.waitForDeployment(); + const erc20TransferFromExtractorAddress = await erc20TransferFromExtractor.getAddress(); + console.log('ERC20TransferFromExtractor deployed to:', erc20TransferFromExtractorAddress); + + /* ============================================================ + * 12c. Deploy mock rules + TransferValidationPolicy + * ============================================================ */ + console.log('\n--- Step 12c: Deploy TransferValidationPolicy with mock rules ---'); + + // Deploy MaxAmountRule (max 1000 tokens) + const MaxAmountRuleFactory = await ethers.getContractFactory('MaxAmountRule'); + const maxTransferAmount = 1000n * 10n ** BigInt(tokenDecimals); + const maxAmountRule = await MaxAmountRuleFactory.deploy(maxTransferAmount); + await maxAmountRule.waitForDeployment(); + const maxAmountRuleAddress = await maxAmountRule.getAddress(); + console.log('MaxAmountRule deployed to:', maxAmountRuleAddress, `(max: ${maxTransferAmount})`); + + // Deploy RestrictedAddressRule (no initially restricted addresses) + const RestrictedAddressRuleFactory = await ethers.getContractFactory('RestrictedAddressRule'); + const restrictedAddressRule = await RestrictedAddressRuleFactory.deploy([]); + await restrictedAddressRule.waitForDeployment(); + const restrictedAddressRuleAddress = await restrictedAddressRule.getAddress(); + console.log('RestrictedAddressRule deployed to:', restrictedAddressRuleAddress); + + // Deploy TransferValidationPolicy with both rules + const transferPolicyConfigParams = abiCoder.encode( + ['address[]'], + [[maxAmountRuleAddress, restrictedAddressRuleAddress]], + ); + const TransferPolicyFactory = await ethers.getContractFactory('TransferValidationPolicy'); + const transferPolicy = await upgrades.deployProxy( + TransferPolicyFactory, + [policyEngineAddress, admin, transferPolicyConfigParams], + { + initializer: 'initialize', + unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], + silenceWarnings: true, + }, + ); + await transferPolicy.waitForDeployment(); + const transferPolicyAddress = await transferPolicy.getAddress(); + console.log('TransferValidationPolicy deployed to:', transferPolicyAddress); + + /* ============================================================ + * 12d. Set extractors and add TransferValidationPolicy + * ============================================================ */ + console.log('\n--- Step 12d: Register extractors & TransferValidationPolicy ---'); + + // Set ERC20TransferExtractor for transfer() + await policyEngine + .connect(deployer) + .setExtractor(selectors.transfer, erc20TransferExtractorAddress); + console.log('ERC20TransferExtractor set for transfer selector'); + + // Set ERC20TransferFromExtractor for transferFrom() + await policyEngine + .connect(deployer) + .setExtractor(selectors.transferFrom, erc20TransferFromExtractorAddress); + console.log('ERC20TransferFromExtractor set for transferFrom selector'); + + // Parameter name constants + const PARAM_SPENDER = keccak256(toUtf8Bytes('spender')); + const PARAM_FROM = keccak256(toUtf8Bytes('from')); + const PARAM_TO = keccak256(toUtf8Bytes('to')); + const PARAM_AMOUNT_TRANSFER = keccak256(toUtf8Bytes('amount')); + + // Add TransferValidationPolicy to transfer() — expects [from, to, amount] + await policyEngine + .connect(deployer) + .addPolicy(cmtatAddress, selectors.transfer, transferPolicyAddress, [ + PARAM_FROM, + PARAM_TO, + PARAM_AMOUNT_TRANSFER, + ]); + console.log('TransferValidationPolicy added for transfer (3 params: from, to, amount)'); + + // Add TransferValidationPolicy to transferFrom() — expects [spender, from, to, amount] + await policyEngine + .connect(deployer) + .addPolicy(cmtatAddress, selectors.transferFrom, transferPolicyAddress, [ + PARAM_SPENDER, + PARAM_FROM, + PARAM_TO, + PARAM_AMOUNT_TRANSFER, + ]); + console.log( + 'TransferValidationPolicy added for transferFrom (4 params: spender, from, to, amount)', + ); + + /* ============================================================ + * 13. Grant operation allowances on RBAC policy + * ============================================================ */ + console.log('\n--- Step 13: Grant RBAC operation allowances ---'); + + // Map selectors to their logical roles + const roleMapping = [ + { selector: selectors.mint, role: MINTER_ROLE, name: 'mint → MINTER_ROLE' }, + { selector: selectors.burn, role: BURNER_ROLE, name: 'burn → BURNER_ROLE' }, + { selector: selectors.burnFrom, role: BURNER_FROM_ROLE, name: 'burnFrom → BURNER_FROM_ROLE' }, + { + selector: selectors.transfer, + role: DEFAULT_ADMIN_ROLE, + name: 'transfer → DEFAULT_ADMIN_ROLE', + }, + { + selector: selectors.transferFrom, + role: DEFAULT_ADMIN_ROLE, + name: 'transferFrom → DEFAULT_ADMIN_ROLE', + }, + { + selector: selectors.forcedTransfer, + role: ENFORCER_ROLE, + name: 'forcedTransfer → ENFORCER_ROLE', + }, + { + selector: selectors.freezePartial, + role: ERC20ENFORCER_ROLE, + name: 'freezePartialTokens → ERC20ENFORCER_ROLE', + }, + { + selector: selectors.unfreezePartial, + role: ERC20ENFORCER_ROLE, + name: 'unfreezePartialTokens → ERC20ENFORCER_ROLE', + }, + { selector: selectors.setName, role: DEFAULT_ADMIN_ROLE, name: 'setName → DEFAULT_ADMIN_ROLE' }, + { + selector: selectors.setSymbol, + role: DEFAULT_ADMIN_ROLE, + name: 'setSymbol → DEFAULT_ADMIN_ROLE', + }, + { + selector: selectors.setSnapshotEngine, + role: SNAPSHOOTER_ROLE, + name: 'setSnapshotEngine → SNAPSHOOTER_ROLE', + }, + { + selector: selectors.setDocumentEngine, + role: DOCUMENT_ROLE, + name: 'setDocumentEngine → DOCUMENT_ROLE', + }, + ]; + + for (const { selector, role, name } of roleMapping) { + await rbacPolicy.connect(deployer).grantOperationAllowanceToRole(selector, role); + console.log(` ${name}`); + } + + /* ============================================================ + * 14. Grant roles to the admin account + * ============================================================ */ + console.log('\n--- Step 14: Grant roles to admin ---'); + const rolesToGrant = [ + { role: MINTER_ROLE, name: 'MINTER_ROLE' }, + { role: BURNER_ROLE, name: 'BURNER_ROLE' }, + { role: BURNER_FROM_ROLE, name: 'BURNER_FROM_ROLE' }, + { role: ENFORCER_ROLE, name: 'ENFORCER_ROLE' }, + { role: ERC20ENFORCER_ROLE, name: 'ERC20ENFORCER_ROLE' }, + { role: SNAPSHOOTER_ROLE, name: 'SNAPSHOOTER_ROLE' }, + { role: DOCUMENT_ROLE, name: 'DOCUMENT_ROLE' }, + ]; + + for (const { role, name } of rolesToGrant) { + await rbacPolicy.connect(deployer).grantRole(role, admin); + console.log(` Granted ${name} to admin`); + } + + /* ============================================================ + * Summary + * ============================================================ */ + + // Resolve implementation addresses for all proxy-deployed contracts + const policyEngineImpl = await upgrades.erc1967.getImplementationAddress(policyEngineAddress); + const pausePolicyImpl = await upgrades.erc1967.getImplementationAddress(pausePolicyAddress); + const rbacPolicyImpl = await upgrades.erc1967.getImplementationAddress(rbacPolicyAddress); + const secureMintPolicyImpl = + await upgrades.erc1967.getImplementationAddress(secureMintPolicyAddress); + const transferPolicyImpl = await upgrades.erc1967.getImplementationAddress(transferPolicyAddress); + + // PolicyEngine uses Transparent Proxy, so it also has a ProxyAdmin + const policyEngineAdmin = await upgrades.erc1967.getAdminAddress(policyEngineAddress); + + console.log('\n========================================'); + console.log('Demo deployment complete!'); + console.log('========================================'); + + console.log('\n--- Proxy Contracts (interact via these addresses) ---'); + console.log('PolicyEngine (proxy): ', policyEngineAddress); + console.log('PausePolicy (proxy): ', pausePolicyAddress); + console.log('RBAC Policy (proxy): ', rbacPolicyAddress); + console.log('SecureMint Policy (proxy): ', secureMintPolicyAddress); + console.log('Transfer Policy (proxy): ', transferPolicyAddress); + + console.log('\n--- Implementation Contracts ---'); + console.log('PolicyEngine (impl): ', policyEngineImpl); + console.log('PausePolicy (impl): ', pausePolicyImpl); + console.log('RBAC Policy (impl): ', rbacPolicyImpl); + console.log('SecureMint Policy (impl): ', secureMintPolicyImpl); + console.log('Transfer Policy (impl): ', transferPolicyImpl); + + console.log('\n--- Proxy Admin ---'); + console.log('PolicyEngine ProxyAdmin: ', policyEngineAdmin); + + console.log('\n--- Non-Proxy Contracts ---'); + console.log('Token (Standalone): ', cmtatAddress); + console.log('MintBurn Extractor: ', extractorAddress); + console.log('ERC20Transfer Extractor: ', erc20TransferExtractorAddress); + console.log('ERC20TransferFrom Extractor:', erc20TransferFromExtractorAddress); + console.log('MaxAmountRule: ', maxAmountRuleAddress); + console.log('RestrictedAddressRule: ', restrictedAddressRuleAddress); + console.log('Mock Reserve Feed: ', mockFeedAddress); + console.log('DocumentEngineMock: ', documentEngineAddress); + console.log('SnapshotEngineMock: ', snapshotEngineAddress); + + console.log('\n--- Configuration ---'); + console.log( + `Reserve amount: 1,000,000 tokens (${reserveAmount} raw with ${tokenDecimals} decimals)`, + ); + console.log('Admin account: ', admin); + + console.log('\n--- Policy Configuration ---'); + console.log(' - PausePolicy protects ALL listed external functions (initially unpaused)'); + console.log(' - RBAC policy protects ALL listed external functions'); + console.log(' - SecureMint policy protects mint() (reserve-backed minting)'); + console.log(' - TransferValidationPolicy protects transfer() and transferFrom()'); + console.log(' → MaxAmountRule: max', maxTransferAmount.toString(), 'raw units per transfer'); + console.log(' → RestrictedAddressRule: no addresses initially restricted'); + console.log( + ' - Policy execution order per function: PausePolicy → RBAC → (SecureMint on mint) → (TransferValidation on transfer/transferFrom)', + ); + console.log( + ' - Admin has MINTER, BURNER, BURNER_FROM, ENFORCER, ERC20ENFORCER, SNAPSHOOTER, DOCUMENT roles', + ); + console.log(' - DocumentEngineMock set at deploy (manages on-chain documents via IERC1643)'); + console.log( + ' - SnapshotEngineMock set at deploy (enables snapshot scheduling for balance tracking)', + ); + console.log('========================================'); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/lite/deploy-lite-standalone.js b/scripts/lite/deploy-lite-standalone.js new file mode 100644 index 0000000..ea81e59 --- /dev/null +++ b/scripts/lite/deploy-lite-standalone.js @@ -0,0 +1,78 @@ +/** + * Script example - do not use it for production + */ +const { ethers, upgrades } = require('hardhat'); +const { ZeroAddress, keccak256, toUtf8Bytes } = require('ethers'); + +async function deployPolicyEngine(initialOwner) { + const Factory = await ethers.getContractFactory('PolicyEngine'); + const contract = await upgrades.deployProxy(Factory, [true, initialOwner], { + initializer: 'initialize', + unsafeAllow: ['constructor'], + silenceWarnings: true, + }); + await contract.waitForDeployment(); + return contract; +} + +async function main() { + const network = await ethers.provider.getNetwork(); + const isHardhatNetwork = network.chainId === 31337n; + + const signers = await ethers.getSigners(); + const deployer = signers[0]; + + if (isHardhatNetwork) { + console.log('Hardhat network detected, using account:', deployer.address); + } else { + console.log('Deploying to network:', network.name, 'with account:', deployer.address); + } + + // To change - set to deployed engine addresses if needed + const admin = isHardhatNetwork ? deployer.address : '0x1000000000000000000000000000000000000001'; + const snapshotEngine = ZeroAddress; + const documentEngine = ZeroAddress; + const ERC20Attributes = { + name: 'Security Token', + symbol: 'ST', + decimalsIrrevocable: 8, + }; + const terms = { + name: 'Token Terms v1', + uri: 'https://cmta.ch/standards/cmta-token-cmtat', + documentHash: keccak256(toUtf8Bytes('terms-v1')), + }; + const extraInformationAttributes = { + tokenId: '1234567890', + terms: terms, + information: 'CMTAT smart contract', + }; + + const policyEngineContract = await deployPolicyEngine(admin); + const policyEngineAddress = await policyEngineContract.getAddress(); + const policyEngineImplAddress = + await upgrades.erc1967.getImplementationAddress(policyEngineAddress); + + const CMTATFactory = await ethers.getContractFactory( + 'ComplianceTokenCMTATLiteStandalone', + deployer, + ); + const cmtat = await CMTATFactory.deploy( + admin, + ERC20Attributes, + extraInformationAttributes, + policyEngineAddress, + snapshotEngine, + documentEngine, + ); + + await cmtat.waitForDeployment(); + console.log('PolicyEngine (proxy): ', policyEngineAddress); + console.log('PolicyEngine (impl): ', policyEngineImplAddress); + console.log('ComplianceTokenCMTATLiteStandalone: ', await cmtat.getAddress()); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/lite/deploy-lite-upgradeable.js b/scripts/lite/deploy-lite-upgradeable.js new file mode 100644 index 0000000..2dce397 --- /dev/null +++ b/scripts/lite/deploy-lite-upgradeable.js @@ -0,0 +1,82 @@ +/** + * Script example - do not use it for production + */ +const { ethers, upgrades } = require('hardhat'); +const { ZeroAddress, keccak256, toUtf8Bytes } = require('ethers'); + +async function deployPolicyEngine(initialOwner) { + const Factory = await ethers.getContractFactory('PolicyEngine'); + const contract = await upgrades.deployProxy(Factory, [true, initialOwner], { + initializer: 'initialize', + unsafeAllow: ['constructor'], + silenceWarnings: true, + }); + await contract.waitForDeployment(); + return contract; +} + +async function main() { + const network = await ethers.provider.getNetwork(); + const isHardhatNetwork = network.chainId === 31337n; + + const signers = await ethers.getSigners(); + const deployer = signers[0]; + + if (isHardhatNetwork) { + console.log('Hardhat network detected, using account:', deployer.address); + } else { + console.log('Deploying to network:', network.name, 'with account:', deployer.address); + } + + // To change - set to deployed engine addresses if needed + const admin = isHardhatNetwork ? deployer.address : '0x1000000000000000000000000000000000000001'; + const snapshotEngine = ZeroAddress; + const documentEngine = ZeroAddress; + const ERC20Attributes = ['Security Token', 'ST', 8]; + const terms = { + name: 'Token Terms v1', + uri: 'https://cmta.ch/standards/cmta-token-cmtat', + documentHash: keccak256(toUtf8Bytes('terms-v1')), + }; + const extraInformationAttributes = [ + '1234567890', + [terms.name, terms.uri, terms.documentHash], + 'CMTAT smart contract', + ]; + + const policyEngineContract = await deployPolicyEngine(admin); + const policyEngineAddress = await policyEngineContract.getAddress(); + + const Factory = await ethers.getContractFactory('ComplianceTokenCMTATLiteUpgradeable', deployer); + const cmtat = await upgrades.deployProxy( + Factory, + [ + admin, + ERC20Attributes, + extraInformationAttributes, + policyEngineAddress, + snapshotEngine, + documentEngine, + ], + { + initializer: 'initialize', + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + }, + ); + + await cmtat.waitForDeployment(); + const cmtatProxyAddress = await cmtat.getAddress(); + const cmtatImplAddress = await upgrades.erc1967.getImplementationAddress(cmtatProxyAddress); + const policyEngineImplAddress = + await upgrades.erc1967.getImplementationAddress(policyEngineAddress); + console.log('PolicyEngine (proxy): ', policyEngineAddress); + console.log('PolicyEngine (impl): ', policyEngineImplAddress); + console.log('ComplianceTokenCMTATLiteUpgradeable (proxy): ', cmtatProxyAddress); + console.log('ComplianceTokenCMTATLiteUpgradeable (impl): ', cmtatImplAddress); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/lite/deploy-lite-uups.js b/scripts/lite/deploy-lite-uups.js new file mode 100644 index 0000000..0d5795c --- /dev/null +++ b/scripts/lite/deploy-lite-uups.js @@ -0,0 +1,86 @@ +/** + * Script example - do not use it for production + */ +const { ethers, upgrades } = require('hardhat'); +const { ZeroAddress, keccak256, toUtf8Bytes } = require('ethers'); + +async function deployPolicyEngine(initialOwner) { + const Factory = await ethers.getContractFactory('PolicyEngine'); + const contract = await upgrades.deployProxy(Factory, [true, initialOwner], { + initializer: 'initialize', + unsafeAllow: ['constructor'], + silenceWarnings: true, + }); + await contract.waitForDeployment(); + return contract; +} + +async function main() { + const network = await ethers.provider.getNetwork(); + const isHardhatNetwork = network.chainId === 31337n; + + const signers = await ethers.getSigners(); + const deployer = signers[0]; + + if (isHardhatNetwork) { + console.log('Hardhat network detected, using account:', deployer.address); + } else { + console.log('Deploying to network:', network.name, 'with account:', deployer.address); + } + + // To change - set to deployed engine addresses if needed + const admin = isHardhatNetwork ? deployer.address : '0x1000000000000000000000000000000000000001'; + const snapshotEngine = ZeroAddress; + const documentEngine = ZeroAddress; + const ERC20Attributes = ['Security Token', 'ST', 8]; + const terms = { + name: 'Token Terms v1', + uri: 'https://cmta.ch/standards/cmta-token-cmtat', + documentHash: keccak256(toUtf8Bytes('terms-v1')), + }; + const extraInformationAttributes = [ + '1234567890', + [terms.name, terms.uri, terms.documentHash], + 'CMTAT smart contract', + ]; + + const policyEngineContract = await deployPolicyEngine(admin); + const policyEngineAddress = await policyEngineContract.getAddress(); + + const Factory = await ethers.getContractFactory( + 'ComplianceTokenCMTATLiteUUPSUpgradeable', + deployer, + ); + const cmtat = await upgrades.deployProxy( + Factory, + [ + admin, + ERC20Attributes, + extraInformationAttributes, + policyEngineAddress, + snapshotEngine, + documentEngine, + ], + { + initializer: 'initialize', + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }, + ); + + await cmtat.waitForDeployment(); + const cmtatProxyAddress = await cmtat.getAddress(); + const cmtatImplAddress = await upgrades.erc1967.getImplementationAddress(cmtatProxyAddress); + const policyEngineImplAddress = + await upgrades.erc1967.getImplementationAddress(policyEngineAddress); + console.log('PolicyEngine (proxy): ', policyEngineAddress); + console.log('PolicyEngine (impl): ', policyEngineImplAddress); + console.log('ComplianceTokenCMTATLiteUUPSUpgradeable (proxy): ', cmtatProxyAddress); + console.log('ComplianceTokenCMTATLiteUUPSUpgradeable (impl): ', cmtatImplAddress); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/slither.sh b/scripts/slither.sh new file mode 100755 index 0000000..18c2c37 --- /dev/null +++ b/scripts/slither.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash +set -euo pipefail + +REPORT_PATH="doc/audits/tools/slither-report.md" + +# Run Slither with JSON output (non-zero exit is normal when findings exist) +slither . --checklist > $REPORT_PATH || true + +echo "" +echo "Reports generated:" +echo "Markdown: $REPORT_PATH" +exit 0 \ No newline at end of file diff --git a/scripts/standard/deploy-standard-standalone.js b/scripts/standard/deploy-standard-standalone.js new file mode 100644 index 0000000..3c1eecc --- /dev/null +++ b/scripts/standard/deploy-standard-standalone.js @@ -0,0 +1,75 @@ +/** + * Script example - do not use it for production + */ +const { ethers, upgrades } = require('hardhat'); +const { ZeroAddress, keccak256, toUtf8Bytes } = require('ethers'); + +async function deployPolicyEngine(initialOwner) { + const Factory = await ethers.getContractFactory('PolicyEngine'); + const contract = await upgrades.deployProxy(Factory, [true, initialOwner], { + initializer: 'initialize', + unsafeAllow: ['constructor'], + silenceWarnings: true, + }); + await contract.waitForDeployment(); + return contract; +} + +async function main() { + const network = await ethers.provider.getNetwork(); + const isHardhatNetwork = network.chainId === 31337n; + + const signers = await ethers.getSigners(); + const deployer = signers[0]; + + if (isHardhatNetwork) { + console.log('Hardhat network detected, using account:', deployer.address); + } else { + console.log('Deploying to network:', network.name, 'with account:', deployer.address); + } + + // To change - set to deployed engine addresses if needed + const admin = isHardhatNetwork ? deployer.address : '0x1000000000000000000000000000000000000001'; + const snapshotEngine = ZeroAddress; + const documentEngine = ZeroAddress; + const ERC20Attributes = { + name: 'Security Token', + symbol: 'ST', + decimalsIrrevocable: 0, + }; + const terms = { + name: 'Token Terms v2', + uri: 'https://cmta.ch/standards/cmta-token-cmtat', + documentHash: keccak256(toUtf8Bytes('terms-v2')), + }; + const extraInformationAttributes = { + tokenId: '1234567890', + terms: terms, + information: 'CMTAT smart contract', + }; + + const policyEngineContract = await deployPolicyEngine(admin); + const policyEngineAddress = await policyEngineContract.getAddress(); + const policyEngineImplAddress = + await upgrades.erc1967.getImplementationAddress(policyEngineAddress); + + const CMTATFactory = await ethers.getContractFactory('ComplianceTokenCMTATStandalone', deployer); + const cmtat = await CMTATFactory.deploy( + admin, + ERC20Attributes, + extraInformationAttributes, + policyEngineAddress, + snapshotEngine, + documentEngine, + ); + + await cmtat.waitForDeployment(); + console.log('PolicyEngine (proxy): ', policyEngineAddress); + console.log('PolicyEngine (impl): ', policyEngineImplAddress); + console.log('ComplianceTokenCMTATStandalone: ', await cmtat.getAddress()); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/standard/deploy-standard-upgradeable.js b/scripts/standard/deploy-standard-upgradeable.js new file mode 100644 index 0000000..46f2f8a --- /dev/null +++ b/scripts/standard/deploy-standard-upgradeable.js @@ -0,0 +1,82 @@ +/** + * Script example - do not use it for production + */ +const { ethers, upgrades } = require('hardhat'); +const { ZeroAddress, keccak256, toUtf8Bytes } = require('ethers'); + +async function deployPolicyEngine(initialOwner) { + const Factory = await ethers.getContractFactory('PolicyEngine'); + const contract = await upgrades.deployProxy(Factory, [true, initialOwner], { + initializer: 'initialize', + unsafeAllow: ['constructor'], + silenceWarnings: true, + }); + await contract.waitForDeployment(); + return contract; +} + +async function main() { + const network = await ethers.provider.getNetwork(); + const isHardhatNetwork = network.chainId === 31337n; + + const signers = await ethers.getSigners(); + const deployer = signers[0]; + + if (isHardhatNetwork) { + console.log('Hardhat network detected, using account:', deployer.address); + } else { + console.log('Deploying to network:', network.name, 'with account:', deployer.address); + } + + // To change - set to deployed engine addresses if needed + const admin = isHardhatNetwork ? deployer.address : '0x1000000000000000000000000000000000000001'; + const snapshotEngine = ZeroAddress; + const documentEngine = ZeroAddress; + const ERC20Attributes = ['Security Token', 'ST', 0]; + const terms = { + name: 'Token Terms v2', + uri: 'https://cmta.ch/standards/cmta-token-cmtat', + documentHash: keccak256(toUtf8Bytes('terms-v2')), + }; + const extraInformationAttributes = [ + '1234567890', + [terms.name, terms.uri, terms.documentHash], + 'CMTAT smart contract', + ]; + + const policyEngineContract = await deployPolicyEngine(admin); + const policyEngineAddress = await policyEngineContract.getAddress(); + + const Factory = await ethers.getContractFactory('ComplianceTokenCMTATUpgradeable', deployer); + const cmtat = await upgrades.deployProxy( + Factory, + [ + admin, + ERC20Attributes, + extraInformationAttributes, + policyEngineAddress, + snapshotEngine, + documentEngine, + ], + { + initializer: 'initialize', + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + }, + ); + + await cmtat.waitForDeployment(); + const cmtatProxyAddress = await cmtat.getAddress(); + const cmtatImplAddress = await upgrades.erc1967.getImplementationAddress(cmtatProxyAddress); + const policyEngineImplAddress = + await upgrades.erc1967.getImplementationAddress(policyEngineAddress); + console.log('PolicyEngine (proxy): ', policyEngineAddress); + console.log('PolicyEngine (impl): ', policyEngineImplAddress); + console.log('ComplianceTokenCMTATUpgradeable (proxy): ', cmtatProxyAddress); + console.log('ComplianceTokenCMTATUpgradeable (impl): ', cmtatImplAddress); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/standard/deploy-standard-uups.js b/scripts/standard/deploy-standard-uups.js new file mode 100644 index 0000000..7d53b33 --- /dev/null +++ b/scripts/standard/deploy-standard-uups.js @@ -0,0 +1,83 @@ +/** + * Script example - do not use it for production + */ +const { ethers, upgrades } = require('hardhat'); +const { ZeroAddress, keccak256, toUtf8Bytes } = require('ethers'); + +async function deployPolicyEngine(initialOwner) { + const Factory = await ethers.getContractFactory('PolicyEngine'); + const contract = await upgrades.deployProxy(Factory, [true, initialOwner], { + initializer: 'initialize', + unsafeAllow: ['constructor'], + silenceWarnings: true, + }); + await contract.waitForDeployment(); + return contract; +} + +async function main() { + const network = await ethers.provider.getNetwork(); + const isHardhatNetwork = network.chainId === 31337n; + + const signers = await ethers.getSigners(); + const deployer = signers[0]; + + if (isHardhatNetwork) { + console.log('Hardhat network detected, using account:', deployer.address); + } else { + console.log('Deploying to network:', network.name, 'with account:', deployer.address); + } + + // To change - set to deployed engine addresses if needed + const admin = isHardhatNetwork ? deployer.address : '0x1000000000000000000000000000000000000001'; + const snapshotEngine = ZeroAddress; + const documentEngine = ZeroAddress; + const ERC20Attributes = ['Security Token', 'ST', 0]; + const terms = { + name: 'Token Terms v2', + uri: 'https://cmta.ch/standards/cmta-token-cmtat', + documentHash: keccak256(toUtf8Bytes('terms-v2')), + }; + const extraInformationAttributes = [ + '1234567890', + [terms.name, terms.uri, terms.documentHash], + 'CMTAT smart contract', + ]; + + const policyEngineContract = await deployPolicyEngine(admin); + const policyEngineAddress = await policyEngineContract.getAddress(); + + const Factory = await ethers.getContractFactory('ComplianceTokenCMTATUUPSUpgradeable', deployer); + const cmtat = await upgrades.deployProxy( + Factory, + [ + admin, + ERC20Attributes, + extraInformationAttributes, + policyEngineAddress, + snapshotEngine, + documentEngine, + ], + { + initializer: 'initialize', + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }, + ); + + await cmtat.waitForDeployment(); + const cmtatProxyAddress = await cmtat.getAddress(); + const cmtatImplAddress = await upgrades.erc1967.getImplementationAddress(cmtatProxyAddress); + const policyEngineImplAddress = + await upgrades.erc1967.getImplementationAddress(policyEngineAddress); + console.log('PolicyEngine (proxy): ', policyEngineAddress); + console.log('PolicyEngine (impl): ', policyEngineImplAddress); + console.log('ComplianceTokenCMTATUUPSUpgradeable (proxy): ', cmtatProxyAddress); + console.log('ComplianceTokenCMTATUUPSUpgradeable (impl): ', cmtatImplAddress); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/slither.config.json b/slither.config.json new file mode 100644 index 0000000..feff532 --- /dev/null +++ b/slither.config.json @@ -0,0 +1,4 @@ +{ + "filter_paths": "node_modules,submodules,test,forge-std,mocks", + "compile_force_framework": "foundry" +} diff --git a/submodules/CMTAT b/submodules/CMTAT new file mode 160000 index 0000000..49544f4 --- /dev/null +++ b/submodules/CMTAT @@ -0,0 +1 @@ +Subproject commit 49544f4de1993008acfc9e848d0bf03bd31d8579 diff --git a/submodules/RuleEngine b/submodules/RuleEngine new file mode 160000 index 0000000..5827604 --- /dev/null +++ b/submodules/RuleEngine @@ -0,0 +1 @@ +Subproject commit 5827604be4e38f65c055a929c7b62462a20f4bbd diff --git a/test/common/ace/CombinedPolicyCommon.js b/test/common/ace/CombinedPolicyCommon.js new file mode 100644 index 0000000..36495a7 --- /dev/null +++ b/test/common/ace/CombinedPolicyCommon.js @@ -0,0 +1,66 @@ +const { expect } = require('chai'); + +/** + * Tests combined PausePolicy + RBAC behavior. + * + * Required `this` context: + * this.cmtat – compliance token instance + * this.admin – owner / authorized signer + * this.address1 – test address + * this.address2 – test address + * this.policyEngine – PolicyEngine instance + * this.pausePolicy – PausePolicy instance + */ +function CombinedPolicyCommon() { + context('Combined PausePolicy + RBAC', function () { + it('testRejectMintWhenPausedEvenWithCorrectRole', async function () { + await this.pausePolicy.connect(this.admin).setPausedState(true); + await expect( + this.cmtat.connect(this.admin).mint(this.address1, 100n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testRejectMintWhenUnpausedWithoutCorrectRole', async function () { + await expect( + this.cmtat.connect(this.address1).mint(this.address2, 100n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowMintWhenUnpausedWithCorrectRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(100n); + }); + + it('testPolicyOrderPauseCheckedBeforeRBAC', async function () { + await this.pausePolicy.connect(this.admin).setPausedState(true); + await expect( + this.cmtat.connect(this.admin).mint(this.address1, 100n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + await this.pausePolicy.connect(this.admin).setPausedState(false); + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(100n); + }); + + it('testFullMintTransferBurnLifecycle', async function () { + const MINT_AMOUNT = 200n; + const TRANSFER_AMOUNT = 50n; + const BURN_AMOUNT = 100n; + + await this.cmtat.connect(this.admin).mint(this.address1, MINT_AMOUNT); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(MINT_AMOUNT); + expect(await this.cmtat.totalSupply()).to.equal(MINT_AMOUNT); + + await this.cmtat.connect(this.address1).transfer(this.address2, TRANSFER_AMOUNT); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(MINT_AMOUNT - TRANSFER_AMOUNT); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(TRANSFER_AMOUNT); + + await this.cmtat.connect(this.admin)['burn(address,uint256)'](this.address1, BURN_AMOUNT); + expect(await this.cmtat.balanceOf(this.address1)).to.equal( + MINT_AMOUNT - TRANSFER_AMOUNT - BURN_AMOUNT, + ); + expect(await this.cmtat.totalSupply()).to.equal(MINT_AMOUNT - BURN_AMOUNT); + }); + }); +} + +module.exports = CombinedPolicyCommon; diff --git a/test/common/ace/DeploymentCommon.js b/test/common/ace/DeploymentCommon.js new file mode 100644 index 0000000..27d1122 --- /dev/null +++ b/test/common/ace/DeploymentCommon.js @@ -0,0 +1,88 @@ +const { expect } = require('chai'); +const { ethers } = require('hardhat'); +const { DEPLOYMENT_DECIMAL, CROSS_CHAIN_ROLE } = require('../../deploymentUtils'); + +/** + * Basic deployment tests for standard (PolicyEngine-based) contracts. + * + * Required `this` context: + * this.cmtat – compliance token instance + * this.admin – owner signer + * this.address1 – test address + * this.policyEngineAddress – PolicyEngine address + */ +function DeploymentCommon() { + context('Deployment', function () { + it('testHasCorrectName', async function () { + expect(await this.cmtat.name()).to.equal('CMTA Token'); + }); + + it('testHasCorrectSymbol', async function () { + expect(await this.cmtat.symbol()).to.equal('CMTAT'); + }); + + it('testHasCorrectDecimals', async function () { + expect(await this.cmtat.decimals()).to.equal(DEPLOYMENT_DECIMAL); + }); + + it('testHasPolicyEngineAttached', async function () { + expect(await this.cmtat.getPolicyEngine()).to.equal(this.policyEngineAddress); + }); + + it('testHasCorrectOwner', async function () { + expect(await this.cmtat.owner()).to.equal(this.admin.address); + }); + + it('testHasZeroTotalSupply', async function () { + expect(await this.cmtat.totalSupply()).to.equal(0n); + }); + + it('testAllowMintWithPolicies', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(100n); + }); + + it('testSupportsInterfaceForCrossChainAndPolicyProtected', async function () { + const iPolicyProtected = new ethers.Interface([ + 'function attachPolicyEngine(address policyEngine)', + 'function getPolicyEngine() view returns (address)', + 'function setContext(bytes context)', + 'function getContext() view returns (bytes)', + 'function clearContext()', + ]); + const ierc7802 = new ethers.Interface([ + 'function crosschainMint(address to, uint256 value)', + 'function crosschainBurn(address from, uint256 value)', + ]); + const interfaceId = (iface, names) => { + const value = + names + .map((name) => BigInt(iface.getFunction(name).selector)) + .reduce((acc, selector) => acc ^ selector, 0n) & 0xffffffffn; + return `0x${value.toString(16).padStart(8, '0')}`; + }; + + const policyProtectedId = interfaceId(iPolicyProtected, [ + 'attachPolicyEngine', + 'getPolicyEngine', + 'setContext', + 'getContext', + 'clearContext', + ]); + const ierc7802Id = interfaceId(ierc7802, ['crosschainMint', 'crosschainBurn']); + + expect(await this.cmtat.supportsInterface(ierc7802Id)).to.equal(true); + expect(await this.cmtat.supportsInterface(policyProtectedId)).to.equal(true); + expect(await this.cmtat.supportsInterface('0xffffffff')).to.equal(false); + }); + + it('testCrosschainMintExecutesMinterTransferOverride', async function () { + await this.rbacPolicy.connect(this.admin).grantRole(CROSS_CHAIN_ROLE, this.admin.address); + await this.cmtat.connect(this.admin).crosschainMint(this.address1, 25n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(25n); + expect(await this.cmtat.totalSupply()).to.equal(25n); + }); + }); +} + +module.exports = DeploymentCommon; diff --git a/test/common/ace/PausePolicyCommon.js b/test/common/ace/PausePolicyCommon.js new file mode 100644 index 0000000..77e312e --- /dev/null +++ b/test/common/ace/PausePolicyCommon.js @@ -0,0 +1,64 @@ +const { expect } = require('chai'); + +/** + * Tests PausePolicy behavior on standard (PolicyEngine-based) contracts. + * + * Required `this` context: + * this.cmtat – compliance token instance + * this.admin – owner / authorized signer + * this.address1 – test address + * this.attacker – unauthorized signer + * this.policyEngine – PolicyEngine instance + * this.pausePolicy – PausePolicy instance + */ +function PausePolicyCommon() { + context('PausePolicy', function () { + it('testAllowMintWhenNotPaused', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(100n); + }); + + it('testRejectMintWhenPaused', async function () { + await this.pausePolicy.connect(this.admin).setPausedState(true); + await expect( + this.cmtat.connect(this.admin).mint(this.address1, 100n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowMintAfterUnpausing', async function () { + await this.pausePolicy.connect(this.admin).setPausedState(true); + await this.pausePolicy.connect(this.admin).setPausedState(false); + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(100n); + }); + + it('testRejectBurnWhenPaused', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.pausePolicy.connect(this.admin).setPausedState(true); + await expect( + this.cmtat.connect(this.admin)['burn(address,uint256)'](this.address1, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testEmitPauseStateChanged', async function () { + await expect(this.pausePolicy.connect(this.admin).setPausedState(true)) + .to.emit(this.pausePolicy, 'PauseStateChanged') + .withArgs(true); + await expect(this.pausePolicy.connect(this.admin).setPausedState(false)) + .to.emit(this.pausePolicy, 'PauseStateChanged') + .withArgs(false); + }); + + it('testRejectSettingSamePauseState', async function () { + await expect(this.pausePolicy.connect(this.admin).setPausedState(false)).to.be.reverted; + }); + + it('testOnlyOwnerCanChangePauseState', async function () { + await expect( + this.pausePolicy.connect(this.attacker).setPausedState(true), + ).to.be.revertedWithCustomError(this.pausePolicy, 'OwnableUnauthorizedAccount'); + }); + }); +} + +module.exports = PausePolicyCommon; diff --git a/test/common/ace/PolicyEngineCommon.js b/test/common/ace/PolicyEngineCommon.js new file mode 100644 index 0000000..8088967 --- /dev/null +++ b/test/common/ace/PolicyEngineCommon.js @@ -0,0 +1,51 @@ +const { expect } = require('chai'); +const { deployPolicyEngine } = require('../../deploymentUtils'); + +/** + * Tests PolicyEngine management on standard (Ownable-based) contracts. + * + * Required `this` context: + * this.cmtat – compliance token instance + * this.admin – owner signer + * this.attacker – unauthorized signer + * this.policyEngine – PolicyEngine instance + * this.cmtatAddress – deployed token address + * this.mintSelector – bytes4 selector for mint(address,uint256) + * this.pausePolicyAddress – PausePolicy address + * this.rbacPolicyAddress – RBACPolicy address + */ +function PolicyEngineCommon() { + context('PolicyEngine Management', function () { + it('testOwnerCanAttachNewPolicyEngine', async function () { + const newPolicyEngine = await deployPolicyEngine(true, this.admin.address); + const newAddr = await newPolicyEngine.getAddress(); + await this.cmtat.connect(this.admin).attachPolicyEngine(newAddr); + expect(await this.cmtat.getPolicyEngine()).to.equal(newAddr); + }); + + it('testNonOwnerCannotAttachPolicyEngine', async function () { + const newPolicyEngine = await deployPolicyEngine(true, this.attacker.address); + const newAddr = await newPolicyEngine.getAddress(); + await expect( + this.cmtat.connect(this.attacker).attachPolicyEngine(newAddr), + ).to.be.revertedWithCustomError(this.cmtat, 'OwnableUnauthorizedAccount'); + }); + + it('testListPoliciesForSelector', async function () { + const policies = await this.policyEngine.getPolicies(this.cmtatAddress, this.mintSelector); + expect(policies.length).to.equal(2); + expect(policies[0]).to.equal(this.pausePolicyAddress); + expect(policies[1]).to.equal(this.rbacPolicyAddress); + }); + + it('testRemovePolicy', async function () { + await this.policyEngine + .connect(this.admin) + .removePolicy(this.cmtatAddress, this.mintSelector, this.pausePolicyAddress); + const policies = await this.policyEngine.getPolicies(this.cmtatAddress, this.mintSelector); + expect(policies.length).to.equal(1); + }); + }); +} + +module.exports = PolicyEngineCommon; diff --git a/test/common/ace/RBACPolicyCommon.js b/test/common/ace/RBACPolicyCommon.js new file mode 100644 index 0000000..4efe456 --- /dev/null +++ b/test/common/ace/RBACPolicyCommon.js @@ -0,0 +1,331 @@ +const { expect } = require('chai'); +const { + MINTER_ROLE, + BURNER_FROM_ROLE, + BURNER_SELF_ROLE, + ENFORCER_ROLE, + CROSS_CHAIN_ROLE, +} = require('../../deploymentUtils'); + +/** + * Tests RoleBasedAccessControlPolicy behavior on standard (PolicyEngine-based) contracts. + * + * Required `this` context: + * this.cmtat – compliance token instance + * this.admin – owner / authorized signer (has MINTER_ROLE + BURNER_ROLE) + * this.address1 – test address + * this.address2 – test address + * this.attacker – unauthorized signer + * this.policyEngine – PolicyEngine instance + * this.rbacPolicy – RoleBasedAccessControlPolicy instance + * this.rbacPolicyAddress – address of rbacPolicy + * this.cmtatAddress – address of cmtat + * this.mintSelector – bytes4 selector for mint(address,uint256) + * this.burnSelector – bytes4 selector for burn(address,uint256) + */ +function RBACPolicyCommon() { + context('RoleBasedAccessControlPolicy', function () { + it('testAllowMintByMinterRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(100n); + }); + + it('testRejectMintWithoutMinterRole', async function () { + await expect( + this.cmtat.connect(this.address1).mint(this.address2, 100n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowMintAfterGrantingMinterRole', async function () { + await this.rbacPolicy.connect(this.admin).grantRole(MINTER_ROLE, this.address1); + await this.cmtat.connect(this.address1).mint(this.address2, 50n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(50n); + }); + + it('testRejectMintAfterRevokingMinterRole', async function () { + await this.rbacPolicy.connect(this.admin).grantRole(MINTER_ROLE, this.address1); + await this.rbacPolicy.connect(this.admin).revokeRole(MINTER_ROLE, this.address1); + await expect( + this.cmtat.connect(this.address1).mint(this.admin, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowBurnByBurnerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.cmtat.connect(this.admin)['burn(address,uint256)'](this.address1, 50n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(50n); + }); + + it('testRejectBurnWithoutBurnerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await expect( + this.cmtat.connect(this.address1)['burn(address,uint256)'](this.address1, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testMultipleRolesForDifferentOperations', async function () { + // Grant MINTER_ROLE to address1 (but not BURNER_ROLE) + await this.rbacPolicy.connect(this.admin).grantRole(MINTER_ROLE, this.address1); + await this.cmtat.connect(this.address1).mint(this.address2, 100n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(100n); + // address1 cannot burn + await expect( + this.cmtat.connect(this.address1)['burn(address,uint256)'](this.address2, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testHasAllowedRole', async function () { + expect(await this.rbacPolicy.hasAllowedRole(this.mintSelector, this.admin)).to.equal(true); + expect(await this.rbacPolicy.hasAllowedRole(this.mintSelector, this.address1)).to.equal( + false, + ); + await this.rbacPolicy.connect(this.admin).grantRole(MINTER_ROLE, this.address1); + expect(await this.rbacPolicy.hasAllowedRole(this.mintSelector, this.address1)).to.equal(true); + }); + + it('testEmitOperationAllowanceEvents', async function () { + const setNameSelector = this.cmtat.interface.getFunction('setName').selector; + const testRole = ethers.keccak256(ethers.toUtf8Bytes('TEST_ROLE')); + await expect( + this.rbacPolicy + .connect(this.admin) + .grantOperationAllowanceToRole(setNameSelector, testRole), + ) + .to.emit(this.rbacPolicy, 'OperationAllowanceGrantedToRole') + .withArgs(setNameSelector, testRole); + await expect( + this.rbacPolicy + .connect(this.admin) + .removeOperationAllowanceFromRole(setNameSelector, testRole), + ) + .to.emit(this.rbacPolicy, 'OperationAllowanceRemovedFromRole') + .withArgs(setNameSelector, testRole); + }); + + it('testRejectDuplicateOperationAllowanceGrant', async function () { + await expect( + this.rbacPolicy + .connect(this.admin) + .grantOperationAllowanceToRole(this.mintSelector, MINTER_ROLE), + ).to.be.reverted; + }); + + it('testOnlyOwnerCanManageOperationAllowances', async function () { + const testRole = ethers.keccak256(ethers.toUtf8Bytes('TEST_ROLE')); + await expect( + this.rbacPolicy + .connect(this.attacker) + .grantOperationAllowanceToRole(this.mintSelector, testRole), + ).to.be.revertedWithCustomError(this.rbacPolicy, 'OwnableUnauthorizedAccount'); + }); + + // ---- forcedTransfer ---- + + it('testAllowForcedTransferByEnforcerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.cmtat + .connect(this.admin) + ['forcedTransfer(address,address,uint256)'](this.address1, this.address2, 50n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(50n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(50n); + }); + + it('testRejectForcedTransferWithoutEnforcerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await expect( + this.cmtat + .connect(this.address1) + ['forcedTransfer(address,address,uint256)'](this.address1, this.address2, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowForcedTransferAfterGrantingEnforcerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.rbacPolicy.connect(this.admin).grantRole(ENFORCER_ROLE, this.address2); + await this.cmtat + .connect(this.address2) + ['forcedTransfer(address,address,uint256)'](this.address1, this.address2, 50n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(50n); + }); + + it('testRejectForcedTransferAfterRevokingEnforcerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.rbacPolicy.connect(this.admin).grantRole(ENFORCER_ROLE, this.address2); + await this.rbacPolicy.connect(this.admin).revokeRole(ENFORCER_ROLE, this.address2); + await expect( + this.cmtat + .connect(this.address2) + ['forcedTransfer(address,address,uint256)'](this.address1, this.address2, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + // ---- freezePartialTokens / unfreezePartialTokens ---- + + it('testAllowFreezeByERC20EnforcerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1, 50n); + expect(await this.cmtat.getFrozenTokens(this.address1)).to.equal(50n); + }); + + it('testRejectFreezeWithoutERC20EnforcerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await expect( + this.cmtat + .connect(this.address1) + ['freezePartialTokens(address,uint256)'](this.address1, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowUnfreezeByERC20EnforcerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1, 50n); + await this.cmtat + .connect(this.admin) + ['unfreezePartialTokens(address,uint256)'](this.address1, 30n); + expect(await this.cmtat.getFrozenTokens(this.address1)).to.equal(20n); + }); + + it('testRejectUnfreezeWithoutERC20EnforcerRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1, 50n); + await expect( + this.cmtat + .connect(this.address1) + ['unfreezePartialTokens(address,uint256)'](this.address1, 30n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + // ---- setName (ERC20 Attribute Management) ---- + + it('testAllowSetNameByAdminRole', async function () { + await this.cmtat.connect(this.admin).setName('New Name'); + expect(await this.cmtat.name()).to.equal('New Name'); + }); + + it('testRejectSetNameWithoutAdminRole', async function () { + await expect( + this.cmtat.connect(this.address1).setName('New Name'), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + // ---- setTokenId (Extra Information Management) ---- + + it('testAllowSetTokenIdByAdminRole', async function () { + await this.cmtat.connect(this.admin).setTokenId('NEW_ISIN'); + expect(await this.cmtat.tokenId()).to.equal('NEW_ISIN'); + }); + + it('testRejectSetTokenIdWithoutAdminRole', async function () { + await expect( + this.cmtat.connect(this.address1).setTokenId('NEW_ISIN'), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + // ---- setDocumentEngine (Document Management) ---- + + it('testAllowSetDocumentEngineByDocumentRole', async function () { + await this.cmtat.connect(this.admin).setDocumentEngine(this.address1); + }); + + it('testRejectSetDocumentEngineWithoutDocumentRole', async function () { + await expect( + this.cmtat.connect(this.address1).setDocumentEngine(this.address2), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + // ---- setSnapshotEngine (Snapshots) ---- + + it('testAllowSetSnapshotEngineBySnapshooterRole', async function () { + await this.cmtat.connect(this.admin).setSnapshotEngine(this.address1); + }); + + it('testRejectSetSnapshotEngineWithoutSnapshooterRole', async function () { + await expect( + this.cmtat.connect(this.address1).setSnapshotEngine(this.address2), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + // ---- setCCIPAdmin ---- + + it('testAllowSetCCIPAdminByAdminRole', async function () { + await this.cmtat.connect(this.admin).setCCIPAdmin(this.address1); + expect(await this.cmtat.getCCIPAdmin()).to.equal(this.address1); + }); + + it('testRejectSetCCIPAdminWithoutAdminRole', async function () { + await expect( + this.cmtat.connect(this.address1).setCCIPAdmin(this.address2), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + // ---- crosschainMint / crosschainBurn (CROSS_CHAIN_ROLE) ---- + + it('testRejectCrosschainMintWithoutCrossChainRole', async function () { + await expect( + this.cmtat.connect(this.address1).crosschainMint(this.address2, 100n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowCrosschainMintWithCrossChainRole', async function () { + await this.rbacPolicy.connect(this.admin).grantRole(CROSS_CHAIN_ROLE, this.address1); + await this.cmtat.connect(this.address1).crosschainMint(this.address2, 100n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(100n); + }); + + it('testRejectCrosschainBurnWithoutCrossChainRole', async function () { + await this.rbacPolicy.connect(this.admin).grantRole(CROSS_CHAIN_ROLE, this.admin); + await this.cmtat.connect(this.admin).crosschainMint(this.address1, 100n); + await expect( + this.cmtat.connect(this.address1).crosschainBurn(this.address1, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowCrosschainBurnWithCrossChainRole', async function () { + await this.rbacPolicy.connect(this.admin).grantRole(CROSS_CHAIN_ROLE, this.admin); + await this.cmtat.connect(this.admin).crosschainMint(this.address1, 100n); + await this.cmtat.connect(this.admin).crosschainBurn(this.address1, 50n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(50n); + }); + + // ---- burnFrom (BURNER_FROM_ROLE) ---- + + it('testRejectBurnFromWithoutBurnerFromRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await expect( + this.cmtat.connect(this.address1).burnFrom(this.address1, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowBurnFromWithBurnerFromRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.cmtat.connect(this.address1).approve(this.admin, 50n); + await this.rbacPolicy.connect(this.admin).grantRole(BURNER_FROM_ROLE, this.admin); + await this.cmtat.connect(this.admin).burnFrom(this.address1, 50n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(50n); + }); + + // ---- burn(uint256) self-burn (BURNER_SELF_ROLE) ---- + + it('testRejectSelfBurnWithoutBurnerSelfRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await expect( + this.cmtat.connect(this.address1)['burn(uint256)'](50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testAllowSelfBurnWithBurnerSelfRole', async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + await this.rbacPolicy.connect(this.admin).grantRole(BURNER_SELF_ROLE, this.address1); + await this.cmtat.connect(this.address1)['burn(uint256)'](50n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(50n); + }); + }); +} + +module.exports = RBACPolicyCommon; diff --git a/test/common/cmtat/BurnModuleCommon.js b/test/common/cmtat/BurnModuleCommon.js new file mode 100644 index 0000000..fb86c93 --- /dev/null +++ b/test/common/cmtat/BurnModuleCommon.js @@ -0,0 +1,46 @@ +const { expect } = require('chai'); + +function BurnModuleCommon() { + context('ERC20 Burn Module', function () { + beforeEach(async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + }); + + it('testCanBurnByAdmin', async function () { + this.logs = await this.cmtat.connect(this.admin)['burn(address,uint256)'](this.address1, 50n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(50n); + await expect(this.logs) + .to.emit(this.cmtat, 'Transfer') + .withArgs(this.address1, ethers.ZeroAddress, 50n); + }); + + it('testCannotBurnByNonBurner', async function () { + await expect( + this.cmtat.connect(this.address1)['burn(address,uint256)'](this.address1, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testCannotBurnMoreThanBalance', async function () { + await expect( + this.cmtat.connect(this.admin)['burn(address,uint256)'](this.address1, 200n), + ).to.be.revertedWithCustomError(this.cmtat, 'ERC20InsufficientBalance'); + }); + + it('testBatchBurn', async function () { + await this.cmtat.connect(this.admin).mint(this.address2, 200n); + await this.cmtat.connect(this.admin).batchBurn([this.address1, this.address2], [30n, 50n]); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(70n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(150n); + }); + + it('testBurnAndMint', async function () { + await this.cmtat + .connect(this.admin) + .burnAndMint(this.address1, this.address2, 30n, 50n, '0x'); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(70n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(50n); + }); + }); +} + +module.exports = BurnModuleCommon; diff --git a/test/common/cmtat/CMTATModuleCommon.js b/test/common/cmtat/CMTATModuleCommon.js new file mode 100644 index 0000000..dbc1340 --- /dev/null +++ b/test/common/cmtat/CMTATModuleCommon.js @@ -0,0 +1,47 @@ +const ERC20BaseCommon = require('./ERC20BaseCommon'); +const MintModuleCommon = require('./MintModuleCommon'); +const BurnModuleCommon = require('./BurnModuleCommon'); +const ERC20EnforcementCommon = require('./ERC20EnforcementCommon'); +const DocumentModuleCommon = require('./DocumentModuleCommon'); +const SnapshotModuleCommon = require('./SnapshotModuleCommon'); +// Snapshot scheduling & global modules from CMTAT +const SnapshotModuleCommonScheduling = require('../../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonScheduling'); +const SnapshotModuleCommonRescheduling = require('../../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonRescheduling'); +const SnapshotModuleCommonUnschedule = require('../../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonUnschedule'); +const SnapshotModuleCommonGetNextSnapshot = require('../../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonGetNextSnapshot'); +const SnapshotModuleMultiplePlannedTest = require('../../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleMultiplePlannedTest'); +const SnapshotModuleOnePlannedSnapshotTest = require('../../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleOnePlannedSnapshotTest'); +const SnapshotModuleZeroPlannedSnapshotTest = require('../../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleZeroPlannedSnapshot'); + +/** + * Aggregates all CMTAT module tests for standard (PolicyEngine-based) contracts. + * + * Each submodule can also be imported individually for selective testing. + * + * Required `this` context (set up by each standard deployment test): + * this.cmtat, this.admin, this.address1, this.address2, this.address3, this.attacker + * this.policyEngine, this.rbacPolicy, this.rbacPolicyAddress, this.cmtatAddress + * this.mintSelector, this.burnSelector + */ +function CMTATModuleCommon(includeSnapshotModules = true, snapshotZeroDefault = true) { + ERC20BaseCommon(); + MintModuleCommon(); + BurnModuleCommon(); + ERC20EnforcementCommon(); + DocumentModuleCommon(); + if (!includeSnapshotModules) { + return; + } + SnapshotModuleCommon(snapshotZeroDefault); + + // Snapshot scheduling & global (from CMTAT) + SnapshotModuleCommonScheduling(); + SnapshotModuleCommonRescheduling(); + SnapshotModuleCommonUnschedule(); + SnapshotModuleCommonGetNextSnapshot(); + SnapshotModuleMultiplePlannedTest(); + SnapshotModuleOnePlannedSnapshotTest(); + SnapshotModuleZeroPlannedSnapshotTest(); +} + +module.exports = CMTATModuleCommon; diff --git a/test/common/cmtat/DocumentModuleCommon.js b/test/common/cmtat/DocumentModuleCommon.js new file mode 100644 index 0000000..57107a1 --- /dev/null +++ b/test/common/cmtat/DocumentModuleCommon.js @@ -0,0 +1,118 @@ +const { expect } = require('chai'); +const { deployCCTStandalone } = require('../../deploymentUtils'); + +const ZERO_ADDRESS = ethers.ZeroAddress; + +function DocumentModuleCommon() { + context('Document Engine Module', function () { + beforeEach(async function () { + this.documentEngineMock = await ethers.deployContract('DocumentEngineMock'); + + if ((await this.cmtat.documentEngine()) === ZERO_ADDRESS) { + await this.cmtat.connect(this.admin).setDocumentEngine(this.documentEngineMock.target); + } + }); + + it('testCanSetAndGetADocument', async function () { + const name = ethers.encodeBytes32String('doc1'); + const uri = 'https://github.com/CMTA/CMTAT'; + const documentHash = ethers.encodeBytes32String('hash1'); + + await this.documentEngineMock.setDocument({ name, uri, documentHash }); + + const doc = await this.cmtat.getDocument(name); + expect(doc.uri).to.equal(uri); + expect(doc.documentHash).to.equal(documentHash); + expect(doc.lastModified).to.be.gt(0); + }); + + it('testCanUpdateADocument', async function () { + const name = ethers.encodeBytes32String('doc1'); + const uri1 = 'https://github.com/CMTA/CMTAT'; + const documentHash1 = ethers.encodeBytes32String('hash1'); + + const uri2 = 'https://github.com/CMTA/CMTAT/V2'; + const documentHash2 = ethers.encodeBytes32String('hash2'); + + await this.documentEngineMock.setDocument([name, uri1, documentHash1]); + await this.documentEngineMock.setDocument([name, uri2, documentHash2]); + + const doc = await this.cmtat.getDocument(name); + expect(doc.uri).to.equal(uri2); + expect(doc.documentHash).to.equal(documentHash2); + expect(doc.lastModified).to.be.gt(0); + }); + + it('testCanGetNullValueIfNoDocument', async function () { + const name = ethers.encodeBytes32String('nonexistent'); + const doc = await this.cmtat.getDocument(name); + expect(doc.uri).to.equal(''); + expect(doc.documentHash).to.equal(ethers.encodeBytes32String('')); + expect(doc.lastModified).to.equal(0); + }); + + it('testCanRemoveADocument', async function () { + const name = ethers.encodeBytes32String('doc1'); + const uri = 'https://github.com/CMTA/CMTAT'; + const documentHash = ethers.encodeBytes32String('hash1'); + + await this.documentEngineMock.setDocument([name, uri, documentHash]); + await this.documentEngineMock.removeDocument(name); + + const doc = await this.cmtat.getDocument(name); + expect(doc.uri).to.equal(''); + expect(doc.documentHash).to.equal(ethers.encodeBytes32String('')); + expect(doc.lastModified).to.equal(0); + }); + + it('testCanReturnAllDocumentNames', async function () { + const name1 = ethers.encodeBytes32String('doc1'); + const uri1 = 'https://github.com/CMTA/CMTAT'; + const documentHash1 = ethers.encodeBytes32String('hash1'); + + const name2 = ethers.encodeBytes32String('doc2'); + const uri2 = 'https://github.com/CMTA/CMTAT/V2'; + const documentHash2 = ethers.encodeBytes32String('hash2'); + + await this.documentEngineMock.setDocument([name1, uri1, documentHash1]); + await this.documentEngineMock.setDocument([name2, uri2, documentHash2]); + + const documentNames = await this.cmtat.getAllDocuments(); + expect(documentNames.length).to.equal(2); + expect(documentNames).to.include(name1); + expect(documentNames).to.include(name2); + }); + + it('testCanSetDocumentEngine', async function () { + const newDocEngineMock = await ethers.deployContract('DocumentEngineMock'); + this.logs = await this.cmtat.connect(this.admin).setDocumentEngine(newDocEngineMock.target); + await expect(this.logs) + .to.emit(this.cmtat, 'DocumentEngine') + .withArgs(newDocEngineMock.target); + expect(await this.cmtat.documentEngine()).to.equal(newDocEngineMock.target); + }); + + it('testCannotSetDocumentEngineWithSameValue', async function () { + await expect( + this.cmtat.connect(this.admin).setDocumentEngine(await this.cmtat.documentEngine()), + ).to.be.revertedWithCustomError(this.cmtat, 'CMTAT_DocumentEngineModule_SameValue'); + }); + + it('testGetEmptyDocumentsIfNoDocumentEngine', async function () { + // Deploy a fresh token with no document engine + const policyEngineAddress = await this.policyEngine.getAddress(); + const freshCmtat = await deployCCTStandalone(this.admin.address, policyEngineAddress); + + const name = ethers.encodeBytes32String('doc1'); + const doc = await freshCmtat.getDocument(name); + expect(doc.uri).to.equal(''); + expect(doc.documentHash).to.equal(ethers.encodeBytes32String('')); + expect(doc.lastModified).to.equal(0); + + const documentNames = await freshCmtat.getAllDocuments(); + expect(documentNames.length).to.equal(0); + }); + }); +} + +module.exports = DocumentModuleCommon; diff --git a/test/common/cmtat/ERC20BaseCommon.js b/test/common/cmtat/ERC20BaseCommon.js new file mode 100644 index 0000000..b9877db --- /dev/null +++ b/test/common/cmtat/ERC20BaseCommon.js @@ -0,0 +1,90 @@ +const { expect } = require('chai'); + +function ERC20BaseCommon() { + context('ERC20 Base Module', function () { + context('Token structure', function () { + it('testHasTheDefinedName', async function () { + expect(await this.cmtat.name()).to.equal('CMTA Token'); + }); + + it('testHasTheDefinedSymbol', async function () { + expect(await this.cmtat.symbol()).to.equal('CMTAT'); + }); + + it('testDecimalsEqual0', async function () { + expect(await this.cmtat.decimals()).to.equal(0); + }); + }); + + context('Balance & Transfer', function () { + const TOKEN_AMOUNTS = [31n, 32n, 33n]; + const TOKEN_INITIAL_SUPPLY = TOKEN_AMOUNTS.reduce((a, b) => a + b); + + beforeEach(async function () { + await this.cmtat.connect(this.admin).mint(this.address1, TOKEN_AMOUNTS[0]); + await this.cmtat.connect(this.admin).mint(this.address2, TOKEN_AMOUNTS[1]); + await this.cmtat.connect(this.admin).mint(this.address3, TOKEN_AMOUNTS[2]); + }); + + it('testHasTheCorrectBalanceBatch', async function () { + const ADDRESSES = [this.address1, this.address2, this.address3]; + const result = await this.cmtat.batchBalanceOf(ADDRESSES); + expect(result[0][0]).to.equal(TOKEN_AMOUNTS[0]); + expect(result[0][1]).to.equal(TOKEN_AMOUNTS[1]); + expect(result[1]).to.equal(TOKEN_INITIAL_SUPPLY); + }); + + it('testTransferFromOneAccountToAnother', async function () { + const AMOUNT = 11n; + this.logs = await this.cmtat.connect(this.address1).transfer(this.address2, AMOUNT); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(TOKEN_AMOUNTS[0] - AMOUNT); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(TOKEN_AMOUNTS[1] + AMOUNT); + await expect(this.logs) + .to.emit(this.cmtat, 'Transfer') + .withArgs(this.address1, this.address2, AMOUNT); + }); + + it('testCannotTransferMoreTokensThanOwn', async function () { + const BALANCE = await this.cmtat.balanceOf(this.address1); + await expect(this.cmtat.connect(this.address1).transfer(this.address2, 50n)) + .to.be.revertedWithCustomError(this.cmtat, 'ERC20InsufficientBalance') + .withArgs(this.address1.address, BALANCE, 50n); + }); + + it('testTransferFromWithAllowance', async function () { + await this.cmtat.connect(this.address1).approve(this.address3, 20n); + const AMOUNT = 11n; + this.logs = await this.cmtat + .connect(this.address3) + .transferFrom(this.address1, this.address2, AMOUNT); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(TOKEN_AMOUNTS[0] - AMOUNT); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(TOKEN_AMOUNTS[1] + AMOUNT); + await expect(this.logs) + .to.emit(this.cmtat, 'Transfer') + .withArgs(this.address1, this.address2, AMOUNT); + }); + + it('testCannotTransferFromWithInsufficientAllowance', async function () { + await this.cmtat.connect(this.address1).approve(this.address3, 20n); + await expect( + this.cmtat.connect(this.address3).transferFrom(this.address1, this.address2, 31n), + ) + .to.be.revertedWithCustomError(this.cmtat, 'ERC20InsufficientAllowance') + .withArgs(this.address3.address, 20n, 31n); + }); + }); + + context('Allowance', function () { + it('testApproveAllowance', async function () { + expect(await this.cmtat.allowance(this.address1, this.address3)).to.equal(0n); + this.logs = await this.cmtat.connect(this.address1).approve(this.address3, 20n); + expect(await this.cmtat.allowance(this.address1, this.address3)).to.equal(20n); + await expect(this.logs) + .to.emit(this.cmtat, 'Approval') + .withArgs(this.address1, this.address3, 20n); + }); + }); + }); +} + +module.exports = ERC20BaseCommon; diff --git a/test/common/cmtat/ERC20EnforcementCommon.js b/test/common/cmtat/ERC20EnforcementCommon.js new file mode 100644 index 0000000..e754637 --- /dev/null +++ b/test/common/cmtat/ERC20EnforcementCommon.js @@ -0,0 +1,78 @@ +const { expect } = require('chai'); + +function ERC20EnforcementCommon() { + context('ERC20 Enforcement Module', function () { + beforeEach(async function () { + await this.cmtat.connect(this.admin).mint(this.address1, 100n); + }); + + it('testFreezePartialTokens', async function () { + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1, 50n); + expect(await this.cmtat.getFrozenTokens(this.address1)).to.equal(50n); + }); + + it('testCannotFreezeWithoutRole', async function () { + await expect( + this.cmtat + .connect(this.address1) + ['freezePartialTokens(address,uint256)'](this.address1, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testUnfreezePartialTokens', async function () { + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1, 50n); + await this.cmtat + .connect(this.admin) + ['unfreezePartialTokens(address,uint256)'](this.address1, 30n); + expect(await this.cmtat.getFrozenTokens(this.address1)).to.equal(20n); + }); + + it('testCannotTransferFrozenTokens', async function () { + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1, 60n); + // Active balance = 100 - 60 = 40, so transferring 50 should fail + await expect( + this.cmtat.connect(this.address1).transfer(this.address2, 50n), + ).to.be.revertedWithCustomError(this.cmtat, 'ERC7943InsufficientUnfrozenBalance'); + }); + + it('testCanTransferActiveBalance', async function () { + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1, 60n); + // Active balance = 40, transferring 40 should work + await this.cmtat.connect(this.address1).transfer(this.address2, 40n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(40n); + }); + + it('testForcedTransfer', async function () { + await this.cmtat + .connect(this.admin) + ['forcedTransfer(address,address,uint256)'](this.address1, this.address2, 50n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(50n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(50n); + }); + + it('testCannotForcedTransferWithoutRole', async function () { + await expect( + this.cmtat + .connect(this.address1) + ['forcedTransfer(address,address,uint256)'](this.address1, this.address2, 50n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testGetActiveBalance', async function () { + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1, 30n); + expect(await this.cmtat.getActiveBalanceOf(this.address1)).to.equal(70n); + }); + }); +} + +module.exports = ERC20EnforcementCommon; diff --git a/test/common/cmtat/MintModuleCommon.js b/test/common/cmtat/MintModuleCommon.js new file mode 100644 index 0000000..439c3a4 --- /dev/null +++ b/test/common/cmtat/MintModuleCommon.js @@ -0,0 +1,51 @@ +const { expect } = require('chai'); +const { MINTER_ROLE } = require('../../deploymentUtils'); + +const ZERO_ADDRESS = ethers.ZeroAddress; + +function MintModuleCommon() { + context('ERC20 Mint Module', function () { + it('testCanBeMintedByAdmin', async function () { + expect(await this.cmtat.balanceOf(this.address1)).to.equal(0n); + this.logs = await this.cmtat.connect(this.admin).mint(this.address1, 20n); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(20n); + expect(await this.cmtat.totalSupply()).to.equal(20n); + await expect(this.logs) + .to.emit(this.cmtat, 'Transfer') + .withArgs(ZERO_ADDRESS, this.address1, 20n); + await expect(this.logs) + .to.emit(this.cmtat, 'Mint') + .withArgs(this.admin, this.address1, 20n, '0x'); + }); + + it('testCanMintByNewMinter', async function () { + await this.rbacPolicy.connect(this.admin).grantRole(MINTER_ROLE, this.address1); + await this.cmtat.connect(this.address1).mint(this.address2, 50n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(50n); + }); + + it('testCannotMintByNonMinter', async function () { + await expect( + this.cmtat.connect(this.address1).mint(this.address1, 20n), + ).to.be.revertedWithCustomError(this.policyEngine, 'PolicyRunRejected'); + }); + + it('testBatchMint', async function () { + const holders = [this.address1, this.address2, this.address3]; + const amounts = [10n, 100n, 1000n]; + await this.cmtat.connect(this.admin).batchMint(holders, amounts); + expect(await this.cmtat.balanceOf(this.address1)).to.equal(10n); + expect(await this.cmtat.balanceOf(this.address2)).to.equal(100n); + expect(await this.cmtat.balanceOf(this.address3)).to.equal(1000n); + expect(await this.cmtat.totalSupply()).to.equal(1110n); + }); + + it('testCannotMintToZeroAddress', async function () { + await expect( + this.cmtat.connect(this.admin).mint(ZERO_ADDRESS, 20n), + ).to.be.revertedWithCustomError(this.cmtat, 'ERC20InvalidReceiver'); + }); + }); +} + +module.exports = MintModuleCommon; diff --git a/test/common/cmtat/SnapshotModuleCommon.js b/test/common/cmtat/SnapshotModuleCommon.js new file mode 100644 index 0000000..ff65700 --- /dev/null +++ b/test/common/cmtat/SnapshotModuleCommon.js @@ -0,0 +1,34 @@ +const { expect } = require('chai'); + +const ZERO_ADDRESS = ethers.ZeroAddress; + +function SnapshotModuleCommon(expectZeroDefault = true) { + context('Snapshot Engine Module', function () { + it('testCanSetSnapshotEngine', async function () { + const snapshotEngineMock = await ethers.deployContract('SnapshotEngineMock', [ + ZERO_ADDRESS, + this.admin, + ]); + this.logs = await this.cmtat.connect(this.admin).setSnapshotEngine(snapshotEngineMock.target); + await expect(this.logs) + .to.emit(this.cmtat, 'SnapshotEngine') + .withArgs(snapshotEngineMock.target); + expect(await this.cmtat.snapshotEngine()).to.equal(snapshotEngineMock.target); + }); + + it('testCannotSetSnapshotEngineWithSameValue', async function () { + const snapshotEngineCurrent = await this.cmtat.snapshotEngine(); + await expect( + this.cmtat.connect(this.admin).setSnapshotEngine(snapshotEngineCurrent), + ).to.be.revertedWithCustomError(this.cmtat, 'CMTAT_SnapshotModule_SameValue'); + }); + + if (expectZeroDefault) { + it('testSnapshotEngineIsZeroByDefault', async function () { + expect(await this.cmtat.snapshotEngine()).to.equal(ZERO_ADDRESS); + }); + } + }); +} + +module.exports = SnapshotModuleCommon; diff --git a/test/custom/erc1404ValidationAndExtractor.test.js b/test/custom/erc1404ValidationAndExtractor.test.js new file mode 100644 index 0000000..8811b9f --- /dev/null +++ b/test/custom/erc1404ValidationAndExtractor.test.js @@ -0,0 +1,203 @@ +const { ethers } = require('hardhat'); +const { expect } = require('chai'); +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { fixture, deployPolicyEngine, deployCCTLiteStandalone } = require('../deploymentUtils'); + +describe('ERC1404 validation and MintBurnExtractor coverage', function () { + async function deployLiteFixture() { + const base = await loadFixture(fixture); + const policyEngine = await deployPolicyEngine(true, base.admin.address); + const policyEngineAddress = await policyEngine.getAddress(); + const cmtat = await deployCCTLiteStandalone(base.admin.address, policyEngineAddress); + return { ...base, policyEngine, cmtat }; + } + + describe('PolicyValidationModuleERC1404 / CCTCMTATBaseERC1404', function () { + beforeEach(async function () { + Object.assign(this, await deployLiteFixture()); + await this.cmtat.connect(this.admin).mint(this.address1.address, 100n); + await this.cmtat.connect(this.admin).mint(this.address2.address, 10n); + }); + + it('returns NoRestriction for unrestricted transfer code', async function () { + const code = await this.cmtat.detectTransferRestriction( + this.address1.address, + this.address2.address, + 10n, + ); + expect(code).to.equal(0n); + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal('NoRestriction'); + }); + + it('returns EnforcedPause when paused', async function () { + await this.cmtat.connect(this.admin).pause(); + const code = await this.cmtat.detectTransferRestriction( + this.address1.address, + this.address2.address, + 10n, + ); + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal('EnforcedPause'); + }); + + it('returns ContractDeactivated when deactivated', async function () { + await this.cmtat.connect(this.admin).pause(); + await this.cmtat.connect(this.admin).deactivateContract(); + const code = await this.cmtat.detectTransferRestriction( + this.address1.address, + this.address2.address, + 10n, + ); + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal('ContractDeactivated'); + }); + + it('returns AddrFromIsFrozen when sender is frozen', async function () { + await this.cmtat.connect(this.admin).setAddressFrozen(this.address1.address, true); + const code = await this.cmtat.detectTransferRestriction( + this.address1.address, + this.address2.address, + 10n, + ); + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal('AddrFromIsFrozen'); + }); + + it('returns AddrToIsFrozen when recipient is frozen', async function () { + await this.cmtat.connect(this.admin).setAddressFrozen(this.address2.address, true); + const code = await this.cmtat.detectTransferRestriction( + this.address1.address, + this.address2.address, + 10n, + ); + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal('AddrToIsFrozen'); + }); + + it('returns AddrSpenderIsFrozen for detectTransferRestrictionFrom', async function () { + await this.cmtat.connect(this.admin).setAddressFrozen(this.address3.address, true); + const code = await this.cmtat.detectTransferRestrictionFrom( + this.address3.address, + this.address1.address, + this.address2.address, + 10n, + ); + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal('AddrSpenderIsFrozen'); + }); + + it('returns downstream restriction code in detectTransferRestrictionFrom when spender is not frozen', async function () { + await this.cmtat.connect(this.admin).setAddressFrozen(this.address2.address, true); + const code = await this.cmtat.detectTransferRestrictionFrom( + this.address3.address, + this.address1.address, + this.address2.address, + 10n, + ); + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal('AddrToIsFrozen'); + }); + + it('returns TRANSFER_OK in detectTransferRestrictionFrom when spender and transfer are valid', async function () { + const code = await this.cmtat.detectTransferRestrictionFrom( + this.address3.address, + this.address1.address, + this.address2.address, + 10n, + ); + expect(code).to.equal(0n); + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal('NoRestriction'); + }); + + it('returns insufficient active balance code and message', async function () { + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1.address, 95n); + + const code = await this.cmtat.detectTransferRestriction( + this.address1.address, + this.address2.address, + 20n, + ); + + expect(await this.cmtat.messageForTransferRestriction(code)).to.equal( + 'AddrFrom:insufficientActiveBalance', + ); + }); + + it('returns UnknownCode for arbitrary unsupported code', async function () { + expect(await this.cmtat.messageForTransferRestriction(255)).to.equal('UnknownCode'); + }); + }); + + describe('MintBurnExtractor', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(fixture)); + this.extractor = await ethers.deployContract('MintBurnExtractor'); + }); + + it('extracts account and amount for mint(address,uint256)', async function () { + const payload = { + selector: '0x40c10f19', + sender: this.admin.address, + data: ethers.AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256'], + [this.address1.address, 123n], + ), + context: '0x', + }; + + const params = await this.extractor.extract(payload); + expect(params.length).to.equal(2); + expect(params[0].name).to.equal(ethers.keccak256(ethers.toUtf8Bytes('account'))); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['address'], params[0].value)[0]).to.equal( + this.address1.address, + ); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['uint256'], params[1].value)[0]).to.equal( + 123n, + ); + }); + + it('extracts account and amount for burnFrom(address,uint256)', async function () { + const payload = { + selector: '0x79cc6790', + sender: this.admin.address, + data: ethers.AbiCoder.defaultAbiCoder().encode( + ['address', 'uint256'], + [this.address2.address, 50n], + ), + context: '0x', + }; + + const params = await this.extractor.extract(payload); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['address'], params[0].value)[0]).to.equal( + this.address2.address, + ); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['uint256'], params[1].value)[0]).to.equal( + 50n, + ); + }); + + it('uses sender as account for burn(uint256)', async function () { + const payload = { + selector: '0x42966c68', + sender: this.address3.address, + data: ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [77n]), + context: '0x', + }; + + const params = await this.extractor.extract(payload); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['address'], params[0].value)[0]).to.equal( + this.address3.address, + ); + expect(ethers.AbiCoder.defaultAbiCoder().decode(['uint256'], params[1].value)[0]).to.equal( + 77n, + ); + }); + + it('reverts on unsupported selector', async function () { + const payload = { + selector: '0x12345678', + sender: this.admin.address, + data: '0x', + context: '0x', + }; + + await expect(this.extractor.extract(payload)).to.be.reverted; + }); + }); +}); diff --git a/test/custom/transferValidationPolicy.test.js b/test/custom/transferValidationPolicy.test.js new file mode 100644 index 0000000..36dd18b --- /dev/null +++ b/test/custom/transferValidationPolicy.test.js @@ -0,0 +1,630 @@ +const { ethers, upgrades } = require('hardhat'); +const { expect } = require('chai'); +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { fixture, deployPolicyEngine, deployCCTLiteStandalone } = require('../deploymentUtils'); + +// Parameter name hashes matching the ERC20TransferFromExtractor +const PARAM_SPENDER = ethers.keccak256(ethers.toUtf8Bytes('spender')); +const PARAM_FROM = ethers.keccak256(ethers.toUtf8Bytes('from')); +const PARAM_TO = ethers.keccak256(ethers.toUtf8Bytes('to')); +const PARAM_AMOUNT = ethers.keccak256(ethers.toUtf8Bytes('amount')); +const TRANSFER_PARAM_NAMES = [PARAM_SPENDER, PARAM_FROM, PARAM_TO, PARAM_AMOUNT]; + +/** + * Deploy TransferValidationPolicy via upgrades.deployProxy + */ +async function deployTransferValidationPolicy(policyEngineAddress, ownerAddress, ruleAddresses) { + const abiCoder = ethers.AbiCoder.defaultAbiCoder(); + const configParams = + ruleAddresses.length > 0 ? abiCoder.encode(['address[]'], [ruleAddresses]) : '0x'; + const Factory = await ethers.getContractFactory('TransferValidationPolicy'); + const policy = await upgrades.deployProxy( + Factory, + [policyEngineAddress, ownerAddress, configParams], + { + initializer: 'initialize', + unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], + silenceWarnings: true, + }, + ); + return policy; +} + +/** + * Deploy ERC20TransferFromExtractor (plain deploy, no proxy needed) + */ +async function deployERC20TransferFromExtractor() { + const extractor = await ethers.deployContract('ERC20TransferFromExtractor'); + return extractor; +} + +describe('TransferValidationPolicy', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(fixture)); + + // Deploy PolicyEngine (defaultAllow = true so mint/burn work without extra policies) + this.policyEngine = await deployPolicyEngine(true, this.admin.address); + this.policyEngineAddress = await this.policyEngine.getAddress(); + + // Deploy Lite Standalone token + this.cmtat = await deployCCTLiteStandalone(this.admin.address, this.policyEngineAddress); + this.cmtatAddress = await this.cmtat.getAddress(); + + // Deploy ERC20TransferFromExtractor + this.extractor = await deployERC20TransferFromExtractor(); + this.extractorAddress = await this.extractor.getAddress(); + + // Get transfer/transferFrom selectors + this.transferSelector = this.cmtat.interface.getFunction('transfer(address,uint256)').selector; + this.transferFromSelector = this.cmtat.interface.getFunction( + 'transferFrom(address,address,uint256)', + ).selector; + + // Set extractor for transfer and transferFrom selectors on the policy engine + await this.policyEngine + .connect(this.admin) + .setExtractor(this.transferSelector, this.extractorAddress); + await this.policyEngine + .connect(this.admin) + .setExtractor(this.transferFromSelector, this.extractorAddress); + + // Mint tokens to admin for test transfers + await this.cmtat.connect(this.admin).mint(this.admin.address, 1000n); + }); + + describe('MaxAmountRule', function () { + beforeEach(async function () { + // Deploy MaxAmountRule with max = 100 + this.maxAmountRule = await ethers.deployContract('MaxAmountRule', [100n]); + this.maxAmountRuleAddress = await this.maxAmountRule.getAddress(); + + // Deploy TransferValidationPolicy with the MaxAmountRule + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [this.maxAmountRuleAddress], + ); + this.transferPolicyAddress = await this.transferPolicy.getAddress(); + + // Add TransferValidationPolicy to the PolicyEngine for transfer and transferFrom + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferFromSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + }); + + describe('transfer', function () { + it('should allow transfer within max amount', async function () { + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 50n)).to.not.be + .reverted; + expect(await this.cmtat.balanceOf(this.address1.address)).to.equal(50n); + }); + + it('should allow transfer at exact max amount', async function () { + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 100n)).to.not.be + .reverted; + expect(await this.cmtat.balanceOf(this.address1.address)).to.equal(100n); + }); + + it('should reject transfer exceeding max amount', async function () { + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 101n)).to.be + .reverted; + }); + }); + + describe('transferFrom', function () { + beforeEach(async function () { + // Admin approves address1 to spend + await this.cmtat.connect(this.admin).approve(this.address1.address, 500n); + }); + + it('should allow transferFrom within max amount', async function () { + await expect( + this.cmtat + .connect(this.address1) + .transferFrom(this.admin.address, this.address2.address, 50n), + ).to.not.be.reverted; + expect(await this.cmtat.balanceOf(this.address2.address)).to.equal(50n); + }); + + it('should reject transferFrom exceeding max amount', async function () { + await expect( + this.cmtat + .connect(this.address1) + .transferFrom(this.admin.address, this.address2.address, 101n), + ).to.be.reverted; + }); + }); + + describe('canTransfer', function () { + it('should return true for transfer within max amount', async function () { + expect(await this.cmtat.canTransfer(this.admin.address, this.address1.address, 50n)).to.be + .true; + }); + + it('should return false for transfer exceeding max amount', async function () { + expect(await this.cmtat.canTransfer(this.admin.address, this.address1.address, 101n)).to.be + .false; + }); + }); + + describe('canTransferFrom', function () { + it('should return true for transferFrom within max amount', async function () { + expect( + await this.cmtat.canTransferFrom( + this.address1.address, + this.admin.address, + this.address2.address, + 50n, + ), + ).to.be.true; + }); + + it('should return false for transferFrom exceeding max amount', async function () { + expect( + await this.cmtat.canTransferFrom( + this.address1.address, + this.admin.address, + this.address2.address, + 101n, + ), + ).to.be.false; + }); + }); + }); + + describe('RestrictedAddressRule', function () { + beforeEach(async function () { + // Deploy RestrictedAddressRule with address2 restricted initially + this.restrictedRule = await ethers.deployContract('RestrictedAddressRule', [ + [this.address2.address], + ]); + this.restrictedRuleAddress = await this.restrictedRule.getAddress(); + + // Deploy TransferValidationPolicy with the RestrictedAddressRule + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [this.restrictedRuleAddress], + ); + this.transferPolicyAddress = await this.transferPolicy.getAddress(); + + // Add TransferValidationPolicy for transfer and transferFrom + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferFromSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + }); + + describe('transfer', function () { + it('should allow transfer to unrestricted address', async function () { + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 50n)).to.not.be + .reverted; + expect(await this.cmtat.balanceOf(this.address1.address)).to.equal(50n); + }); + + it('should reject transfer to restricted address', async function () { + await expect(this.cmtat.connect(this.admin).transfer(this.address2.address, 50n)).to.be + .reverted; + }); + + it('should reject transfer from restricted address', async function () { + // First give address2 some tokens via unrestricted path (remove restriction temporarily) + await this.restrictedRule.setRestricted(this.address2.address, false); + await this.cmtat.connect(this.admin).transfer(this.address2.address, 100n); + // Re-restrict + await this.restrictedRule.setRestricted(this.address2.address, true); + + await expect(this.cmtat.connect(this.address2).transfer(this.address1.address, 50n)).to.be + .reverted; + }); + + it('should allow transfer after removing restriction', async function () { + await this.restrictedRule.setRestricted(this.address2.address, false); + await expect(this.cmtat.connect(this.admin).transfer(this.address2.address, 50n)).to.not.be + .reverted; + expect(await this.cmtat.balanceOf(this.address2.address)).to.equal(50n); + }); + }); + + describe('canTransfer', function () { + it('should return true for unrestricted addresses', async function () { + expect(await this.cmtat.canTransfer(this.admin.address, this.address1.address, 50n)).to.be + .true; + }); + + it('should return false when recipient is restricted', async function () { + expect(await this.cmtat.canTransfer(this.admin.address, this.address2.address, 50n)).to.be + .false; + }); + + it('should return false when sender is restricted', async function () { + expect(await this.cmtat.canTransfer(this.address2.address, this.address1.address, 50n)).to + .be.false; + }); + }); + }); + + describe('Multiple rules (MaxAmount + RestrictedAddress)', function () { + beforeEach(async function () { + this.maxAmountRule = await ethers.deployContract('MaxAmountRule', [200n]); + this.restrictedRule = await ethers.deployContract('RestrictedAddressRule', [ + [this.address3.address], + ]); + + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [await this.maxAmountRule.getAddress(), await this.restrictedRule.getAddress()], + ); + this.transferPolicyAddress = await this.transferPolicy.getAddress(); + + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferFromSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + }); + + it('should allow valid transfer (within amount, unrestricted)', async function () { + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 100n)).to.not.be + .reverted; + }); + + it('should reject transfer exceeding max amount even to unrestricted address', async function () { + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 201n)).to.be + .reverted; + }); + + it('should reject transfer to restricted address even within max amount', async function () { + await expect(this.cmtat.connect(this.admin).transfer(this.address3.address, 50n)).to.be + .reverted; + }); + + it('canTransfer should return false when either rule rejects', async function () { + // Exceeds max + expect(await this.cmtat.canTransfer(this.admin.address, this.address1.address, 201n)).to.be + .false; + // Restricted recipient + expect(await this.cmtat.canTransfer(this.admin.address, this.address3.address, 50n)).to.be + .false; + }); + + it('canTransfer should return true when both rules pass', async function () { + expect(await this.cmtat.canTransfer(this.admin.address, this.address1.address, 100n)).to.be + .true; + }); + }); + + describe('Policy management', function () { + it('should work with no rules configured', async function () { + // Deploy policy with no rules — all transfers should pass + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [], + ); + this.transferPolicyAddress = await this.transferPolicy.getAddress(); + + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 500n)).to.not.be + .reverted; + }); + + it('should allow owner to update rules via setRules', async function () { + // Start with no rules + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [], + ); + this.transferPolicyAddress = await this.transferPolicy.getAddress(); + + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + + // Transfer should succeed with no rules + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 500n)).to.not.be + .reverted; + + // Now add a MaxAmountRule via setRules + const maxAmountRule = await ethers.deployContract('MaxAmountRule', [100n]); + await expect( + this.transferPolicy.connect(this.admin).setRules([await maxAmountRule.getAddress()]), + ) + .to.emit(this.transferPolicy, 'RulesUpdated') + .withArgs(0n, 1n); + + // Transfer above max should now fail + await expect(this.cmtat.connect(this.admin).transfer(this.address2.address, 101n)).to.be + .reverted; + + // Transfer within max should still succeed + await expect(this.cmtat.connect(this.admin).transfer(this.address2.address, 50n)).to.not.be + .reverted; + }); + + it('should not allow non-owner to call setRules', async function () { + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [], + ); + + const maxAmountRule = await ethers.deployContract('MaxAmountRule', [100n]); + await expect( + this.transferPolicy.connect(this.address1).setRules([await maxAmountRule.getAddress()]), + ).to.be.reverted; + }); + + it('should emit RulesUpdated with previous and new count when replacing rules', async function () { + const rule1 = await ethers.deployContract('MaxAmountRule', [100n]); + const rule2 = await ethers.deployContract('RestrictedAddressRule', [[]]); + const rule3 = await ethers.deployContract('MaxAmountRule', [500n]); + + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [await rule1.getAddress(), await rule2.getAddress()], + ); + + await expect(this.transferPolicy.connect(this.admin).setRules([await rule3.getAddress()])) + .to.emit(this.transferPolicy, 'RulesUpdated') + .withArgs(2n, 1n); + }); + + it('should report correct rules and rulesCount', async function () { + const rule1 = await ethers.deployContract('MaxAmountRule', [100n]); + const rule2 = await ethers.deployContract('RestrictedAddressRule', [[]]); + + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [await rule1.getAddress(), await rule2.getAddress()], + ); + + expect(await this.transferPolicy.rulesCount()).to.equal(2n); + const rules = await this.transferPolicy.rules(); + expect(rules[0]).to.equal(await rule1.getAddress()); + expect(rules[1]).to.equal(await rule2.getAddress()); + }); + }); + + describe('Direct run() parameter layouts', function () { + beforeEach(async function () { + this.maxAmountRule = await ethers.deployContract('MaxAmountRule', [100n]); + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [await this.maxAmountRule.getAddress()], + ); + }); + + it('covers 3-parameter layout branch and allows transfer within max', async function () { + const params = [ + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.admin.address]), + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.address1.address]), + ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [50n]), + ]; + + const result = await this.transferPolicy.run( + this.admin.address, + this.cmtatAddress, + this.transferSelector, + params, + '0x', + ); + expect(result).to.equal(2); // PolicyResult.Continue + }); + + it('covers 3-parameter layout branch and rejects transfer above max', async function () { + const params = [ + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.admin.address]), + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.address1.address]), + ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [101n]), + ]; + + await expect( + this.transferPolicy.run( + this.admin.address, + this.cmtatAddress, + this.transferSelector, + params, + '0x', + ), + ).to.be.reverted; + }); + + it('reverts with InvalidParametersLength when run() has 0 parameters', async function () { + const params = []; + + await expect( + this.transferPolicy.run( + this.admin.address, + this.cmtatAddress, + this.transferSelector, + params, + '0x', + ), + ) + .to.be.revertedWithCustomError(this.transferPolicy, 'InvalidParametersLength') + .withArgs(0n); + }); + + it('reverts with InvalidParametersLength when run() has 1 parameter', async function () { + const params = [ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.admin.address])]; + + await expect( + this.transferPolicy.run( + this.admin.address, + this.cmtatAddress, + this.transferSelector, + params, + '0x', + ), + ) + .to.be.revertedWithCustomError(this.transferPolicy, 'InvalidParametersLength') + .withArgs(1n); + }); + + it('reverts with InvalidParametersLength when run() has 2 parameters', async function () { + const params = [ + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.admin.address]), + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.address1.address]), + ]; + + await expect( + this.transferPolicy.run( + this.admin.address, + this.cmtatAddress, + this.transferSelector, + params, + '0x', + ), + ) + .to.be.revertedWithCustomError(this.transferPolicy, 'InvalidParametersLength') + .withArgs(2n); + }); + + it('reverts with InvalidParametersLength when run() has 5 parameters', async function () { + const params = [ + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.admin.address]), + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.address1.address]), + ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [50n]), + ethers.AbiCoder.defaultAbiCoder().encode(['address'], [this.address2.address]), + ethers.AbiCoder.defaultAbiCoder().encode(['uint256'], [1n]), + ]; + + await expect( + this.transferPolicy.run( + this.admin.address, + this.cmtatAddress, + this.transferSelector, + params, + '0x', + ), + ) + .to.be.revertedWithCustomError(this.transferPolicy, 'InvalidParametersLength') + .withArgs(5n); + }); + }); + + describe('No policy attached (defaultAllow = true)', function () { + it('should allow transfers when no policy is registered for transfer selector', async function () { + // PolicyEngine has defaultAllow = true and no policy for transfer + await expect(this.cmtat.connect(this.admin).transfer(this.address1.address, 500n)).to.not.be + .reverted; + }); + + it('canTransfer should return true when no policy is registered', async function () { + expect(await this.cmtat.canTransfer(this.admin.address, this.address1.address, 500n)).to.be + .true; + }); + }); + + describe('canTransfer with module-level restrictions', function () { + beforeEach(async function () { + // Set up MaxAmountRule policy on transfer selector + this.maxAmountRule = await ethers.deployContract('MaxAmountRule', [100n]); + this.transferPolicy = await deployTransferValidationPolicy( + this.policyEngineAddress, + this.admin.address, + [await this.maxAmountRule.getAddress()], + ); + this.transferPolicyAddress = await this.transferPolicy.getAddress(); + + await this.policyEngine + .connect(this.admin) + .addPolicy( + this.cmtatAddress, + this.transferSelector, + this.transferPolicyAddress, + TRANSFER_PARAM_NAMES, + ); + + // Give address1 some tokens + await this.cmtat.connect(this.admin).transfer(this.address1.address, 50n); + }); + + it('canTransfer should return false when sender is frozen', async function () { + await this.cmtat.connect(this.admin).setAddressFrozen(this.address1.address, true); + expect(await this.cmtat.canTransfer(this.address1.address, this.address2.address, 10n)).to.be + .false; + }); + + it('canTransfer should return false when recipient is frozen', async function () { + await this.cmtat.connect(this.admin).setAddressFrozen(this.address2.address, true); + expect(await this.cmtat.canTransfer(this.address1.address, this.address2.address, 10n)).to.be + .false; + }); + + it('canTransfer should return false when contract is paused', async function () { + await this.cmtat.connect(this.admin).pause(); + expect(await this.cmtat.canTransfer(this.address1.address, this.address2.address, 10n)).to.be + .false; + }); + + it('canTransfer should return false when transfer exceeds active balance (frozen tokens)', async function () { + // Freeze 40 of address1's 50 tokens → active balance = 10 + await this.cmtat + .connect(this.admin) + ['freezePartialTokens(address,uint256)'](this.address1.address, 40n); + expect(await this.cmtat.canTransfer(this.address1.address, this.address2.address, 20n)).to.be + .false; + }); + + it('canTransfer should return true for valid transfer with no module restrictions', async function () { + expect(await this.cmtat.canTransfer(this.address1.address, this.address2.address, 10n)).to.be + .true; + }); + }); +}); diff --git a/test/custom/validationModulePolicyEngine.coverage.test.js b/test/custom/validationModulePolicyEngine.coverage.test.js new file mode 100644 index 0000000..d3d8e78 --- /dev/null +++ b/test/custom/validationModulePolicyEngine.coverage.test.js @@ -0,0 +1,63 @@ +const { expect } = require('chai'); +const { ethers } = require('hardhat'); + +describe('ValidationModulePolicyEngine coverage branches', function () { + beforeEach(async function () { + [this.deployer, this.address1, this.address2, this.address3] = await ethers.getSigners(); + }); + + it('returns true in _tryCheckPolicies when no policy engine is attached', async function () { + const harness = await ethers.deployContract('ValidationModulePolicyEngineHarness'); + + const ok = await harness.exposedTryCheckPolicies( + '0xa9059cbb', + this.address1.address, + ethers.AbiCoder.defaultAbiCoder().encode(['address', 'uint256'], [this.address2.address, 1n]), + ); + + expect(ok).to.equal(true); + }); + + it('returns true in _transferred when no policy engine is attached', async function () { + const harness = await ethers.deployContract('ValidationModulePolicyEngineHarness'); + + const ok = await harness.exposedTransferred.staticCall( + this.address1.address, + this.address2.address, + this.address3.address, + 0n, + ); + + expect(ok).to.equal(true); + }); + + it('clears non-empty context after _transferred when policy engine is attached', async function () { + const engine = await ethers.deployContract('MockPolicyEngine'); + const harness = await ethers.deployContract('ValidationModulePolicyEngineHarness'); + await harness.initializeWithPolicyEngine(await engine.getAddress()); + + await harness.setContext('0x1234'); + expect(await harness.getContext()).to.equal('0x1234'); + + const ok = await harness.exposedTransferred.staticCall( + this.address1.address, + this.address2.address, + this.address3.address, + 0n, + ); + + expect(ok).to.equal(true); + + await harness.exposedTransferred( + this.address1.address, + this.address2.address, + this.address3.address, + 0n, + ); + + expect(await harness.getContext()).to.equal('0x'); + + const payload = await engine.lastPayload(); + expect(payload.context).to.equal('0x1234'); + }); +}); diff --git a/test/deployment/liteStandaloneDeployment.test.js b/test/deployment/liteStandaloneDeployment.test.js new file mode 100644 index 0000000..9baeb2e --- /dev/null +++ b/test/deployment/liteStandaloneDeployment.test.js @@ -0,0 +1,68 @@ +const { + loadFixture, + deployCCTLiteStandalone, + createLiteFixture, + createLiteFixtureWithSnapshot, +} = require('../deploymentUtils'); + +// Reuse CMTAT common modules +const PauseModuleCommon = require('../../submodules/CMTAT/test/common/PauseModuleCommon'); +const ERC20MintModuleCommon = require('../../submodules/CMTAT/test/common/ERC20MintModuleCommon'); +const ERC20BurnModuleCommon = require('../../submodules/CMTAT/test/common/ERC20BurnModuleCommon'); +const ERC20BaseModuleCommon = require('../../submodules/CMTAT/test/common/ERC20BaseModuleCommon'); +const EnforcementModuleCommon = require('../../submodules/CMTAT/test/common/EnforcementModuleCommon'); +const ERC20EnforcementModuleCommon = require('../../submodules/CMTAT/test/common/ERC20EnforcementModuleCommon'); +const VersionModuleCommon = require('../../submodules/CMTAT/test/common/VersionModuleCommon'); +const ERC20CrossChainModuleCommon = require('../../submodules/CMTAT/test/common/ERC20CrossChainModuleCommon'); +const CCIPModuleCommon = require('../../submodules/CMTAT/test/common/CCIPModuleCommon'); +const ExtraInfoModuleCommon = require('../../submodules/CMTAT/test/common/ExtraInfoModuleCommon'); +const DocumentModuleCommon = require('../../submodules/CMTAT/test/common/DocumentModule/DocumentModuleCommon'); +const SnapshotModuleCommon = require('../common/cmtat/SnapshotModuleCommon'); +// Snapshot scheduling & global modules from CMTAT +const SnapshotModuleCommonScheduling = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonScheduling'); +const SnapshotModuleCommonRescheduling = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonRescheduling'); +const SnapshotModuleCommonUnschedule = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonUnschedule'); +const SnapshotModuleCommonGetNextSnapshot = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonGetNextSnapshot'); +const SnapshotModuleMultiplePlannedTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleMultiplePlannedTest'); +const SnapshotModuleOnePlannedSnapshotTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleOnePlannedSnapshotTest'); +const SnapshotModuleZeroPlannedSnapshotTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleZeroPlannedSnapshot'); + +const liteFixture = createLiteFixture(deployCCTLiteStandalone); +const liteFixtureWithSnapshot = createLiteFixtureWithSnapshot(deployCCTLiteStandalone); + +describe('ComplianceTokenCMTATLiteStandalone', function () { + context('snapshotEngine = 0 (no snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(liteFixture)); + this.dontCheckTimestamp = true; + }); + + VersionModuleCommon(); + PauseModuleCommon(); + ERC20MintModuleCommon(); + ERC20BurnModuleCommon(); + ERC20BaseModuleCommon(); + EnforcementModuleCommon(); + ERC20EnforcementModuleCommon(); + ERC20CrossChainModuleCommon(); + CCIPModuleCommon(); + ExtraInfoModuleCommon(); + DocumentModuleCommon(); + }); + + context('snapshotEngine is set (snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(liteFixtureWithSnapshot)); + this.dontCheckTimestamp = true; + }); + + SnapshotModuleCommon(false); + SnapshotModuleCommonScheduling(); + SnapshotModuleCommonRescheduling(); + SnapshotModuleCommonUnschedule(); + SnapshotModuleCommonGetNextSnapshot(); + SnapshotModuleMultiplePlannedTest(); + SnapshotModuleOnePlannedSnapshotTest(); + SnapshotModuleZeroPlannedSnapshotTest(); + }); +}); diff --git a/test/deployment/liteUUPSUpgradeableDeployment.test.js b/test/deployment/liteUUPSUpgradeableDeployment.test.js new file mode 100644 index 0000000..3399ee2 --- /dev/null +++ b/test/deployment/liteUUPSUpgradeableDeployment.test.js @@ -0,0 +1,141 @@ +const { ethers, upgrades } = require('hardhat'); +const { expect } = require('chai'); +const { + loadFixture, + deployCCTLiteUUPSUpgradeable, + createLiteFixture, + createLiteFixtureWithSnapshot, +} = require('../deploymentUtils'); + +// Reuse CMTAT common modules +const PauseModuleCommon = require('../../submodules/CMTAT/test/common/PauseModuleCommon'); +const ERC20MintModuleCommon = require('../../submodules/CMTAT/test/common/ERC20MintModuleCommon'); +const ERC20BurnModuleCommon = require('../../submodules/CMTAT/test/common/ERC20BurnModuleCommon'); +const ERC20BaseModuleCommon = require('../../submodules/CMTAT/test/common/ERC20BaseModuleCommon'); +const EnforcementModuleCommon = require('../../submodules/CMTAT/test/common/EnforcementModuleCommon'); +const ERC20EnforcementModuleCommon = require('../../submodules/CMTAT/test/common/ERC20EnforcementModuleCommon'); +const VersionModuleCommon = require('../../submodules/CMTAT/test/common/VersionModuleCommon'); +const ERC20CrossChainModuleCommon = require('../../submodules/CMTAT/test/common/ERC20CrossChainModuleCommon'); +const CCIPModuleCommon = require('../../submodules/CMTAT/test/common/CCIPModuleCommon'); +const ExtraInfoModuleCommon = require('../../submodules/CMTAT/test/common/ExtraInfoModuleCommon'); +const DocumentModuleCommon = require('../../submodules/CMTAT/test/common/DocumentModule/DocumentModuleCommon'); +const SnapshotModuleCommon = require('../common/cmtat/SnapshotModuleCommon'); +// Snapshot scheduling & global modules from CMTAT +const SnapshotModuleCommonScheduling = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonScheduling'); +const SnapshotModuleCommonRescheduling = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonRescheduling'); +const SnapshotModuleCommonUnschedule = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonUnschedule'); +const SnapshotModuleCommonGetNextSnapshot = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonGetNextSnapshot'); +const SnapshotModuleMultiplePlannedTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleMultiplePlannedTest'); +const SnapshotModuleOnePlannedSnapshotTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleOnePlannedSnapshotTest'); +const SnapshotModuleZeroPlannedSnapshotTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleZeroPlannedSnapshot'); + +const PROXY_UPGRADE_ROLE = ethers.keccak256(ethers.toUtf8Bytes('PROXY_UPGRADE_ROLE')); + +const liteFixture = createLiteFixture(deployCCTLiteUUPSUpgradeable); +const liteFixtureWithSnapshot = createLiteFixtureWithSnapshot(deployCCTLiteUUPSUpgradeable); + +describe('ComplianceTokenCMTATLiteUUPSUpgradeable', function () { + context('snapshotEngine = 0 (no snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(liteFixture)); + this.dontCheckTimestamp = true; + }); + + context('Re-initialization', function () { + it('testCannotBeReinitialized', async function () { + const policyEngineAddress = await this.policyEngine.getAddress(); + await expect( + this.cmtat + .connect(this.admin) + .initialize( + this.admin.address, + ['CMTA Token', 'CMTAT', 0], + [ + 'CMTAT_ISIN', + ['doc1', 'https://example.com/doc1', ethers.keccak256(ethers.toUtf8Bytes('h'))], + 'CMTAT_info', + ], + policyEngineAddress, + ethers.ZeroAddress, + ethers.ZeroAddress, + ), + ).to.be.revertedWithCustomError(this.cmtat, 'InvalidInitialization'); + }); + }); + + context('UUPS Upgrade', function () { + it('testAdminWithRoleCanUpgrade', async function () { + await this.cmtat.connect(this.admin).grantRole(PROXY_UPGRADE_ROLE, this.admin.address); + const FactoryV2 = await ethers.getContractFactory( + 'ComplianceTokenCMTATLiteUUPSUpgradeable', + this.admin, + ); + await upgrades.upgradeProxy(await this.cmtat.getAddress(), FactoryV2, { + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }); + }); + + it('testCannotUpgradeWithoutProxyUpgradeRole', async function () { + const FactoryV2 = await ethers.getContractFactory( + 'ComplianceTokenCMTATLiteUUPSUpgradeable', + this.attacker, + ); + await expect( + upgrades.upgradeProxy(await this.cmtat.getAddress(), FactoryV2, { + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }), + ).to.be.revertedWithCustomError(this.cmtat, 'AccessControlUnauthorizedAccount'); + }); + + it('testStatePreservedAfterUpgrade', async function () { + await this.cmtat.connect(this.admin).mint(this.address1.address, 100n); + expect(await this.cmtat.balanceOf(this.address1.address)).to.equal(100n); + await this.cmtat.connect(this.admin).grantRole(PROXY_UPGRADE_ROLE, this.admin.address); + const FactoryV2 = await ethers.getContractFactory( + 'ComplianceTokenCMTATLiteUUPSUpgradeable', + this.admin, + ); + const upgraded = await upgrades.upgradeProxy(await this.cmtat.getAddress(), FactoryV2, { + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }); + expect(await upgraded.balanceOf(this.address1.address)).to.equal(100n); + expect(await upgraded.name()).to.equal('CMTA Token'); + expect(await upgraded.symbol()).to.equal('CMTAT'); + }); + }); + + VersionModuleCommon(); + PauseModuleCommon(); + ERC20MintModuleCommon(); + ERC20BurnModuleCommon(); + ERC20BaseModuleCommon(); + EnforcementModuleCommon(); + ERC20EnforcementModuleCommon(); + ERC20CrossChainModuleCommon(); + CCIPModuleCommon(); + ExtraInfoModuleCommon(); + DocumentModuleCommon(); + }); + + context('snapshotEngine is set (snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(liteFixtureWithSnapshot)); + this.dontCheckTimestamp = true; + }); + + SnapshotModuleCommon(false); + SnapshotModuleCommonScheduling(); + SnapshotModuleCommonRescheduling(); + SnapshotModuleCommonUnschedule(); + SnapshotModuleCommonGetNextSnapshot(); + SnapshotModuleMultiplePlannedTest(); + SnapshotModuleOnePlannedSnapshotTest(); + SnapshotModuleZeroPlannedSnapshotTest(); + }); +}); diff --git a/test/deployment/liteUpgradeableDeployment.test.js b/test/deployment/liteUpgradeableDeployment.test.js new file mode 100644 index 0000000..6bbba7a --- /dev/null +++ b/test/deployment/liteUpgradeableDeployment.test.js @@ -0,0 +1,92 @@ +const { ethers } = require('hardhat'); +const { expect } = require('chai'); +const { + loadFixture, + deployCCTLiteUpgradeable, + createLiteFixture, + createLiteFixtureWithSnapshot, +} = require('../deploymentUtils'); + +// Reuse CMTAT common modules +const PauseModuleCommon = require('../../submodules/CMTAT/test/common/PauseModuleCommon'); +const ERC20MintModuleCommon = require('../../submodules/CMTAT/test/common/ERC20MintModuleCommon'); +const ERC20BurnModuleCommon = require('../../submodules/CMTAT/test/common/ERC20BurnModuleCommon'); +const ERC20BaseModuleCommon = require('../../submodules/CMTAT/test/common/ERC20BaseModuleCommon'); +const EnforcementModuleCommon = require('../../submodules/CMTAT/test/common/EnforcementModuleCommon'); +const ERC20EnforcementModuleCommon = require('../../submodules/CMTAT/test/common/ERC20EnforcementModuleCommon'); +const VersionModuleCommon = require('../../submodules/CMTAT/test/common/VersionModuleCommon'); +const ERC20CrossChainModuleCommon = require('../../submodules/CMTAT/test/common/ERC20CrossChainModuleCommon'); +const CCIPModuleCommon = require('../../submodules/CMTAT/test/common/CCIPModuleCommon'); +const ExtraInfoModuleCommon = require('../../submodules/CMTAT/test/common/ExtraInfoModuleCommon'); +const DocumentModuleCommon = require('../../submodules/CMTAT/test/common/DocumentModule/DocumentModuleCommon'); +const SnapshotModuleCommon = require('../common/cmtat/SnapshotModuleCommon'); +// Snapshot scheduling & global modules from CMTAT +const SnapshotModuleCommonScheduling = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonScheduling'); +const SnapshotModuleCommonRescheduling = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonRescheduling'); +const SnapshotModuleCommonUnschedule = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonUnschedule'); +const SnapshotModuleCommonGetNextSnapshot = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/SnapshotModuleCommonGetNextSnapshot'); +const SnapshotModuleMultiplePlannedTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleMultiplePlannedTest'); +const SnapshotModuleOnePlannedSnapshotTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleOnePlannedSnapshotTest'); +const SnapshotModuleZeroPlannedSnapshotTest = require('../../submodules/CMTAT/test/common/SnapshotModuleCommon/global/SnapshotModuleZeroPlannedSnapshot'); + +const liteFixture = createLiteFixture(deployCCTLiteUpgradeable); +const liteFixtureWithSnapshot = createLiteFixtureWithSnapshot(deployCCTLiteUpgradeable); + +describe('ComplianceTokenCMTATLiteUpgradeable', function () { + context('snapshotEngine = 0 (no snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(liteFixture)); + this.dontCheckTimestamp = true; + }); + + context('Re-initialization', function () { + it('testCannotBeReinitialized', async function () { + const policyEngineAddress = await this.policyEngine.getAddress(); + await expect( + this.cmtat + .connect(this.admin) + .initialize( + this.admin.address, + ['CMTA Token', 'CMTAT', 0], + [ + 'CMTAT_ISIN', + ['doc1', 'https://example.com/doc1', ethers.keccak256(ethers.toUtf8Bytes('h'))], + 'CMTAT_info', + ], + policyEngineAddress, + ethers.ZeroAddress, + ethers.ZeroAddress, + ), + ).to.be.revertedWithCustomError(this.cmtat, 'InvalidInitialization'); + }); + }); + + VersionModuleCommon(); + PauseModuleCommon(); + ERC20MintModuleCommon(); + ERC20BurnModuleCommon(); + ERC20BaseModuleCommon(); + EnforcementModuleCommon(); + ERC20EnforcementModuleCommon(); + ERC20CrossChainModuleCommon(); + CCIPModuleCommon(); + ExtraInfoModuleCommon(); + DocumentModuleCommon(); + }); + + context('snapshotEngine is set (snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(liteFixtureWithSnapshot)); + this.dontCheckTimestamp = true; + }); + + SnapshotModuleCommon(false); + SnapshotModuleCommonScheduling(); + SnapshotModuleCommonRescheduling(); + SnapshotModuleCommonUnschedule(); + SnapshotModuleCommonGetNextSnapshot(); + SnapshotModuleMultiplePlannedTest(); + SnapshotModuleOnePlannedSnapshotTest(); + SnapshotModuleZeroPlannedSnapshotTest(); + }); +}); diff --git a/test/deployment/standaloneDeployment.test.js b/test/deployment/standaloneDeployment.test.js new file mode 100644 index 0000000..33cadc3 --- /dev/null +++ b/test/deployment/standaloneDeployment.test.js @@ -0,0 +1,41 @@ +const { + loadFixture, + deployCCTStandalone, + createStandardFixture, + createStandardFixtureWithSnapshot, +} = require('../deploymentUtils'); + +// ACE-specific common modules +const DeploymentCommon = require('../common/ace/DeploymentCommon'); +const PausePolicyCommon = require('../common/ace/PausePolicyCommon'); +const RBACPolicyCommon = require('../common/ace/RBACPolicyCommon'); +const CombinedPolicyCommon = require('../common/ace/CombinedPolicyCommon'); +const PolicyEngineCommon = require('../common/ace/PolicyEngineCommon'); +const CMTATModuleCommon = require('../common/cmtat/CMTATModuleCommon'); + +const standardFixture = createStandardFixture(deployCCTStandalone); +const standardFixtureWithSnapshot = createStandardFixtureWithSnapshot(deployCCTStandalone); + +describe('ComplianceTokenCMTATStandalone', function () { + context('snapshotEngine = 0 (no snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(standardFixture)); + this.dontCheckTimestamp = true; + }); + + DeploymentCommon(); + PausePolicyCommon(); + RBACPolicyCommon(); + CombinedPolicyCommon(); + PolicyEngineCommon(); + CMTATModuleCommon(false); + }); + + context('snapshotEngine is set (snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(standardFixtureWithSnapshot)); + this.dontCheckTimestamp = true; + }); + CMTATModuleCommon(true, false); + }); +}); diff --git a/test/deployment/upgradeableDeployment.test.js b/test/deployment/upgradeableDeployment.test.js new file mode 100644 index 0000000..36310d4 --- /dev/null +++ b/test/deployment/upgradeableDeployment.test.js @@ -0,0 +1,64 @@ +const { ethers } = require('hardhat'); +const { expect } = require('chai'); +const { + loadFixture, + deployCCTUpgradeable, + createStandardFixture, + createStandardFixtureWithSnapshot, +} = require('../deploymentUtils'); + +// ACE-specific common modules +const DeploymentCommon = require('../common/ace/DeploymentCommon'); +const PausePolicyCommon = require('../common/ace/PausePolicyCommon'); +const RBACPolicyCommon = require('../common/ace/RBACPolicyCommon'); +const CombinedPolicyCommon = require('../common/ace/CombinedPolicyCommon'); +const PolicyEngineCommon = require('../common/ace/PolicyEngineCommon'); +const CMTATModuleCommon = require('../common/cmtat/CMTATModuleCommon'); + +const standardFixture = createStandardFixture(deployCCTUpgradeable); +const standardFixtureWithSnapshot = createStandardFixtureWithSnapshot(deployCCTUpgradeable); + +describe('ComplianceTokenCMTATUpgradeable', function () { + context('snapshotEngine = 0 (no snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(standardFixture)); + this.dontCheckTimestamp = true; + }); + + context('Re-initialization', function () { + it('testCannotBeReinitialized', async function () { + await expect( + this.cmtat + .connect(this.admin) + .initialize( + this.admin.address, + ['CMTA Token', 'CMTAT', 0], + [ + 'CMTAT_ISIN', + ['doc1', 'https://example.com/doc1', ethers.keccak256(ethers.toUtf8Bytes('h'))], + 'CMTAT_info', + ], + this.policyEngineAddress, + ethers.ZeroAddress, + ethers.ZeroAddress, + ), + ).to.be.revertedWithCustomError(this.cmtat, 'InvalidInitialization'); + }); + }); + + DeploymentCommon(); + PausePolicyCommon(); + RBACPolicyCommon(); + CombinedPolicyCommon(); + PolicyEngineCommon(); + CMTATModuleCommon(false); + }); + + context('snapshotEngine is set (snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(standardFixtureWithSnapshot)); + this.dontCheckTimestamp = true; + }); + CMTATModuleCommon(true, false); + }); +}); diff --git a/test/deployment/uupsUpgradeableDeployment.test.js b/test/deployment/uupsUpgradeableDeployment.test.js new file mode 100644 index 0000000..40d4e72 --- /dev/null +++ b/test/deployment/uupsUpgradeableDeployment.test.js @@ -0,0 +1,111 @@ +const { ethers, upgrades } = require('hardhat'); +const { expect } = require('chai'); +const { + loadFixture, + deployCCTUUPSUpgradeable, + createStandardFixture, + createStandardFixtureWithSnapshot, +} = require('../deploymentUtils'); + +// ACE-specific common modules +const DeploymentCommon = require('../common/ace/DeploymentCommon'); +const PausePolicyCommon = require('../common/ace/PausePolicyCommon'); +const RBACPolicyCommon = require('../common/ace/RBACPolicyCommon'); +const CombinedPolicyCommon = require('../common/ace/CombinedPolicyCommon'); +const PolicyEngineCommon = require('../common/ace/PolicyEngineCommon'); +const CMTATModuleCommon = require('../common/cmtat/CMTATModuleCommon'); + +const standardFixture = createStandardFixture(deployCCTUUPSUpgradeable); +const standardFixtureWithSnapshot = createStandardFixtureWithSnapshot(deployCCTUUPSUpgradeable); + +describe('ComplianceTokenCMTATUUPSUpgradeable', function () { + context('snapshotEngine = 0 (no snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(standardFixture)); + this.dontCheckTimestamp = true; + }); + + context('Re-initialization', function () { + it('testCannotBeReinitialized', async function () { + await expect( + this.cmtat + .connect(this.admin) + .initialize( + this.admin.address, + ['CMTA Token', 'CMTAT', 0], + [ + 'CMTAT_ISIN', + ['doc1', 'https://example.com/doc1', ethers.keccak256(ethers.toUtf8Bytes('h'))], + 'CMTAT_info', + ], + this.policyEngineAddress, + ethers.ZeroAddress, + ethers.ZeroAddress, + ), + ).to.be.revertedWithCustomError(this.cmtat, 'InvalidInitialization'); + }); + }); + + context('UUPS Upgrade', function () { + it('testOwnerCanUpgrade', async function () { + const FactoryV2 = await ethers.getContractFactory( + 'ComplianceTokenCMTATUUPSUpgradeable', + this.admin, + ); + await upgrades.upgradeProxy(await this.cmtat.getAddress(), FactoryV2, { + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }); + }); + + it('testNonOwnerCannotUpgrade', async function () { + const FactoryV2 = await ethers.getContractFactory( + 'ComplianceTokenCMTATUUPSUpgradeable', + this.attacker, + ); + await expect( + upgrades.upgradeProxy(await this.cmtat.getAddress(), FactoryV2, { + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }), + ).to.be.revertedWithCustomError(this.cmtat, 'OwnableUnauthorizedAccount'); + }); + + it('testStatePreservedAfterUpgrade', async function () { + await this.cmtat.connect(this.admin).mint(this.address1.address, 100n); + expect(await this.cmtat.balanceOf(this.address1.address)).to.equal(100n); + + const FactoryV2 = await ethers.getContractFactory( + 'ComplianceTokenCMTATUUPSUpgradeable', + this.admin, + ); + const upgraded = await upgrades.upgradeProxy(await this.cmtat.getAddress(), FactoryV2, { + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }); + + expect(await upgraded.balanceOf(this.address1.address)).to.equal(100n); + expect(await upgraded.name()).to.equal('CMTA Token'); + expect(await upgraded.symbol()).to.equal('CMTAT'); + }); + }); + + DeploymentCommon(); + PausePolicyCommon(); + RBACPolicyCommon(); + CombinedPolicyCommon(); + PolicyEngineCommon(); + CMTATModuleCommon(false); + }); + + context('snapshotEngine is set (snapshot suites)', function () { + beforeEach(async function () { + Object.assign(this, await loadFixture(standardFixtureWithSnapshot)); + this.dontCheckTimestamp = true; + }); + CMTATModuleCommon(true, false); + }); +}); diff --git a/test/deploymentUtils.js b/test/deploymentUtils.js new file mode 100644 index 0000000..3045945 --- /dev/null +++ b/test/deploymentUtils.js @@ -0,0 +1,509 @@ +const { ethers, upgrades } = require('hardhat'); +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); + +const ZERO_ADDRESS = ethers.ZeroAddress; +const DEPLOYMENT_DECIMAL = 0n; +const TERMS = [ + 'doc1', + 'https://example.com/doc1', + '0x6a12eff2f559a5e529ca2c563c53194f6463ed5c61d1ae8f8731137467ab0279', +]; + +// Role constants (match CMTAT convention) +const MINTER_ROLE = ethers.keccak256(ethers.toUtf8Bytes('MINTER_ROLE')); +const BURNER_ROLE = ethers.keccak256(ethers.toUtf8Bytes('BURNER_ROLE')); +const BURNER_FROM_ROLE = ethers.keccak256(ethers.toUtf8Bytes('BURNER_FROM_ROLE')); +const BURNER_SELF_ROLE = ethers.keccak256(ethers.toUtf8Bytes('BURNER_SELF_ROLE')); +const PAUSER_ROLE = ethers.keccak256(ethers.toUtf8Bytes('PAUSER_ROLE')); +const ENFORCER_ROLE = ethers.keccak256(ethers.toUtf8Bytes('ENFORCER_ROLE')); +const ERC20ENFORCER_ROLE = ethers.keccak256(ethers.toUtf8Bytes('ERC20ENFORCER_ROLE')); +const DOCUMENT_ROLE = ethers.keccak256(ethers.toUtf8Bytes('DOCUMENT_ROLE')); +const SNAPSHOOTER_ROLE = ethers.keccak256(ethers.toUtf8Bytes('SNAPSHOOTER_ROLE')); +const CROSS_CHAIN_ROLE = ethers.keccak256(ethers.toUtf8Bytes('CROSS_CHAIN_ROLE')); +const DEFAULT_ADMIN_ROLE = '0x0000000000000000000000000000000000000000000000000000000000000000'; + +/** + * Fixture matching CMTAT signer convention + */ +async function fixture() { + const [ + _, + admin, + address1, + address2, + address3, + deployerAddress, + fakeRuleEngine, + ruleEngine, + attacker, + ] = await ethers.getSigners(); + return { + _, + admin, + address1, + address2, + address3, + deployerAddress, + fakeRuleEngine, + ruleEngine, + attacker, + }; +} + +/* ======== ACE Infrastructure Deploy Helpers ======== */ + +async function deployPolicyEngine(defaultAllow, initialOwner) { + const Factory = await ethers.getContractFactory('PolicyEngine'); + const policyEngine = await upgrades.deployProxy(Factory, [defaultAllow, initialOwner], { + initializer: 'initialize', + unsafeAllow: ['constructor'], + silenceWarnings: true, + }); + return policyEngine; +} + +async function deployPausePolicy(policyEngineAddress, ownerAddress, initiallyPaused = false) { + const abiCoder = ethers.AbiCoder.defaultAbiCoder(); + const configParams = abiCoder.encode(['bool'], [initiallyPaused]); + const Factory = await ethers.getContractFactory('PausePolicy'); + const pausePolicy = await upgrades.deployProxy( + Factory, + [policyEngineAddress, ownerAddress, configParams], + { + initializer: 'initialize', + unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], + silenceWarnings: true, + }, + ); + return pausePolicy; +} + +async function deployRBACPolicy(policyEngineAddress, ownerAddress) { + const Factory = await ethers.getContractFactory('RoleBasedAccessControlPolicy'); + const rbacPolicy = await upgrades.deployProxy( + Factory, + [policyEngineAddress, ownerAddress, '0x'], + { + initializer: 'initialize', + unsafeAllow: ['constructor', 'missing-initializer', 'missing-initializer-call'], + silenceWarnings: true, + }, + ); + return rbacPolicy; +} + +/* ======== Standard Contract Deploy Helpers ======== */ + +async function deployCCTStandalone( + admin, + policyEngineAddress, + snapshotEngine = ZERO_ADDRESS, + documentEngine = ZERO_ADDRESS, +) { + const cmtat = await ethers.deployContract('ComplianceTokenCMTATStandalone', [ + admin, + ['CMTA Token', 'CMTAT', DEPLOYMENT_DECIMAL], + ['CMTAT_ISIN', TERMS, 'CMTAT_info'], + policyEngineAddress, + snapshotEngine, + documentEngine, + ]); + return cmtat; +} + +async function deployCCTUpgradeable( + admin, + policyEngineAddress, + snapshotEngine = ZERO_ADDRESS, + documentEngine = ZERO_ADDRESS, +) { + const Factory = await ethers.getContractFactory('ComplianceTokenCMTATUpgradeable'); + const cmtat = await upgrades.deployProxy( + Factory, + [ + admin, + ['CMTA Token', 'CMTAT', DEPLOYMENT_DECIMAL], + ['CMTAT_ISIN', TERMS, 'CMTAT_info'], + policyEngineAddress, + snapshotEngine, + documentEngine, + ], + { + initializer: 'initialize', + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + }, + ); + return cmtat; +} + +/* ======== Lite Contract Deploy Helpers ======== */ + +async function deployCCTLiteStandalone( + admin, + policyEngineAddress, + snapshotEngine = ZERO_ADDRESS, + documentEngine = ZERO_ADDRESS, +) { + const cmtat = await ethers.deployContract('ComplianceTokenCMTATLiteStandalone', [ + admin, + ['CMTA Token', 'CMTAT', DEPLOYMENT_DECIMAL], + ['CMTAT_ISIN', TERMS, 'CMTAT_info'], + policyEngineAddress, + snapshotEngine, + documentEngine, + ]); + return cmtat; +} + +async function deployCCTLiteUpgradeable( + admin, + policyEngineAddress, + snapshotEngine = ZERO_ADDRESS, + documentEngine = ZERO_ADDRESS, +) { + const Factory = await ethers.getContractFactory('ComplianceTokenCMTATLiteUpgradeable'); + const cmtat = await upgrades.deployProxy( + Factory, + [ + admin, + ['CMTA Token', 'CMTAT', DEPLOYMENT_DECIMAL], + ['CMTAT_ISIN', TERMS, 'CMTAT_info'], + policyEngineAddress, + snapshotEngine, + documentEngine, + ], + { + initializer: 'initialize', + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + }, + ); + return cmtat; +} + +/* ======== UUPS Contract Deploy Helpers ======== */ + +async function deployCCTUUPSUpgradeable( + admin, + policyEngineAddress, + snapshotEngine = ZERO_ADDRESS, + documentEngine = ZERO_ADDRESS, +) { + const Factory = await ethers.getContractFactory('ComplianceTokenCMTATUUPSUpgradeable'); + const cmtat = await upgrades.deployProxy( + Factory, + [ + admin, + ['CMTA Token', 'CMTAT', DEPLOYMENT_DECIMAL], + ['CMTAT_ISIN', TERMS, 'CMTAT_info'], + policyEngineAddress, + snapshotEngine, + documentEngine, + ], + { + initializer: 'initialize', + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }, + ); + return cmtat; +} + +async function deployCCTLiteUUPSUpgradeable( + admin, + policyEngineAddress, + snapshotEngine = ZERO_ADDRESS, + documentEngine = ZERO_ADDRESS, +) { + const Factory = await ethers.getContractFactory('ComplianceTokenCMTATLiteUUPSUpgradeable'); + const cmtat = await upgrades.deployProxy( + Factory, + [ + admin, + ['CMTA Token', 'CMTAT', DEPLOYMENT_DECIMAL], + ['CMTAT_ISIN', TERMS, 'CMTAT_info'], + policyEngineAddress, + snapshotEngine, + documentEngine, + ], + { + initializer: 'initialize', + unsafeAllow: ['missing-initializer', 'constructor'], + silenceWarnings: true, + kind: 'uups', + }, + ); + return cmtat; +} + +/* ======== Fixture Factories ======== */ + +/** + * Creates a fixture for standard (PolicyEngine + RBAC) deployment tests. + * All contract deployment, policy registration, and role grants happen once; + * loadFixture snapshots the state and restores it for each test. + */ +function createStandardFixture(deployTokenFn) { + return async function standardFixture() { + const [ + _, + admin, + address1, + address2, + address3, + deployerAddress, + fakeRuleEngine, + ruleEngine, + attacker, + ] = await ethers.getSigners(); + + // Deploy ACE infrastructure + const policyEngine = await deployPolicyEngine(true, admin.address); + const policyEngineAddress = await policyEngine.getAddress(); + + const pausePolicy = await deployPausePolicy(policyEngineAddress, admin.address, false); + const pausePolicyAddress = await pausePolicy.getAddress(); + + const rbacPolicy = await deployRBACPolicy(policyEngineAddress, admin.address); + const rbacPolicyAddress = await rbacPolicy.getAddress(); + + // Deploy compliance token + const cmtat = await deployTokenFn(admin.address, policyEngineAddress); + const cmtatAddress = await cmtat.getAddress(); + + // Collect all selectors + const mintSelector = cmtat.interface.getFunction('mint(address,uint256)').selector; + const burnSelector = cmtat.interface.getFunction('burn(address,uint256)').selector; + const selfBurnSelector = cmtat.interface.getFunction('burn(uint256)').selector; + const burnFromSelector = cmtat.interface.getFunction('burnFrom').selector; + const transferSelector = cmtat.interface.getFunction('transfer(address,uint256)').selector; + const transferFromSelector = cmtat.interface.getFunction( + 'transferFrom(address,address,uint256)', + ).selector; + const forcedTransferSelector = cmtat.interface.getFunction( + 'forcedTransfer(address,address,uint256)', + ).selector; + const freezeSelector = cmtat.interface.getFunction( + 'freezePartialTokens(address,uint256)', + ).selector; + const unfreezeSelector = cmtat.interface.getFunction( + 'unfreezePartialTokens(address,uint256)', + ).selector; + const setNameSelector = cmtat.interface.getFunction('setName').selector; + const setTokenIdSelector = cmtat.interface.getFunction('setTokenId').selector; + const setDocumentEngineSelector = cmtat.interface.getFunction('setDocumentEngine').selector; + const setSnapshotEngineSelector = cmtat.interface.getFunction('setSnapshotEngine').selector; + const setCCIPAdminSelector = cmtat.interface.getFunction('setCCIPAdmin').selector; + const crosschainMintSelector = cmtat.interface.getFunction('crosschainMint').selector; + const crosschainBurnSelector = cmtat.interface.getFunction('crosschainBurn').selector; + + const allSelectors = [ + mintSelector, + burnSelector, + selfBurnSelector, + burnFromSelector, + forcedTransferSelector, + freezeSelector, + unfreezeSelector, + setNameSelector, + setTokenIdSelector, + setDocumentEngineSelector, + setSnapshotEngineSelector, + setCCIPAdminSelector, + crosschainMintSelector, + crosschainBurnSelector, + ]; + + // Add PausePolicy + RBAC to all admin selectors + for (const sel of allSelectors) { + await policyEngine.connect(admin).addPolicy(cmtatAddress, sel, pausePolicyAddress, []); + await policyEngine.connect(admin).addPolicy(cmtatAddress, sel, rbacPolicyAddress, []); + } + + // Transfer selectors get PausePolicy only (no RBAC - anyone can transfer) + await policyEngine + .connect(admin) + .addPolicy(cmtatAddress, transferSelector, pausePolicyAddress, []); + await policyEngine + .connect(admin) + .addPolicy(cmtatAddress, transferFromSelector, pausePolicyAddress, []); + + // Grant operation allowances + const opAllowances = [ + [mintSelector, MINTER_ROLE], + [burnSelector, BURNER_ROLE], + [selfBurnSelector, BURNER_SELF_ROLE], + [burnFromSelector, BURNER_FROM_ROLE], + [forcedTransferSelector, ENFORCER_ROLE], + [freezeSelector, ERC20ENFORCER_ROLE], + [unfreezeSelector, ERC20ENFORCER_ROLE], + [setNameSelector, DEFAULT_ADMIN_ROLE], + [setTokenIdSelector, DEFAULT_ADMIN_ROLE], + [setDocumentEngineSelector, DOCUMENT_ROLE], + [setSnapshotEngineSelector, SNAPSHOOTER_ROLE], + [setCCIPAdminSelector, DEFAULT_ADMIN_ROLE], + [crosschainMintSelector, CROSS_CHAIN_ROLE], + [crosschainBurnSelector, CROSS_CHAIN_ROLE], + ]; + for (const [sel, role] of opAllowances) { + await rbacPolicy.connect(admin).grantOperationAllowanceToRole(sel, role); + } + + // Grant roles to admin + const adminRoles = [ + MINTER_ROLE, + BURNER_ROLE, + ENFORCER_ROLE, + ERC20ENFORCER_ROLE, + DOCUMENT_ROLE, + SNAPSHOOTER_ROLE, + ]; + for (const role of adminRoles) { + await rbacPolicy.connect(admin).grantRole(role, admin.address); + } + + return { + _, + admin, + address1, + address2, + address3, + deployerAddress, + fakeRuleEngine, + ruleEngine, + attacker, + policyEngine, + policyEngineAddress, + pausePolicy, + pausePolicyAddress, + rbacPolicy, + rbacPolicyAddress, + cmtat, + cmtatAddress, + mintSelector, + burnSelector, + selfBurnSelector, + burnFromSelector, + transferSelector, + transferFromSelector, + forcedTransferSelector, + freezeSelector, + unfreezeSelector, + setNameSelector, + setTokenIdSelector, + setDocumentEngineSelector, + setSnapshotEngineSelector, + setCCIPAdminSelector, + crosschainMintSelector, + crosschainBurnSelector, + erc1404: true, + }; + }; +} + +async function withSnapshotEngine(baseFixture) { + const cmtatAddress = baseFixture.cmtatAddress ?? (await baseFixture.cmtat.getAddress()); + const transferEngineMock = await ethers.deployContract('SnapshotEngineMock', [ + cmtatAddress, + baseFixture.admin.address, + ]); + await transferEngineMock.waitForDeployment(); + await ( + await baseFixture.cmtat + .connect(baseFixture.admin) + .setSnapshotEngine(await transferEngineMock.getAddress()) + ).wait(); + return { + ...baseFixture, + cmtatAddress, + transferEngineMock, + }; +} + +function createStandardFixtureWithSnapshot(deployTokenFn) { + const baseFactory = createStandardFixture(deployTokenFn); + return async function standardFixtureWithSnapshot() { + const base = await baseFactory(); + return withSnapshotEngine(base); + }; +} + +/** + * Creates a fixture for lite (AccessControl + PolicyEngine for validation) deployment tests. + * Deploys just the PolicyEngine and token; no PausePolicy or RBAC needed. + */ +function createLiteFixture(deployTokenFn) { + return async function liteFixture() { + const [ + _, + admin, + address1, + address2, + address3, + deployerAddress, + fakeRuleEngine, + ruleEngine, + attacker, + ] = await ethers.getSigners(); + + const policyEngine = await deployPolicyEngine(true, admin.address); + const cmtat = await deployTokenFn(admin.address, await policyEngine.getAddress()); + + return { + _, + admin, + address1, + address2, + address3, + deployerAddress, + fakeRuleEngine, + ruleEngine, + attacker, + policyEngine, + cmtat, + erc1404: true, + }; + }; +} + +function createLiteFixtureWithSnapshot(deployTokenFn) { + const baseFactory = createLiteFixture(deployTokenFn); + return async function liteFixtureWithSnapshot() { + const base = await baseFactory(); + return withSnapshotEngine(base); + }; +} + +module.exports = { + ZERO_ADDRESS, + DEPLOYMENT_DECIMAL, + TERMS, + MINTER_ROLE, + BURNER_ROLE, + BURNER_FROM_ROLE, + BURNER_SELF_ROLE, + PAUSER_ROLE, + ENFORCER_ROLE, + ERC20ENFORCER_ROLE, + DOCUMENT_ROLE, + SNAPSHOOTER_ROLE, + CROSS_CHAIN_ROLE, + DEFAULT_ADMIN_ROLE, + fixture, + loadFixture, + deployPolicyEngine, + deployPausePolicy, + deployRBACPolicy, + deployCCTStandalone, + deployCCTUpgradeable, + deployCCTUUPSUpgradeable, + deployCCTLiteStandalone, + deployCCTLiteUpgradeable, + deployCCTLiteUUPSUpgradeable, + createStandardFixture, + createStandardFixtureWithSnapshot, + createLiteFixture, + createLiteFixtureWithSnapshot, +};