Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
dovgopoly committed Mar 4, 2024
1 parent 97a2d11 commit 87e7c2a
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 96 deletions.
4 changes: 4 additions & 0 deletions contracts/TokenF.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
93 changes: 42 additions & 51 deletions contracts/kyc/modules/AbstractKYCModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,91 +10,82 @@ 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);
_;
}

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"
);
}
}
}

function _KYCModuleRole() internal view virtual returns (bytes32) {
return IAgentAccessControl(_tokenF).getAgentRole();
}

uint256[47] private _gap;
uint256[48] private _gap;
}
30 changes: 25 additions & 5 deletions contracts/kyc/modules/RarimoModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) {
Expand Down
40 changes: 1 addition & 39 deletions contracts/regulatory/modules/AbstractRegulatoryModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
9 changes: 8 additions & 1 deletion contracts/regulatory/modules/TransferLimitsModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 87e7c2a

Please sign in to comment.