From 87e7c2ab64b30db4d8782de9985da9c730fd6497 Mon Sep 17 00:00:00 2001 From: dovgopoly Date: Mon, 4 Mar 2024 16:52:01 +0200 Subject: [PATCH] fixes --- contracts/TokenF.sol | 4 + contracts/kyc/modules/AbstractKYCModule.sol | 93 +++++++++---------- contracts/kyc/modules/RarimoModule.sol | 30 +++++- .../modules/AbstractRegulatoryModule.sol | 40 +------- .../modules/TransferLimitsModule.sol | 9 +- 5 files changed, 80 insertions(+), 96 deletions(-) diff --git a/contracts/TokenF.sol b/contracts/TokenF.sol index d3b0967..af62b72 100644 --- a/contracts/TokenF.sol +++ b/contracts/TokenF.sol @@ -16,6 +16,10 @@ abstract contract TokenF is Diamond, DiamondERC20, AgentAccessControl { bytes4 public constant FORCED_TRANSFER_SELECTOR = this.forcedTransfer.selector; bytes4 public constant RECOVERY_SELECTOR = this.recovery.selector; + uint8 public constant TRANSFER_SENDER = 1; + uint8 public constant TRANSFER_RECIPIENT = 2; + uint8 public constant TRANSFER_OPERATOR = 3; + function transfer(address to_, uint256 amount_) public virtual override returns (bool) { _canTransfer(msg.sender, to_, amount_, address(0)); _isKYCed(msg.sender, to_, amount_, address(0)); diff --git a/contracts/kyc/modules/AbstractKYCModule.sol b/contracts/kyc/modules/AbstractKYCModule.sol index c500e13..4ec32c4 100644 --- a/contracts/kyc/modules/AbstractKYCModule.sol +++ b/contracts/kyc/modules/AbstractKYCModule.sol @@ -10,6 +10,12 @@ import {IKYCModule} from "../../interfaces/IKYCModule.sol"; abstract contract AbstractKYCModule is IKYCModule, Initializable { using EnumerableSet for EnumerableSet.Bytes32Set; + struct ClaimTopicsParams { + bytes4 selector; + uint8 transferRole; + bytes32[] claimTopics; + } + modifier onlyRole(bytes32 role_) { IAgentAccessControl(_tokenF).checkRole(role_, msg.sender); _; @@ -17,78 +23,63 @@ abstract contract AbstractKYCModule is IKYCModule, Initializable { address private _tokenF; - mapping(bytes4 => bool) private _bypassedSelectors; - EnumerableSet.Bytes32Set private _claimTopics; + mapping(bytes4 => mapping(uint8 => EnumerableSet.Bytes32Set)) private _claimTopics; function __AbstractKYCModule_init(address tokenF_) internal onlyInitializing { _tokenF = tokenF_; } - function addBypassedSelectors( - bytes4[] memory selectors_ - ) public virtual onlyRole(_KYCModuleRole()) { - _addBypassedSelectors(selectors_); - } - - function removeBypassedSelectors( - bytes4[] memory selectors_ - ) public virtual onlyRole(_KYCModuleRole()) { - _removeBypassedSelectors(selectors_); - } - function addClaimTopics( - bytes32[] memory claimTopics_ + ClaimTopicsParams[] memory requests_ ) public virtual onlyRole(_KYCModuleRole()) { - _addClaimTopics(claimTopics_); + _addClaimTopics(requests_); } function removeClaimTopics( - bytes32[] memory claimTopics_ + ClaimTopicsParams[] memory requests_ ) public virtual onlyRole(_KYCModuleRole()) { - _removeClaimTopics(claimTopics_); - } - - function isBypassedSelector(bytes4 selector_) public view virtual returns (bool) { - return _bypassedSelectors[selector_]; + _removeClaimTopics(requests_); } - function getClaimTopics() public view virtual returns (bytes32[] memory) { - return _claimTopics.values(); + function getClaimTopics( + bytes4 selector_, + uint8 transferRole_, + bytes memory + ) public view virtual returns (bytes32[] memory) { + return _claimTopics[selector_][transferRole_].values(); } function getTokenF() public view virtual override returns (address) { return _tokenF; } - function _addBypassedSelectors(bytes4[] memory selectors_) internal virtual { - for (uint256 i = 0; i < selectors_.length; ++i) { - bytes4 selector_ = selectors_[i]; - - require(!_bypassedSelectors[selector_], "KYCModule: selector is bypassed"); - - _bypassedSelectors[selector_] = true; - } - } - - function _removeBypassedSelectors(bytes4[] memory selectors_) internal virtual { - for (uint256 i = 0; i < selectors_.length; ++i) { - bytes4 selector_ = selectors_[i]; - - require(_bypassedSelectors[selector_], "KYCModule: selector is not bypassed"); - - delete _bypassedSelectors[selector_]; - } - } - - function _addClaimTopics(bytes32[] memory claimTopics_) internal virtual { - for (uint256 i = 0; i < claimTopics_.length; ++i) { - require(_claimTopics.add(claimTopics_[i]), "KYCModule: claim topic exists"); + function _addClaimTopics(ClaimTopicsParams[] memory requests_) internal virtual { + for (uint256 i = 0; i < requests_.length; ++i) { + ClaimTopicsParams memory request_ = requests_[i]; + + for (uint256 j = 0; j < request_.claimTopics.length; ++j) { + require( + _claimTopics[request_.selector][request_.transferRole].add( + request_.claimTopics[j] + ), + "KYCModule: claim topic exists" + ); + } } } - function _removeClaimTopics(bytes32[] memory claimTopics_) internal virtual { - for (uint256 i = 0; i < claimTopics_.length; ++i) { - require(_claimTopics.remove(claimTopics_[i]), "KYCModule: claim topic doesn't exist"); + function _removeClaimTopics(ClaimTopicsParams[] memory requests_) internal virtual { + for (uint256 i = 0; i < requests_.length; ++i) { + ClaimTopicsParams memory request_ = requests_[i]; + + for (uint256 j = 0; j < request_.claimTopics.length; ++j) { + require( + _claimTopics[request_.selector][request_.transferRole].remove( + request_.claimTopics[j] + ), + "KYCModule: claim topic doesn't exist" + ); + } } } @@ -96,5 +87,5 @@ abstract contract AbstractKYCModule is IKYCModule, Initializable { return IAgentAccessControl(_tokenF).getAgentRole(); } - uint256[47] private _gap; + uint256[48] private _gap; } diff --git a/contracts/kyc/modules/RarimoModule.sol b/contracts/kyc/modules/RarimoModule.sol index dbfff29..9fd95a6 100644 --- a/contracts/kyc/modules/RarimoModule.sol +++ b/contracts/kyc/modules/RarimoModule.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.20; import {ISBT} from "@solarity/solidity-lib/interfaces/tokens/ISBT.sol"; import {AbstractKYCModule} from "./AbstractKYCModule.sol"; +import {TokenF} from "../../TokenF.sol"; abstract contract RarimoModule is AbstractKYCModule { address private _sbt; @@ -14,17 +15,36 @@ abstract contract RarimoModule is AbstractKYCModule { function isKYCed( bytes4 selector_, - address, + address from_, address to_, uint256, - address, + address operator_, bytes memory ) public view virtual override returns (bool) { - if (isBypassedSelector(selector_)) { - return true; + TokenF tokenF_ = TokenF(payable(getTokenF())); + + if ( + from_ != address(0) && + !_isKYCed(from_, getClaimTopics(selector_, tokenF_.TRANSFER_SENDER(), "")) + ) { + return false; + } + + if ( + to_ != address(0) && + !_isKYCed(from_, getClaimTopics(selector_, tokenF_.TRANSFER_RECIPIENT(), "")) + ) { + return false; + } + + if ( + operator_ != address(0) && + !_isKYCed(operator_, getClaimTopics(selector_, tokenF_.TRANSFER_OPERATOR(), "")) + ) { + return false; } - return _isKYCed(to_, getClaimTopics()); + return true; } function getSBT() public view virtual returns (address) { diff --git a/contracts/regulatory/modules/AbstractRegulatoryModule.sol b/contracts/regulatory/modules/AbstractRegulatoryModule.sol index c81fcd8..552edc3 100644 --- a/contracts/regulatory/modules/AbstractRegulatoryModule.sol +++ b/contracts/regulatory/modules/AbstractRegulatoryModule.sol @@ -14,55 +14,17 @@ abstract contract AbstractRegulatoryModule is IRegulatoryModule, Initializable { address private _tokenF; - mapping(bytes4 => bool) private _bypassedSelectors; - function __AbstractRegulatoryModule_init(address tokenF_) internal onlyInitializing { _tokenF = tokenF_; } - function addBypassedSelectors( - bytes4[] memory selectors_ - ) public virtual onlyRole(_RModuleRole()) { - _addBypassedSelectors(selectors_); - } - - function removeBypassedSelectors( - bytes4[] memory selectors_ - ) public virtual onlyRole(_RModuleRole()) { - _removeBypassedSelectors(selectors_); - } - - function isBypassedSelector(bytes4 selector_) public view virtual returns (bool) { - return _bypassedSelectors[selector_]; - } - function getTokenF() public view virtual override returns (address) { return _tokenF; } - function _addBypassedSelectors(bytes4[] memory selectors_) internal virtual { - for (uint256 i = 0; i < selectors_.length; ++i) { - bytes4 selector_ = selectors_[i]; - - require(!_bypassedSelectors[selector_], "RModule: selector is bypassed"); - - _bypassedSelectors[selector_] = true; - } - } - - function _removeBypassedSelectors(bytes4[] memory selectors_) internal virtual { - for (uint256 i = 0; i < selectors_.length; ++i) { - bytes4 selector_ = selectors_[i]; - - require(_bypassedSelectors[selector_], "RModule: selector is not bypassed"); - - delete _bypassedSelectors[selector_]; - } - } - function _RModuleRole() internal view virtual returns (bytes32) { return IAgentAccessControl(_tokenF).getAgentRole(); } - uint256[48] private _gap; + uint256[49] private _gap; } diff --git a/contracts/regulatory/modules/TransferLimitsModule.sol b/contracts/regulatory/modules/TransferLimitsModule.sol index db90891..52a928f 100644 --- a/contracts/regulatory/modules/TransferLimitsModule.sol +++ b/contracts/regulatory/modules/TransferLimitsModule.sol @@ -4,6 +4,7 @@ pragma solidity ^0.8.20; import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import {AbstractRegulatoryModule} from "./AbstractRegulatoryModule.sol"; +import {TokenF} from "../../TokenF.sol"; abstract contract TransferLimitsModule is AbstractRegulatoryModule { uint256 public constant MAX_TRANSFER_LIMIT = type(uint256).max; @@ -48,7 +49,13 @@ abstract contract TransferLimitsModule is AbstractRegulatoryModule { address, bytes memory ) public view virtual override returns (bool) { - if (isBypassedSelector(selector_)) { + TokenF tokenF_ = TokenF(payable(getTokenF())); + + if ( + selector_ == tokenF_.BURN_SELECTOR() || + selector_ == tokenF_.FORCED_TRANSFER_SELECTOR() || + selector_ == tokenF_.RECOVERY_SELECTOR() + ) { return true; }