Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

ERC-3643 interfaces management #223

Merged
merged 2 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 4 additions & 12 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,11 @@ All notable changes to this project will be documented in this file.

- **ERC-165 Interface Implementation**:
- Implemented ERC-165 support across all major contracts in the suite, allowing them to explicitly declare the interfaces they support. This enhancement improves interoperability and makes it easier for external contracts and tools to interact with T-REX contracts.
- ERC-165 support was added to the following contracts:
- `Token`
- `IdentityRegistry`
- `IdentityRegistryStorage`
- `TrustedIssuersRegistry`
- `ClaimTopicsRegistry`
- `TREXGateway`
- `DVATransferManager`
- `ModularCompliance`
- Compliance Modules (e.g., `CountryAllowModule`, `TransferRestrictModule`)
- `TREXImplementationAuthority`
- `IAFactory`
- Each contract now implements the `supportsInterface` function to identify the supported interfaces, ensuring compliance with ERC-165 standards.
- In addition to implementing ERC-165, the ERC-3643 interfaces were organized into a new directory, with each interface inheriting from the original ERC-3643 standard interface. This setup allows for future expansion and maintains uniformity across the suite:
- `IERC3643`, `IERC3643IdentityRegistry`, `IERC3643Compliance`, `IERC3643ClaimTopicsRegistry`, `IERC3643TrustedIssuersRegistry`, `IERC3643IdentityRegistryStorage`
- For contracts that extend the ERC-3643 standard with new functions, `supportsInterface` now checks for both the new interface ID and the original ERC-3643 interface ID.
- For interfaces that did not change, `supportsInterface` checks for the ERC-3643 interface ID directly, omitting the empty version-specific interface to avoid redundancy.

- **Add and Set Module in a Single Transaction**:
- Introduced the `addAndSetModule` function in the `ModularCompliance` contract, allowing the contract owner to add a new compliance module and interact with it in a single transaction.
Expand Down
16 changes: 6 additions & 10 deletions contracts/DVD/DVDTransferManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ import "../roles/AgentRole.sol";
import "../token/IToken.sol";
import "../errors/CommonErrors.sol";
import "../errors/InvalidArgumentErrors.sol";
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";


/// events

Expand Down Expand Up @@ -388,20 +390,14 @@ contract DVDTransferManager is Ownable {
}

/**
* @dev check if `_token` corresponds to a functional TREX token (with identity registry initiated)
* @dev check if `_token` corresponds to a TREX token
* @param _token the address token to check
* the function will try to call `identityRegistry()` on
* the address, which is a getter specific to TREX tokens
* if the call pass and returns an address it means that
* the token is a TREX, otherwise it's not a TREX
* the function will check if the address implements IERC3643
* return `true` if the token is a TREX, `false` otherwise
*/
function isTREX(address _token) public view returns (bool) {
try IToken(_token).identityRegistry() returns (IIdentityRegistry _ir) {
if (address(_ir) != address(0)) {
return true;
}
return false;
try IERC165(_token).supportsInterface(type(IERC3643).interfaceId) returns (bool _trex) {
return _trex;
}
catch {
return false;
Expand Down
470 changes: 470 additions & 0 deletions contracts/ERC-3643/IERC3643.sol

Large diffs are not rendered by default.

74 changes: 74 additions & 0 deletions contracts/ERC-3643/IERC3643ClaimTopicsRegistry.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: CC0-1.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
pragma solidity 0.8.26;

/// Events

/// @dev This event is emitted when a claim topic has been added to the ClaimTopicsRegistry.
/// @param _claimTopic is the required claim added to the Claim Topics Registry.
event ClaimTopicAdded(uint256 indexed _claimTopic);

/// @dev This event is emitted when a claim topic has been removed from the ClaimTopicsRegistry.
/// @param _claimTopic is the required claim removed from the Claim Topics Registry.
event ClaimTopicRemoved(uint256 indexed _claimTopic);

interface IERC3643ClaimTopicsRegistry {
/**
* @dev Add a trusted claim topic (For example: KYC=1, AML=2).
* Only owner can call.
* emits `ClaimTopicAdded` event
* cannot add more than 15 topics for 1 token as adding more could create gas issues
* @param _claimTopic The claim topic index
*/
function addClaimTopic(uint256 _claimTopic) external;

/**
* @dev Remove a trusted claim topic (For example: KYC=1, AML=2).
* Only owner can call.
* emits `ClaimTopicRemoved` event
* @param _claimTopic The claim topic index
*/
function removeClaimTopic(uint256 _claimTopic) external;

/**
* @dev Get the trusted claim topics for the security token
* @return Array of trusted claim topics
*/
function getClaimTopics() external view returns (uint256[] memory);
}
150 changes: 150 additions & 0 deletions contracts/ERC-3643/IERC3643Compliance.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// SPDX-License-Identifier: CC0-1.0
//
// :+#####%%%%%%%%%%%%%%+
// .-*@@@%+.:+%@@@@@%%#***%@@%=
// :=*%@@@#=. :#@@% *@@@%=
// .-+*%@%*-.:+%@@@@@@+. -*+: .=#. :%@@@%-
// :=*@@@@%%@@@@@@@@@%@@@- .=#@@@%@%= =@@@@#.
// -=+#%@@%#*=:. :%@@@@%. -*@@#*@@@@@@@#=:- *@@@@+
// =@@%=:. :=: *@@@@@%#- =%*%@@@@#+-. =+ :%@@@%-
// -@@%. .+@@@ =+=-. @@#- +@@@%- =@@@@%:
// :@@@. .+@@#%: : .=*=-::.-%@@@+*@@= +@@@@#.
// %@@: +@%%* =%@@@@@@@@@@@#. .*@%- +@@@@*.
// #@@= .+@@@@%:=*@@@@@- :%@%: .*@@@@+
// *@@* +@@@#-@@%-:%@@* +@@#. :%@@@@-
// -@@% .:-=++*##%%%@@@@@@@@@@@@*. :@+.@@@%: .#@@+ =@@@@#:
// .@@@*-+*#%%%@@@@@@@@@@@@@@@@%%#**@@%@@@. *@=*@@# :#@%= .#@@@@#-
// -%@@@@@@@@@@@@@@@*+==-:-@@@= *@# .#@*-=*@@@@%= -%@@@* =@@@@@%-
// -+%@@@#. %@%%= -@@:+@: -@@* *@@*-:: -%@@%=. .*@@@@@#
// *@@@* +@* *@@##@@- #@*@@+ -@@= . :+@@@#: .-+@@@%+-
// +@@@%*@@:..=@@@@* .@@@* .#@#. .=+- .=%@@@*. :+#@@@@*=:
// =@@@@%@@@@@@@@@@@@@@@@@@@@@@%- :+#*. :*@@@%=. .=#@@@@%+:
// .%@@= ..... .=#@@+. .#@@@*: -*%@@@@%+.
// +@@#+===---:::... .=%@@*- +@@@+. -*@@@@@%+.
// -@@@@@@@@@@@@@@@@@@@@@@%@@@@= -@@@+ -#@@@@@#=.
// ..:::---===+++***###%%%@@@#- .#@@+ -*@@@@@#=.
// @@@@@@+. +@@*. .+@@@@@%=.
// -@@@@@= =@@%: -#@@@@%+.
// +@@@@@. =@@@= .+@@@@@*:
// #@@@@#:%@@#. :*@@@@#-
// @@@@@%@@@= :#@@@@+.
// :@@@@@@@#.:#@@@%-
// +@@@@@@-.*@@@*:
// #@@@@#.=@@@+.
// @@@@+-%@%=
// :@@@#%@%=
// +@@@@%-
// :#%%=
//
pragma solidity 0.8.26;

/// Events

/// @dev This event is emitted when a token has been bound to the compliance contract.
/// @param _token is the address of the token to bind.
event TokenBound(address _token);

/// @dev This event is emitted when a token has been unbound from the compliance contract.
/// @param _token is the address of the token to unbind.
event TokenUnbound(address _token);

interface IERC3643Compliance {


/// Functions

/// initialization of the compliance contract

/**
* @dev binds a token to the compliance contract
* @param _token address of the token to bind
* This function can be called ONLY by the owner of the compliance contract
* Emits a TokenBound event
*/
function bindToken(address _token) external;

/**
* @dev unbinds a token from the compliance contract
* @param _token address of the token to unbind
* This function can be called ONLY by the owner of the compliance contract
* Emits a TokenUnbound event
*/
function unbindToken(address _token) external;



// compliance check and state update
/**
* @dev function called whenever tokens are transferred
* from one wallet to another
* this function can update state variables in the modules bound to the compliance
* these state variables being used by the module checks to decide if a transfer
* is compliant or not depending on the values stored in these state variables and on
* the parameters of the modules
* This function can be called ONLY by the token contract bound to the compliance
* @param _from The address of the sender
* @param _to The address of the receiver
* @param _amount The amount of tokens involved in the transfer
* This function calls moduleTransferAction() on each module bound to the compliance contract
*/
function transferred(
address _from,
address _to,
uint256 _amount
) external;

/**
* @dev function called whenever tokens are created on a wallet
* this function can update state variables in the modules bound to the compliance
* these state variables being used by the module checks to decide if a transfer
* is compliant or not depending on the values stored in these state variables and on
* the parameters of the modules
* This function can be called ONLY by the token contract bound to the compliance
* @param _to The address of the receiver
* @param _amount The amount of tokens involved in the minting
* This function calls moduleMintAction() on each module bound to the compliance contract
*/
function created(address _to, uint256 _amount) external;

/**
* @dev function called whenever tokens are destroyed from a wallet
* this function can update state variables in the modules bound to the compliance
* these state variables being used by the module checks to decide if a transfer
* is compliant or not depending on the values stored in these state variables and on
* the parameters of the modules
* This function can be called ONLY by the token contract bound to the compliance
* @param _from The address on which tokens are burnt
* @param _amount The amount of tokens involved in the burn
* This function calls moduleBurnAction() on each module bound to the compliance contract
*/
function destroyed(address _from, uint256 _amount) external;

/**
* @dev checks that the transfer is compliant.
* default compliance always returns true
* READ ONLY FUNCTION, this function cannot be used to increment
* counters, emit events, ...
* @param _from The address of the sender
* @param _to The address of the receiver
* @param _amount The amount of tokens involved in the transfer
* This function will call moduleCheck() on every module bound to the compliance
* If each of the module checks return TRUE, this function will return TRUE as well
* returns FALSE otherwise
*/
function canTransfer(
address _from,
address _to,
uint256 _amount
) external view returns (bool);

/// check the parameters of the compliance contract

function isTokenBound(address _token) external view returns (bool);

/**
* @dev getter for the address of the token bound
* returns the address of the token
*/
function getTokenBound() external view returns (address);

}
Loading
Loading