Please follow https://changelog.md conventions and the other conventions below
Given a version number MAJOR.MINOR.PATCH, increment the:
- 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
- MINOR version when the new version adds functionality in a backward compatible manner
- PATCH version when the new version makes backward compatible bug fixes
Addedfor new features.Changedfor changes in existing functionality.Deprecatedfor soon-to-be removed features.Removedfor now removed features.Fixedfor any bug fixes.Securityin case of vulnerabilities.
Reference: keepachangelog.com/en/1.1.0/
Custom changelog tag: Dependencies, Documentation, Testing
Before a new release, perform the following tasks
- Code: Update the version name, variable VERSION
- Run formatter and linter
forge fmt
forge lint- Documentation
- Perform a code coverage and update the files in the corresponding directory ./doc/coverage
- Perform an audit with several audit tools (Aderyn and Slither), update the report in the corresponding directory ./doc/security/audits/tools
- Update surya doc by running the 3 scripts in ./doc/script
- Update changelog
- 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.jsandfoundry.toml. - Standardize local OpenZeppelin imports on
@openzeppelin/contracts/...and remove the legacyOZ/remapping to avoid Hardhat source-name collisions.
RuleEngineOwnable.supportsInterfaceincorrectly advertisedIAccessControlvia the inheritedAccessControl.supportsInterfacefallback. Replaced with an explicit whitelist;supportsInterface(IAccessControl)now returnsfalseas expected (Nethermind AuditAgent finding 2).- Advertise ERC-3643 compliance interface ID (
0x3144991c) and IERC7551Compliance subset interface ID (0x7157797f) insupportsInterfacefor bothRuleEngineandRuleEngineOwnable(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.jsSolidity config shape so Hardhat applies the configured optimizer and EVM target instead of falling back to defaults.
- Move deployable contracts to
src/deployment/and rename RBAC deployable contractRuleEnginetoRuleEngine. RuleEngine.supportsInterfacenow advertisesIAccessControlEnumerable.
- Switch
RuleEngineRBAC base from OpenZeppelinAccessControltoAccessControlEnumerablewhile keeping the custom "default admin has all roles" behavior. - Remove
AccessControlinheritance fromRulesManagementModule; RBAC responsibilities are now explicitly held byRuleEngine, while the module remains access-control agnostic.
- 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 grantedRULES_MANAGEMENT_ROLEor 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.canReturnTransferRestrictionCodeand_messageForTransferRestriction: codes must be unique across rules, or rules sharing a code must return the same message (Nethermind AuditAgent finding 4). - Add NatSpec on
setRulesdocumenting the empty-array rejection by design and referring toclearRulesfor explicit removal (Nethermind AuditAgent finding 7).
- Add
testDoesNotSupportIAccessControlInterfacetoRuleEngineOwnableCoverageassertingIAccessControlis not advertised. - Add ERC-3643 and IERC7551Compliance
supportsInterfacecoverage tests to bothRuleEngineCoverageandRuleEngineOwnableCoverage. - Add mock interfaces
src/mocks/ICompliance.solandsrc/mocks/IERC7551ComplianceSubset.solused by coverage tests. - Extend
RuleEngineDeploymentinterface coverage to assert support forIAccessControlEnumerable. - Add a small Hardhat smoke test (
test/hardhat/RuleEngine.smoke.js) to confirmRuleEnginecan be compiled, deployed, and queried through Hardhat. - Add the npm script
test:hardhatto run the Hardhat smoke test directly.
- 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.
Commit: f3e27c190635e91a64215276f4757d65eb2d2b2c
- Add
RuleEngineOwnablecontract variant using ERC-173 ownership (Ownable) as an alternative to the RBAC-basedRuleEngine. ERC-3643 compliance specification recommends ERC-173 for ownership. - Add ERC-165
supportsInterfacecheck when adding rules viaaddRule/setRules, ensuring that only valid rule contracts (implementingIRule) 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).
- Fix deployment script
CMTATWithRuleEngineScript: deploy CMTAT with the deployer as admin instead of a hardcoded address, which causedsetRuleEngineto revert withAccessControlUnauthorizedAccount. - Remove dead code in
RuleEngineOwnableconstructor: the custom zero-address owner check was unreachable becauseOwnable(owner_)already reverts withOwnableInvalidOwner(address(0)). - Remove duplicate code across rule contracts.
- 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)
- Resolve all
forge lintwarnings: 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 fmtandforge lintfor formatting and linting. - Run
forge fmton the entire codebase.
- Add deployment script tests (
test/script/) forCMTATWithRuleEngineScriptandRuleEngineScript. - Add
RuleEngineOwnabletest suite: deployment, access control, ERC-3643 compliance, rules management, and coverage tests. - Add
IRuleInterfaceIdtest 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.
- 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.
Commit: f3283c3b8a99089c3c6f674150831003a6bd2927
- 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->RulesManagementModuleMetaTxModuleStandalone->ERC2771ModuleStandalone
-
Update RuleEngine to CMTAT v3.0.0-rc5
-
Add "partial" support of spender check introduced with CMTAT v3.0.0-rc5
-
Change several functions
operateOnTransfer->transferred(...)
-
Add functions
detectTransferRestrictionFromandcanTransferFrom
-
- Fix a bug present in the Conditional Transfer rule and improve the corresponding tests.
- 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
- Small optimization in WhitelistWrapper; add a break in a loop
- Set Solidity version to 0.8.26 in config file
- 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
- 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.
- Implement the new architecture for the RuleEngine, with ValidationRule and OperationRule
- Add the rule ConditionalTransfer as an Operation rule
- Add the rule Blacklist as a Validation rule
- Whitelist and blacklist rules share a part of their code.
- Upgrade the library CMTAT to the version v2.4.0
- Fix a minor bug when rules are deleted with clearRules
- Upgrade the library CMTAT to the version v2.3.1
- Use custom errors instead of revert message (gas optimization)
- Add the rule
SanctionList - Upgrade OpenZeppelin to the version v5.0.0
- Upgrade the library CMTAT to the vesion v2.3.0
- Set the number of runs for the optimizer to 200 for Hardhat and Foundry, see https://docs.soliditylang.org/en/v0.8.17/using-the-compiler.html#optimizer-options
The release 1.0.2 contains mainly the different fixes and improvements related to the audit performed on the version 1.0.1.
Documentation
- Update the documentation for the release
- Add slither report
- Install hardhat in order to generic docgen documentation
General modifications
- Upgrade the library CMTAT to the latest version 2.3.0-rc.0 (pull/28)
- In RuleEngine,
ruleLengthis changed torulesCount()
- In RuleEngine,
- Add the gasless suport / MetaTx module (pull/27)
- RuleWhitelist: update RuleWhitelist to use code from IEIP1404Wrapper (pull/29)
Audit report
This version also includes improvements suggested by the audit report, addressing the following findings:
General
- CVF-10: use a floating pragma for the version (pull/25)
- CVF2, CVF-6: remove the function kill for the contracts RuleEngine and Whitelist (pull/17)
RuleEngine
- CVF-1 / removeRule: add an additional argument with the rule index hint (pull/23)
- CVF-7, CVF-8, CVF-9: check for duplicate rule (pull/20)
Whitelist
- CVF-3: use a local variable for iterate inside a loop (pull/18/)
- CVF-4, CVF-5: remove useless conditional statement (pull/19/)
- CVF-15, CVF-16, CVF-17: improve readibility (pull/24)
- Update the library CMTAT to the version 2.2
- Update the library OpenZeppelin to the version 4.8.1
- Improve integration test with CMTAT
- 🎉 first release!<