Skip to content

Commit

Permalink
Merge pull request #251 from CMTA/dev
Browse files Browse the repository at this point in the history
Release 2.4.0
  • Loading branch information
rya-sge authored May 3, 2024
2 parents 5a8e27b + 4cc326e commit 23a1e59
Show file tree
Hide file tree
Showing 290 changed files with 17,697 additions and 15,973 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Setup NodeJS 16
- name: Setup NodeJS 20.5.0
uses: actions/setup-node@v3
with:
node-version: 16.17.0
node-version: 20.5.0

- name: Show NodeJS version
run: npm --version
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ bin/*
.vscode/
#PlantUML
out
docOut
#drawio
*.bkp
*.dtmp
Expand All @@ -17,4 +18,4 @@ cache
#manticore
mcore_*
#secrets
.env
.env
72 changes: 71 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,83 @@

Please follow <https://changelog.md/> conventions.

## 2.4.0

The modifications between the version v2.3.0 and this version are not audited !!!

- Improve tests & update the code
- `ERC20SnapshotInternal` inherits from `ICMTATSnapshot`



## 2.4.0-rc.1 - 20240319

The modifications between the version v2.3.0 and this version are not audited !!!

**snapshotModule**

- Create an interface `ICMTATSnapshot` with the main public functions for the SnapshotModule to make easier the calls to a contract including a snapshotModule, useful e.g. for debt payment.
- Replace `getSnapshotInfoBatch` by `SnapshotInfo`. This function gets a user's balance specified in parameter and the total supply.
- Add a new function `SnapshotInfoBatch` to get several user's balances and the total supply.

**ERC20BaseModule**
Add a function `balanceInfo` to get the balance for a list of addresses and the total supply
Useful to perform transfer restriction based on the user's balance (e.g vesting rule or partial lock).

**ValidationModule**
Create an internal function ` _validateTransferByModule` which performs check with others module (PauseModule & EnforcementModule)

**Other**

- Upgrade OpenZeppelin to the version [v5.0.2](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.0.2)
- Upgrade Solidity to the version [0.8.22](https://soliditylang.org/blog/2023/10/25/solidity-0.8.22-release-announcement/) in the truffle and hardhat config files.

## 2.4.0-rc.0 - 20240129

The modifications between the version v2.3.0 and this version are not audited !!!

**New architecture for the RuleEngine** [#250](https://github.com/CMTA/CMTAT/pull/250)

- A new function `operateOnTransfer` is added and use inside the ValidationModule.
- Contrary to `validateTransfer`, this function has to be protected by an access control (if not implemented as view or pure)
- This function can be used to perform operation which modifies the state of the blockchain (storage) by the RuleEngine.
- The RuleEngine inherits now from *IRuleEngine* wich contains in its interface the function `operateOnTransfer` + IERC-1404
- The function `validateTransfer` is still available to verify a transfer without performing operation. The behavior is the same than with the previous CMTAT version.

**snapshotModule** [#256](https://github.com/CMTA/CMTAT/pull/256)

- Split the snapshotModuleInternal in two parts : one with the inheritance with ERC-20 and the other part with the base function and does not inherit from ERC-20.
Thus, if we want to build a snapshotModule with the RuleEngine, we can use the base contract to avoid the inheritance with ERC-20.
- Add a function `getSnapshotInfoBatch` to avoid multiple calls when computing debt payment

**AuthorizationEngine** [#254](https://github.com/CMTA/CMTAT/pull/254)

- Add the AuthorizationEngine. With that, it is possible to add supplementary check on the functions `grantRole` and `revokeRole`without modifying the CMTAT.

**BurnModule**

- rename `forceBurn` and `forceBurnBatch` in `burn` and `burnBatch`
- Add a function `burnFrom` with a specific role (useful for bridge) for compatibility with CCIP [Ccip #260](https://github.com/CMTA/CMTAT/pull/260)
- Add a function `burnAndMint` to perform a burn/mint operation atomically.

**Gas optimization**

- Add factory contract for deployment with Transparent and beacon proxy [Contract factory #259](https://github.com/CMTA/CMTAT/pull/259)
- Remove useless init function in internal modules (Done) [remove init functions in wrapper modules #237](https://github.com/CMTA/CMTAT/pull/237)

**Other**

- Remove custom approval function [Remove custom function allowance #225](https://github.com/CMTA/CMTAT/issues/225) (Done)
- upgrade some JS libraries
- Upgrade OpenZeppelin to the version [v5.0.1](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.0.1)

## 2.3.1

This version contains breaking changes with the version v2.3.0.

- Remove useless functions init in wrapper modules [#230](https://github.com/CMTA/CMTAT/issues/230)
- Add missing tests in EnforcementModule [#239](https://github.com/CMTA/CMTAT/issues/239)
- Use calldate instead of memory [#224](https://github.com/CMTA/CMTAT/issues/224)
- Use calldata instead of memory [#224](https://github.com/CMTA/CMTAT/issues/224)
- Upgrade OpenZeppelin to the version [v.5.0.0](https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable/releases/tag/v5.0.0)

## 2.3.1-rc.0 - 20230925
Expand Down
2 changes: 1 addition & 1 deletion FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,5 +100,5 @@ Normally, you can run the test suite and generate a code coverage report with `n

Please clone the repository and open the file inside your browser.

You will find a summary of all automatic tests in
You will find a list of automatic tests in
[test.pdf](https://github.com/CMTA/CMTAT/blob/master/doc/general/test/test.pdf).
77 changes: 61 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,24 @@ Please see the OpenZeppelin [Upgrades plugins](https://docs.openzeppelin.com/upg
Note that deployment via a proxy is not mandatory, but is recommended by CMTA.



#### Factory

Factory contracts are available to deploy the CMTAT with a beacon proxy or a transparent proxy.

[CMTAT_BEACON_FACTORY.sol](./contracts/deployment/CMTAT_BEACON_FACTORY.sol)

[CMTAT_TRANSPARENT_FACTORY.sol](./contracts/deployment/CMTAT_TRANSPARENT_FACTORY.sol)

Beacon Proxy factory: the factory will use the same beacon for each beacon proxy. This beacon provides the address of the implementation contract, a CMTAT_PROXY contract. If you upgrade the beacon to point to a new implementation, it will change the implementation contract for all beacon proxy.

![factory-Beacon Factory.drawio](./doc/schema/drawio/factory-BeaconFactory.drawio.png)

Transparent Proxy factory: the factory will use the same implementation for each transparent proxy deployed. Each transparent proxy has its owned proxy admin, deployed inside the constructor of the transparent proxy. Each transparent proxy can upgrade their implementation to a new one independently and without impact on other proxies.

![factory-Transparent Factory.drawio](./doc/schema/drawio/factory-TransparentFactory.drawio.png)


### Gasless support

The CMTAT supports client-side gasless transactions using the [Gas Station Network](https://docs.opengsn.org/#the-problem) (GSN) pattern, the main open standard for transfering fee payment to another account than that of the transaction issuer. The contract uses the OpenZeppelin contract `ERC2771ContextUpgradeable`, which allows a contract to get the original client with `_msgSender()` instead of the fee payer given by `msg.sender` while allowing upgrades on the main contract (see *Deployment via a proxy* above).
Expand Down Expand Up @@ -109,27 +127,56 @@ Generally, these modules are not required to be compliant with the CMTA specific
| Name | Documentation | Main File |
| ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| MetaTxModule | [metatx.md](doc/modules/presentation/extensions/metatx.md) | [MetaTxModule.sol](./contracts/modules/wrapper/extensions/MetaTxModule.sol) |
| SnapshotModule* | [snapshot.md](doc/modules/presentation/extensions/snapshot.md) | [SnapshotModule.sol](./contracts/modules/wrapper/extensions/SnapshotModule.sol) |
| SnapshotModule | [snapshot.md](doc/modules/presentation/extensions/snapshot.md) | [SnapshotModule.sol](./contracts/modules/wrapper/extensions/SnapshotModule.sol) |
| creditEventModule | [creditEvents.md](doc/modules/presentation/extensions/Debt/creditEvents.md) | [CreditEventsModule.sol](./contracts/modules/wrapper/extensions/DebtModule/CreditEventsModule.sol) |
| DebtBaseModule | [debtBase.md](doc/modules/presentation/extensions/Debt/debtBase.md) | [DebtBaseModule.sol](./contracts/modules/wrapper/extensions/DebtModule/DebtBaseModule.sol) |

*not imported by default

### Security

| Name | Documentation | Main File |
| ------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| AuthorizationModule | [authorization.md](./doc/modules/presentation/security/authorization.md) | [AuthorizationModule.sol](./contracts/modules/security/AuthorizationModule.sol) |

## Engine

### RuleEngine

The `RuleEngine` is an external contract used to apply transfer restriction to the CMTAT through whitelisting, blacklisting,...

### SnapshotModule
This contract is defined in the `ValidationModule`.

This module designed for future support of dividend and interest distribution, was not covered by the audit made by ABDK and it is no longer imported by default inside the CMTAT.
An example of RuleEngine is also available on [Github](https://github.com/CMTA/RuleEngine).

If you want to add this module, you have to uncomment the specific lines "SnapshotModule" in [CMTAT_BASE.sol](./contracts/modules/CMTAT_BASE.sol).
Here is the list of the different version available for each CMTAT version.

A CMTAT version inheriting from the SnapshotModule and used for **testing** purpose is available in [CMTATSnapshotStandaloneTest.sol](./contracts/test/CMTATSnapshot/CMTATSnapshotStandaloneTest.sol) and [CMTATSnapshotProxyTest.sol](./contracts/test/CMTATSnapshot/CMTATSnapshotProxyTest.sol).
| Name | RuleEngine |
| ----------------------- | ------------------------------------------------------------ |
| CMTAT 2.4.0 (unaudited) | Still in development |
| CMTAT 2.3.0 | [RuleEngine v1.0.2](https://github.com/CMTA/RuleEngine/releases/tag/v1.0.2) |
| CMTAT 2.0 (unaudited) | [RuleEngine 1.0](https://github.com/CMTA/RuleEngine/releases/tag/1.0) (unaudited) |
| CMTAT 1.0 | No ruleEngine available |

This contract acts as a controller and can call different contract rule to apply rule on each transfer.

A possible rule is a whitelist rule where only the address inside the whitelist can perform a transfer

Since the version 2.4.0, the requirement to use a RuleEngine are the following:

The `RuleEngine` has to import an implement the interface `IRuleEngine` which declares the function `operateOnTransfer`.

This interface can be found in [./contracts/interfaces/engine/IRuleEngine.sol](./contracts/interfaces/engine/IRuleEngine.sol).

Before each transfer, the CMTAT calls the function `operateOnTransfer` which is the entrypoint for the RuleEngine.

### AuthorizationEngine

The `AuthorizationEngine` is an external contract to add supplementary check on the functions `grantRole` and `revokeRole`from the CMTAT.

This contract is managed in the `AuthorizationModule`.

The `AuthorizationEngine` has to import an implement the interface `IAuthorizationEngine` which declares the functions `operateOnGrantRole` and `operateOnRevokeRole`

This interface can be found in [./contracts/interfaces/engine/IAuthorizationEngine.sol](./contracts/interfaces/engine/IAuthorizationEngine.sol).


## Security
Expand Down Expand Up @@ -172,18 +219,16 @@ The report is available in [ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf](doc/audits/ABDK

You will find the report produced by [Slither](https://github.com/crytic/slither) in

| Version | File |
| ------- | ------------------------------------------------------------ |
| v2.3.0 | [v2.3.0-slither-report.md](doc/audits/tools/v2.3.0-slither-report.md) |
| v2.3.1 | [v2.3.1-slither-report.md](doc/audits/tools/v2.3.1-slither-report.md) |
| Version | File |
| ------------ | ------------------------------------------------------------ |
| Last version | [slither-report.md](doc/audits/tools/slither-report.md) |
| v2.3.0 | [v2.3.0-slither-report.md](doc/audits/tools/v2.3.0-slither-report.md) |
| v2.3.1 | [v2.3.1-slither-report.md](doc/audits/tools/v2.3.1-slither-report.md) |


### Test

- A summary of automatic tests is available in [test.pdf](doc/general/test/test.pdf).
- A code coverage is available in [index.html](doc/general/test/coverage/index.html).

> Note that we do not perform tests on the internal functions `init` of the different modules.
A code coverage is available in [index.html](doc/general/test/coverage/index.html).


### Remarks
Expand Down Expand Up @@ -215,4 +260,4 @@ CMTA providers further documentation describing the CMTAT framework in a platfor

## Intellectual property

The code is copyright (c) Capital Market and Technology Association, 2018-2023, and is released under [Mozilla Public License 2.0](./LICENSE.md).
The code is copyright (c) Capital Market and Technology Association, 2018-2024, and is released under [Mozilla Public License 2.0](./LICENSE.md).
7 changes: 4 additions & 3 deletions contracts/CMTAT_STANDALONE.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ contract CMTAT_STANDALONE is CMTAT_BASE {
* @notice Contract version for standalone deployment
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
* @param admin address of the admin of contract (Access Control)
* @param authorizationEngineIrrevocable
* @param nameIrrevocable name of the token
* @param symbolIrrevocable name of the symbol
* @param decimalsIrrevocable number of decimals used to get its user representation, should be 0 to be compliant with the CMTAT specifications.
Expand All @@ -22,21 +23,21 @@ contract CMTAT_STANDALONE is CMTAT_BASE {
constructor(
address forwarderIrrevocable,
address admin,
uint48 initialDelay,
IAuthorizationEngine authorizationEngineIrrevocable,
string memory nameIrrevocable,
string memory symbolIrrevocable,
uint8 decimalsIrrevocable,
string memory tokenId_,
string memory terms_,
IERC1404Wrapper ruleEngine_,
IRuleEngine ruleEngine_,
string memory information_,
uint256 flag_
) MetaTxModule(forwarderIrrevocable) {
// Initialize the contract to avoid front-running
// Warning : do not initialize the proxy
initialize(
admin,
initialDelay,
authorizationEngineIrrevocable,
nameIrrevocable,
symbolIrrevocable,
decimalsIrrevocable,
Expand Down
102 changes: 102 additions & 0 deletions contracts/deployment/CMTAT_BEACON_FACTORY.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//SPDX-License-Identifier: MPL-2.0
pragma solidity ^0.8.20;

import "@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol";

import '@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol';
import "../CMTAT_PROXY.sol";
import "../modules/CMTAT_BASE.sol";
import "../libraries/FactoryErrors.sol";
import '@openzeppelin/contracts/access/AccessControl.sol';

/**
* @notice Factory to deploy beacon proxy
*
*/
contract CMTAT_BEACON_FACTORY is AccessControl {
// Private
mapping(uint256 => address) private cmtats;
uint256 private cmtatCounterId;
// public
/// @dev Role to deploy CMTAT
bytes32 public constant CMTAT_DEPLOYER_ROLE = keccak256("CMTAT_DEPLOYER_ROLE");
UpgradeableBeacon public immutable beacon;
address[] public cmtatsList;
event CMTAT(address indexed CMTAT, uint256 id);

/**
* @param implementation_ contract implementation
* @param factoryAdmin admin
* @param beaconOwner owner
*/
constructor(address implementation_, address factoryAdmin, address beaconOwner) {
if(factoryAdmin == address(0)){
revert FactoryErrors.CMTAT_Factory_AddressZeroNotAllowedForFactoryAdmin();
}
if(beaconOwner == address(0)){
revert FactoryErrors.CMTAT_Factory_AddressZeroNotAllowedForBeaconOwner();
}
if(implementation_ == address(0)){
revert FactoryErrors.CMTAT_Factory_AddressZeroNotAllowedForLogicContract();
}
beacon = new UpgradeableBeacon(implementation_, beaconOwner);
_grantRole(DEFAULT_ADMIN_ROLE, factoryAdmin);
_grantRole(CMTAT_DEPLOYER_ROLE, factoryAdmin);
}

/**
* @notice deploy CMTAT with a beacon proxy
*
*/
function deployCMTAT(
// CMTAT function initialize
address admin,
IAuthorizationEngine authorizationEngineIrrevocable,
string memory nameIrrevocable,
string memory symbolIrrevocable,
uint8 decimalsIrrevocable,
string memory tokenId_,
string memory terms_,
IRuleEngine ruleEngine_,
string memory information_,
uint256 flag_
) public onlyRole(CMTAT_DEPLOYER_ROLE) returns(BeaconProxy cmtat) {
cmtat = new BeaconProxy(
address(beacon),
abi.encodeWithSelector(
CMTAT_PROXY(address(0)).initialize.selector,
admin,
authorizationEngineIrrevocable,
nameIrrevocable,
symbolIrrevocable,
decimalsIrrevocable,
tokenId_,
terms_,
ruleEngine_,
information_,
flag_
)
);
cmtats[cmtatCounterId] = address(cmtat);
emit CMTAT(address(cmtat), cmtatCounterId);
cmtatCounterId++;
cmtatsList.push(address(cmtat));
return cmtat;
}

/**
* @notice get CMTAT proxy address
*
*/
function getAddress(uint256 cmtatID_) external view returns (address) {
return cmtats[cmtatID_];
}

/**
* @notice get the implementation address from the beacon
* @return implementation address
*/
function implementation() public view returns (address) {
return beacon.implementation();
}
}
Loading

0 comments on commit 23a1e59

Please sign in to comment.