Skip to content
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
22 changes: 17 additions & 5 deletions contracts/core/KYCCompliance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ pragma solidity ^0.8.21;

import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {SetHelper} from "@solarity/solidity-lib/libs/arrays/SetHelper.sol";

import {IKYCCompliance} from "../interfaces/core/IKYCCompliance.sol";

import {IAssetF} from "../interfaces/IAssetF.sol";
Expand All @@ -22,7 +20,9 @@ import {AbstractKYCModule} from "../modules/AbstractKYCModule.sol";
*/
abstract contract KYCCompliance is IKYCCompliance, KYCComplianceStorage, AgentAccessControl {
using EnumerableSet for EnumerableSet.AddressSet;
using SetHelper for EnumerableSet.AddressSet;

error FailedToAddKYCModule(address kycModule);
error FailedToRemoveKYCModule(address kycModule);

function __KYCCompliance_init() internal onlyInitializing {}

Expand Down Expand Up @@ -54,11 +54,23 @@ abstract contract KYCCompliance is IKYCCompliance, KYCComplianceStorage, AgentAc
}

function _addKYCModules(address[] memory kycModules_) internal virtual {
_getKYCComplianceStorage().kycModules.strictAdd(kycModules_);
KYCCStorage storage $ = _getKYCComplianceStorage();

uint256 length_ = kycModules_.length;
for (uint256 i = 0; i < length_; ++i) {
address kycModule_ = kycModules_[i];
require($.kycModules.add(kycModule_), FailedToAddKYCModule(kycModule_));
}
}

function _removeKYCModules(address[] memory kycModules_) internal virtual {
_getKYCComplianceStorage().kycModules.strictRemove(kycModules_);
KYCCStorage storage $ = _getKYCComplianceStorage();

uint256 length_ = kycModules_.length;
for (uint256 i = 0; i < length_; ++i) {
address kycModule_ = kycModules_[i];
require($.kycModules.remove(kycModule_), FailedToRemoveKYCModule(kycModule_));
}
}

function _KYCComplianceRole() internal view virtual returns (bytes32) {
Expand Down
28 changes: 23 additions & 5 deletions contracts/core/RegulatoryCompliance.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ pragma solidity ^0.8.21;

import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {SetHelper} from "@solarity/solidity-lib/libs/arrays/SetHelper.sol";

import {IRegulatoryCompliance} from "../interfaces/core/IRegulatoryCompliance.sol";

import {IAssetF} from "../interfaces/IAssetF.sol";
Expand All @@ -26,7 +24,9 @@ abstract contract RegulatoryCompliance is
AgentAccessControl
{
using EnumerableSet for EnumerableSet.AddressSet;
using SetHelper for EnumerableSet.AddressSet;

error FailedToAddRegulatoryModule(address regulatoryModule);
error FailedToRemoveRegulatoryModule(address regulatoryModule);

modifier onlyThisContract() {
require(msg.sender == address(this), SenderIsNotThisContract(msg.sender));
Expand Down Expand Up @@ -72,11 +72,29 @@ abstract contract RegulatoryCompliance is
}

function _addRegulatoryModules(address[] memory regulatoryModules_) internal virtual {
_getRegulatoryComplianceStorage().regulatoryModules.strictAdd(regulatoryModules_);
RCStorage storage $ = _getRegulatoryComplianceStorage();

uint256 length_ = regulatoryModules_.length;
for (uint256 i = 0; i < length_; ++i) {
address regulatoryModule_ = regulatoryModules_[i];
require(
$.regulatoryModules.add(regulatoryModule_),
FailedToAddRegulatoryModule(regulatoryModule_)
);
}
}

function _removeRegulatoryModules(address[] memory regulatoryModules_) internal virtual {
_getRegulatoryComplianceStorage().regulatoryModules.strictRemove(regulatoryModules_);
RCStorage storage $ = _getRegulatoryComplianceStorage();

uint256 length_ = regulatoryModules_.length;
for (uint256 i = 0; i < length_; ++i) {
address regulatoryModule_ = regulatoryModules_[i];
require(
$.regulatoryModules.remove(regulatoryModule_),
FailedToRemoveRegulatoryModule(regulatoryModule_)
);
}
}

function _regulatoryComplianceRole() internal view virtual returns (bytes32) {
Expand Down
23 changes: 18 additions & 5 deletions contracts/modules/AbstractModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ pragma solidity ^0.8.21;
import {Initializable} from "@openzeppelin/contracts/proxy/utils/Initializable.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";

import {SetHelper} from "@solarity/solidity-lib/libs/arrays/SetHelper.sol";

import {IAgentAccessControl} from "../interfaces/core/IAgentAccessControl.sol";

import {IAssetF} from "../interfaces/IAssetF.sol";
Expand All @@ -20,7 +18,6 @@ import {IAssetF} from "../interfaces/IAssetF.sol";
*/
abstract contract AbstractModule is Initializable {
using EnumerableSet for EnumerableSet.Bytes32Set;
using SetHelper for EnumerableSet.Bytes32Set;

// keccak256("tokenf.standard.abstract.module.storage")
bytes32 private constant ABSTRACT_MODULE_STORAGE =
Expand All @@ -43,6 +40,8 @@ abstract contract AbstractModule is Initializable {
}

error HandlerNotSet();
error FailedToAddHandlerTopic(bytes32 handlerTopic);
error FailedToRemoveHandlerTopic(bytes32 handlerTopic);

function __AbstractModule_init(address assetF_) internal onlyInitializing {
AbstractModuleStorage storage $ = _getAbstractModuleStorage();
Expand Down Expand Up @@ -140,7 +139,14 @@ abstract contract AbstractModule is Initializable {
) internal virtual {
AbstractModuleStorage storage $ = _getAbstractModuleStorage();

$.handlerTopics[contextKey_].strictAdd(handlerTopics_);
uint256 length_ = handlerTopics_.length;
for (uint256 i = 0; i < length_; ++i) {
bytes32 handlerTopic_ = handlerTopics_[i];
require(
$.handlerTopics[contextKey_].add(handlerTopic_),
FailedToAddHandlerTopic(handlerTopic_)
);
}
}

/**
Expand All @@ -158,7 +164,14 @@ abstract contract AbstractModule is Initializable {
) internal virtual {
AbstractModuleStorage storage $ = _getAbstractModuleStorage();

$.handlerTopics[contextKey_].strictRemove(handlerTopics_);
uint256 length_ = handlerTopics_.length;
for (uint256 i = 0; i < length_; ++i) {
bytes32 handlerTopic_ = handlerTopics_[i];
require(
$.handlerTopics[contextKey_].remove(handlerTopic_),
FailedToRemoveHandlerTopic(handlerTopic_)
);
}
}

/**
Expand Down
100 changes: 13 additions & 87 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@tokenf/contracts",
"version": "0.4.0",
"version": "0.4.1",
"license": "MIT",
"author": "Distributed Lab",
"description": "On-chain Real World Assets Tokenization Framework",
Expand Down Expand Up @@ -40,7 +40,7 @@
"dependencies": {
"@openzeppelin/contracts": "5.3.0",
"@openzeppelin/contracts-upgradeable": "5.3.0",
"@solarity/solidity-lib": "3.1.4"
"@solarity/solidity-lib": "3.2.8"
},
"devDependencies": {
"@metamask/eth-sig-util": "^8.2.0",
Expand Down
4 changes: 2 additions & 2 deletions test/core/KYCCompliance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe("KYCCompliance", () => {

it("should not add KYC modules if duplicates", async () => {
await expect(kycComplianceProxy.connect(agent).addKYCModules([kycCorrect, kycCorrect]))
.to.be.revertedWithCustomError(kycComplianceProxy, "ElementAlreadyExistsAddress")
.to.be.revertedWithCustomError(kycComplianceProxy, "FailedToAddKYCModule")
.withArgs(kycCorrect);
});

Expand All @@ -113,7 +113,7 @@ describe("KYCCompliance", () => {

it("should not remove KYC modules if no module", async () => {
await expect(kycComplianceProxy.connect(agent).removeKYCModules([kycCorrect]))
.to.be.revertedWithCustomError(kycComplianceProxy, "NoSuchAddress")
.to.be.revertedWithCustomError(kycComplianceProxy, "FailedToRemoveKYCModule")
.withArgs(kycCorrect);
});

Expand Down
4 changes: 2 additions & 2 deletions test/core/RegulatoryCompliance.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ describe("RegulatoryCompliance", () => {

it("should not add regulatory modules if duplicates", async () => {
await expect(rComplianceProxy.connect(agent).addRegulatoryModules([rCorrect, rCorrect]))
.to.be.revertedWithCustomError(rComplianceProxy, "ElementAlreadyExistsAddress")
.to.be.revertedWithCustomError(rComplianceProxy, "FailedToAddRegulatoryModule")
.withArgs(rCorrect);
});

Expand All @@ -123,7 +123,7 @@ describe("RegulatoryCompliance", () => {

it("should not remove regulatory modules if no module", async () => {
await expect(rComplianceProxy.connect(agent).removeRegulatoryModules([rCorrect]))
.to.be.revertedWithCustomError(rComplianceProxy, "NoSuchAddress")
.to.be.revertedWithCustomError(rComplianceProxy, "FailedToRemoveRegulatoryModule")
.withArgs(rCorrect);
});

Expand Down
4 changes: 2 additions & 2 deletions test/modules/AbstractModules.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ describe("AbstractModules", () => {

it("should not add handler topics if duplicates", async () => {
await expect(module.connect(agent).addHandlerTopics(ZERO_BYTES32, [ZERO_BYTES32, ZERO_BYTES32]))
.to.be.revertedWithCustomError(module, "ElementAlreadyExistsBytes32")
.to.be.revertedWithCustomError(module, "FailedToAddHandlerTopic")
.withArgs(ZERO_BYTES32);
});

Expand All @@ -148,7 +148,7 @@ describe("AbstractModules", () => {

it("should not remove handler topics if no handler topic", async () => {
await expect(module.connect(agent).removeHandlerTopics(ZERO_BYTES32, [ZERO_BYTES32]))
.to.be.revertedWithCustomError(module, "NoSuchBytes32")
.to.be.revertedWithCustomError(module, "FailedToRemoveHandlerTopic")
.withArgs(ZERO_BYTES32);
});

Expand Down