diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7de80a8..9cb1742 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,10 @@ Please follow [https://changelog.md/](https://changelog.md/) conventions.
- Update surya doc by running the 3 scripts in [./doc/script](./doc/script)
- Update changelog
+## v2.0.5
+
+- Fix a bug present in the Conditional Transfer rule and improve the corresponding tests.
+
## v2.0.4
- Fix a bug present in the Conditional Transfer rule and the corresponding test.
diff --git a/doc/coverage/coverage/index-sort-b.html b/doc/coverage/coverage/index-sort-b.html
index 48c5eac..79c22e9 100644
--- a/doc/coverage/coverage/index-sort-b.html
+++ b/doc/coverage/coverage/index-sort-b.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -94,7 +94,7 @@
0 / 2
- test/RuleConditionalTransfer
+ test/RuleConditionalTransfer/utils
@@ -165,18 +165,6 @@
100.0 %
12 / 12
-
- src/rules/operation
-
-
-
- 99.0 %
- 96 / 97
- 94.4 %
- 17 / 18
- 100.0 %
- 29 / 29
-
src/rules/operation/abstract
@@ -201,6 +189,18 @@
100.0 %
32 / 32
+
+ src/rules/operation
+
+
+
+ 99.1 %
+ 105 / 106
+ 94.4 %
+ 17 / 18
+ 100.0 %
+ 33 / 33
+
diff --git a/doc/coverage/coverage/index-sort-f.html b/doc/coverage/coverage/index-sort-f.html
index 7596014..4c104bd 100644
--- a/doc/coverage/coverage/index-sort-f.html
+++ b/doc/coverage/coverage/index-sort-f.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -144,17 +144,17 @@
src/rules/operation
-
+
- 99.0 %
- 96 / 97
+ 99.1 %
+ 105 / 106
94.4 %
17 / 18
100.0 %
- 29 / 29
+ 33 / 33
- test/RuleConditionalTransfer
+ test/RuleConditionalTransfer/utils
diff --git a/doc/coverage/coverage/index-sort-l.html b/doc/coverage/coverage/index-sort-l.html
index f725c93..f352c82 100644
--- a/doc/coverage/coverage/index-sort-l.html
+++ b/doc/coverage/coverage/index-sort-l.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -144,38 +144,38 @@
src/rules/operation
-
+
- 99.0 %
- 96 / 97
+ 99.1 %
+ 105 / 106
94.4 %
17 / 18
100.0 %
- 29 / 29
+ 33 / 33
- test/RuleConditionalTransfer
+ src/rules/validation/abstract
100.0 %
10 / 10
100.0 %
- 1 / 1
- -
- 0 / 0
+ 3 / 3
+ 100.0 %
+ 4 / 4
- src/rules/validation/abstract
+ test/RuleConditionalTransfer/utils
100.0 %
10 / 10
100.0 %
- 3 / 3
- 100.0 %
- 4 / 4
+ 1 / 1
+ -
+ 0 / 0
src/modules
diff --git a/doc/coverage/coverage/index.html b/doc/coverage/coverage/index.html
index 7fae7e6..92f429f 100644
--- a/doc/coverage/coverage/index.html
+++ b/doc/coverage/coverage/index.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -120,14 +120,14 @@
src/rules/operation
-
+
- 99.0 %
- 96 / 97
+ 99.1 %
+ 105 / 106
94.4 %
17 / 18
100.0 %
- 29 / 29
+ 33 / 33
src/rules/operation/abstract
@@ -178,7 +178,7 @@
6 / 6
- test/RuleConditionalTransfer
+ test/RuleConditionalTransfer/utils
diff --git a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html
index 9abe59d..9ab57f2 100644
--- a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html
+++ b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html
index ef1e98d..6dcfe5d 100644
--- a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html
+++ b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html
index 66de358..0600472 100644
--- a/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html
+++ b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html
index a3a8550..347d446 100644
--- a/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html
+++ b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html
index 967d63b..29ef250 100644
--- a/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html
+++ b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html
index d004e29..3b01d2b 100644
--- a/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html
+++ b/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/index-sort-b.html b/doc/coverage/coverage/script/index-sort-b.html
index 80a522c..9a13b3e 100644
--- a/doc/coverage/coverage/script/index-sort-b.html
+++ b/doc/coverage/coverage/script/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/index-sort-f.html b/doc/coverage/coverage/script/index-sort-f.html
index d4d37ee..89cfad4 100644
--- a/doc/coverage/coverage/script/index-sort-f.html
+++ b/doc/coverage/coverage/script/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/index-sort-l.html b/doc/coverage/coverage/script/index-sort-l.html
index 265a85d..0303269 100644
--- a/doc/coverage/coverage/script/index-sort-l.html
+++ b/doc/coverage/coverage/script/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/script/index.html b/doc/coverage/coverage/script/index.html
index 7973acc..11ddb92 100644
--- a/doc/coverage/coverage/script/index.html
+++ b/doc/coverage/coverage/script/index.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html b/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html
index b0956d5..eabf2d9 100644
--- a/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
@@ -74,35 +74,35 @@
RuleEngine.validateTransfer
- 10
-
-
- RuleEngine.detectTransferRestriction
- 17
+ 12
RuleEngine.messageForTransferRestriction
18
+
+ RuleEngine.detectTransferRestriction
+ 20
+
RuleEngine.operateOnTransfer
- 54
+ 69
RuleEngine.
- 190
+ 205
RuleEngine.hasRole
- 269
+ 299
RuleEngine._contextSuffixLength
- 528
+ 588
RuleEngine._msgSender
- 528
+ 588
diff --git a/doc/coverage/coverage/src/RuleEngine.sol.func.html b/doc/coverage/coverage/src/RuleEngine.sol.func.html
index e8728dc..f12d35b 100644
--- a/doc/coverage/coverage/src/RuleEngine.sol.func.html
+++ b/doc/coverage/coverage/src/RuleEngine.sol.func.html
@@ -37,7 +37,7 @@
-
+
@@ -70,11 +70,11 @@
RuleEngine.
- 190
+ 205
RuleEngine._contextSuffixLength
- 528
+ 588
RuleEngine._msgData
@@ -82,15 +82,15 @@
RuleEngine._msgSender
- 528
+ 588
RuleEngine.detectTransferRestriction
- 17
+ 20
RuleEngine.hasRole
- 269
+ 299
RuleEngine.messageForTransferRestriction
@@ -98,11 +98,11 @@
RuleEngine.operateOnTransfer
- 54
+ 69
RuleEngine.validateTransfer
- 10
+ 12
diff --git a/doc/coverage/coverage/src/RuleEngine.sol.gcov.html b/doc/coverage/coverage/src/RuleEngine.sol.gcov.html
index 09ddcda..b32d492 100644
--- a/doc/coverage/coverage/src/RuleEngine.sol.gcov.html
+++ b/doc/coverage/coverage/src/RuleEngine.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -102,13 +102,13 @@
31 : : address forwarderIrrevocable,
32 : : address tokenContract
33 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 34 [ + ]: 190 : if (admin == address(0)) {
+ 34 [ + ]: 205 : if (admin == address(0)) {
35 : 1 : revert RuleEngine_AdminWithAddressZeroNotAllowed();
36 : : }
- 37 [ + ]: 189 : if (tokenContract != address(0)) {
- 38 : 71 : _grantRole(TOKEN_CONTRACT_ROLE, tokenContract);
+ 37 [ + ]: 204 : if (tokenContract != address(0)) {
+ 38 : 86 : _grantRole(TOKEN_CONTRACT_ROLE, tokenContract);
39 : : }
- 40 : 189 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ 40 : 204 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
41 : : }
42 : :
43 : : /**
@@ -124,22 +124,22 @@
53 : : uint256 _amount
54 : : ) public view override returns (uint8) {
55 : : // Validation
- 56 : 27 : uint8 code = RuleEngineValidation.detectTransferRestrictionValidation(
+ 56 : 32 : uint8 code = RuleEngineValidation.detectTransferRestrictionValidation(
57 : : _from,
58 : : _to,
59 : : _amount
60 : : );
- 61 [ + ]: 27 : if (code != uint8(REJECTED_CODE_BASE.TRANSFER_OK)) {
+ 61 [ + ]: 32 : if (code != uint8(REJECTED_CODE_BASE.TRANSFER_OK)) {
62 : 15 : return code;
63 : : }
64 : :
65 : : // Operation
- 66 : 12 : uint256 rulesLength = _rulesOperation.length;
- 67 : 12 : for (uint256 i = 0; i < rulesLength; ++i) {
- 68 : 7 : uint8 restriction = IRuleValidation(_rulesOperation[i])
+ 66 : 17 : uint256 rulesLength = _rulesOperation.length;
+ 67 : 17 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 68 : 12 : uint8 restriction = IRuleValidation(_rulesOperation[i])
69 : : .detectTransferRestriction(_from, _to, _amount);
- 70 [ + ]: 7 : if (restriction > 0) {
- 71 : 6 : return restriction;
+ 70 [ + ]: 12 : if (restriction > 0) {
+ 71 : 11 : return restriction;
72 : : }
73 : : }
74 : :
@@ -158,8 +158,8 @@
87 : : address _to,
88 : : uint256 _amount
89 : : ) public view override returns (bool) {
- 90 : 10 : return
- 91 : 10 : detectTransferRestriction(_from, _to, _amount) ==
+ 90 : 12 : return
+ 91 : 12 : detectTransferRestriction(_from, _to, _amount) ==
92 : : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
93 : : }
94 : :
@@ -208,12 +208,12 @@
137 : : ) external override onlyRole(TOKEN_CONTRACT_ROLE) returns (bool isValid) {
138 : : // Validate the transfer
139 : : if (
- 140 : 53 : !RuleEngineValidation.validateTransferValidation(from, to, amount)
+ 140 : 68 : !RuleEngineValidation.validateTransferValidation(from, to, amount)
141 [ + ]: 10 : ) {
142 : 10 : return false;
143 : : }
144 : : // Apply operation on RuleEngine
- 145 : 43 : return RuleEngineOperation._operateOnTransfer(from, to, amount);
+ 145 : 58 : return RuleEngineOperation._operateOnTransfer(from, to, amount);
146 : : }
147 : :
148 : : /* ============ ACCESS CONTROL ============ */
@@ -225,10 +225,10 @@
154 : : address account
155 : : ) public view virtual override(AccessControl) returns (bool) {
156 : : // The Default Admin has all roles
- 157 [ + ]: 537 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
- 158 : 205 : return true;
+ 157 [ + ]: 597 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
+ 158 : 220 : return true;
159 : : }
- 160 : 332 : return AccessControl.hasRole(role, account);
+ 160 : 377 : return AccessControl.hasRole(role, account);
161 : : }
162 : :
163 : : /*//////////////////////////////////////////////////////////////
@@ -244,7 +244,7 @@
173 : : override(ERC2771Context, Context)
174 : : returns (address sender)
175 : : {
- 176 : 528 : return ERC2771Context._msgSender();
+ 176 : 588 : return ERC2771Context._msgSender();
177 : : }
178 : :
179 : : /**
@@ -268,7 +268,7 @@
197 : : override(ERC2771Context, Context)
198 : : returns (uint256)
199 : : {
- 200 : 528 : return ERC2771Context._contextSuffixLength();
+ 200 : 588 : return ERC2771Context._contextSuffixLength();
201 : : }
202 : : }
diff --git a/doc/coverage/coverage/src/index-sort-b.html b/doc/coverage/coverage/src/index-sort-b.html
index 7546912..576ca6d 100644
--- a/doc/coverage/coverage/src/index-sort-b.html
+++ b/doc/coverage/coverage/src/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/index-sort-f.html b/doc/coverage/coverage/src/index-sort-f.html
index da325bc..8962246 100644
--- a/doc/coverage/coverage/src/index-sort-f.html
+++ b/doc/coverage/coverage/src/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/index-sort-l.html b/doc/coverage/coverage/src/index-sort-l.html
index aad9a38..f6e4883 100644
--- a/doc/coverage/coverage/src/index-sort-l.html
+++ b/doc/coverage/coverage/src/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/index.html b/doc/coverage/coverage/src/index.html
index 2325d70..0762168 100644
--- a/doc/coverage/coverage/src/index.html
+++ b/doc/coverage/coverage/src/index.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html
index 4b20f11..260f236 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
@@ -106,11 +106,11 @@
RuleEngineOperation._operateOnTransfer
- 43
+ 58
RuleEngineOperation.addRuleOperation
- 70
+ 85
diff --git a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html
index 0a529ba..323d585 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html
@@ -37,7 +37,7 @@
-
+
@@ -74,7 +74,7 @@
RuleEngineOperation._operateOnTransfer
- 43
+ 58
RuleEngineOperation._removeRuleOperation
@@ -82,7 +82,7 @@
RuleEngineOperation.addRuleOperation
- 70
+ 85
RuleEngineOperation.clearRulesOperation
diff --git a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html
index 5bdd2e0..75768bd 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -137,8 +137,8 @@
66 : : function addRuleOperation(
67 : : IRuleOperation rule_
68 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
- 69 : 70 : RuleInternal._addRule(_rulesOperation, address(rule_));
- 70 : 68 : emit AddRule(address(rule_));
+ 69 : 85 : RuleInternal._addRule(_rulesOperation, address(rule_));
+ 70 : 83 : emit AddRule(address(rule_));
71 : : }
72 : :
73 : : /**
@@ -225,18 +225,18 @@
154 : : address _to,
155 : : uint256 _amount
156 : : ) internal returns (bool isValid) {
- 157 : 43 : uint256 rulesLength = _rulesOperation.length;
- 158 : 43 : for (uint256 i = 0; i < rulesLength; ++i) {
- 159 : 35 : bool result = IRuleOperation(_rulesOperation[i]).operateOnTransfer(
+ 157 : 58 : uint256 rulesLength = _rulesOperation.length;
+ 158 : 58 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 159 : 50 : bool result = IRuleOperation(_rulesOperation[i]).operateOnTransfer(
160 : : _from,
161 : : _to,
162 : : _amount
163 : : );
- 164 [ + ]: 35 : if (!result) {
- 165 : 17 : return false;
+ 164 [ + ]: 50 : if (!result) {
+ 165 : 24 : return false;
166 : : }
167 : : }
- 168 : 26 : return true;
+ 168 : 34 : return true;
169 : : }
170 : : }
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html
index f670d0f..3f2eb78 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html
index 816d60c..8e114c8 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html
index 65e2e88..92443af 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -102,8 +102,8 @@
31 : : address _to,
32 : : uint256 _amount
33 : : ) public view override returns (uint8) {
- 34 : 85 : uint256 rulesLength = _rulesValidation.length;
- 35 : 85 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 34 : 105 : uint256 rulesLength = _rulesValidation.length;
+ 35 : 105 : for (uint256 i = 0; i < rulesLength; ++i) {
36 : 43 : uint8 restriction = IRuleValidation(_rulesValidation[i])
37 : : .detectTransferRestriction(_from, _to, _amount);
38 [ + ]: 43 : if (restriction > 0) {
@@ -111,7 +111,7 @@
40 : : }
41 : : }
42 : :
- 43 : 57 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 43 : 77 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
44 : : }
45 : :
46 : : /**
@@ -126,8 +126,8 @@
55 : : address _to,
56 : : uint256 _amount
57 : : ) public view override returns (bool) {
- 58 : 55 : return
- 59 : 55 : detectTransferRestrictionValidation(_from, _to, _amount) ==
+ 58 : 70 : return
+ 59 : 70 : detectTransferRestrictionValidation(_from, _to, _amount) ==
60 : : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
61 : : }
62 : : }
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html
index 1405993..31de5ea 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html
index 236b1cc..d05c663 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html
index 357b381..1c29fc2 100644
--- a/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html
+++ b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html
index 12c3e74..7456c15 100644
--- a/doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
@@ -82,7 +82,7 @@
RuleInternal._addRule
- 188
+ 203
diff --git a/doc/coverage/coverage/src/modules/RuleInternal.sol.func.html b/doc/coverage/coverage/src/modules/RuleInternal.sol.func.html
index c32d37a..239df15 100644
--- a/doc/coverage/coverage/src/modules/RuleInternal.sol.func.html
+++ b/doc/coverage/coverage/src/modules/RuleInternal.sol.func.html
@@ -37,7 +37,7 @@
-
+
@@ -70,7 +70,7 @@
RuleInternal._addRule
- 188
+ 203
RuleInternal._getRuleIndex
diff --git a/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html
index 3b5b318..cd50bce 100644
--- a/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html
+++ b/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -112,14 +112,14 @@
41 : : *
42 : : */
43 : : function _addRule(address[] storage _rules, address rule_) internal {
- 44 [ + ]: 188 : if (address(rule_) == address(0x0)) {
+ 44 [ + ]: 203 : if (address(rule_) == address(0x0)) {
45 : 2 : revert RuleEngine_RuleAddressZeroNotAllowed();
46 : : }
47 [ + ]: 2 : if (_ruleIsPresent[rule_]) {
48 : 2 : revert RuleEngine_RuleAlreadyExists();
49 : : }
- 50 : 184 : _rules.push(rule_);
- 51 : 184 : _ruleIsPresent[rule_] = true;
+ 50 : 199 : _rules.push(rule_);
+ 51 : 199 : _ruleIsPresent[rule_] = true;
52 : : }
53 : :
54 : : /**
diff --git a/doc/coverage/coverage/src/modules/index-sort-b.html b/doc/coverage/coverage/src/modules/index-sort-b.html
index de7034e..1356192 100644
--- a/doc/coverage/coverage/src/modules/index-sort-b.html
+++ b/doc/coverage/coverage/src/modules/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
@@ -82,26 +82,26 @@
Branches
- RuleEngineValidation.sol
+ RuleEngineValidationCommon.sol
100.0 %
- 8 / 8
+ 19 / 19
100.0 %
- 2 / 2
+ 10 / 10
100.0 %
1 / 1
- RuleEngineValidationCommon.sol
+ RuleEngineValidation.sol
100.0 %
- 19 / 19
+ 8 / 8
100.0 %
- 10 / 10
+ 2 / 2
100.0 %
1 / 1
diff --git a/doc/coverage/coverage/src/modules/index-sort-f.html b/doc/coverage/coverage/src/modules/index-sort-f.html
index 2c1a718..f0cc112 100644
--- a/doc/coverage/coverage/src/modules/index-sort-f.html
+++ b/doc/coverage/coverage/src/modules/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/modules/index-sort-l.html b/doc/coverage/coverage/src/modules/index-sort-l.html
index afc3be8..7d113ca 100644
--- a/doc/coverage/coverage/src/modules/index-sort-l.html
+++ b/doc/coverage/coverage/src/modules/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/modules/index.html b/doc/coverage/coverage/src/modules/index.html
index 241dc35..60ae93b 100644
--- a/doc/coverage/coverage/src/modules/index.html
+++ b/doc/coverage/coverage/src/modules/index.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html
index 35b44d1..7f4ab01 100644
--- a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -69,7 +69,7 @@
Hit count
- RuleConditionalTransfer._msgData
+ RuleConditionalTransfer._msgData
0
@@ -96,17 +96,17 @@
RuleConditionalTransfer._cancelTransferRequest
9
-
- RuleConditionalTransfer.detectTransferRestriction
- 31
-
RuleConditionalTransfer.getRequestByStatus
35
RuleConditionalTransfer.operateOnTransfer
- 35
+ 50
+
+
+ RuleConditionalTransfer.detectTransferRestriction
+ 56
RuleConditionalTransfer.getRequestTrade
@@ -114,31 +114,31 @@
RuleConditionalTransfer._validateApproval
- 59
+ 97
RuleConditionalTransfer._validateBurnMint
- 63
+ 103
RuleConditionalTransfer._validateTransfer
- 66
+ 106
RuleConditionalTransfer.createTransferRequest
- 104
+ 114
RuleConditionalTransfer.
- 143
+ 158
- RuleConditionalTransfer._contextSuffixLength
- 745
+ RuleConditionalTransfer._contextSuffixLength
+ 829
- RuleConditionalTransfer._msgSender
- 745
+ RuleConditionalTransfer._msgSender
+ 829
diff --git a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html
index 6ab25e2..fba2e82 100644
--- a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html
+++ b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -70,35 +70,35 @@
RuleConditionalTransfer.
- 143
+ 158
RuleConditionalTransfer._cancelTransferRequest
9
- RuleConditionalTransfer._contextSuffixLength
- 745
+ RuleConditionalTransfer._contextSuffixLength
+ 829
- RuleConditionalTransfer._msgData
+ RuleConditionalTransfer._msgData
0
- RuleConditionalTransfer._msgSender
- 745
+ RuleConditionalTransfer._msgSender
+ 829
RuleConditionalTransfer._validateApproval
- 59
+ 97
RuleConditionalTransfer._validateBurnMint
- 63
+ 103
RuleConditionalTransfer._validateTransfer
- 66
+ 106
RuleConditionalTransfer.canReturnTransferRestrictionCode
@@ -114,7 +114,7 @@
RuleConditionalTransfer.createTransferRequest
- 104
+ 114
RuleConditionalTransfer.createTransferRequestBatch
@@ -122,7 +122,7 @@
RuleConditionalTransfer.detectTransferRestriction
- 31
+ 56
RuleConditionalTransfer.getRequestByStatus
@@ -138,7 +138,7 @@
RuleConditionalTransfer.operateOnTransfer
- 35
+ 50
diff --git a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html
index 8040d48..476c0ca 100644
--- a/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -101,14 +101,14 @@
30 : : IRuleEngine ruleEngineContract,
31 : : OPTION memory options_
32 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 33 [ + ]: 143 : if (admin == address(0)) {
+ 33 [ + ]: 158 : if (admin == address(0)) {
34 : 1 : revert RuleConditionalTransfer_AdminWithAddressZeroNotAllowed();
35 : : }
- 36 : 142 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 37 [ + ]: 142 : if (address(ruleEngineContract) != address(0x0)) {
- 38 : 138 : _grantRole(RULE_ENGINE_CONTRACT_ROLE, address(ruleEngineContract));
+ 36 : 157 : _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ 37 [ + ]: 157 : if (address(ruleEngineContract) != address(0x0)) {
+ 38 : 153 : _grantRole(RULE_ENGINE_CONTRACT_ROLE, address(ruleEngineContract));
39 : : }
- 40 : 142 : options = options_;
+ 40 : 157 : options = options_;
41 : : }
42 : :
43 : : /*//////////////////////////////////////////////////////////////
@@ -129,15 +129,15 @@
58 : : onlyRole(RULE_ENGINE_CONTRACT_ROLE)
59 : : returns (bool isValid)
60 : : {
- 61 [ + + ]: 35 : if (_validateTransfer(_from, _to)) {
- 62 : 6 : return true;
+ 61 [ + + ]: 50 : if (_validateTransfer(_from, _to)) {
+ 62 : 8 : return true;
63 : : } else {
- 64 : 29 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
- 65 [ + + ]: 29 : if (_validateApproval(key)) {
- 66 : 12 : _updateProcessedTransfer(key);
- 67 : 12 : return true;
+ 64 : 42 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
+ 65 [ + + ]: 42 : if (_validateApproval(key)) {
+ 66 : 18 : _updateProcessedTransfer(key);
+ 67 : 18 : return true;
68 : : } else {
- 69 : 17 : return false;
+ 69 : 24 : return false;
70 : : }
71 : : }
72 : : }
@@ -151,14 +151,14 @@
80 : : // WAIT => Will set a new delay to approve
81 : : // APPROVED => will overwrite previous status
82 : : // DENIED => reject
- 83 : 107 : address from = _msgSender();
- 84 : 107 : bytes32 key = keccak256(abi.encode(from, to, value));
- 85 [ + ]: 107 : if (transferRequests[key].status == STATUS.DENIED) {
+ 83 : 117 : address from = _msgSender();
+ 84 : 117 : bytes32 key = keccak256(abi.encode(from, to, value));
+ 85 [ + ]: 117 : if (transferRequests[key].status == STATUS.DENIED) {
86 : 1 : revert RuleConditionalTransfer_TransferDenied();
87 : : }
- 88 [ + + ]: 106 : if (_checkRequestStatus(key)) {
- 89 : 103 : uint256 requestIdLocal = requestId;
- 90 : 103 : TransferRequest memory newTransferApproval = TransferRequest({
+ 88 [ + + ]: 116 : if (_checkRequestStatus(key)) {
+ 89 : 113 : uint256 requestIdLocal = requestId;
+ 90 : 113 : TransferRequest memory newTransferApproval = TransferRequest({
91 : : key: key,
92 : : id: requestIdLocal,
93 : : keyElement: TransferRequestKeyElement({
@@ -170,10 +170,10 @@
99 : : maxTime: 0,
100 : : status: STATUS.WAIT
101 : : });
- 102 : 103 : transferRequests[key] = newTransferApproval;
- 103 : 103 : IdToKey[requestIdLocal] = key;
- 104 : 103 : emit transferWaiting(key, from, to, value, requestId);
- 105 : 103 : ++requestId;
+ 102 : 113 : transferRequests[key] = newTransferApproval;
+ 103 : 113 : IdToKey[requestIdLocal] = key;
+ 104 : 113 : emit transferWaiting(key, from, to, value, requestId);
+ 105 : 113 : ++requestId;
106 : : } else {
107 : : // Overwrite previous approval
108 : 3 : transferRequests[key].askTime = block.timestamp;
@@ -288,14 +288,14 @@
217 : : uint256 _amount
218 : : ) public view override returns (uint8) {
219 : : // No need of approval if from and to are in the whitelist
- 220 [ + ]: 31 : if (_validateTransfer(_from, _to)) {
+ 220 [ + ]: 56 : if (_validateTransfer(_from, _to)) {
221 : 1 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
222 : : }
- 223 : 30 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
- 224 [ + + ]: 30 : if (_validateApproval(key)) {
- 225 : 6 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 223 : 55 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
+ 224 [ + + ]: 55 : if (_validateApproval(key)) {
+ 225 : 8 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
226 : : } else {
- 227 : 24 : return CODE_TRANSFER_REQUEST_NOT_APPROVED;
+ 227 : 47 : return CODE_TRANSFER_REQUEST_NOT_APPROVED;
228 : : }
229 : : }
230 : :
@@ -333,9 +333,9 @@
262 : : address _to
263 : : ) internal view returns (bool) {
264 : : // No need of approval if from and to are in the whitelist
- 265 [ + ]: 66 : if (address(whitelistConditionalTransfer) != address(0)) {
+ 265 [ + ]: 106 : if (address(whitelistConditionalTransfer) != address(0)) {
266 : : if (
- 267 : 30 : whitelistConditionalTransfer.addressIsListed(_from) &&
+ 267 : 36 : whitelistConditionalTransfer.addressIsListed(_from) &&
268 : 5 : whitelistConditionalTransfer.addressIsListed(_to)
269 [ + ]: 3 : ) {
270 : 3 : return true;
@@ -343,10 +343,10 @@
272 : : }
273 : :
274 : : // Mint & Burn
- 275 [ + ]: 63 : if (_validateBurnMint(_from, _to)) {
- 276 : 4 : return true;
+ 275 [ + ]: 103 : if (_validateBurnMint(_from, _to)) {
+ 276 : 6 : return true;
277 : : }
- 278 : 59 : return false;
+ 278 : 97 : return false;
279 : : }
280 : :
281 : : function _cancelTransferRequest(uint256 requestId_) internal {
@@ -381,14 +381,14 @@
310 : : ) internal view returns (bool isValid) {
311 : : // Mint & Burn
312 : : if (
- 313 : 63 : (_from == address(0) &&
+ 313 : 103 : (_from == address(0) &&
314 : : options.issuance.authorizedMintWithoutApproval) ||
315 : : (_to == address(0) &&
316 : : options.issuance.authorizedBurnWithoutApproval)
- 317 [ + ]: 4 : ) {
- 318 : 4 : return true;
+ 317 [ + ]: 6 : ) {
+ 318 : 6 : return true;
319 : : }
- 320 : 59 : return false;
+ 320 : 97 : return false;
321 : : }
322 : :
323 : : /**
@@ -401,64 +401,75 @@
330 : : bytes32 key
331 : : ) internal view returns (bool isValid) {
332 : : // If automatic approval is activate and time to approve the request has passed
- 333 : : // Warning: overflow possible if timeLimitBeforeAutomaticApproval == max(uint256)
- 334 : 59 : bool automaticApprovalCondition = options
- 335 : : .automaticApproval
- 336 : : .isActivate &&
- 337 : 21 : block.timestamp >=
- 338 : : (transferRequests[key].askTime +
- 339 : : options.automaticApproval.timeLimitBeforeAutomaticApproval);
- 340 : : // If the transfer is approved and delay to perform the transfer is respected
- 341 : 59 : bool isTransferApproved = (transferRequests[key].status ==
- 342 : : STATUS.APPROVED) &&
- 343 : : (transferRequests[key].maxTime >= block.timestamp);
- 344 [ + + ]: 59 : if (automaticApprovalCondition || isTransferApproved) {
- 345 : 18 : return true;
- 346 : : } else {
- 347 : 41 : return false;
- 348 : : }
- 349 : : }
- 350 : :
- 351 : : /*//////////////////////////////////////////////////////////////
- 352 : : ERC-2771
- 353 : : //////////////////////////////////////////////////////////////*/
- 354 : :
- 355 : : /**
- 356 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 357 : : */
- 358 : : function _msgSender()
- 359 : : internal
- 360 : : view
- 361 : : override(ERC2771Context, Context)
- 362 : : returns (address sender)
- 363 : : {
- 364 : 745 : return ERC2771Context._msgSender();
- 365 : : }
- 366 : :
- 367 : : /**
- 368 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 369 : : */
- 370 : : function _msgData()
- 371 : : internal
- 372 : : view
- 373 : : override(ERC2771Context, Context)
- 374 : : returns (bytes calldata)
- 375 : : {
- 376 : 0 : return ERC2771Context._msgData();
- 377 : : }
- 378 : :
- 379 : : /**
- 380 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 381 : : */
- 382 : : function _contextSuffixLength()
- 383 : : internal
- 384 : : view
- 385 : : override(ERC2771Context, Context)
- 386 : : returns (uint256)
- 387 : : {
- 388 : 745 : return ERC2771Context._contextSuffixLength();
- 389 : : }
- 390 : : }
+ 333 : 97 : if(transferRequests[key].status == STATUS.NONE
+ 334 : : ||
+ 335 : 50 : transferRequests[key].status == STATUS.DENIED
+ 336 : : ||
+ 337 : 47 : transferRequests[key].status == STATUS.EXECUTED)
+ 338 [ + ]: 50 : {
+ 339 : 50 : return false;
+ 340 : : }
+ 341 : 47 : bool isTransferApproved;
+ 342 : 47 : bool automaticApprovalCondition;
+ 343 [ + ]: 47 : if(transferRequests[key].status ==
+ 344 [ + ]: 20 : STATUS.APPROVED){
+ 345 : 20 : isTransferApproved = (transferRequests[key].maxTime >= block.timestamp);
+ 346 : : } else if(options
+ 347 : : .automaticApproval
+ 348 [ + ]: 27 : .isActivate){
+ 349 : : // Warning: overflow possible if timeLimitBeforeAutomaticApproval == max(uint256)
+ 350 : 27 : automaticApprovalCondition= block.timestamp >=
+ 351 : : (transferRequests[key].askTime +
+ 352 : : options.automaticApproval.timeLimitBeforeAutomaticApproval);
+ 353 : : }
+ 354 : : // If the transfer is approved and delay to perform the transfer is respected
+ 355 [ + + ]: 47 : if (automaticApprovalCondition || isTransferApproved) {
+ 356 : 26 : return true;
+ 357 : : } else {
+ 358 : 21 : return false;
+ 359 : : }
+ 360 : : }
+ 361 : :
+ 362 : : /*//////////////////////////////////////////////////////////////
+ 363 : : ERC-2771
+ 364 : : //////////////////////////////////////////////////////////////*/
+ 365 : :
+ 366 : : /**
+ 367 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 368 : : */
+ 369 : : function _msgSender()
+ 370 : : internal
+ 371 : : view
+ 372 : : override(ERC2771Context, Context)
+ 373 : : returns (address sender)
+ 374 : : {
+ 375 : 829 : return ERC2771Context._msgSender();
+ 376 : : }
+ 377 : :
+ 378 : : /**
+ 379 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 380 : : */
+ 381 : : function _msgData()
+ 382 : : internal
+ 383 : : view
+ 384 : : override(ERC2771Context, Context)
+ 385 : : returns (bytes calldata)
+ 386 : : {
+ 387 : 0 : return ERC2771Context._msgData();
+ 388 : : }
+ 389 : :
+ 390 : : /**
+ 391 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 392 : : */
+ 393 : : function _contextSuffixLength()
+ 394 : : internal
+ 395 : : view
+ 396 : : override(ERC2771Context, Context)
+ 397 : : returns (uint256)
+ 398 : : {
+ 399 : 829 : return ERC2771Context._contextSuffixLength();
+ 400 : : }
+ 401 : : }
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html
index 1071825..acebdd7 100644
--- a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
@@ -82,10 +82,6 @@
RuleConditionalTransferOperator.setAutomaticTransfer
- 3
-
-
- RuleConditionalTransferOperator.setTimeLimit
4
@@ -93,7 +89,7 @@
5
- RuleConditionalTransferOperator.setIssuanceOptions
+ RuleConditionalTransferOperator.setTimeLimit
5
@@ -109,20 +105,24 @@
7
- RuleConditionalTransferOperator.setAutomaticApproval
+ RuleConditionalTransferOperator.setIssuanceOptions
7
- RuleConditionalTransferOperator._resetRequestStatus
+ RuleConditionalTransferOperator._resetRequestStatus
10
- RuleConditionalTransferOperator._updateProcessedTransfer
- 12
+ RuleConditionalTransferOperator.setAutomaticApproval
+ 10
RuleConditionalTransferOperator._createTransferRequestWithApproval
- 15
+ 17
+
+
+ RuleConditionalTransferOperator._updateProcessedTransfer
+ 18
RuleConditionalTransferOperator.setConditionalWhitelist
@@ -130,23 +130,23 @@
RuleConditionalTransferOperator.approveTransferRequest
- 33
+ 40
RuleConditionalTransferOperator._approveTransferRequestKeyElement
- 41
+ 48
- RuleConditionalTransferOperator._approveRequest
- 46
+ RuleConditionalTransferOperator._approveRequest
+ 53
- RuleConditionalTransferOperator._checkRequestStatus
- 121
+ RuleConditionalTransferOperator._checkRequestStatus
+ 133
RuleConditionalTransferOperator.hasRole
- 280
+ 310
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html
index 33ceb63..bbcca68 100644
--- a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html
+++ b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html
@@ -37,7 +37,7 @@
-
+
@@ -69,32 +69,32 @@
Hit count
- RuleConditionalTransferOperator._approveRequest
- 46
+ RuleConditionalTransferOperator._approveRequest
+ 53
RuleConditionalTransferOperator._approveTransferRequestKeyElement
- 41
+ 48
- RuleConditionalTransferOperator._checkRequestStatus
- 121
+ RuleConditionalTransferOperator._checkRequestStatus
+ 133
RuleConditionalTransferOperator._createTransferRequestWithApproval
- 15
+ 17
- RuleConditionalTransferOperator._resetRequestStatus
+ RuleConditionalTransferOperator._resetRequestStatus
10
- RuleConditionalTransferOperator._updateProcessedTransfer
- 12
+ RuleConditionalTransferOperator._updateProcessedTransfer
+ 18
RuleConditionalTransferOperator.approveTransferRequest
- 33
+ 40
RuleConditionalTransferOperator.approveTransferRequestBatch
@@ -118,7 +118,7 @@
RuleConditionalTransferOperator.hasRole
- 280
+ 310
RuleConditionalTransferOperator.resetRequestStatus
@@ -130,11 +130,11 @@
RuleConditionalTransferOperator.setAutomaticApproval
- 7
+ 10
RuleConditionalTransferOperator.setAutomaticTransfer
- 3
+ 4
RuleConditionalTransferOperator.setConditionalWhitelist
@@ -142,11 +142,11 @@
RuleConditionalTransferOperator.setIssuanceOptions
- 5
+ 7
RuleConditionalTransferOperator.setTimeLimit
- 4
+ 5
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html
index 54a9877..8a6d8ca 100644
--- a/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -114,23 +114,23 @@
43 : : ISSUANCE calldata issuance_
44 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
45 : : if (
- 46 : 4 : options.issuance.authorizedMintWithoutApproval !=
+ 46 : 6 : options.issuance.authorizedMintWithoutApproval !=
47 : : issuance_.authorizedMintWithoutApproval
- 48 [ + ]: 2 : ) {
- 49 : 2 : options.issuance.authorizedMintWithoutApproval = issuance_
+ 48 [ + ]: 3 : ) {
+ 49 : 3 : options.issuance.authorizedMintWithoutApproval = issuance_
50 : : .authorizedMintWithoutApproval;
51 : : }
52 : : if (
- 53 : 4 : options.issuance.authorizedBurnWithoutApproval !=
+ 53 : 6 : options.issuance.authorizedBurnWithoutApproval !=
54 : : issuance_.authorizedBurnWithoutApproval
- 55 [ + ]: 2 : ) {
- 56 : 2 : options.issuance.authorizedBurnWithoutApproval = issuance_
+ 55 [ + ]: 3 : ) {
+ 56 : 3 : options.issuance.authorizedBurnWithoutApproval = issuance_
57 : : .authorizedBurnWithoutApproval;
58 : : }
59 : : }
60 : :
61 : : /**
- 62 : : * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
+ 62 : : * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
63 : : * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
64 : : * If the allowance is not sufficient, the request will be approved, but without performing the transfer.
65 : : */
@@ -138,7 +138,7 @@
67 : : AUTOMATIC_TRANSFER calldata automaticTransfer_
68 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
69 : : if (
- 70 : 2 : automaticTransfer_.isActivate !=
+ 70 : 3 : automaticTransfer_.isActivate !=
71 : : options.automaticTransfer.isActivate
72 [ + ]: 2 : ) {
73 : 2 : options.automaticTransfer.isActivate = automaticTransfer_
@@ -146,7 +146,7 @@
75 : : }
76 : : // No need to put the cmtat to zero to deactivate automaticTransfer
77 : : if (
- 78 : 2 : address(automaticTransfer_.cmtat) !=
+ 78 : 3 : address(automaticTransfer_.cmtat) !=
79 : : address(options.automaticTransfer.cmtat)
80 [ + ]: 2 : ) {
81 : 2 : options.automaticTransfer.cmtat = automaticTransfer_.cmtat;
@@ -162,17 +162,17 @@
91 : : TIME_LIMIT memory timeLimit_
92 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
93 : : if (
- 94 : 3 : options.timeLimit.timeLimitToApprove !=
+ 94 : 4 : options.timeLimit.timeLimitToApprove !=
95 : : timeLimit_.timeLimitToApprove
- 96 [ + ]: 3 : ) {
- 97 : 3 : options.timeLimit.timeLimitToApprove = timeLimit_
+ 96 [ + ]: 4 : ) {
+ 97 : 4 : options.timeLimit.timeLimitToApprove = timeLimit_
98 : : .timeLimitToApprove;
99 : : }
100 : : if (
- 101 : 3 : options.timeLimit.timeLimitToTransfer !=
+ 101 : 4 : options.timeLimit.timeLimitToTransfer !=
102 : : timeLimit_.timeLimitToTransfer
- 103 [ + ]: 3 : ) {
- 104 : 3 : options.timeLimit.timeLimitToTransfer = timeLimit_
+ 103 [ + ]: 4 : ) {
+ 104 : 4 : options.timeLimit.timeLimitToTransfer = timeLimit_
105 : : .timeLimitToTransfer;
106 : : }
107 : : }
@@ -186,17 +186,17 @@
115 : : AUTOMATIC_APPROVAL memory automaticApproval_
116 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
117 : : if (
- 118 : 6 : options.automaticApproval.isActivate !=
+ 118 : 9 : options.automaticApproval.isActivate !=
119 : : automaticApproval_.isActivate
120 [ + ]: 6 : ) {
121 : 6 : options.automaticApproval.isActivate = automaticApproval_
122 : : .isActivate;
123 : : }
124 : : if (
- 125 : 6 : options.automaticApproval.timeLimitBeforeAutomaticApproval !=
+ 125 : 9 : options.automaticApproval.timeLimitBeforeAutomaticApproval !=
126 : : automaticApproval_.timeLimitBeforeAutomaticApproval
- 127 [ + ]: 6 : ) {
- 128 : 6 : options
+ 127 [ + ]: 9 : ) {
+ 128 : 9 : options
129 : : .automaticApproval
130 : : .timeLimitBeforeAutomaticApproval = automaticApproval_
131 : : .timeLimitBeforeAutomaticApproval;
@@ -223,7 +223,7 @@
152 : : uint256 partialValue,
153 : : bool isApproved
154 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 155 : 32 : _approveTransferRequestKeyElement(keyElement, partialValue, isApproved);
+ 155 : 39 : _approveTransferRequestKeyElement(keyElement, partialValue, isApproved);
156 : : }
157 : :
158 : : /**
@@ -353,10 +353,10 @@
282 : : address account
283 : : ) public view virtual override(AccessControl) returns (bool) {
284 : : // The Default Admin has all roles
- 285 [ + ]: 630 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
- 286 : 124 : return true;
+ 285 [ + ]: 704 : if (AccessControl.hasRole(DEFAULT_ADMIN_ROLE, account)) {
+ 286 : 137 : return true;
287 : : }
- 288 : 506 : return AccessControl.hasRole(role, account);
+ 288 : 567 : return AccessControl.hasRole(role, account);
289 : : }
290 : :
291 : : /*//////////////////////////////////////////////////////////////
@@ -367,21 +367,21 @@
296 : : uint256 partialValue,
297 : : bool isApproved
298 : : ) internal {
- 299 [ + ]: 41 : if (partialValue > keyElement.value) {
+ 299 [ + ]: 48 : if (partialValue > keyElement.value) {
300 : 1 : revert RuleConditionalTransfer_InvalidValueApproved();
301 : : }
- 302 : 40 : bytes32 key = keccak256(
+ 302 : 47 : bytes32 key = keccak256(
303 : : abi.encode(keyElement.from, keyElement.to, keyElement.value)
304 : : );
- 305 : 40 : TransferRequest memory transferRequest = transferRequests[key];
- 306 [ + + ]: 40 : if (partialValue > 0) {
- 307 [ + ]: 7 : if (!isApproved) {
+ 305 : 47 : TransferRequest memory transferRequest = transferRequests[key];
+ 306 [ + + ]: 47 : if (partialValue > 0) {
+ 307 [ + ]: 9 : if (!isApproved) {
308 : 1 : revert RuleConditionalTransfer_CannotDeniedPartially();
309 : : }
310 : : // Denied the first request
- 311 : 6 : _approveRequest(transferRequest, false);
+ 311 : 8 : _approveRequest(transferRequest, false);
312 : : // Create new request
- 313 : 6 : _createTransferRequestWithApproval(
+ 313 : 8 : _createTransferRequestWithApproval(
314 : : TransferRequestKeyElement({
315 : : from: keyElement.from,
316 : : to: keyElement.to,
@@ -389,155 +389,159 @@
318 : : })
319 : : );
320 : : } else {
- 321 : 33 : _approveRequest(transferRequest, isApproved);
+ 321 : 38 : _approveRequest(transferRequest, isApproved);
322 : : }
323 : : }
324 : :
325 : : function _createTransferRequestWithApproval(
326 : : TransferRequestKeyElement memory keyElement_
- 327 : : ) internal onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 327 : : ) internal {
328 : : // WAIT => Will overwrite
329 : : // APPROVED => will overwrite previous status with a new delay
330 : : // DENIED => will overwrite
- 331 : 15 : bytes32 key = keccak256(
+ 331 : 17 : bytes32 key = keccak256(
332 : : abi.encode(keyElement_.from, keyElement_.to, keyElement_.value)
333 : : );
- 334 [ + + ]: 15 : if (_checkRequestStatus(key)) {
- 335 : 14 : TransferRequest memory newTransferApproval = TransferRequest({
- 336 : : key: key,
- 337 : : id: requestId,
- 338 : : keyElement: keyElement_,
- 339 : : askTime: 0,
- 340 : : // Warning: overflow possible if timeLimitToTransfer == max(uint256)
- 341 : : maxTime: block.timestamp +
- 342 : : options.timeLimit.timeLimitToTransfer,
- 343 : : status: STATUS.APPROVED
- 344 : : });
- 345 : 14 : transferRequests[key] = newTransferApproval;
- 346 : 14 : IdToKey[requestId] = key;
- 347 : 14 : emit transferApproved(
- 348 : : key,
- 349 : : keyElement_.from,
- 350 : : keyElement_.to,
- 351 : : keyElement_.value,
- 352 : : requestId
- 353 : : );
- 354 : 14 : ++requestId;
- 355 : : } else {
- 356 : : // Overwrite previous approval
- 357 : : // Warning: overflow possible if timeLimitToTransfer == max(uint256)
- 358 : 1 : transferRequests[key].maxTime =
- 359 : : block.timestamp +
- 360 : : options.timeLimit.timeLimitToTransfer;
- 361 : 1 : transferRequests[key].status = STATUS.APPROVED;
- 362 : 1 : emit transferApproved(
- 363 : : key,
- 364 : : keyElement_.from,
- 365 : : keyElement_.to,
- 366 : : keyElement_.value,
- 367 : : transferRequests[key].id
- 368 : : );
- 369 : : }
- 370 : : }
- 371 : :
- 372 : : function _resetRequestStatus(bytes32 key) internal {
- 373 : 10 : transferRequests[key].status = STATUS.NONE;
- 374 : 10 : emit transferReset(
- 375 : : key,
- 376 : : transferRequests[key].keyElement.from,
- 377 : : transferRequests[key].keyElement.to,
- 378 : : transferRequests[key].keyElement.value,
- 379 : : transferRequests[key].id
- 380 : : );
- 381 : : }
- 382 : :
- 383 : : function _checkRequestStatus(bytes32 key) internal view returns (bool) {
- 384 : : // Status NONE not enough because reset is possible
- 385 : 121 : return
- 386 : 121 : (transferRequests[key].status == STATUS.NONE) &&
- 387 : : (transferRequests[key].key == 0x0);
- 388 : : }
- 389 : :
- 390 : : function _approveRequest(
- 391 : : TransferRequest memory transferRequest,
- 392 : : bool isApproved
- 393 : : ) internal {
- 394 : : // status
- 395 [ + ]: 46 : if (transferRequest.status != STATUS.WAIT) {
- 396 : 1 : revert RuleConditionalTransfer_Wrong_Status();
- 397 : : }
- 398 [ + + ]: 27 : if (isApproved) {
- 399 : : // Time
- 400 : : if (
- 401 : 27 : block.timestamp >
- 402 : : (transferRequest.askTime + options.timeLimit.timeLimitToApprove)
- 403 [ + ]: 3 : ) {
- 404 : 3 : revert RuleConditionalTransfer_timeExceeded();
- 405 : : }
- 406 : : // Set status
- 407 : 24 : transferRequests[transferRequest.key].status = STATUS.APPROVED;
- 408 : : // Set max time
- 409 : 24 : transferRequests[transferRequest.key].maxTime =
- 410 : : block.timestamp +
- 411 : : options.timeLimit.timeLimitToTransfer;
- 412 : 24 : emit transferApproved(
- 413 : : transferRequest.key,
- 414 : : transferRequest.keyElement.from,
- 415 : : transferRequest.keyElement.to,
- 416 : : transferRequest.keyElement.value,
- 417 : : transferRequests[transferRequest.key].id
- 418 : : );
- 419 : : if (
- 420 : 24 : options.automaticTransfer.isActivate &&
- 421 : 2 : address(options.automaticTransfer.cmtat) != address(0)
- 422 [ + ]: 2 : ) {
- 423 : : // Transfer with approval
- 424 : : // External call
- 425 : : if (
- 426 : 2 : options.automaticTransfer.cmtat.allowance(
- 427 : : transferRequest.keyElement.from,
- 428 : : address(this)
- 429 : : ) >= transferRequest.keyElement.value
- 430 [ + ]: 2 : ) {
- 431 : : // Will call the ruleEngine and the rule again...
- 432 : 2 : options.automaticTransfer.cmtat.safeTransferFrom(
- 433 : : transferRequest.keyElement.from,
- 434 : : transferRequest.keyElement.to,
- 435 : : transferRequest.keyElement.value
- 436 : : );
- 437 : : }
- 438 : : }
- 439 : : } else {
- 440 : 18 : transferRequests[transferRequest.key].status = STATUS.DENIED;
- 441 : 18 : emit transferDenied(
- 442 : : transferRequest.key,
- 443 : : transferRequest.keyElement.from,
- 444 : : transferRequest.keyElement.to,
- 445 : : transferRequest.keyElement.value,
- 446 : : transferRequests[transferRequest.key].id
- 447 : : );
- 448 : : }
- 449 : : }
- 450 : :
- 451 : : /**
- 452 : : * @notice update the request during a transfer
- 453 : : */
- 454 : : function _updateProcessedTransfer(bytes32 key) internal {
- 455 : : // Reset to zero
- 456 : 12 : transferRequests[key].maxTime = 0;
- 457 : 12 : transferRequests[key].askTime = 0;
- 458 : : // Change status
- 459 : 12 : transferRequests[key].status = STATUS.EXECUTED;
- 460 : : // Emit event
- 461 : 12 : emit transferProcessed(
- 462 : : key,
- 463 : : transferRequests[key].keyElement.from,
- 464 : : transferRequests[key].keyElement.to,
- 465 : : transferRequests[key].keyElement.value,
- 466 : : transferRequests[key].id
- 467 : : );
- 468 : : }
- 469 : : }
+ 334 [ + + ]: 17 : if (_checkRequestStatus(key)) {
+ 335 : : // Only if it is a new request
+ 336 : 16 : TransferRequest memory newTransferApproval = TransferRequest({
+ 337 : : key: key,
+ 338 : : id: requestId,
+ 339 : : keyElement: keyElement_,
+ 340 : : askTime: 0,
+ 341 : : // Warning: overflow possible if timeLimitToTransfer == max(uint256)
+ 342 : : maxTime: block.timestamp +
+ 343 : : options.timeLimit.timeLimitToTransfer,
+ 344 : : status: STATUS.APPROVED
+ 345 : : });
+ 346 : 16 : transferRequests[key] = newTransferApproval;
+ 347 : 16 : IdToKey[requestId] = key;
+ 348 : 16 : emit transferApproved(
+ 349 : : key,
+ 350 : : keyElement_.from,
+ 351 : : keyElement_.to,
+ 352 : : keyElement_.value,
+ 353 : : requestId
+ 354 : : );
+ 355 : 16 : ++requestId;
+ 356 : : } else {
+ 357 : : // Overwrite previous approval
+ 358 : : // Warning: overflow possible if timeLimitToTransfer == max(uint256)
+ 359 : 1 : transferRequests[key].maxTime =
+ 360 : : block.timestamp +
+ 361 : : options.timeLimit.timeLimitToTransfer;
+ 362 : 1 : transferRequests[key].status = STATUS.APPROVED;
+ 363 : 1 : emit transferApproved(
+ 364 : : key,
+ 365 : : keyElement_.from,
+ 366 : : keyElement_.to,
+ 367 : : keyElement_.value,
+ 368 : : transferRequests[key].id
+ 369 : : );
+ 370 : : }
+ 371 : : }
+ 372 : :
+ 373 : : function _resetRequestStatus(bytes32 key) internal {
+ 374 : 10 : transferRequests[key].status = STATUS.NONE;
+ 375 : 10 : emit transferReset(
+ 376 : : key,
+ 377 : : transferRequests[key].keyElement.from,
+ 378 : : transferRequests[key].keyElement.to,
+ 379 : : transferRequests[key].keyElement.value,
+ 380 : : transferRequests[key].id
+ 381 : : );
+ 382 : : }
+ 383 : :
+ 384 : : /**
+ 385 : : * @dev check if it is a new request or not
+ 386 : : */
+ 387 : : function _checkRequestStatus(bytes32 key) internal view returns (bool) {
+ 388 : : // Status NONE not enough because reset is possible
+ 389 : 133 : return
+ 390 : 133 : (transferRequests[key].status == STATUS.NONE) &&
+ 391 : : (transferRequests[key].key == 0x0);
+ 392 : : }
+ 393 : :
+ 394 : : function _approveRequest(
+ 395 : : TransferRequest memory transferRequest,
+ 396 : : bool isApproved
+ 397 : : ) internal {
+ 398 : : // status
+ 399 [ + ]: 53 : if (transferRequest.status != STATUS.WAIT) {
+ 400 : 1 : revert RuleConditionalTransfer_Wrong_Status();
+ 401 : : }
+ 402 [ + + ]: 32 : if (isApproved) {
+ 403 : : // Time
+ 404 : : if (
+ 405 : 32 : block.timestamp >
+ 406 : : (transferRequest.askTime + options.timeLimit.timeLimitToApprove)
+ 407 [ + ]: 3 : ) {
+ 408 : 3 : revert RuleConditionalTransfer_timeExceeded();
+ 409 : : }
+ 410 : : // Set status
+ 411 : 29 : transferRequests[transferRequest.key].status = STATUS.APPROVED;
+ 412 : : // Set max time
+ 413 : 29 : transferRequests[transferRequest.key].maxTime =
+ 414 : : block.timestamp +
+ 415 : : options.timeLimit.timeLimitToTransfer;
+ 416 : 29 : emit transferApproved(
+ 417 : : transferRequest.key,
+ 418 : : transferRequest.keyElement.from,
+ 419 : : transferRequest.keyElement.to,
+ 420 : : transferRequest.keyElement.value,
+ 421 : : transferRequests[transferRequest.key].id
+ 422 : : );
+ 423 : : if (
+ 424 : 29 : options.automaticTransfer.isActivate &&
+ 425 : 7 : address(options.automaticTransfer.cmtat) != address(0)
+ 426 [ + ]: 7 : ) {
+ 427 : : // Transfer with approval
+ 428 : : // External call
+ 429 : : if (
+ 430 : 7 : options.automaticTransfer.cmtat.allowance(
+ 431 : : transferRequest.keyElement.from,
+ 432 : : address(this)
+ 433 : : ) >= transferRequest.keyElement.value
+ 434 [ + ]: 3 : ) {
+ 435 : : // Will call the ruleEngine and the rule again...
+ 436 : 3 : options.automaticTransfer.cmtat.safeTransferFrom(
+ 437 : : transferRequest.keyElement.from,
+ 438 : : transferRequest.keyElement.to,
+ 439 : : transferRequest.keyElement.value
+ 440 : : );
+ 441 : : }
+ 442 : : }
+ 443 : : } else {
+ 444 : 20 : transferRequests[transferRequest.key].status = STATUS.DENIED;
+ 445 : 20 : emit transferDenied(
+ 446 : : transferRequest.key,
+ 447 : : transferRequest.keyElement.from,
+ 448 : : transferRequest.keyElement.to,
+ 449 : : transferRequest.keyElement.value,
+ 450 : : transferRequests[transferRequest.key].id
+ 451 : : );
+ 452 : : }
+ 453 : : }
+ 454 : :
+ 455 : : /**
+ 456 : : * @notice update the request during a transfer
+ 457 : : */
+ 458 : : function _updateProcessedTransfer(bytes32 key) internal {
+ 459 : : // Reset to zero
+ 460 : 18 : transferRequests[key].maxTime = 0;
+ 461 : 18 : transferRequests[key].askTime = 0;
+ 462 : : // Change status
+ 463 : 18 : transferRequests[key].status = STATUS.EXECUTED;
+ 464 : : // Emit event
+ 465 : 18 : emit transferProcessed(
+ 466 : : key,
+ 467 : : transferRequests[key].keyElement.from,
+ 468 : : transferRequests[key].keyElement.to,
+ 469 : : transferRequests[key].keyElement.value,
+ 470 : : transferRequests[key].id
+ 471 : : );
+ 472 : : }
+ 473 : : }
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html
index 106bf3c..e47a898 100644
--- a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html
+++ b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html
index 510afd6..aaae3fc 100644
--- a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html
+++ b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html
index a7a93e9..2ec5b2c 100644
--- a/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html
+++ b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/operation/abstract/index.html b/doc/coverage/coverage/src/rules/operation/abstract/index.html
index a540778..1428f56 100644
--- a/doc/coverage/coverage/src/rules/operation/abstract/index.html
+++ b/doc/coverage/coverage/src/rules/operation/abstract/index.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/operation/index-sort-b.html b/doc/coverage/coverage/src/rules/operation/index-sort-b.html
index 3311178..d14d712 100644
--- a/doc/coverage/coverage/src/rules/operation/index-sort-b.html
+++ b/doc/coverage/coverage/src/rules/operation/index-sort-b.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -84,14 +84,14 @@
RuleConditionalTransfer.sol
-
+
- 99.0 %
- 96 / 97
+ 99.1 %
+ 105 / 106
94.4 %
17 / 18
100.0 %
- 29 / 29
+ 33 / 33
diff --git a/doc/coverage/coverage/src/rules/operation/index-sort-f.html b/doc/coverage/coverage/src/rules/operation/index-sort-f.html
index fae09be..d28f603 100644
--- a/doc/coverage/coverage/src/rules/operation/index-sort-f.html
+++ b/doc/coverage/coverage/src/rules/operation/index-sort-f.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -84,14 +84,14 @@
RuleConditionalTransfer.sol
-
+
- 99.0 %
- 96 / 97
+ 99.1 %
+ 105 / 106
94.4 %
17 / 18
100.0 %
- 29 / 29
+ 33 / 33
diff --git a/doc/coverage/coverage/src/rules/operation/index-sort-l.html b/doc/coverage/coverage/src/rules/operation/index-sort-l.html
index 068336b..ece5b0b 100644
--- a/doc/coverage/coverage/src/rules/operation/index-sort-l.html
+++ b/doc/coverage/coverage/src/rules/operation/index-sort-l.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -84,14 +84,14 @@
RuleConditionalTransfer.sol
-
+
- 99.0 %
- 96 / 97
+ 99.1 %
+ 105 / 106
94.4 %
17 / 18
100.0 %
- 29 / 29
+ 33 / 33
diff --git a/doc/coverage/coverage/src/rules/operation/index.html b/doc/coverage/coverage/src/rules/operation/index.html
index 2f73491..260d74e 100644
--- a/doc/coverage/coverage/src/rules/operation/index.html
+++ b/doc/coverage/coverage/src/rules/operation/index.html
@@ -31,13 +31,13 @@
-
-
-
+
+
+
-
+
@@ -49,8 +49,8 @@
-
-
+
+
@@ -84,14 +84,14 @@
RuleConditionalTransfer.sol
-
+
- 99.0 %
- 96 / 97
+ 99.1 %
+ 105 / 106
94.4 %
17 / 18
100.0 %
- 29 / 29
+ 33 / 33
diff --git a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html
index cdeff24..a23344e 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html
index 43a0389..0168a37 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html
index 0e56a74..bea5e34 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html
index 6a8afe3..76ad884 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html
index 7ab15b8..f3eefa0 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html
index b1c19fc..299cb3a 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html
index bcf0b58..3983775 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html
index 836283a..855b26a 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html
index 3df1691..729cd39 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html
index d3e7dc3..50d42d4 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html
index ea009eb..87ddb39 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html
index 1f9bba8..497bf06 100644
--- a/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html
index 693be82..98ee305 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
@@ -98,7 +98,7 @@
RuleAddressList.addressIsListed
- 95
+ 101
RuleAddressList.
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html
index 54c594d..ed5ebcb 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html
@@ -37,7 +37,7 @@
-
+
@@ -94,7 +94,7 @@
RuleAddressList.addressIsListed
- 95
+ 101
RuleAddressList.addressIsListedBatch
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html
index 7524536..2cd242c 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -173,7 +173,7 @@
102 : : function addressIsListed(
103 : : address _targetAddress
104 : : ) public view returns (bool) {
- 105 : 153 : return _addressIsListed(_targetAddress);
+ 105 : 159 : return _addressIsListed(_targetAddress);
106 : : }
107 : :
108 : : /**
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html
index e6dec90..5b3956f 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
@@ -90,7 +90,7 @@
RuleAddressListInternal._addressIsListed
- 208
+ 214
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html
index c02568e..d5e1465 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html
@@ -37,7 +37,7 @@
-
+
@@ -78,7 +78,7 @@
RuleAddressListInternal._addressIsListed
- 208
+ 214
RuleAddressListInternal._numberListedAddress
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html
index 430dde9..f91cf24 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -167,7 +167,7 @@
96 : : function _addressIsListed(
97 : : address _targetAddress
98 : : ) internal view returns (bool) {
- 99 : 208 : return list[_targetAddress];
+ 99 : 214 : return list[_targetAddress];
100 : : }
101 : : }
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html
index a60ef87..5f6b1ad 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html
index 94eba9b..d55918c 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html
index 8f7e785..94dea7d 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html
index 0892ee8..b24b451 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html
index f8c0470..9025b1d 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
@@ -70,7 +70,7 @@
RuleValidateTransfer.validateTransfer
- 26
+ 40
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html
index 417fbf9..cef3f12 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html
@@ -37,7 +37,7 @@
-
+
@@ -70,7 +70,7 @@
RuleValidateTransfer.validateTransfer
- 26
+ 40
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html
index 8544ad8..c350c3b 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -89,8 +89,8 @@
18 : : uint256 _amount
19 : : ) public view override returns (bool isValid) {
20 : : // does not work without this keyword "Undeclared identifier"
- 21 : 26 : return
- 22 : 26 : this.detectTransferRestriction(_from, _to, _amount) ==
+ 21 : 40 : return
+ 22 : 40 : this.detectTransferRestriction(_from, _to, _amount) ==
23 : : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
24 : : }
25 : : }
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html
index e0f9046..d40fb06 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html
index 56bd216..b899bc1 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html
index 7f454e0..20b596c 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html
index 80167d5..32f7fc4 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html
index 5d75ddb..37e913e 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html
index 62c92d4..51f2975 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/abstract/index.html b/doc/coverage/coverage/src/rules/validation/abstract/index.html
index 7f73c12..74cd455 100644
--- a/doc/coverage/coverage/src/rules/validation/abstract/index.html
+++ b/doc/coverage/coverage/src/rules/validation/abstract/index.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/index-sort-b.html
index 43d72a6..d627eb6 100644
--- a/doc/coverage/coverage/src/rules/validation/index-sort-b.html
+++ b/doc/coverage/coverage/src/rules/validation/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/index-sort-f.html
index b040fdc..7939279 100644
--- a/doc/coverage/coverage/src/rules/validation/index-sort-f.html
+++ b/doc/coverage/coverage/src/rules/validation/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/src/rules/validation/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/index-sort-l.html
index 59f017d..e147ebd 100644
--- a/doc/coverage/coverage/src/rules/validation/index-sort-l.html
+++ b/doc/coverage/coverage/src/rules/validation/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
@@ -82,28 +82,28 @@
Branches
- RuleWhitelistWrapper.sol
+ RuleSanctionList.sol
96.4 %
27 / 28
- 83.3 %
- 5 / 6
+ 90.0 %
+ 9 / 10
100.0 %
- 9 / 9
+ 11 / 11
- RuleSanctionList.sol
+ RuleWhitelistWrapper.sol
96.4 %
27 / 28
- 90.0 %
- 9 / 10
+ 83.3 %
+ 5 / 6
100.0 %
- 11 / 11
+ 9 / 9
RuleWhitelist.sol
diff --git a/doc/coverage/coverage/src/rules/validation/index.html b/doc/coverage/coverage/src/rules/validation/index.html
index 1f69f9d..3d1ec09 100644
--- a/doc/coverage/coverage/src/rules/validation/index.html
+++ b/doc/coverage/coverage/src/rules/validation/index.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.func-sort-c.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func-sort-c.html
similarity index 69%
rename from doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.func-sort-c.html
rename to doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func-sort-c.html
index 67433ed..88c2a09 100644
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.func-sort-c.html
+++ b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func-sort-c.html
@@ -4,22 +4,22 @@
- LCOV - lcov.info - test/RuleConditionalTransfer/RuleCTDeployment.sol - functions
-
+ LCOV - lcov.info - test/RuleConditionalTransfer/utils/RuleCTDeployment.sol - functions
+
LCOV - code coverage report
-
+
-
+
@@ -37,7 +37,7 @@
-
+
@@ -53,20 +53,20 @@
-
+
-
+
- Function Name
- Hit count
+ Function Name
+ Hit count
RuleCTDeployment.
@@ -76,7 +76,7 @@
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.func.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func.html
similarity index 68%
rename from doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.func.html
rename to doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func.html
index 3e62922..ead2a6c 100644
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.func.html
+++ b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.func.html
@@ -4,22 +4,22 @@
- LCOV - lcov.info - test/RuleConditionalTransfer/RuleCTDeployment.sol - functions
-
+ LCOV - lcov.info - test/RuleConditionalTransfer/utils/RuleCTDeployment.sol - functions
+
LCOV - code coverage report
-
+
-
+
@@ -37,7 +37,7 @@
-
+
@@ -53,20 +53,20 @@
-
+
-
+
- Function Name
- Hit count
+ Function Name
+ Hit count
RuleCTDeployment.
@@ -76,7 +76,7 @@
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.gcov.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.gcov.html
similarity index 90%
rename from doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.gcov.html
rename to doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.gcov.html
index 3d19389..471014d 100644
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/RuleCTDeployment.sol.gcov.html
+++ b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol.gcov.html
@@ -4,22 +4,22 @@
- LCOV - lcov.info - test/RuleConditionalTransfer/RuleCTDeployment.sol
-
+ LCOV - lcov.info - test/RuleConditionalTransfer/utils/RuleCTDeployment.sol
+
LCOV - code coverage report
-
+
-
+
@@ -37,7 +37,7 @@
-
+
@@ -53,12 +53,12 @@
-
+
-
+
@@ -73,7 +73,7 @@
2 : : pragma solidity ^0.8.20;
3 : :
4 : : import "forge-std/Test.sol";
- 5 : : import "../HelperContract.sol";
+ 5 : : import "../../HelperContract.sol";
6 : : import "src/RuleEngine.sol";
7 : :
8 : : /**
@@ -133,7 +133,7 @@
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-b.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-b.html
similarity index 68%
rename from doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-b.html
rename to doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-b.html
index 672842a..273564b 100644
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-b.html
+++ b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-b.html
@@ -4,22 +4,22 @@
- LCOV - lcov.info - test/RuleConditionalTransfer
-
+ LCOV - lcov.info - test/RuleConditionalTransfer/utils
+
LCOV - code coverage report
-
+
-
+
@@ -37,7 +37,7 @@
-
+
@@ -53,12 +53,12 @@
-
+
-
+
@@ -76,15 +76,15 @@
- Filename
- Line Coverage
- Functions
- Branches
+ Filename
+ Line Coverage
+ Functions
+ Branches
RuleCTDeployment.sol
-
+
100.0 %
10 / 10
@@ -98,7 +98,7 @@
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-f.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-f.html
similarity index 68%
rename from doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-f.html
rename to doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-f.html
index 314b064..cfa53fa 100644
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-f.html
+++ b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-f.html
@@ -4,22 +4,22 @@
- LCOV - lcov.info - test/RuleConditionalTransfer
-
+ LCOV - lcov.info - test/RuleConditionalTransfer/utils
+
LCOV - code coverage report
-
+
-
+
@@ -37,7 +37,7 @@
-
+
@@ -53,12 +53,12 @@
-
+
-
+
@@ -76,15 +76,15 @@
- Filename
- Line Coverage
- Functions
- Branches
+ Filename
+ Line Coverage
+ Functions
+ Branches
RuleCTDeployment.sol
-
+
100.0 %
10 / 10
@@ -98,7 +98,7 @@
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-l.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-l.html
similarity index 68%
rename from doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-l.html
rename to doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-l.html
index f6226c1..8cfb2ca 100644
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/index-sort-l.html
+++ b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index-sort-l.html
@@ -4,22 +4,22 @@
- LCOV - lcov.info - test/RuleConditionalTransfer
-
+ LCOV - lcov.info - test/RuleConditionalTransfer/utils
+
LCOV - code coverage report
-
+
-
+
@@ -37,7 +37,7 @@
-
+
@@ -53,12 +53,12 @@
-
+
-
+
@@ -76,15 +76,15 @@
- Filename
- Line Coverage
- Functions
- Branches
+ Filename
+ Line Coverage
+ Functions
+ Branches
RuleCTDeployment.sol
-
+
100.0 %
10 / 10
@@ -98,7 +98,7 @@
diff --git a/doc/coverage/coverage/test/RuleConditionalTransfer/index.html b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index.html
similarity index 68%
rename from doc/coverage/coverage/test/RuleConditionalTransfer/index.html
rename to doc/coverage/coverage/test/RuleConditionalTransfer/utils/index.html
index 114f296..0fb4392 100644
--- a/doc/coverage/coverage/test/RuleConditionalTransfer/index.html
+++ b/doc/coverage/coverage/test/RuleConditionalTransfer/utils/index.html
@@ -4,22 +4,22 @@
- LCOV - lcov.info - test/RuleConditionalTransfer
-
+ LCOV - lcov.info - test/RuleConditionalTransfer/utils
+
LCOV - code coverage report
-
+
-
+
@@ -37,7 +37,7 @@
-
+
@@ -53,12 +53,12 @@
-
+
-
+
@@ -76,15 +76,15 @@
- Filename
- Line Coverage
- Functions
- Branches
+ Filename
+ Line Coverage
+ Functions
+ Branches
RuleCTDeployment.sol
-
+
100.0 %
10 / 10
@@ -98,7 +98,7 @@
diff --git a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func-sort-c.html b/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func-sort-c.html
index ecfe634..a8ae820 100644
--- a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func-sort-c.html
+++ b/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
@@ -70,7 +70,7 @@
CMTATDeployment.
- 71
+ 86
diff --git a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func.html b/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func.html
index 4b8a007..a912669 100644
--- a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func.html
+++ b/doc/coverage/coverage/test/utils/CMTATDeployment.sol.func.html
@@ -37,7 +37,7 @@
-
+
@@ -70,7 +70,7 @@
CMTATDeployment.
- 71
+ 86
diff --git a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.gcov.html b/doc/coverage/coverage/test/utils/CMTATDeployment.sol.gcov.html
index a4ba3e9..a0b1546 100644
--- a/doc/coverage/coverage/test/utils/CMTATDeployment.sol.gcov.html
+++ b/doc/coverage/coverage/test/utils/CMTATDeployment.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
@@ -85,26 +85,26 @@
14 : :
15 : : constructor() {
16 : : // CMTAT
- 17 : 71 : ICMTATConstructor.ERC20Attributes
+ 17 : 86 : ICMTATConstructor.ERC20Attributes
18 : : memory erc20Attributes = ICMTATConstructor.ERC20Attributes(
19 : : "CMTA Token",
20 : : "CMTAT",
21 : : 0
22 : : );
- 23 : 71 : ICMTATConstructor.BaseModuleAttributes
+ 23 : 86 : ICMTATConstructor.BaseModuleAttributes
24 : : memory baseModuleAttributes = ICMTATConstructor
25 : : .BaseModuleAttributes(
26 : : "CMTAT_ISIN",
27 : : "https://cmta.ch",
28 : : "CMTAT_info"
29 : : );
- 30 : 71 : ICMTATConstructor.Engine memory engines = ICMTATConstructor.Engine(
+ 30 : 86 : ICMTATConstructor.Engine memory engines = ICMTATConstructor.Engine(
31 : : IRuleEngine(ZERO_ADDRESS),
32 : : IDebtEngine(ZERO_ADDRESS),
33 : : IAuthorizationEngine(ZERO_ADDRESS),
34 : : IERC1643(ZERO_ADDRESS)
35 : : );
- 36 : 71 : cmtat = new CMTAT_STANDALONE(
+ 36 : 86 : cmtat = new CMTAT_STANDALONE(
37 : : ZERO_ADDRESS,
38 : : DEFAULT_ADMIN_ADDRESS,
39 : : erc20Attributes,
diff --git a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html
index f157fde..32ca64b 100644
--- a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html
+++ b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html
index 7e9b52c..12d4508 100644
--- a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html
+++ b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html
index 6189674..6a45b5a 100644
--- a/doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html
+++ b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/test/utils/index-sort-b.html b/doc/coverage/coverage/test/utils/index-sort-b.html
index ddf11e9..500c424 100644
--- a/doc/coverage/coverage/test/utils/index-sort-b.html
+++ b/doc/coverage/coverage/test/utils/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
@@ -81,18 +81,6 @@
Functions
Branches
-
- SanctionListOracle.sol
-
-
-
- 66.7 %
- 2 / 3
- 75.0 %
- 3 / 4
- -
- 0 / 0
-
CMTATDeployment.sol
@@ -105,6 +93,18 @@
-
0 / 0
+
+ SanctionListOracle.sol
+
+
+
+ 66.7 %
+ 2 / 3
+ 75.0 %
+ 3 / 4
+ -
+ 0 / 0
+
diff --git a/doc/coverage/coverage/test/utils/index-sort-f.html b/doc/coverage/coverage/test/utils/index-sort-f.html
index 9463e98..ff0b711 100644
--- a/doc/coverage/coverage/test/utils/index-sort-f.html
+++ b/doc/coverage/coverage/test/utils/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/test/utils/index-sort-l.html b/doc/coverage/coverage/test/utils/index-sort-l.html
index 23698d8..b1f3e52 100644
--- a/doc/coverage/coverage/test/utils/index-sort-l.html
+++ b/doc/coverage/coverage/test/utils/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/coverage/test/utils/index.html b/doc/coverage/coverage/test/utils/index.html
index 0fa7340..0cb6aec 100644
--- a/doc/coverage/coverage/test/utils/index.html
+++ b/doc/coverage/coverage/test/utils/index.html
@@ -37,7 +37,7 @@
-
+
diff --git a/doc/coverage/lcov.info b/doc/coverage/lcov.info
index b0b67e6..a4e6aaf 100644
--- a/doc/coverage/lcov.info
+++ b/doc/coverage/lcov.info
@@ -51,31 +51,31 @@ end_of_record
TN:
SF:src/RuleEngine.sol
FN:29,RuleEngine.
-FNDA:190,RuleEngine.
-DA:34,190
+FNDA:205,RuleEngine.
+DA:34,205
BRDA:34,0,0,1
DA:35,1
-DA:37,189
-BRDA:37,1,0,71
-DA:38,71
-DA:40,189
+DA:37,204
+BRDA:37,1,0,86
+DA:38,86
+DA:40,204
FN:50,RuleEngine.detectTransferRestriction
-FNDA:17,RuleEngine.detectTransferRestriction
-DA:56,27
-DA:61,27
+FNDA:20,RuleEngine.detectTransferRestriction
+DA:56,32
+DA:61,32
BRDA:61,2,0,15
DA:62,15
-DA:66,12
-DA:67,12
-DA:68,7
-DA:70,7
-BRDA:70,3,0,6
-DA:71,6
+DA:66,17
+DA:67,17
+DA:68,12
+DA:70,12
+BRDA:70,3,0,11
+DA:71,11
DA:75,6
FN:85,RuleEngine.validateTransfer
-FNDA:10,RuleEngine.validateTransfer
-DA:90,10
-DA:91,10
+FNDA:12,RuleEngine.validateTransfer
+DA:90,12
+DA:91,12
FN:100,RuleEngine.messageForTransferRestriction
FNDA:18,RuleEngine.messageForTransferRestriction
DA:104,18
@@ -94,27 +94,27 @@ DA:122,1
DA:123,1
DA:127,7
FN:133,RuleEngine.operateOnTransfer
-FNDA:54,RuleEngine.operateOnTransfer
-DA:140,53
+FNDA:69,RuleEngine.operateOnTransfer
+DA:140,68
DA:141,10
BRDA:141,6,0,10
DA:142,10
-DA:145,43
+DA:145,58
FN:152,RuleEngine.hasRole
-FNDA:269,RuleEngine.hasRole
-DA:157,537
-BRDA:157,7,0,205
-DA:158,205
-DA:160,332
+FNDA:299,RuleEngine.hasRole
+DA:157,597
+BRDA:157,7,0,220
+DA:158,220
+DA:160,377
FN:170,RuleEngine._msgSender
-FNDA:528,RuleEngine._msgSender
-DA:176,528
+FNDA:588,RuleEngine._msgSender
+DA:176,588
FN:182,RuleEngine._msgData
FNDA:0,RuleEngine._msgData
DA:188,0
FN:194,RuleEngine._contextSuffixLength
-FNDA:528,RuleEngine._contextSuffixLength
-DA:200,528
+FNDA:588,RuleEngine._contextSuffixLength
+DA:200,588
FNF:9
FNH:8
LF:39
@@ -125,7 +125,7 @@ end_of_record
TN:
SF:src/modules/MetaTxModuleStandalone.sol
FN:11,MetaTxModuleStandalone.
-FNDA:545,MetaTxModuleStandalone.
+FNDA:575,MetaTxModuleStandalone.
FNF:1
FNH:1
LF:0
@@ -153,9 +153,9 @@ DA:54,17
DA:56,17
DA:58,14
FN:66,RuleEngineOperation.addRuleOperation
-FNDA:70,RuleEngineOperation.addRuleOperation
-DA:69,70
-DA:70,68
+FNDA:85,RuleEngineOperation.addRuleOperation
+DA:69,85
+DA:70,83
FN:83,RuleEngineOperation.removeRuleOperation
FNDA:5,RuleEngineOperation.removeRuleOperation
DA:87,5
@@ -176,14 +176,14 @@ FN:137,RuleEngineOperation.rulesOperation
FNDA:5,RuleEngineOperation.rulesOperation
DA:143,5
FN:152,RuleEngineOperation._operateOnTransfer
-FNDA:43,RuleEngineOperation._operateOnTransfer
-DA:157,43
-DA:158,43
-DA:159,35
-DA:164,35
-BRDA:164,1,0,17
-DA:165,17
-DA:168,26
+FNDA:58,RuleEngineOperation._operateOnTransfer
+DA:157,58
+DA:158,58
+DA:159,50
+DA:164,50
+BRDA:164,1,0,24
+DA:165,24
+DA:168,34
FNF:11
FNH:11
LF:25
@@ -195,17 +195,17 @@ TN:
SF:src/modules/RuleEngineValidation.sol
FN:29,RuleEngineValidation.detectTransferRestrictionValidation
FNDA:3,RuleEngineValidation.detectTransferRestrictionValidation
-DA:34,85
-DA:35,85
+DA:34,105
+DA:35,105
DA:36,43
DA:38,43
BRDA:38,0,0,28
DA:39,28
-DA:43,57
+DA:43,77
FN:53,RuleEngineValidation.validateTransferValidation
FNDA:2,RuleEngineValidation.validateTransferValidation
-DA:58,55
-DA:59,55
+DA:58,70
+DA:59,70
FNF:2
FNH:2
LF:8
@@ -280,15 +280,15 @@ DA:30,44
DA:31,44
DA:33,44
FN:43,RuleInternal._addRule
-FNDA:188,RuleInternal._addRule
-DA:44,188
+FNDA:203,RuleInternal._addRule
+DA:44,203
BRDA:44,3,0,2
DA:45,2
DA:47,2
BRDA:47,4,0,2
DA:48,2
-DA:50,184
-DA:51,184
+DA:50,199
+DA:51,199
FN:64,RuleInternal._removeRule
FNDA:55,RuleInternal._removeRule
DA:69,55
@@ -319,44 +319,44 @@ end_of_record
TN:
SF:src/rules/operation/RuleConditionalTransfer.sol
FN:27,RuleConditionalTransfer.
-FNDA:143,RuleConditionalTransfer.
-DA:33,143
+FNDA:158,RuleConditionalTransfer.
+DA:33,158
BRDA:33,0,0,1
DA:34,1
-DA:36,142
-DA:37,142
-BRDA:37,1,0,138
-DA:38,138
-DA:40,142
+DA:36,157
+DA:37,157
+BRDA:37,1,0,153
+DA:38,153
+DA:40,157
FN:51,RuleConditionalTransfer.operateOnTransfer
-FNDA:35,RuleConditionalTransfer.operateOnTransfer
-DA:61,35
-BRDA:61,2,0,6
-BRDA:61,2,1,17
-DA:62,6
-DA:64,29
-DA:65,29
-BRDA:65,3,0,12
-BRDA:65,3,1,17
-DA:66,12
-DA:67,12
-DA:69,17
+FNDA:50,RuleConditionalTransfer.operateOnTransfer
+DA:61,50
+BRDA:61,2,0,8
+BRDA:61,2,1,24
+DA:62,8
+DA:64,42
+DA:65,42
+BRDA:65,3,0,18
+BRDA:65,3,1,24
+DA:66,18
+DA:67,18
+DA:69,24
FN:79,RuleConditionalTransfer.createTransferRequest
-FNDA:104,RuleConditionalTransfer.createTransferRequest
-DA:83,107
-DA:84,107
-DA:85,107
+FNDA:114,RuleConditionalTransfer.createTransferRequest
+DA:83,117
+DA:84,117
+DA:85,117
BRDA:85,4,0,1
DA:86,1
-DA:88,106
-BRDA:88,5,0,103
+DA:88,116
+BRDA:88,5,0,113
BRDA:88,5,1,3
-DA:89,103
-DA:90,103
-DA:102,103
-DA:103,103
-DA:104,103
-DA:105,103
+DA:89,113
+DA:90,113
+DA:102,113
+DA:103,113
+DA:104,113
+DA:105,113
DA:108,3
DA:109,3
DA:110,3
@@ -406,16 +406,16 @@ DA:201,36
DA:202,36
DA:205,35
FN:214,RuleConditionalTransfer.detectTransferRestriction
-FNDA:31,RuleConditionalTransfer.detectTransferRestriction
-DA:220,31
+FNDA:56,RuleConditionalTransfer.detectTransferRestriction
+DA:220,56
BRDA:220,12,0,1
DA:221,1
-DA:223,30
-DA:224,30
-BRDA:224,13,0,6
-BRDA:224,13,1,6
-DA:225,6
-DA:227,24
+DA:223,55
+DA:224,55
+BRDA:224,13,0,8
+BRDA:224,13,1,8
+DA:225,8
+DA:227,47
FN:236,RuleConditionalTransfer.canReturnTransferRestrictionCode
FNDA:2,RuleConditionalTransfer.canReturnTransferRestrictionCode
DA:239,2
@@ -427,18 +427,18 @@ BRDA:250,14,1,1
DA:251,2
DA:253,1
FN:260,RuleConditionalTransfer._validateTransfer
-FNDA:66,RuleConditionalTransfer._validateTransfer
-DA:265,66
-BRDA:265,15,0,30
-DA:267,30
+FNDA:106,RuleConditionalTransfer._validateTransfer
+DA:265,106
+BRDA:265,15,0,36
+DA:267,36
DA:268,5
DA:269,3
BRDA:269,16,0,3
DA:270,3
-DA:275,63
-BRDA:275,17,0,4
-DA:276,4
-DA:278,59
+DA:275,103
+BRDA:275,17,0,6
+DA:276,6
+DA:278,97
FN:281,RuleConditionalTransfer._cancelTransferRequest
FNDA:9,RuleConditionalTransfer._cancelTransferRequest
DA:282,9
@@ -455,37 +455,50 @@ BRDA:294,20,0,1
DA:295,1
DA:297,6
FN:307,RuleConditionalTransfer._validateBurnMint
-FNDA:63,RuleConditionalTransfer._validateBurnMint
-DA:313,63
-DA:317,4
-BRDA:317,21,0,4
-DA:318,4
-DA:320,59
+FNDA:103,RuleConditionalTransfer._validateBurnMint
+DA:313,103
+DA:317,6
+BRDA:317,21,0,6
+DA:318,6
+DA:320,97
FN:329,RuleConditionalTransfer._validateApproval
-FNDA:59,RuleConditionalTransfer._validateApproval
-DA:334,59
-DA:337,21
-DA:341,59
-DA:344,59
-BRDA:344,22,0,18
-BRDA:344,22,1,41
-DA:345,18
-DA:347,41
-FN:358,RuleConditionalTransfer._msgSender
-FNDA:745,RuleConditionalTransfer._msgSender
-DA:364,745
-FN:370,RuleConditionalTransfer._msgData
+FNDA:97,RuleConditionalTransfer._validateApproval
+DA:333,97
+DA:335,50
+DA:337,47
+DA:338,50
+BRDA:338,22,0,50
+DA:339,50
+DA:341,47
+DA:342,47
+DA:343,47
+DA:344,20
+BRDA:344,23,0,20
+BRDA:343,23,1,27
+DA:345,20
+DA:348,27
+BRDA:348,24,0,27
+DA:350,27
+DA:355,47
+BRDA:355,25,0,26
+BRDA:355,25,1,21
+DA:356,26
+DA:358,21
+FN:369,RuleConditionalTransfer._msgSender
+FNDA:829,RuleConditionalTransfer._msgSender
+DA:375,829
+FN:381,RuleConditionalTransfer._msgData
FNDA:0,RuleConditionalTransfer._msgData
-DA:376,0
-FN:382,RuleConditionalTransfer._contextSuffixLength
-FNDA:745,RuleConditionalTransfer._contextSuffixLength
-DA:388,745
+DA:387,0
+FN:393,RuleConditionalTransfer._contextSuffixLength
+FNDA:829,RuleConditionalTransfer._contextSuffixLength
+DA:399,829
FNF:18
FNH:17
-LF:97
-LH:96
-BRF:29
-BRH:29
+LF:106
+LH:105
+BRF:33
+BRH:33
end_of_record
TN:
SF:src/rules/operation/abstract/RuleConditionalTransferOperator.sol
@@ -494,51 +507,51 @@ FNDA:26,RuleConditionalTransferOperator.setConditionalWhitelist
DA:35,26
DA:36,26
FN:42,RuleConditionalTransferOperator.setIssuanceOptions
-FNDA:5,RuleConditionalTransferOperator.setIssuanceOptions
-DA:46,4
-DA:48,2
-BRDA:48,0,0,2
-DA:49,2
-DA:53,4
-DA:55,2
-BRDA:55,1,0,2
-DA:56,2
+FNDA:7,RuleConditionalTransferOperator.setIssuanceOptions
+DA:46,6
+DA:48,3
+BRDA:48,0,0,3
+DA:49,3
+DA:53,6
+DA:55,3
+BRDA:55,1,0,3
+DA:56,3
FN:66,RuleConditionalTransferOperator.setAutomaticTransfer
-FNDA:3,RuleConditionalTransferOperator.setAutomaticTransfer
-DA:70,2
+FNDA:4,RuleConditionalTransferOperator.setAutomaticTransfer
+DA:70,3
DA:72,2
BRDA:72,2,0,2
DA:73,2
-DA:78,2
+DA:78,3
DA:80,2
BRDA:80,3,0,2
DA:81,2
FN:90,RuleConditionalTransferOperator.setTimeLimit
-FNDA:4,RuleConditionalTransferOperator.setTimeLimit
-DA:94,3
-DA:96,3
-BRDA:96,4,0,3
-DA:97,3
-DA:101,3
-DA:103,3
-BRDA:103,5,0,3
-DA:104,3
+FNDA:5,RuleConditionalTransferOperator.setTimeLimit
+DA:94,4
+DA:96,4
+BRDA:96,4,0,4
+DA:97,4
+DA:101,4
+DA:103,4
+BRDA:103,5,0,4
+DA:104,4
FN:114,RuleConditionalTransferOperator.setAutomaticApproval
-FNDA:7,RuleConditionalTransferOperator.setAutomaticApproval
-DA:118,6
+FNDA:10,RuleConditionalTransferOperator.setAutomaticApproval
+DA:118,9
DA:120,6
BRDA:120,6,0,6
DA:121,6
-DA:125,6
-DA:127,6
-BRDA:127,7,0,6
-DA:128,6
+DA:125,9
+DA:127,9
+BRDA:127,7,0,9
+DA:128,9
FN:138,RuleConditionalTransferOperator.createTransferRequestWithApproval
FNDA:6,RuleConditionalTransferOperator.createTransferRequestWithApproval
DA:141,5
FN:150,RuleConditionalTransferOperator.approveTransferRequest
-FNDA:33,RuleConditionalTransferOperator.approveTransferRequest
-DA:155,32
+FNDA:40,RuleConditionalTransferOperator.approveTransferRequest
+DA:155,39
FN:161,RuleConditionalTransferOperator.approveTransferRequestWithId
FNDA:5,RuleConditionalTransferOperator.approveTransferRequestWithId
DA:165,4
@@ -599,80 +612,80 @@ DA:270,1
DA:271,3
DA:272,3
FN:280,RuleConditionalTransferOperator.hasRole
-FNDA:280,RuleConditionalTransferOperator.hasRole
-DA:285,630
-BRDA:285,18,0,124
-DA:286,124
-DA:288,506
+FNDA:310,RuleConditionalTransferOperator.hasRole
+DA:285,704
+BRDA:285,18,0,137
+DA:286,137
+DA:288,567
FN:294,RuleConditionalTransferOperator._approveTransferRequestKeyElement
-FNDA:41,RuleConditionalTransferOperator._approveTransferRequestKeyElement
-DA:299,41
+FNDA:48,RuleConditionalTransferOperator._approveTransferRequestKeyElement
+DA:299,48
BRDA:299,19,0,1
DA:300,1
-DA:302,40
-DA:305,40
-DA:306,40
-BRDA:306,20,0,7
-BRDA:306,20,1,6
-DA:307,7
+DA:302,47
+DA:305,47
+DA:306,47
+BRDA:306,20,0,9
+BRDA:306,20,1,8
+DA:307,9
BRDA:307,21,0,1
DA:308,1
-DA:311,6
-DA:313,6
-DA:321,33
+DA:311,8
+DA:313,8
+DA:321,38
FN:325,RuleConditionalTransferOperator._createTransferRequestWithApproval
-FNDA:15,RuleConditionalTransferOperator._createTransferRequestWithApproval
-DA:331,15
-DA:334,15
-BRDA:334,22,0,14
+FNDA:17,RuleConditionalTransferOperator._createTransferRequestWithApproval
+DA:331,17
+DA:334,17
+BRDA:334,22,0,16
BRDA:334,22,1,1
-DA:335,14
-DA:345,14
-DA:346,14
-DA:347,14
-DA:354,14
-DA:358,1
-DA:361,1
+DA:336,16
+DA:346,16
+DA:347,16
+DA:348,16
+DA:355,16
+DA:359,1
DA:362,1
-FN:372,RuleConditionalTransferOperator._resetRequestStatus
+DA:363,1
+FN:373,RuleConditionalTransferOperator._resetRequestStatus
FNDA:10,RuleConditionalTransferOperator._resetRequestStatus
-DA:373,10
DA:374,10
-FN:383,RuleConditionalTransferOperator._checkRequestStatus
-FNDA:121,RuleConditionalTransferOperator._checkRequestStatus
-DA:385,121
-DA:386,121
-FN:390,RuleConditionalTransferOperator._approveRequest
-FNDA:46,RuleConditionalTransferOperator._approveRequest
-DA:395,46
-BRDA:395,23,0,1
-DA:396,1
-DA:398,27
-BRDA:398,24,0,27
-BRDA:398,24,1,18
-DA:401,27
-DA:403,3
-BRDA:403,25,0,3
-DA:404,3
-DA:407,24
-DA:409,24
-DA:412,24
-DA:420,24
-DA:421,2
-DA:422,2
-BRDA:422,26,0,2
-DA:426,2
-DA:430,2
-BRDA:430,27,0,2
-DA:432,2
-DA:440,18
-DA:441,18
-FN:454,RuleConditionalTransferOperator._updateProcessedTransfer
-FNDA:12,RuleConditionalTransferOperator._updateProcessedTransfer
-DA:456,12
-DA:457,12
-DA:459,12
-DA:461,12
+DA:375,10
+FN:387,RuleConditionalTransferOperator._checkRequestStatus
+FNDA:133,RuleConditionalTransferOperator._checkRequestStatus
+DA:389,133
+DA:390,133
+FN:394,RuleConditionalTransferOperator._approveRequest
+FNDA:53,RuleConditionalTransferOperator._approveRequest
+DA:399,53
+BRDA:399,23,0,1
+DA:400,1
+DA:402,32
+BRDA:402,24,0,32
+BRDA:402,24,1,20
+DA:405,32
+DA:407,3
+BRDA:407,25,0,3
+DA:408,3
+DA:411,29
+DA:413,29
+DA:416,29
+DA:424,29
+DA:425,7
+DA:426,7
+BRDA:426,26,0,7
+DA:430,7
+DA:434,3
+BRDA:434,27,0,3
+DA:436,3
+DA:444,20
+DA:445,20
+FN:458,RuleConditionalTransferOperator._updateProcessedTransfer
+FNDA:18,RuleConditionalTransferOperator._updateProcessedTransfer
+DA:460,18
+DA:461,18
+DA:463,18
+DA:465,18
FNF:20
FNH:20
LF:113
@@ -894,8 +907,8 @@ FN:92,RuleAddressList.numberListedAddress
FNDA:24,RuleAddressList.numberListedAddress
DA:93,24
FN:102,RuleAddressList.addressIsListed
-FNDA:95,RuleAddressList.addressIsListed
-DA:105,153
+FNDA:101,RuleAddressList.addressIsListed
+DA:105,159
FN:112,RuleAddressList.addressIsListedBatch
FNDA:28,RuleAddressList.addressIsListedBatch
DA:115,28
@@ -962,8 +975,8 @@ FN:86,RuleAddressListInternal._numberListedAddress
FNDA:24,RuleAddressListInternal._numberListedAddress
DA:87,24
FN:96,RuleAddressListInternal._addressIsListed
-FNDA:208,RuleAddressListInternal._addressIsListed
-DA:99,208
+FNDA:214,RuleAddressListInternal._addressIsListed
+DA:99,214
FNF:6
FNH:6
LF:22
@@ -974,9 +987,9 @@ end_of_record
TN:
SF:src/rules/validation/abstract/RuleValidateTransfer.sol
FN:15,RuleValidateTransfer.validateTransfer
-FNDA:26,RuleValidateTransfer.validateTransfer
-DA:21,26
-DA:22,26
+FNDA:40,RuleValidateTransfer.validateTransfer
+DA:21,40
+DA:22,40
FNF:1
FNH:1
LF:2
@@ -1021,7 +1034,7 @@ BRF:0
BRH:0
end_of_record
TN:
-SF:test/RuleConditionalTransfer/RuleCTDeployment.sol
+SF:test/RuleConditionalTransfer/utils/RuleCTDeployment.sol
FN:13,RuleCTDeployment.
FNDA:13,RuleCTDeployment.
DA:14,13
@@ -1044,11 +1057,11 @@ end_of_record
TN:
SF:test/utils/CMTATDeployment.sol
FN:15,CMTATDeployment.
-FNDA:71,CMTATDeployment.
-DA:17,71
-DA:23,71
-DA:30,71
-DA:36,71
+FNDA:86,CMTATDeployment.
+DA:17,86
+DA:23,86
+DA:30,86
+DA:36,86
FNF:1
FNH:1
LF:4
diff --git a/doc/schema/rule/conditionalTransfer.drawio b/doc/schema/rule/conditionalTransfer.drawio
index 43823b2..9f632cc 100644
--- a/doc/schema/rule/conditionalTransfer.drawio
+++ b/doc/schema/rule/conditionalTransfer.drawio
@@ -1 +1 @@
-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
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/doc/surya/surya_graph/surya_graph_RuleAddressList.sol.png b/doc/surya/surya_graph/surya_graph_RuleAddressList.sol.png
index e43eaeb..3344dd4 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleAddressList.sol.png and b/doc/surya/surya_graph/surya_graph_RuleAddressList.sol.png differ
diff --git a/doc/surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png b/doc/surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png
index 63ada00..47fb63b 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png and b/doc/surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png differ
diff --git a/doc/surya/surya_graph/surya_graph_RuleConditionalTransferOperator.sol.png b/doc/surya/surya_graph/surya_graph_RuleConditionalTransferOperator.sol.png
index 9458b0d..eef7ac6 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleConditionalTransferOperator.sol.png and b/doc/surya/surya_graph/surya_graph_RuleConditionalTransferOperator.sol.png differ
diff --git a/doc/surya/surya_graph/surya_graph_RuleEngine.sol.png b/doc/surya/surya_graph/surya_graph_RuleEngine.sol.png
index 6a4e628..f3dbdf8 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleEngine.sol.png and b/doc/surya/surya_graph/surya_graph_RuleEngine.sol.png differ
diff --git a/doc/surya/surya_graph/surya_graph_RuleEngineOperation.sol.png b/doc/surya/surya_graph/surya_graph_RuleEngineOperation.sol.png
index d6f49ab..2b42825 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleEngineOperation.sol.png and b/doc/surya/surya_graph/surya_graph_RuleEngineOperation.sol.png differ
diff --git a/doc/surya/surya_graph/surya_graph_RuleEngineValidationCommon.sol.png b/doc/surya/surya_graph/surya_graph_RuleEngineValidationCommon.sol.png
index 8f9337d..2987ded 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleEngineValidationCommon.sol.png and b/doc/surya/surya_graph/surya_graph_RuleEngineValidationCommon.sol.png differ
diff --git a/doc/surya/surya_graph/surya_graph_RuleInternal.sol.png b/doc/surya/surya_graph/surya_graph_RuleInternal.sol.png
index e48ebdb..c4af7de 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleInternal.sol.png and b/doc/surya/surya_graph/surya_graph_RuleInternal.sol.png differ
diff --git a/doc/surya/surya_graph/surya_graph_RuleSanctionList.sol.png b/doc/surya/surya_graph/surya_graph_RuleSanctionList.sol.png
index 53fed6e..b0d47f4 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleSanctionList.sol.png and b/doc/surya/surya_graph/surya_graph_RuleSanctionList.sol.png differ
diff --git a/doc/surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png b/doc/surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png
index a7849b2..c3dae87 100644
Binary files a/doc/surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png and b/doc/surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png differ
diff --git a/doc/surya/surya_report/surya_report_RuleAddressList.sol.md b/doc/surya/surya_report/surya_report_RuleAddressList.sol.md
index 5e11c02..0479115 100644
--- a/doc/surya/surya_report/surya_report_RuleAddressList.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleAddressList.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/abstract/RuleAddressList/RuleAddressList.sol | 7c34b72694e29bec42ce60e5d6c33971c583d109 |
+| ./rules/validation/abstract/RuleAddressList/RuleAddressList.sol | a5490babb4ea88b10fd8d5adfceafb4f14fae5e3 |
### Contracts Description Table
@@ -24,6 +24,7 @@
| └ | numberListedAddress | Public ❗️ | |NO❗️ |
| └ | addressIsListed | Public ❗️ | |NO❗️ |
| └ | addressIsListedBatch | Public ❗️ | |NO❗️ |
+| └ | hasRole | Public ❗️ | |NO❗️ |
| └ | _msgSender | Internal 🔒 | | |
| └ | _msgData | Internal 🔒 | | |
| └ | _contextSuffixLength | Internal 🔒 | | |
diff --git a/doc/surya/surya_report/surya_report_RuleAddressListInternal.sol.md b/doc/surya/surya_report/surya_report_RuleAddressListInternal.sol.md
index 223099a..6c302c5 100644
--- a/doc/surya/surya_report/surya_report_RuleAddressListInternal.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleAddressListInternal.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol | c32f77690c4c1ffcf5541e91fba1c838a17890ee |
+| ./rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol | bbe6d63aba425456591b7f2fa12e8aaa81c12bbb |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleAddressListInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleAddressListInvariantStorage.sol.md
index 26d1af6..bbf441e 100644
--- a/doc/surya/surya_report/surya_report_RuleAddressListInvariantStorage.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleAddressListInvariantStorage.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol | e67c0b26d249da1c2ac7d643f60b8f605ae24fb8 |
+| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol | 992fb7e7916167eae37d614c6fc47413afebcd82 |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleBlacklistInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleBlacklistInvariantStorage.sol.md
index ab2beae..641e318 100644
--- a/doc/surya/surya_report/surya_report_RuleBlacklistInvariantStorage.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleBlacklistInvariantStorage.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol | 6853e61c8827b0b47e12d55e1075cb9fdcc1058b |
+| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol | ba066cb426060eaca152daa5bb489970c2f9c539 |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleConditionalTransfer.sol.md b/doc/surya/surya_report/surya_report_RuleConditionalTransfer.sol.md
index 784cf24..2e44d15 100644
--- a/doc/surya/surya_report/surya_report_RuleConditionalTransfer.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleConditionalTransfer.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/operation/RuleConditionalTransfer.sol | eaf4569f1376ea3e0d975f9c9c1c5e078abf0c8d |
+| ./rules/operation/RuleConditionalTransfer.sol | d6c1c14a4196e7582019e913f409416d118edbd8 |
### Contracts Description Table
@@ -17,17 +17,18 @@
||||||
| **RuleConditionalTransfer** | Implementation | RuleValidateTransfer, IRuleOperation, RuleConditionalTransferOperator, MetaTxModuleStandalone |||
| └ | | Public ❗️ | 🛑 | MetaTxModuleStandalone |
+| └ | operateOnTransfer | Public ❗️ | 🛑 | onlyRole |
| └ | createTransferRequest | Public ❗️ | 🛑 |NO❗️ |
| └ | createTransferRequestBatch | Public ❗️ | 🛑 |NO❗️ |
| └ | cancelTransferRequest | Public ❗️ | 🛑 |NO❗️ |
| └ | cancelTransferRequestBatch | Public ❗️ | 🛑 |NO❗️ |
-| └ | _cancelTransferRequest | Internal 🔒 | 🛑 | |
| └ | getRequestTrade | Public ❗️ | |NO❗️ |
| └ | getRequestByStatus | Public ❗️ | |NO❗️ |
-| └ | operateOnTransfer | Public ❗️ | 🛑 | onlyRole |
| └ | detectTransferRestriction | Public ❗️ | |NO❗️ |
| └ | canReturnTransferRestrictionCode | External ❗️ | |NO❗️ |
| └ | messageForTransferRestriction | External ❗️ | |NO❗️ |
+| └ | _validateTransfer | Internal 🔒 | | |
+| └ | _cancelTransferRequest | Internal 🔒 | 🛑 | |
| └ | _validateBurnMint | Internal 🔒 | | |
| └ | _validateApproval | Internal 🔒 | | |
| └ | _msgSender | Internal 🔒 | | |
diff --git a/doc/surya/surya_report/surya_report_RuleConditionalTransferInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleConditionalTransferInvariantStorage.sol.md
index f8c33db..944844d 100644
--- a/doc/surya/surya_report/surya_report_RuleConditionalTransferInvariantStorage.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleConditionalTransferInvariantStorage.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol | d0c0060b1a859c8d1d91db9c023496ca709c3297 |
+| ./rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol | 71ed84800ef21f7f0964ed6dfa744eb444cded98 |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleConditionalTransferOperator.sol.md b/doc/surya/surya_report/surya_report_RuleConditionalTransferOperator.sol.md
index 6f572fc..e426528 100644
--- a/doc/surya/surya_report/surya_report_RuleConditionalTransferOperator.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleConditionalTransferOperator.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/operation/abstract/RuleConditionalTransferOperator.sol | 16b39f4a6d66b9b22ad4e7c5d673ce48afbeeb1f |
+| ./rules/operation/abstract/RuleConditionalTransferOperator.sol | 51e02c78db77b0f0984e14cfad7a5def39bc1964 |
### Contracts Description Table
@@ -29,8 +29,9 @@
| └ | approveTransferRequestBatch | Public ❗️ | 🛑 | onlyRole |
| └ | createTransferRequestWithApprovalBatch | Public ❗️ | 🛑 | onlyRole |
| └ | resetRequestStatusBatch | Public ❗️ | 🛑 | onlyRole |
+| └ | hasRole | Public ❗️ | |NO❗️ |
| └ | _approveTransferRequestKeyElement | Internal 🔒 | 🛑 | |
-| └ | _createTransferRequestWithApproval | Public ❗️ | 🛑 | onlyRole |
+| └ | _createTransferRequestWithApproval | Internal 🔒 | 🛑 | |
| └ | _resetRequestStatus | Internal 🔒 | 🛑 | |
| └ | _checkRequestStatus | Internal 🔒 | | |
| └ | _approveRequest | Internal 🔒 | 🛑 | |
diff --git a/doc/surya/surya_report/surya_report_RuleEngine.sol.md b/doc/surya/surya_report/surya_report_RuleEngine.sol.md
index bb1329a..90cf24e 100644
--- a/doc/surya/surya_report/surya_report_RuleEngine.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleEngine.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./RuleEngine.sol | 442f079ba0d2f4ec3c497569b1c891452bd967dc |
+| ./RuleEngine.sol | e13fc0c25fc199c56abd6dfbad3496431af1359f |
### Contracts Description Table
@@ -21,6 +21,7 @@
| └ | validateTransfer | Public ❗️ | |NO❗️ |
| └ | messageForTransferRestriction | External ❗️ | |NO❗️ |
| └ | operateOnTransfer | External ❗️ | 🛑 | onlyRole |
+| └ | hasRole | Public ❗️ | |NO❗️ |
| └ | _msgSender | Internal 🔒 | | |
| └ | _msgData | Internal 🔒 | | |
| └ | _contextSuffixLength | Internal 🔒 | | |
diff --git a/doc/surya/surya_report/surya_report_RuleEngineOperation.sol.md b/doc/surya/surya_report/surya_report_RuleEngineOperation.sol.md
index 792bdd8..9083954 100644
--- a/doc/surya/surya_report/surya_report_RuleEngineOperation.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleEngineOperation.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/RuleEngineOperation.sol | 1e2f612e6fd60aaec03b4ad3c9651085f87026c1 |
+| ./modules/RuleEngineOperation.sol | 1e1185c6f479770d66aabb692a54d331cbaf8f4d |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleEngineValidationCommon.sol.md b/doc/surya/surya_report/surya_report_RuleEngineValidationCommon.sol.md
index 8dc81cd..c806888 100644
--- a/doc/surya/surya_report/surya_report_RuleEngineValidationCommon.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleEngineValidationCommon.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/RuleEngineValidationCommon.sol | 922d0811abdd53bcc6a893c0c7877ec6402b6bfe |
+| ./modules/RuleEngineValidationCommon.sol | a942b2dc5791016dbf30c12b5778f1c65e167b0d |
### Contracts Description Table
@@ -18,14 +18,14 @@
| **RuleEngineValidationCommon** | Implementation | AccessControl, RuleInternal, IRuleEngineValidationCommon |||
| └ | setRulesValidation | Public ❗️ | 🛑 | onlyRole |
| └ | clearRulesValidation | Public ❗️ | 🛑 | onlyRole |
-| └ | _clearRulesValidation | Internal 🔒 | 🛑 | |
| └ | addRuleValidation | Public ❗️ | 🛑 | onlyRole |
| └ | removeRuleValidation | Public ❗️ | 🛑 | onlyRole |
-| └ | _removeRuleValidation | Internal 🔒 | 🛑 | |
| └ | rulesCountValidation | External ❗️ | |NO❗️ |
| └ | getRuleIndexValidation | External ❗️ | |NO❗️ |
| └ | ruleValidation | External ❗️ | |NO❗️ |
| └ | rulesValidation | External ❗️ | |NO❗️ |
+| └ | _clearRulesValidation | Internal 🔒 | 🛑 | |
+| └ | _removeRuleValidation | Internal 🔒 | 🛑 | |
### Legend
diff --git a/doc/surya/surya_report/surya_report_RuleInternal.sol.md b/doc/surya/surya_report/surya_report_RuleInternal.sol.md
index 598612a..0eddb1f 100644
--- a/doc/surya/surya_report/surya_report_RuleInternal.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleInternal.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./modules/RuleInternal.sol | c11e264f542c2c3250efdca62099221472d5c81e |
+| ./modules/RuleInternal.sol | 7bad85bfbad52abc2ab9082628bf6bba2ee116f4 |
### Contracts Description Table
@@ -19,7 +19,7 @@
| └ | _setRules | Internal 🔒 | 🛑 | |
| └ | _addRule | Internal 🔒 | 🛑 | |
| └ | _removeRule | Internal 🔒 | 🛑 | |
-| └ | getRuleIndex | Internal 🔒 | | |
+| └ | _getRuleIndex | Internal 🔒 | | |
### Legend
diff --git a/doc/surya/surya_report/surya_report_RuleSanctionList.sol.md b/doc/surya/surya_report/surya_report_RuleSanctionList.sol.md
index 45eaabb..0140d39 100644
--- a/doc/surya/surya_report/surya_report_RuleSanctionList.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleSanctionList.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/RuleSanctionList.sol | 44e135ac7c8e51d025a876e23e08a9fdc968a3a3 |
+| ./rules/validation/RuleSanctionList.sol | 9d4f8926804ab2569d4f0e26e73c348c831fee3f |
### Contracts Description Table
@@ -24,6 +24,8 @@
| └ | detectTransferRestriction | Public ❗️ | |NO❗️ |
| └ | canReturnTransferRestrictionCode | External ❗️ | |NO❗️ |
| └ | messageForTransferRestriction | External ❗️ | |NO❗️ |
+| └ | hasRole | Public ❗️ | |NO❗️ |
+| └ | _setSanctionListOracle | Internal 🔒 | 🛑 | |
| └ | _msgSender | Internal 🔒 | | |
| └ | _msgData | Internal 🔒 | | |
| └ | _contextSuffixLength | Internal 🔒 | | |
diff --git a/doc/surya/surya_report/surya_report_RuleSanctionListInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleSanctionListInvariantStorage.sol.md
index 3f6b036..5126a0e 100644
--- a/doc/surya/surya_report/surya_report_RuleSanctionListInvariantStorage.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleSanctionListInvariantStorage.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/abstract/RuleSanctionListInvariantStorage.sol | c3a182c89805e4bd84eab1a1a8c9cad843eb6fdf |
+| ./rules/validation/abstract/RuleSanctionListInvariantStorage.sol | dfda2a2bbee5719c4820c0df23d78552fa08cc90 |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleWhitelist.sol.md b/doc/surya/surya_report/surya_report_RuleWhitelist.sol.md
index 4b5d8e8..24eadcc 100644
--- a/doc/surya/surya_report/surya_report_RuleWhitelist.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleWhitelist.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/RuleWhitelist.sol | 23d835c06c94cfc07433db85afa3a493771d44b4 |
+| ./rules/validation/RuleWhitelist.sol | c2fba89995e430d0f0965b24bf853772f3a51184 |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleWhitelistCommon.sol.md b/doc/surya/surya_report/surya_report_RuleWhitelistCommon.sol.md
index f0fb30b..276b8be 100644
--- a/doc/surya/surya_report/surya_report_RuleWhitelistCommon.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleWhitelistCommon.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/abstract/RuleWhitelistCommon.sol | 4f33cf6f0e6d78cc0f2a2ffaa19c21bb7be95efa |
+| ./rules/validation/abstract/RuleWhitelistCommon.sol | 38cb316c3cba0fc3945d7b4ba1069ae4f3480bb0 |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleWhitelistInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleWhitelistInvariantStorage.sol.md
index 8218aa1..8591a82 100644
--- a/doc/surya/surya_report/surya_report_RuleWhitelistInvariantStorage.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleWhitelistInvariantStorage.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol | 037d720155c2c175e32d029e91fa0f639c0afe6c |
+| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol | a49ed4b2f4e846464b80004e3d79c797320b6e5b |
### Contracts Description Table
diff --git a/doc/surya/surya_report/surya_report_RuleWhitelistWrapper.sol.md b/doc/surya/surya_report/surya_report_RuleWhitelistWrapper.sol.md
index 6b1d582..69ab3b3 100644
--- a/doc/surya/surya_report/surya_report_RuleWhitelistWrapper.sol.md
+++ b/doc/surya/surya_report/surya_report_RuleWhitelistWrapper.sol.md
@@ -5,7 +5,7 @@
| File Name | SHA-1 Hash |
|-------------|--------------|
-| ./rules/validation/RuleWhitelistWrapper.sol | 6fb02b05c189d5c5be34023ec0ee623996068517 |
+| ./rules/validation/RuleWhitelistWrapper.sol | b9e309a42544f758b4cfbe05e1739e2a828ce237 |
### Contracts Description Table
@@ -18,6 +18,7 @@
| **RuleWhitelistWrapper** | Implementation | RuleEngineValidationCommon, MetaTxModuleStandalone, RuleWhitelistCommon |||
| └ | | Public ❗️ | 🛑 | MetaTxModuleStandalone |
| └ | detectTransferRestriction | Public ❗️ | |NO❗️ |
+| └ | hasRole | Public ❗️ | |NO❗️ |
| └ | _msgSender | Internal 🔒 | | |
| └ | _msgData | Internal 🔒 | | |
| └ | _contextSuffixLength | Internal 🔒 | | |
diff --git a/src/RuleEngine.sol b/src/RuleEngine.sol
index 48b95c8..6cc14f8 100644
--- a/src/RuleEngine.sol
+++ b/src/RuleEngine.sol
@@ -20,7 +20,7 @@ contract RuleEngine is
* @notice
* Get the current version of the smart contract
*/
- string public constant VERSION = "2.0.4";
+ string public constant VERSION = "2.0.5";
/**
* @param admin Address of the contract (Access Control)
diff --git a/src/rules/operation/RuleConditionalTransfer.sol b/src/rules/operation/RuleConditionalTransfer.sol
index 733424b..ee5e5c0 100644
--- a/src/rules/operation/RuleConditionalTransfer.sol
+++ b/src/rules/operation/RuleConditionalTransfer.sol
@@ -330,17 +330,28 @@ contract RuleConditionalTransfer is
bytes32 key
) internal view returns (bool isValid) {
// If automatic approval is activate and time to approve the request has passed
- // Warning: overflow possible if timeLimitBeforeAutomaticApproval == max(uint256)
- bool automaticApprovalCondition = options
+ if(transferRequests[key].status == STATUS.NONE
+ ||
+ transferRequests[key].status == STATUS.DENIED
+ ||
+ transferRequests[key].status == STATUS.EXECUTED)
+ {
+ return false;
+ }
+ bool isTransferApproved;
+ bool automaticApprovalCondition;
+ if(transferRequests[key].status ==
+ STATUS.APPROVED){
+ isTransferApproved = (transferRequests[key].maxTime >= block.timestamp);
+ } else if(options
.automaticApproval
- .isActivate &&
- block.timestamp >=
+ .isActivate){
+ // Warning: overflow possible if timeLimitBeforeAutomaticApproval == max(uint256)
+ automaticApprovalCondition= block.timestamp >=
(transferRequests[key].askTime +
options.automaticApproval.timeLimitBeforeAutomaticApproval);
+ }
// If the transfer is approved and delay to perform the transfer is respected
- bool isTransferApproved = (transferRequests[key].status ==
- STATUS.APPROVED) &&
- (transferRequests[key].maxTime >= block.timestamp);
if (automaticApprovalCondition || isTransferApproved) {
return true;
} else {
diff --git a/src/rules/operation/abstract/RuleConditionalTransferOperator.sol b/src/rules/operation/abstract/RuleConditionalTransferOperator.sol
index 3d0d9a2..b96b55a 100644
--- a/src/rules/operation/abstract/RuleConditionalTransferOperator.sol
+++ b/src/rules/operation/abstract/RuleConditionalTransferOperator.sol
@@ -59,7 +59,7 @@ abstract contract RuleConditionalTransferOperator is
}
/**
- * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
+ * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
* To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
* If the allowance is not sufficient, the request will be approved, but without performing the transfer.
*/
@@ -332,6 +332,7 @@ abstract contract RuleConditionalTransferOperator is
abi.encode(keyElement_.from, keyElement_.to, keyElement_.value)
);
if (_checkRequestStatus(key)) {
+ // Only if it is a new request
TransferRequest memory newTransferApproval = TransferRequest({
key: key,
id: requestId,
@@ -380,6 +381,9 @@ abstract contract RuleConditionalTransferOperator is
);
}
+ /**
+ * @dev check if it is a new request or not
+ */
function _checkRequestStatus(bytes32 key) internal view returns (bool) {
// Status NONE not enough because reset is possible
return
diff --git a/test/RuleConditionalTransfer/CMTATIntegration.t.sol b/test/RuleConditionalTransfer/CMTATIntegration.t.sol
index 4e7f358..8f04ddf 100644
--- a/test/RuleConditionalTransfer/CMTATIntegration.t.sol
+++ b/test/RuleConditionalTransfer/CMTATIntegration.t.sol
@@ -5,28 +5,12 @@ import "forge-std/Test.sol";
import "CMTAT/CMTAT_STANDALONE.sol";
import "../HelperContract.sol";
import "src/RuleEngine.sol";
+import "./utils/CMTATIntegrationShare.sol";
/**
* @title Integration test with the CMTAT
*/
-contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
- uint256 ADDRESS1_BALANCE_INIT = 31;
- uint256 ADDRESS2_BALANCE_INIT = 32;
- uint256 ADDRESS3_BALANCE_INIT = 33;
-
- uint256 FLAG = 5;
-
- uint256 defaultValue = 10;
- bytes32 defaultKey =
- keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
-
- TransferRequestKeyElement transferRequestInput =
- TransferRequestKeyElement({
- from: ADDRESS1,
- to: ADDRESS2,
- value: defaultValue
- });
-
+contract CMTATIntegrationConditionalTransfer is Test, HelperContract, CMTATIntegrationShare {
// Arrange
function setUp() public {
TIME_LIMIT memory timeLimit_ = TIME_LIMIT({
@@ -108,429 +92,70 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
/******* Transfer *******/
function testCannotTransferWithoutApproval() public {
- // Arrange
- vm.prank(ADDRESS1);
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- 21
- )
- );
- // Act
- CMTAT_CONTRACT.transfer(ADDRESS2, 21);
+ CMTATIntegrationShare.testShareCannotTransferWithoutApproval();
}
function testCanMakeATransferIfApproved() public {
- // Arrange
- vm.prank(ADDRESS1);
- // Act
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
- ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
-
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
-
- // Act
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
-
- // Assert
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT - defaultValue);
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
- assertEq(resUint256, ADDRESS2_BALANCE_INIT + defaultValue);
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
- assertEq(resUint256, 33);
+ CMTATIntegrationShare.testShareCanMakeATransferIfApproved();
}
function testCanMakeAPartialTransferIfPartiallyApproved() public {
- // Arrange
- _createTransferRequest();
-
- uint256 partialValue = 5;
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
- emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- partialValue,
- true
- );
-
- // Act
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(key, ADDRESS1, ADDRESS2, partialValue, 1);
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, partialValue);
-
- // Assert
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT - partialValue);
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
- assertEq(resUint256, ADDRESS2_BALANCE_INIT + partialValue);
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
- assertEq(resUint256, 33);
+ CMTATIntegrationShare.testShareCanMakeAPartialTransferIfPartiallyApproved();
}
function testCannotMakeAWholeTransferIfPartiallyApproved() public {
- // Arrange
- _createTransferRequest();
- uint256 partialValue = 5;
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
- emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- partialValue,
- true
- );
-
- // Act
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- defaultValue
- )
- );
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCannotMakeAWholeTransferIfPartiallyApproved();
}
-
function testCannotMakeATransferIfDelayExceeded() public {
- // Arrange
- vm.prank(ADDRESS1);
- // Act
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
- ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
-
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
-
- // +30 days and one second
- vm.warp(block.timestamp + 2592001);
- // Act
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- defaultValue
- )
- );
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ // // +30 days and one second
+ CMTATIntegrationShare.testShareCannotMakeATransferIfDelayExceeded(2592001);
}
function testCannotMakeATransferIfDelayJustInTime() public {
- // Arrange
- _createTransferRequest();
-
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
// 30 days
- vm.warp(block.timestamp + 2592000);
- // Act
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCannotMakeATransferIfDelayJustInTime(2592000);
}
function testCanSetTimeLimitWithTransferExceeded() public {
- TIME_LIMIT memory timeLimit_ = TIME_LIMIT({
- timeLimitToApprove: 1 days,
- timeLimitToTransfer: 1 days
- });
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setTimeLimit(timeLimit_);
- // Arrange
- _createTransferRequest();
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
-
- // Assert
+ // Assert
// Timeout
// >1 days
- vm.warp(block.timestamp + 1 days + 1 seconds);
-
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- defaultValue
- )
- );
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCanSetTimeLimitWithTransferExceeded(1 days + 1 seconds);
}
function testCanMintWithoutApproval() public {
- // Act
- vm.prank(DEFAULT_ADMIN_ADDRESS);
- CMTAT_CONTRACT.mint(ADDRESS1, 11);
-
- // Assert
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT + 11);
+ CMTATIntegrationShare.testShareCanMintWithoutApproval();
}
function testCanBurnWithoutApproval() public {
- // Act
- vm.prank(DEFAULT_ADMIN_ADDRESS);
- CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "test");
-
- // Assert
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT - defaultValue);
+ CMTATIntegrationShare.testShareCanBurnWithoutApproval();
}
function testCannotMintWithoutApproval() public {
- ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval: false,
- authorizedBurnWithoutApproval: true
- });
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
- // Act
- vm.prank(DEFAULT_ADMIN_ADDRESS);
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ZERO_ADDRESS,
- ADDRESS1,
- 11
- )
- );
- CMTAT_CONTRACT.mint(ADDRESS1, 11);
+ CMTATIntegrationShare.testShareCannotMintWithoutApproval();
}
function testCannotBurnWithoutApproval() public {
- ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval: true,
- authorizedBurnWithoutApproval: false
- });
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
- // Act
- vm.prank(DEFAULT_ADMIN_ADDRESS);
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ZERO_ADDRESS,
- defaultValue
- )
- );
- CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "test");
+ CMTATIntegrationShare.testShareCannotBurnWithoutApproval();
}
function testAutomaticTransferIfOptionsSet() public {
- AUTOMATIC_TRANSFER memory automaticTransferTest = AUTOMATIC_TRANSFER({
- isActivate: true,
- cmtat: CMTAT_CONTRACT
- });
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setAutomaticTransfer(automaticTransferTest);
-
- // Aproval
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.approve(address(ruleConditionalTransfer), defaultValue);
-
- // Arrange
- _createTransferRequest();
-
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
+ CMTATIntegrationShare.testShareAutomaticTransferIfOptionsSet();
}
function testCanTransferIfAutomaticApprovalSetAndTimeExceedsJustInTime()
public
{
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
- isActivate: true,
- timeLimitBeforeAutomaticApproval: 90 days
- });
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- // Arrange
- _createTransferRequest();
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
-
- vm.warp(block.timestamp + 90 days);
- // Act
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertEq(resBool, true);
- vm.prank(ADDRESS1);
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCanTransferIfAutomaticApprovalSetAndTimeExceedsJustInTime();
}
function testCanTransferIfAutomaticApprovalSetAndTimeExceeds() public {
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
- isActivate: true,
- timeLimitBeforeAutomaticApproval: 90 days
- });
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- // Arrange
- _createTransferRequest();
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
-
- vm.warp(block.timestamp + 91 days);
- // Act
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertEq(resBool, true);
- vm.prank(ADDRESS1);
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCanTransferIfAutomaticApprovalSetAndTimeExceeds();
}
function testCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds()
public
{
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
- isActivate: true,
- timeLimitBeforeAutomaticApproval: 90 days
- });
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- // Arrange
- _createTransferRequest();
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
-
- resBool = CMTAT_CONTRACT.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- // Time not exceeds
- vm.warp(block.timestamp + 85 days);
- // Act
- vm.prank(ADDRESS1);
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- defaultValue
- )
- );
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds();
}
}
diff --git a/test/RuleConditionalTransfer/CMTATIntegrationConditionalTransfer.t.sol b/test/RuleConditionalTransfer/CMTATIntegrationConditionalTransfer.t.sol
index 87d796e..bfd35b5 100644
--- a/test/RuleConditionalTransfer/CMTATIntegrationConditionalTransfer.t.sol
+++ b/test/RuleConditionalTransfer/CMTATIntegrationConditionalTransfer.t.sol
@@ -5,27 +5,12 @@ import "forge-std/Test.sol";
import "CMTAT/CMTAT_STANDALONE.sol";
import "../HelperContract.sol";
import "src/RuleEngine.sol";
+import "./utils/CMTATIntegrationShare.sol";
/**
* @title Integration test with the CMTAT
*/
-contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
- uint256 ADDRESS1_BALANCE_INIT = 31;
- uint256 ADDRESS2_BALANCE_INIT = 32;
- uint256 ADDRESS3_BALANCE_INIT = 33;
-
- uint256 FLAG = 5;
-
- uint256 defaultValue = 10;
- bytes32 defaultKey =
- keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
-
- TransferRequestKeyElement transferRequestInput =
- TransferRequestKeyElement({
- from: ADDRESS1,
- to: ADDRESS2,
- value: defaultValue
- });
+contract CMTATIntegrationConditionalTransfer is Test, HelperContract, CMTATIntegrationShare {
// Arrange
function setUp() public {
@@ -273,404 +258,65 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
/***** Test from CMTAT integration */
function testCannotTransferWithoutApproval() public {
- // Arrange
- vm.prank(ADDRESS1);
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- 21
- )
- );
- // Act
- CMTAT_CONTRACT.transfer(ADDRESS2, 21);
+ CMTATIntegrationShare.testShareCannotTransferWithoutApproval();
}
function testCanMakeATransferIfApproved() public {
- // Arrange
- vm.prank(ADDRESS1);
- // Act
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
- ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
-
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
-
- // Act
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
-
- // Assert
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT - defaultValue);
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
- assertEq(resUint256, ADDRESS2_BALANCE_INIT + defaultValue);
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
- assertEq(resUint256, 33);
+ CMTATIntegrationShare.testShareCanMakeATransferIfApproved();
}
-
function testCanMakeAPartialTransferIfPartiallyApproved() public {
- // Arrange
- _createTransferRequest();
-
- uint256 partialValue = 5;
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
- emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- partialValue,
- true
- );
-
- // Act
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(key, ADDRESS1, ADDRESS2, partialValue, 1);
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, partialValue);
-
- // Assert
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT - partialValue);
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
- assertEq(resUint256, ADDRESS2_BALANCE_INIT + partialValue);
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
- assertEq(resUint256, 33);
+ CMTATIntegrationShare.testShareCanMakeAPartialTransferIfPartiallyApproved();
}
function testCannotMakeAWholeTransferIfPartiallyApproved() public {
- // Arrange
- _createTransferRequest();
- uint256 partialValue = 5;
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
- emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- partialValue,
- true
- );
-
- // Act
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- defaultValue
- )
- );
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCannotMakeAWholeTransferIfPartiallyApproved();
}
function testCannotMakeATransferIfDelayExceeded() public {
- // Arrange
- vm.prank(ADDRESS1);
- // Act
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
- ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
-
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
-
- // +30 days and one second
- vm.warp(block.timestamp + 2592001);
- // Act
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- defaultValue
- )
- );
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCannotMakeATransferIfDelayExceeded(2592001);
}
function testCannotMakeATransferIfDelayJustInTime() public {
- // Arrange
- _createTransferRequest();
-
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
// 30 days
- vm.warp(block.timestamp + 2592000);
- // Act
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCannotMakeATransferIfDelayJustInTime(2592000);
}
function testCanSetTimeLimitWithTransferExceeded() public {
- TIME_LIMIT memory timeLimit_ = TIME_LIMIT({
- timeLimitToApprove: 1 days,
- timeLimitToTransfer: 1 days
- });
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setTimeLimit(timeLimit_);
- // Arrange
- _createTransferRequest();
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
-
- // Assert
- // Timeout
- // >1 days
- vm.warp(block.timestamp + 1 days + 1 seconds);
-
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- defaultValue
- )
- );
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCanSetTimeLimitWithTransferExceeded(1 days + 1 seconds);
}
function testCanMintWithoutApproval() public {
- // Act
- vm.prank(DEFAULT_ADMIN_ADDRESS);
- CMTAT_CONTRACT.mint(ADDRESS1, 11);
-
- // Assert
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT + 11);
+ CMTATIntegrationShare.testShareCanMintWithoutApproval();
}
function testCanBurnWithoutApproval() public {
- // Act
- vm.prank(DEFAULT_ADMIN_ADDRESS);
- CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "test");
-
- // Assert
- resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT - defaultValue);
+ CMTATIntegrationShare.testShareCanBurnWithoutApproval();
}
function testCannotMintWithoutApproval() public {
- ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval: false,
- authorizedBurnWithoutApproval: true
- });
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
- // Act
- vm.prank(DEFAULT_ADMIN_ADDRESS);
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ZERO_ADDRESS,
- ADDRESS1,
- 11
- )
- );
- CMTAT_CONTRACT.mint(ADDRESS1, 11);
+ CMTATIntegrationShare.testShareCannotMintWithoutApproval();
}
function testCannotBurnWithoutApproval() public {
- ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval: true,
- authorizedBurnWithoutApproval: false
- });
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
- // Act
- vm.prank(DEFAULT_ADMIN_ADDRESS);
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ZERO_ADDRESS,
- defaultValue
- )
- );
- CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "test");
+ CMTATIntegrationShare.testShareCannotBurnWithoutApproval();
}
-
- function testAutomaticTransferIfOptionsSet() public {
- AUTOMATIC_TRANSFER memory automaticTransferTest = AUTOMATIC_TRANSFER({
- isActivate: true,
- cmtat: CMTAT_CONTRACT
- });
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setAutomaticTransfer(automaticTransferTest);
-
- // Aproval
- vm.prank(ADDRESS1);
- CMTAT_CONTRACT.approve(address(ruleConditionalTransfer), defaultValue);
-
- // Arrange
- _createTransferRequest();
-
- // Act
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- vm.expectEmit(true, true, true, true);
- emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(
- transferRequestInput,
- 0,
- true
- );
+ function testAutomaticTransferIfOptionsSet() public {
+ CMTATIntegrationShare.testShareAutomaticTransferIfOptionsSet();
}
function testCanTransferIfAutomaticApprovalSetAndTimeExceedsJustInTime()
public
{
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
- isActivate: true,
- timeLimitBeforeAutomaticApproval: 90 days
- });
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- // Arrange
- _createTransferRequest();
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
-
- vm.warp(block.timestamp + 90 days);
- // Act
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertEq(resBool, true);
- vm.prank(ADDRESS1);
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCanTransferIfAutomaticApprovalSetAndTimeExceedsJustInTime();
}
function testCanTransferIfAutomaticApprovalSetAndTimeExceeds() public {
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
- isActivate: true,
- timeLimitBeforeAutomaticApproval: 90 days
- });
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
- // Arrange
- _createTransferRequest();
-
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertFalse(resBool);
-
- vm.warp(block.timestamp + 91 days);
- // Act
- resBool = ruleConditionalTransfer.validateTransfer(
- ADDRESS1,
- ADDRESS2,
- defaultValue
- );
- assertEq(resBool, true);
- vm.prank(ADDRESS1);
- vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCanTransferIfAutomaticApprovalSetAndTimeExceeds();
}
function testCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds()
public
{
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
- isActivate: true,
- timeLimitBeforeAutomaticApproval: 90 days
- });
- vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
- // Arrange
- _createTransferRequest();
-
- // Time not exceeds
- vm.warp(block.timestamp + 85 days);
- // Act
- vm.prank(ADDRESS1);
- vm.expectRevert(
- abi.encodeWithSelector(
- Errors.CMTAT_InvalidTransfer.selector,
- ADDRESS1,
- ADDRESS2,
- defaultValue
- )
- );
- CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ CMTATIntegrationShare.testShareCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds();
}
}
diff --git a/test/RuleConditionalTransfer/CMTATIntegrationTest2.t.sol b/test/RuleConditionalTransfer/CMTATIntegrationTest2.t.sol
new file mode 100644
index 0000000..7e1252e
--- /dev/null
+++ b/test/RuleConditionalTransfer/CMTATIntegrationTest2.t.sol
@@ -0,0 +1,182 @@
+// SPDX-License-Identifier: MPL-2.0
+pragma solidity ^0.8.20;
+
+import "forge-std/Test.sol";
+import "CMTAT/CMTAT_STANDALONE.sol";
+import "../HelperContract.sol";
+import "src/RuleEngine.sol";
+import "./utils/CMTATIntegrationShare.sol";
+
+/**
+ * @title Integration test with the CMTAT
+ * @dev set blocktimestamp to a value different from 0
+ */
+contract CMTATIntegrationConditionalTransferWithTimeStampSet is Test, HelperContract, CMTATIntegrationShare {
+ uint256 TIME_LIMIT_AUTO_APPROVAL = 259200; //3 days;
+ uint256 TIME_LIMIT_TO_APPROVE = 432000; //5 days;
+ uint256 TIME_LIMIT_TO_TRANSFER = 259200; //3 days
+ // Arrange
+ function setUp() public {
+ // global arrange
+ cmtatDeployment = new CMTATDeployment();
+ CMTAT_CONTRACT = cmtatDeployment.cmtat();
+
+ TIME_LIMIT memory timeLimit_ = TIME_LIMIT({
+ timeLimitToApprove: TIME_LIMIT_TO_APPROVE, // 5days
+ timeLimitToTransfer: TIME_LIMIT_TO_TRANSFER
+ });
+ ISSUANCE memory issuanceOption_ = ISSUANCE({
+ authorizedMintWithoutApproval: true,
+ authorizedBurnWithoutApproval: true
+ });
+
+ AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
+ isActivate: true,
+ timeLimitBeforeAutomaticApproval: TIME_LIMIT_AUTO_APPROVAL
+ });
+
+ AUTOMATIC_TRANSFER memory automaticTransfer_ = AUTOMATIC_TRANSFER({
+ isActivate: true,
+ cmtat: IERC20(address(CMTAT_CONTRACT))
+ });
+ OPTION memory options = OPTION({
+ issuance: issuanceOption_,
+ timeLimit: timeLimit_,
+ automaticApproval: automaticApproval_,
+ automaticTransfer: automaticTransfer_
+ });
+
+
+
+ // RuleEngine
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleEngineMock = new RuleEngine(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS,
+ address(CMTAT_CONTRACT)
+ );
+
+ // RuleConditionalTransfer
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleConditionalTransfer = new RuleConditionalTransfer(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
+ // specific arrange
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleConditionalTransfer.grantRole(
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE,
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS
+ );
+
+ // RuleEngine
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleEngineMock.addRuleOperation(ruleConditionalTransfer);
+
+ // Mint
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.mint(ADDRESS1, ADDRESS1_BALANCE_INIT);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.mint(ADDRESS2, ADDRESS2_BALANCE_INIT);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.mint(ADDRESS3, ADDRESS3_BALANCE_INIT);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+
+ // We set the Rule Engine
+ CMTAT_CONTRACT.setRuleEngine(ruleEngineMock);
+
+ vm.warp(1734531338);
+ }
+
+ function _createTransferRequest() internal {
+ vm.prank(ADDRESS1);
+ // Act
+ vm.expectEmit(true, true, true, true);
+ emit transferWaiting(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
+ }
+
+ /******* Transfer *******/
+ function testCannotTransferWithoutApproval() public {
+ // Arrange - Assert
+ // ConditionalTransfer
+ resUint8 = ruleConditionalTransfer.detectTransferRestriction(
+ address(0xD65Fb7036518F4B34482E0a1905Dc6e3Fc379FF0),
+ address(0xD65Fb7036518F4B34482E0a1905Dc6e3Fc379FF0),
+ defaultValue
+ );
+ assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
+ resUint8 = ruleConditionalTransfer.detectTransferRestriction(
+ ADDRESS1,
+ ADDRESS2,
+ 5
+ );
+ assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
+ // Assert
+ // Arrange
+ CMTATIntegrationShare.testShareCannotTransferWithoutApproval();
+ }
+
+ function testCanMakeATransferIfApproved() public {
+ CMTATIntegrationShare.testShareCanMakeATransferIfApproved();
+ }
+
+ function testCanMakeAPartialTransferIfPartiallyApproved() public {
+ CMTATIntegrationShare.testShareCanMakeAPartialTransferIfPartiallyApproved();
+ }
+
+ function testCannotMakeAWholeTransferIfPartiallyApproved() public {
+ CMTATIntegrationShare.testShareCannotMakeAWholeTransferIfPartiallyApproved();
+
+ }
+
+ function testCannotMakeATransferIfDelayExceeded() public {
+ CMTATIntegrationShare.testShareCannotMakeATransferIfDelayExceeded(TIME_LIMIT_TO_TRANSFER + 1 seconds);
+ }
+
+ function testCanMakeATransferIfDelayJustInTime() public {
+ CMTATIntegrationShare.testShareCannotMakeATransferIfDelayJustInTime(TIME_LIMIT_TO_TRANSFER);
+ }
+
+ function testCanSetTimeLimitWithTransferExceeded() public {
+ CMTATIntegrationShare.testShareCanSetTimeLimitWithTransferExceeded(1 days + 1 seconds);
+ }
+
+ function testCanMintWithoutApproval() public {
+ CMTATIntegrationShare.testShareCanMintWithoutApproval();
+ }
+
+ function testCanBurnWithoutApproval() public {
+ CMTATIntegrationShare.testShareCanBurnWithoutApproval();
+ }
+
+ function testCannotMintWithoutApproval() public {
+ CMTATIntegrationShare.testShareCannotMintWithoutApproval();
+ }
+
+ function testCannotBurnWithoutApproval() public {
+ CMTATIntegrationShare.testShareCannotBurnWithoutApproval();
+ }
+
+ function testAutomaticTransferIfOptionsSet() public {
+ CMTATIntegrationShare.testShareAutomaticTransferIfOptionsSet();
+ }
+
+ function testCanTransferIfAutomaticApprovalSetAndTimeExceedsJustInTime()
+ public
+ {
+ CMTATIntegrationShare.testShareCanTransferIfAutomaticApprovalSetAndTimeExceedsJustInTime();
+ }
+
+ function testCanTransferIfAutomaticApprovalSetAndTimeExceeds() public {
+ CMTATIntegrationShare.testShareCanTransferIfAutomaticApprovalSetAndTimeExceeds();
+ }
+
+ function testCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds()
+ public
+ {
+ CMTATIntegrationShare.testShareCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds();
+ }
+}
diff --git a/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol
index 34d15c0..6703fa6 100644
--- a/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol
+++ b/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol
@@ -59,7 +59,7 @@ contract RuleConditionalTransferTest is Test, HelperContract {
// Arrange
function setUp() public {
TIME_LIMIT memory timeLimit_ = TIME_LIMIT({
- timeLimitToApprove: 7 days,
+ timeLimitToApprove: 3 days,
timeLimitToTransfer: 30 days
});
@@ -640,7 +640,6 @@ contract RuleConditionalTransferTest is Test, HelperContract {
function testCanApproveRequestCreatedByHolderWithId() public {
// Arrange
_createTransferRequest();
-
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
@@ -792,6 +791,8 @@ contract RuleConditionalTransferTest is Test, HelperContract {
function testCanDeniedRequestCreatedByHolderWithId() public {
// Arrange
_createTransferRequest();
+ // can still approve
+ vm.warp(block.timestamp + 1);
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
diff --git a/test/RuleConditionalTransfer/RuleConditionalTransferAccessControl.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransferAccessControl.t.sol
index 8054259..07cf3dd 100644
--- a/test/RuleConditionalTransfer/RuleConditionalTransferAccessControl.t.sol
+++ b/test/RuleConditionalTransfer/RuleConditionalTransferAccessControl.t.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../HelperContract.sol";
import "src/RuleEngine.sol";
-import "./RuleCTDeployment.sol";
+import "./utils/RuleCTDeployment.sol";
/**
* @title Tests on the Access Control
diff --git a/test/RuleConditionalTransfer/RuleConditionalTransferDeployment.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransferDeployment.t.sol
index 954ba40..fa6cf9f 100644
--- a/test/RuleConditionalTransfer/RuleConditionalTransferDeployment.t.sol
+++ b/test/RuleConditionalTransfer/RuleConditionalTransferDeployment.t.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../HelperContract.sol";
import "src/RuleEngine.sol";
-import "./RuleCTDeployment.sol";
+import "./utils/RuleCTDeployment.sol";
/**
* @title General functions of the RuleWhitelist
diff --git a/test/RuleConditionalTransfer/RuleConditionalTransferRestriction.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransferRestriction.t.sol
index 4c6be2f..35eeb58 100644
--- a/test/RuleConditionalTransfer/RuleConditionalTransferRestriction.t.sol
+++ b/test/RuleConditionalTransfer/RuleConditionalTransferRestriction.t.sol
@@ -56,6 +56,15 @@ contract RuleEngineOperationTest is Test, HelperContract {
}
function testCanDetectTransferRestrictionOK() public {
+ // Arrange - Assert
+ resUint8 = ruleConditionalTransfer.detectTransferRestriction(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+
+ // Assert
+ assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
// Arrange
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
diff --git a/test/RuleConditionalTransfer/utils/CMTATIntegrationShare.sol b/test/RuleConditionalTransfer/utils/CMTATIntegrationShare.sol
new file mode 100644
index 0000000..be4cb79
--- /dev/null
+++ b/test/RuleConditionalTransfer/utils/CMTATIntegrationShare.sol
@@ -0,0 +1,483 @@
+// SPDX-License-Identifier: MPL-2.0
+pragma solidity ^0.8.20;
+
+import "forge-std/Test.sol";
+import "CMTAT/CMTAT_STANDALONE.sol";
+import "../../HelperContract.sol";
+import "src/RuleEngine.sol";
+
+/**
+ * @title Integration testShare with the CMTAT
+ */
+contract CMTATIntegrationShare is Test, HelperContract {
+ uint256 ADDRESS1_BALANCE_INIT = 31;
+ uint256 ADDRESS2_BALANCE_INIT = 32;
+ uint256 ADDRESS3_BALANCE_INIT = 33;
+
+ uint256 FLAG = 5;
+
+ uint256 defaultValue = 10;
+ bytes32 defaultKey =
+ keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+
+ TransferRequestKeyElement transferRequestInput =
+ TransferRequestKeyElement({
+ from: ADDRESS1,
+ to: ADDRESS2,
+ value: defaultValue
+ });
+
+ function _createTransferRequestShare() internal {
+ vm.prank(ADDRESS1);
+ // Act
+ vm.expectEmit(true, true, true, true);
+ emit transferWaiting(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
+ }
+
+ /******* Transfer *******/
+ function testShareCannotTransferWithoutApproval() internal {
+ // Arrange
+ vm.prank(ADDRESS1);
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ 21
+ )
+ );
+ // Act
+ CMTAT_CONTRACT.transfer(ADDRESS2, 21);
+ }
+
+ function testShareCanMakeATransferIfApproved() internal {
+ // Arrange - Assert
+ // ConditionalTransfer
+ resUint8 = ruleConditionalTransfer.detectTransferRestriction(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ // Assert
+ assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
+ // CMTAT
+ // Arrange - Assert
+ resUint8 = CMTAT_CONTRACT.detectTransferRestriction(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ // Assert
+ assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
+ // Arrange
+ vm.prank(ADDRESS1);
+ // Act
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
+
+ // Act
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ vm.expectEmit(true, true, true, true);
+ emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
+
+ // Act
+ vm.expectEmit(true, true, true, true);
+ emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+
+ // Assert
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
+ assertEq(resUint256, ADDRESS1_BALANCE_INIT - defaultValue);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
+ assertEq(resUint256, ADDRESS2_BALANCE_INIT + defaultValue);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
+ assertEq(resUint256, 33);
+ }
+
+ function testShareCanMakeAPartialTransferIfPartiallyApproved() internal {
+ // Arrange
+ _createTransferRequestShare();
+
+ uint256 partialValue = 5;
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
+ // Act
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ vm.expectEmit(true, true, true, true);
+ emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
+ emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ true
+ );
+
+ // Act
+ vm.expectEmit(true, true, true, true);
+ emit transferProcessed(key, ADDRESS1, ADDRESS2, partialValue, 1);
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, partialValue);
+
+ // Assert
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
+ assertEq(resUint256, ADDRESS1_BALANCE_INIT - partialValue);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
+ assertEq(resUint256, ADDRESS2_BALANCE_INIT + partialValue);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
+ assertEq(resUint256, 33);
+ }
+
+ function testShareCannotMakeAWholeTransferIfPartiallyApproved() internal {
+ // Arrange
+ _createTransferRequestShare();
+ uint256 partialValue = 5;
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
+ // Act
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ vm.expectEmit(true, true, true, true);
+ emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
+ emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ true
+ );
+
+ // Act
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ }
+
+ function testShareCannotMakeATransferIfDelayExceeded(uint256 timeDelay) internal {
+ // Arrange
+ vm.prank(ADDRESS1);
+ // Act
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
+
+ // Act
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ vm.expectEmit(true, true, true, true);
+ emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
+
+
+ vm.warp(block.timestamp + timeDelay);
+ // Act
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ }
+
+ function testShareCannotMakeATransferIfDelayJustInTime(uint256 timeDelay) internal {
+ // Arrange
+ _createTransferRequestShare();
+
+ // Act
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ vm.expectEmit(true, true, true, true);
+ emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
+ // 30 days
+ vm.warp(block.timestamp + timeDelay);
+ // Act
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ }
+
+ function testShareCanSetTimeLimitWithTransferExceeded(uint256 timeDelay) internal {
+ TIME_LIMIT memory timeLimit_ = TIME_LIMIT({
+ timeLimitToApprove: 1 days,
+ timeLimitToTransfer: 1 days
+ });
+ // Act
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.setTimeLimit(timeLimit_);
+ // Arrange
+ _createTransferRequestShare();
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
+
+ // Assert
+ // Timeout
+ // >1 days
+ vm.warp(block.timestamp + timeDelay);
+
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ }
+
+ function testShareCanMintWithoutApproval() internal {
+ // Act
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.mint(ADDRESS1, 11);
+
+ // Assert
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
+ assertEq(resUint256, ADDRESS1_BALANCE_INIT + 11);
+ }
+
+ function testShareCanBurnWithoutApproval() internal {
+ // Act
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "testShare");
+
+ // Assert
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
+ assertEq(resUint256, ADDRESS1_BALANCE_INIT - defaultValue);
+ }
+
+ function testShareCannotMintWithoutApproval() internal {
+ ISSUANCE memory issuanceOption_ = ISSUANCE({
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: true
+ });
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
+ // Act
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ZERO_ADDRESS,
+ ADDRESS1,
+ 11
+ )
+ );
+ CMTAT_CONTRACT.mint(ADDRESS1, 11);
+ }
+
+ function testShareCannotBurnWithoutApproval() internal {
+ ISSUANCE memory issuanceOption_ = ISSUANCE({
+ authorizedMintWithoutApproval: true,
+ authorizedBurnWithoutApproval: false
+ });
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
+ // Act
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ZERO_ADDRESS,
+ defaultValue
+ )
+ );
+ CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "testShare");
+ }
+
+ function testShareAutomaticTransferIfOptionsSet() internal {
+ AUTOMATIC_TRANSFER memory automaticTransfertestShare = AUTOMATIC_TRANSFER({
+ isActivate: true,
+ cmtat: CMTAT_CONTRACT
+ });
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.setAutomaticTransfer(automaticTransfertestShare);
+
+ // Aproval
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.approve(address(ruleConditionalTransfer), defaultValue);
+
+ // Arrange
+ _createTransferRequestShare();
+
+ // Act
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ vm.expectEmit(true, true, true, true);
+ emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ vm.expectEmit(true, true, true, true);
+ emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
+ }
+
+ function testShareCanTransferIfAutomaticApprovalSetAndTimeExceedsJustInTime()
+ internal
+ {
+ AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
+ isActivate: true,
+ timeLimitBeforeAutomaticApproval: 90 days
+ });
+
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
+
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+ // Arrange
+ _createTransferRequestShare();
+
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+
+ vm.warp(block.timestamp + 90 days);
+ // Act
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertEq(resBool, true);
+ vm.prank(ADDRESS1);
+ vm.expectEmit(true, true, true, true);
+ emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ }
+
+ function testShareCanTransferIfAutomaticApprovalSetAndTimeExceeds() internal {
+ AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
+ isActivate: true,
+ timeLimitBeforeAutomaticApproval: 90 days
+ });
+
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
+
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+ // Arrange
+ _createTransferRequestShare();
+
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+
+ vm.warp(block.timestamp + 91 days);
+ // Act
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertEq(resBool, true);
+ vm.prank(ADDRESS1);
+ vm.expectEmit(true, true, true, true);
+ emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ }
+
+ function testShareCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds()
+ internal
+ {
+ AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
+ isActivate: true,
+ timeLimitBeforeAutomaticApproval: 90 days
+ });
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+ vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
+
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+ // Arrange
+ _createTransferRequestShare();
+
+ resBool = ruleConditionalTransfer.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+
+ resBool = CMTAT_CONTRACT.validateTransfer(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
+ assertFalse(resBool);
+ // Time not exceeds
+ vm.warp(block.timestamp + 85 days);
+ // Act
+ vm.prank(ADDRESS1);
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
+ }
+}
diff --git a/test/RuleConditionalTransfer/RuleCTDeployment.sol b/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol
similarity index 97%
rename from test/RuleConditionalTransfer/RuleCTDeployment.sol
rename to test/RuleConditionalTransfer/utils/RuleCTDeployment.sol
index 23615be..0ad98b1 100644
--- a/test/RuleConditionalTransfer/RuleCTDeployment.sol
+++ b/test/RuleConditionalTransfer/utils/RuleCTDeployment.sol
@@ -2,7 +2,7 @@
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
-import "../HelperContract.sol";
+import "../../HelperContract.sol";
import "src/RuleEngine.sol";
/**