Skip to content

Releases: CMTA/RuleEngine

v3.0.0-rc3

07 May 12:23
5827604

Choose a tag to compare

Security

  • Enforce an on-chain maximum rule count in RulesManagementModule to mitigate transfer liveness risk from unbounded per-transfer rule iteration (Nethermind AuditAgent finding 3 follow-up).
  • Add cap checks in both addRule and setRules, reverting with RuleEngine_RulesManagementModule_MaxRulesExceeded(uint256) when exceeded.
  • Enforce on-chain privilege-separation for rule accounts:
    • RuleEngine.grantRole now reverts for any role when account is currently in the rules set.
    • RuleEngineOwnable and RuleEngineOwnable2Step now reject transferOwnership targets that are currently in the rules set.
  • Add T-REX compatibility path for compliance binding operations with admission control:
    • token self-calls (msg.sender == token) for bindToken(token) / unbindToken(token) are supported only when explicitly approved.
    • unapproved token self-calls are rejected and still require manager/owner authorization.

Added

  • Add maxRules() and setMaxRules(uint256) to IRulesManagementModule.
  • Add DEFAULT_MAX_RULES = 10 and initialize module state with this default cap.
  • Add SetMaxRules(uint256) event emitted on cap updates.
  • Add interface ID libraries:
    • ERC1404InterfaceId for IERC1404 (0xab84a5c8)
    • OwnableInterfaceId for IERC173 (0x7f5828d0)
    • Ownable2StepInterfaceId for Ownable2Step-specific methods (0x9ab669ef)
  • Add dedicated access-control hook for cap governance:
    • RuleEngine: DEFAULT_ADMIN_ROLE can update cap.
    • RuleEngineOwnable and RuleEngineOwnable2Step: owner can update cap.
  • Add RuleEngine_RulesManagementModule_RuleAccountCannotReceivePrivileges() error for rule-account privilege/ownership target protection.
  • Add token self-binding approval management to IERC3643ComplianceExtended / ERC3643ComplianceExtendedModule:
    • setTokenSelfBindingApproval(address token, bool approved)
    • isTokenSelfBindingApproved(address token)
    • TokenSelfBindingApprovalSet(address indexed token, bool approved) event.
  • Add batch self-binding approval API in IERC3643ComplianceExtended / ERC3643ComplianceExtendedModule:
    • setTokenSelfBindingApprovalBatch(address[] tokens, bool approved).
    • TokenSelfBindingApprovalBatchSet(address[] tokens, bool approved) event.

Changed

  • Ownable variants now rely on OpenZeppelin ERC165 inheritance in RuleEngineOwnableShared for base ERC-165 advertisement and extend it with RuleEngine + ERC-173 interface IDs.
  • supportsInterface advertisement now explicitly includes IERC1404 in addition to IERC1404Extend.
  • RuleEngineOwnable2Step.supportsInterface now advertises the Ownable2Step-specific interface ID in addition to inherited RuleEngine/Ownable interfaces.
  • ERC3643ComplianceModule authorization logic now requires explicit per-token approval for token-driven self-bind/self-unbind flows.
  • Split compliance interfaces between standard and extensions:
    • IERC3643Compliance now contains the base ERC-3643 compliance surface.
    • supplementary functions are grouped in IERC3643ComplianceExtended and advertised through a dedicated ERC-165 extension interface ID.
  • Split compliance modules between standard and extensions:
    • ERC3643ComplianceModule now contains the base ERC-3643 compliance surface.
    • supplementary functions are grouped in ERC3643ComplianceExtendedModule.
  • Batch self-binding approval event emission now uses a single batch event (TokenSelfBindingApprovalBatchSet) per call instead of per-token TokenSelfBindingApprovalSet emissions.

Testing

  • Add tests for default cap value, cap enforcement for addRule and setRules, and access control on setMaxRules.
  • Add event-emission coverage for SetMaxRules.
  • Extend interface advertisement tests to validate interface IDs through both:
    • library constants
    • type(<mock interface>).interfaceId
      for IERC1404 and IERC173.
  • Extend RuleEngineOwnable2Step interface support tests to assert:
    • library constant support (Ownable2StepInterfaceId.IOWNABLE2STEP_INTERFACE_ID)
    • mock interface support (type(IOwnable2StepSubset).interfaceId).
  • Add RBAC tests ensuring roles cannot be granted to rule accounts.
  • Add ownable and ownable2step tests ensuring ownership cannot be transferred to rule accounts.
  • Add compliance-binding authorization tests across RBAC/ownable/ownable2step variants for:
    • approved token self-bind
    • approved token self-unbind
    • unapproved token self-bind/self-unbind denial
    • cross-token bind/unbind denial
  • Add tests for self-binding approval management across RBAC/ownable/ownable2step variants:
    • single approval set
    • batch approval set
    • zero-address rejection
    • unauthorized caller rejection.
  • Add ERC-3643 setCompliance-style migration test with a dedicated mock token to validate unbind(old) + bind(new) flow against RuleEngine self-binding approval controls.

Documentation

  • Clarify README multi-token guidance with explicit data-plane vs control-plane wording:
    • data-plane = runtime compliance callbacks (transferred, created, destroyed)
    • control-plane = governance/configuration actions (bindToken, unbindToken, role grants, ownership changes, and rule management)
  • Document that token-privilege separation in multi-token setups is an operational recommendation (not enforced on-chain) to preserve integrator flexibility for token-driven control-plane extensions.
  • Document ERC-3643 setCompliance compatibility details in README:
    • token self-bind/self-unbind feature support
    • required explicit self-binding approval
    • recommended operational sequence for compliance migration.

Acknowledge
We would like to thank @0xsereel, @Domson97, as well as CMTA Tech Comite for their valuable feedback and contributions to this release. Their input played an important role in improving the project, and we sincerely appreciate their support.

v3.0.0-rc2

14 Apr 11:25
ec4a24a

Choose a tag to compare

Dependencies

  • Update CMTAT submodule to v3.2.0.
  • Update OpenZeppelin Contracts and OpenZeppelin Contracts Upgradeable submodules to v5.6.1.
  • Set Solidity version to 0.8.34 in hardhat.config.js and foundry.toml.
  • Standardize local OpenZeppelin imports on @openzeppelin/contracts/... and remove the legacy OZ/ remapping to avoid Hardhat source-name collisions.

Fixed

  • RuleEngineOwnable.supportsInterface incorrectly advertised IAccessControl via the inherited AccessControl.supportsInterface fallback. Replaced with an explicit whitelist; supportsInterface(IAccessControl) now returns false as expected (Nethermind AuditAgent finding 2).
  • Advertise ERC-3643 compliance interface ID (0x3144991c) and IERC7551Compliance subset interface ID (0x7157797f) in supportsInterface for both RuleEngine and RuleEngineOwnable (Nethermind AuditAgent finding 6).
  • Fix Hardhat compatibility after the OpenZeppelin upgrade by removing duplicate import namespaces that resolved to the same file under hardhat-foundry.
  • Fix hardhat.config.js Solidity config shape so Hardhat applies the configured optimizer and EVM target instead of falling back to defaults.

Added

  • Move deployable contracts to src/deployment/ and rename RBAC deployable contract RuleEngine to RuleEngine.
  • RuleEngine.supportsInterface now advertises IAccessControlEnumerable.

Changed

  • Switch RuleEngine RBAC base from OpenZeppelin AccessControl to AccessControlEnumerable while keeping the custom "default admin has all roles" behavior.
  • Remove AccessControl inheritance from RulesManagementModule; RBAC responsibilities are now explicitly held by RuleEngine, while the module remains access-control agnostic.

Security

  • Add NatSpec and README warnings on bindToken / unbindToken: in a multi-tenant setup (multiple tokens sharing one engine), all bound tokens must be equally trusted and governed together; ERC-3643 callbacks do not carry the token address to rules (Nethermind AuditAgent finding 1).
  • Add NatSpec warnings on addRule, setRules, and _transferred: rule contracts must not be granted RULES_MANAGEMENT_ROLE or admin privileges (Nethermind AuditAgent finding 5).
  • Add NatSpec warnings on addRule, setRules, and _transferred: no on-chain maximum rule count is enforced; operators are responsible for sizing the rule set for the target chain gas limits (Nethermind AuditAgent finding 3).
  • Add restriction-code uniqueness convention to IRule.canReturnTransferRestrictionCode and _messageForTransferRestriction: codes must be unique across rules, or rules sharing a code must return the same message (Nethermind AuditAgent finding 4).
  • Add NatSpec on setRules documenting the empty-array rejection by design and referring to clearRules for explicit removal (Nethermind AuditAgent finding 7).

Testing

  • Add testDoesNotSupportIAccessControlInterface to RuleEngineOwnableCoverage asserting IAccessControl is not advertised.
  • Add ERC-3643 and IERC7551Compliance supportsInterface coverage tests to both RuleEngineCoverage and RuleEngineOwnableCoverage.
  • Add mock interfaces src/mocks/ICompliance.sol and src/mocks/IERC7551ComplianceSubset.sol used by coverage tests.
  • Extend RuleEngineDeployment interface coverage to assert support for IAccessControlEnumerable.
  • Add a small Hardhat smoke test (test/hardhat/RuleEngine.smoke.js) to confirm RuleEngine can be compiled, deployed, and queried through Hardhat.
  • Add the npm script test:hardhat to run the Hardhat smoke test directly.

Documentation

  • Add Nethermind AuditAgent scan #1 report and remediation assessment (doc/security/audits/tools/nethermind-audit-agent/).
  • Update README Security section with Nethermind AuditAgent findings summary table.
  • Update README toolchain and testing sections to mention Hardhat compilation support and the small Hardhat smoke test.

v3.0.0-rc1

16 Feb 14:59
f3e27c1

Choose a tag to compare

Added

  • Add RuleEngineOwnable contract variant using ERC-173 ownership (Ownable) as an alternative to the RBAC-based RuleEngine. ERC-3643 compliance specification recommends ERC-173 for ownership.
  • Add ERC-165 supportsInterface check when adding rules via addRule / setRules, ensuring that only valid rule contracts (implementing IRule) can be registered.
  • Use CMTAT library for ERC-165 interface ID constants (RuleEngineInterfaceId, ERC1404ExtendInterfaceId).
  • Add compatibility with CMTAT v3.0.0 and v3.2.0-rc0 (dual-version test support via CMTATDeploymentV3).

Fixed

  • Fix deployment script CMTATWithRuleEngineScript: deploy CMTAT with the deployer as admin instead of a hardcoded address, which caused setRuleEngine to revert with AccessControlUnauthorizedAccount.
  • Remove dead code in RuleEngineOwnable constructor: the custom zero-address owner check was unreachable because Ownable(owner_) already reverts with OwnableInvalidOwner(address(0)).
  • Remove duplicate code across rule contracts.

Dependencies

  • Update CMTAT library to v3.2.0-rc0
  • Update OpenZeppelin Contracts to v5.4.0
  • Update Foundry (forge-std) to v1.10.0
  • Set Solidity version to 0.8.33 and EVM version to Prague (Pectra upgrade)

Code quality

  • Resolve all forge lint warnings: convert plain imports to named imports, remove unused imports, rename variables/functions to mixedCase, refactor modifier logic, and add targeted lint suppressions where appropriate.
  • Replace Prettier and Ethlint/Solium with Foundry-native forge fmt and forge lint for formatting and linting.
  • Run forge fmt on the entire codebase.

Testing

  • Add deployment script tests (test/script/) for CMTATWithRuleEngineScript and RuleEngineScript.
  • Add RuleEngineOwnable test suite: deployment, access control, ERC-3643 compliance, rules management, and coverage tests.
  • Add IRuleInterfaceId test for ERC-165 interface ID computation.
  • Add integration tests with CMTAT v3.0.0 and v3.2.0-rc0.
  • Improve code coverage with additional edge-case tests.

Documentation

  • Expand README with contract variants comparison, constructor API, access control details, and ERC-173 ownership documentation.
  • Add formatting & linting section to README and TOOLCHAIN documentation.
  • Update surya diagrams, coverage reports, and specification documents.

Acknowledge

We would like to thank @amilazz, as well as CMTA Tech Comite for their valuable feedback and contributions to this release. Their input played an important role in improving the project, and we sincerely appreciate their support.

v3.0.0-rc0

15 Aug 11:21
f3283c3

Choose a tag to compare

  • Rule contracts, requires to perform compliance check, have now their own dedicated GitHub repository. It means that these contract will be developed and audited separately from the RuleEngine. This provides more flexibility and makes it easier to manage audits.

  • There is now only one type of rule (read-write rules). Before that:

    • First RuleEngine version (audited) had only one type of rule, read-only (whitelist, blacklist)
    • A second RuleEngine version (not audited) had two types of rules: operation (read-write) and validation (read-only). A read-write rule is typically a ConditionalTransfer check which require each transfer must be pre-approved.
  • Implement ERC-3643 compliance interface, which means that the RuleEngine can be also used with an ERC-3643 token to perform supplementary compliance check on transfer.

  • Technical:

    • Use EnumerableSet from OpenZeppelin to store rules, which reduce the whole contract code size.
    • Rename several abstract contract
      RuleEngineOperation-> RulesManagementModule
      MetaTxModuleStandalone -> ERC2771ModuleStandalone

v2.1.0

04 Jul 16:13
461d32f

Choose a tag to compare

  • Update RuleEngine to CMTAT v3.0.0-rc5

  • Update OpenZeppelin to v.5.3.0

  • Add "partial" support of spender check introduced with CMTAT v3.0.0-rc5

  • Change several functions
    --- operateOnTransfer -> transferred(...)
    ----Add functions detectTransferRestrictionFrom and canTransferFrom

v2.0.5

21 Dec 13:05
b03f2e9

Choose a tag to compare

Fix a bug present in the Conditional Transfer rule with the option automatic approval and improve the corresponding tests.

git clone https://github.com/CMTA/RuleEngine
git checkout v2.0.5
forge install
forge build
cd lib/CMTAT
npm install

v2.0.4

16 Dec 08:39
53e12a6

Choose a tag to compare

  • Fix a bug present in the Conditional Transfer rule and the corresponding test.
  • Config file:
    Set Solidity version to 0.8.27 in config file
    Set EVM version to Cancun
  • Add events for the following rules : whitelist/blacklist and sanctionList rules
  • Some improvements in testing
    Integration test with CMTAT: set the CMTAT version to v2.5.1
  • Access control: The default admin has by default all the roles for the RuleEngine and the different rules

git clone https://github.com/CMTA/RuleEngine
git checkout v2.0.4
forge install
forge build
cd lib/CMTAT
npm install

v2.0.3

10 Sep 07:21
9a35496

Choose a tag to compare

  • Small optimization in WhitelistWrapper; add a break in a loop
  • Set Solidity version to 0.8.26 in config file
  • Add constant VERSION

The release does not include the .git folder, which does not allow installing dependencies.
The easiest solution is to clone the project and perform a git checkout on the version tag

git clone https://github.com/CMTA/RuleEngine
git checkout v2.0.3
forge install
forge build

v2.0.2

17 Jun 09:49
24f69f7

Choose a tag to compare

  • Create abstract contract ruleWhitelistCommon to contain code shared between ruleWhitelist & ruleWhitelistWrapper
  • Split ADDRESS_LIST_ROLE in two distinct roles : ADDRESS_LIST_ADD_ROLE && ADDRESS_LIST_REMOVE_ROLE

The release does not include the .git folder, which does not allow installing dependencies.
The easiest solution is to clone the project and perform a git checkout on the version tag

git clone https://github.com/CMTA/RuleEngine
git checkout v2.0.2
forge install
forge build

v2.0.1

11 Jun 08:49
061f26c

Choose a tag to compare

Add a new rule WhitelistWrapper
This rule can be used to restrict transfers from/to only addresses inside a group of whitelist rules managed by different operators.

`The release does not include the .git folder, which does not allow installing dependencies.
The easiest solution is to clone the project and perform a git checkout on the version tag

git clone https://github.com/CMTA/RuleEngine
git checkout v2.0.1
forge install
forge build