Skip to content

Commit

Permalink
Merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
rya-sge committed Aug 7, 2023
2 parents ce870ca + a4c660f commit 9f40618
Show file tree
Hide file tree
Showing 67 changed files with 1,200 additions and 560 deletions.
105 changes: 105 additions & 0 deletions FAQ.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# FAQ

This FAQ is intended to developers familiar with smart contracts
development.

## Toolkit support

> Why do you continue using Truffle instead of migrating to HardHat or Foundry?
Regarding [Hardhat](https://hardhat.org/):

- Our tests are not working with Hardhat so to migrate to hardhat, we will have to update our tests which will require a lot of works.
- Moreover, we do not see a use case where hardhat will be better than Truffle.
- Hardhat has a lot of plugins, but for example, for the coverage, we can run the coverage without be fully compatible with Hardhat.

Regarding [Foundry](https://book.getfoundry.sh/):

- The plugin "upgrades plugin" by OpenZeppelin is not available with Foundry and it is a very good tool to check the proxy implementation and perform automatic tests. See [https://docs.openzeppelin.com/upgrades-plugins/1.x/](https://docs.openzeppelin.com/upgrades-plugins/1.x/)
- The tests for the gasless module (MetaTx) would be difficult to write
in Solidity, as Foundry requires, see [https://github.com/CMTA/CMTAT/blob/master/test/common/MetaTxModuleCommon.js](https://github.com/CMTA/CMTAT/blob/master/test/common/MetaTxModuleCommon.js)
- The OpenZeppelin libraries that we use have their tests mainly written in JavaScript, which provides a good basis for our tests
- Performance wise, we observed that Foundry is superior to Truffle, notably to test the Snapshot module
- We have a repository [CMTA/CMTAT-Foundry](https://github.com/CMTA/CMTAT-foundry) that provides experimental support for Foundry, but it does not provide complete support and testing for the latest CMTAT version.


> Do you plan to fully support Foundry in the near future?
For the foreseeable future, we plan to keep Truffle as the main
development and testing suite.

We have not planned to export all the tests from the Truffle suite to
their Solidity version equivalent suitable to Foundry, though some tests
are already available.

The CMTAT-Foundry repository uses CMTAT as a submodule, whose version is
documented in its
[README](https://github.com/CMTA/CMTAT-Foundry/blob/main/README.md#cmtat---using-the-foundry-suite).


> Can Hardhat be used to run tests?
No, please use Truffle to run the tests.


## Modules

> What is the reason the Snapshot module wasn't audited in version v2.3.0?
This module was left out of scope because it is not used yet (and not
included in a default deployment) and will be
subject to changes soon.

> What is the status of [ERC1404](https://erc1404) compatibility?
We have not planned to be fully compatible with ERC1404 (which, in fact,
is only an EIP at the time of writing).
CMTAT includes the two functions defind by ERC1404, namely
`detectTransferRestriction` and `messageForTransferRestriction`.
Thus CMTAT can provide the same functionality as ERC1404.

However, from a pure technical perspective, CMTAT is not fully compliant
with the ERC1404 specification, due the way it inherits the ERC20
interface.

> What is the purpose of the flag parameter in the Base module?
It is just a variable to include some additional information under the form of bit fields.
It is not used inside the code because it is destined to provide more
information on the tokens to the "outside", for example for the token
owners.


> Is the Validation module optional?
Generally, for a CMTAT token, the Validation functionality is optional
from the legal perspective (please contact admin@cmta.ch for detailed
information).

However, in order to use the functions from the Pause and Enforcement
modules, our CMTAT implementation requires the Validation module
Therefore, the Validation module is effectively required *in this
implementation*.

If you remove the Validation module and want to use the Pause or the
Enforcement module, you have to call the functions of modules inside the
main contracts. It was initially the case but we have changed this
behaviour when addressing an issue reported by a security audit.
Here is an old version:
[https://github.com/CMTA/CMTAT/blob/ed23bfc69cfacc932945da751485c6472705c975/contracts/CMTAT.sol#L205](https://github.com/CMTA/CMTAT/blob/ed23bfc69cfacc932945da751485c6472705c975/contracts/CMTAT.sol#L205),
and the relevant Pull [Request](https://github.com/CMTA/CMTAT/pull/153).


## Documentation

> What is the code coverage of the test suite?
A [code coverage report](https://github.com/CMTA/CMTAT/blob/master/doc/general/test/coverage/index.html)
is available.

Normally, you can run the test suite and generate a code coverage report with `npx hardhat coverage`.

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

You will find a summary of all automatic tests in
[test.pdf](https://github.com/CMTA/CMTAT/blob/master/doc/general/test/test.pdf).
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ The CMTAT was developed by a working group of CMTA's Technical Committee that in

The preferred way to receive comments is through the GitHub issue tracker. Private comments and questions can be sent to the CMTA secretariat at <a href="mailto:admin@cmta.ch">admin@cmta.ch</a>. For security matters, please see [SECURITY.md](./SECURITY.MD).

Note that CMTAT may be used in other jurisdictions than Switzerland, and for tokenizing various asset types, beyond equity and debt products.

## Functionality

### Overview
Expand Down Expand Up @@ -147,7 +149,7 @@ The second audit covered version [2.2](https://github.com/CMTA/CMTAT/releases/ta

Version 2.3 contains the different fixes and improvements related to this audit.

The report is available in [ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf](doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf).
The report is available in [ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf](doc/audits/ABDK_CMTA_CMTATRuleEngine_v_1_0/ABDK_CMTA_CMTATRuleEngine_v_1_0.pdf).

### Tools

Expand Down
4 changes: 2 additions & 2 deletions contracts/CMTAT_PROXY.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import "./modules/CMTAT_BASE.sol";

contract CMTAT_PROXY is CMTAT_BASE {
/**
@notice Contract version for the deployment with a proxy
@param forwarderIrrevocable address of the forwarder, required for the gasless support
* @notice Contract version for the deployment with a proxy
* @param forwarderIrrevocable address of the forwarder, required for the gasless support
*/
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(
Expand Down
23 changes: 13 additions & 10 deletions contracts/CMTAT_STANDALONE.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,25 @@ import "./modules/CMTAT_BASE.sol";

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 nameIrrevocable name of the token
@param symbolIrrevocable name of the symbol
@param tokenId name of the tokenId
@param terms terms associated with the token
@param ruleEngine address of the ruleEngine to apply rules to transfers
@param information additional information to describe the token
@param flag add information under the form of bit(0, 1)
* @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 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.
* @param tokenId_ name of the tokenId
* @param terms_ terms associated with the token
* @param ruleEngine_ address of the ruleEngine to apply rules to transfers
* @param information_ additional information to describe the token
* @param flag_ add information under the form of bit(0, 1)
*/
/// @custom:oz-upgrades-unsafe-allow constructor
constructor(
address forwarderIrrevocable,
address admin,
string memory nameIrrevocable,
string memory symbolIrrevocable,
uint8 decimalsIrrevocable,
string memory tokenId_,
string memory terms_,
IEIP1404Wrapper ruleEngine_,
Expand All @@ -35,6 +37,7 @@ contract CMTAT_STANDALONE is CMTAT_BASE {
admin,
nameIrrevocable,
symbolIrrevocable,
decimalsIrrevocable,
tokenId_,
terms_,
ruleEngine_,
Expand Down
40 changes: 26 additions & 14 deletions contracts/modules/CMTAT_BASE.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,24 @@ abstract contract CMTAT_BASE is
CreditEventsModule
{
/**
@notice
initialize the proxy contract
The calls to this function will revert if the contract was deployed without a proxy
* @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 nameIrrevocable name of the token
* @param symbolIrrevocable name of the symbol
* @param decimalsIrrevocable number of decimals of the token, must be 0 to be compliant with Swiss law as per CMTAT specifications (non-zero decimal number may be needed for other use cases)
* @param tokenId_ name of the tokenId
* @param terms_ terms associated with the token
* @param ruleEngine_ address of the ruleEngine to apply rules to transfers
* @param information_ additional information to describe the token
* @param flag_ add information under the form of bit(0, 1)
*/
function initialize(
address admin,
string memory nameIrrevocable,
string memory symbolIrrevocable,
uint8 decimalsIrrevocable,
string memory tokenId_,
string memory terms_,
IEIP1404Wrapper ruleEngine_,
Expand All @@ -60,6 +70,7 @@ abstract contract CMTAT_BASE is
admin,
nameIrrevocable,
symbolIrrevocable,
decimalsIrrevocable,
tokenId_,
terms_,
ruleEngine_,
Expand All @@ -69,12 +80,13 @@ abstract contract CMTAT_BASE is
}

/**
@dev calls the different initialize functions from the different modules
* @dev calls the different initialize functions from the different modules
*/
function __CMTAT_init(
address admin,
string memory nameIrrevocable,
string memory symbolIrrevocable,
uint8 decimalsIrrevocable,
string memory tokenId_,
string memory terms_,
IEIP1404Wrapper ruleEngine_,
Expand Down Expand Up @@ -107,7 +119,7 @@ abstract contract CMTAT_BASE is
__MintModule_init_unchained();
// EnforcementModule_init_unchained is called before ValidationModule_init_unchained due to inheritance
__EnforcementModule_init_unchained();
__ERC20Module_init_unchained(0);
__ERC20Module_init_unchained(decimalsIrrevocable);
// PauseModule_init_unchained is called before ValidationModule_init_unchained due to inheritance
__PauseModule_init_unchained();
__ValidationModule_init_unchained();
Expand All @@ -132,7 +144,7 @@ abstract contract CMTAT_BASE is
}

/**
@notice Returns the number of decimals used to get its user representation.
* @notice Returns the number of decimals used to get its user representation.
*/
function decimals()
public
Expand All @@ -157,12 +169,12 @@ abstract contract CMTAT_BASE is
return ERC20BaseModule.transferFrom(sender, recipient, amount);
}

/*
@dev
SnapshotModule:
- override SnapshotModuleInternal if you add the SnapshotModule
e.g. override(SnapshotModuleInternal, ERC20Upgradeable)
- remove the keyword view
/**
* @dev
* SnapshotModule:
* - override SnapshotModuleInternal if you add the SnapshotModule
* e.g. override(SnapshotModuleInternal, ERC20Upgradeable)
* - remove the keyword view
*/
function _beforeTokenTransfer(
address from,
Expand All @@ -179,7 +191,7 @@ abstract contract CMTAT_BASE is
}

/**
@dev This surcharge is not necessary if you do not use the MetaTxModule
* @dev This surcharge is not necessary if you do not use the MetaTxModule
*/
function _msgSender()
internal
Expand All @@ -191,7 +203,7 @@ abstract contract CMTAT_BASE is
}

/**
@dev This surcharge is not necessary if you do not use the MetaTxModule
* @dev This surcharge is not necessary if you do not use the MetaTxModule
*/
function _msgData()
internal
Expand Down
58 changes: 52 additions & 6 deletions contracts/modules/wrapper/mandatory/BurnModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import "../../../../openzeppelin-contracts-upgradeable/contracts/proxy/utils/Ini
import "../../security/AuthorizationModule.sol";

abstract contract BurnModule is ERC20Upgradeable, AuthorizationModule {
event Burn(address indexed owner, uint256 amount, string reason);
/**
* @notice Emitted when the specified `value` amount of tokens owned by `owner`are destroyed with the given `reason`
*/
event Burn(address indexed owner, uint256 value, string reason);

function __BurnModule_init(
string memory name_,
Expand Down Expand Up @@ -35,17 +38,60 @@ abstract contract BurnModule is ERC20Upgradeable, AuthorizationModule {
}

/**
* @dev Destroys `amount` tokens from `account`
*
* @notice Destroys a `value` amount of tokens from `account`, by transferring it to address(0).
* @dev
* See {ERC20-_burn}
* Emits a {Burn} event
* Emits a {Transfer} event with `to` set to the zero address (emits inside _burn).
* Requirements:
* - the caller must have the `BURNER_ROLE`.
*/
function forceBurn(
address account,
uint256 amount,
uint256 value,
string memory reason
) public onlyRole(BURNER_ROLE) {
_burn(account, amount);
emit Burn(account, amount, reason);
_burn(account, value);
emit Burn(account, value, reason);
}

/**
*
* @notice batch version of {forceBurn}.
* @dev
* See {ERC20-_burn} and {OpenZeppelin ERC1155_burnBatch}.
*
* For each burn action:
* -Emits a {Burn} event
* -Emits a {Transfer} event with `to` set to the zero address (emits inside _burn).
* The burn `reason`is the same for all `accounts` which tokens are burnt.
* Requirements:
* - `accounts` and `values` must have the same length
* - the caller must have the `BURNER_ROLE`.
*/
function forceBurnBatch(
address[] calldata accounts,
uint256[] calldata values,
string memory reason
) public onlyRole(BURNER_ROLE) {
require(
accounts.length > 0,
"CMTAT: accounts is empty"
);
// We do not check that values is not empty since
// this require will throw an error in this case.
require(
accounts.length == values.length,
"CMTAT: accounts and values length mismatch"
);

for (uint256 i = 0; i < accounts.length; ) {
_burn(accounts[i], values[i]);
emit Burn(accounts[i], values[i], reason);
unchecked {
++i;
}
}
}

uint256[50] private __gap;
Expand Down
Loading

0 comments on commit 9f40618

Please sign in to comment.