From 297f1ffd53d8c654d3d2d7779b9f9ed79ec3972a Mon Sep 17 00:00:00 2001
From: Ryan Sauge <71391932+rya-sge@users.noreply.github.com>
Date: Fri, 20 Dec 2024 16:53:54 +0100
Subject: [PATCH] Fix bug with conditionalTransfer and automatic approval
---
CHANGELOG.md | 4 +
doc/coverage/coverage/index-sort-b.html | 38 +-
doc/coverage/coverage/index-sort-f.html | 22 +-
doc/coverage/coverage/index-sort-l.html | 36 +-
doc/coverage/coverage/index.html | 22 +-
...ithRuleEngineScript.s.sol.func-sort-c.html | 2 +-
.../CMTATWithRuleEngineScript.s.sol.func.html | 2 +-
.../CMTATWithRuleEngineScript.s.sol.gcov.html | 2 +-
.../RuleEngineScript.s.sol.func-sort-c.html | 2 +-
.../script/RuleEngineScript.s.sol.func.html | 2 +-
.../script/RuleEngineScript.s.sol.gcov.html | 2 +-
.../coverage/script/index-sort-b.html | 2 +-
.../coverage/script/index-sort-f.html | 2 +-
.../coverage/script/index-sort-l.html | 2 +-
doc/coverage/coverage/script/index.html | 2 +-
.../src/RuleEngine.sol.func-sort-c.html | 22 +-
.../coverage/src/RuleEngine.sol.func.html | 16 +-
.../coverage/src/RuleEngine.sol.gcov.html | 42 +-
doc/coverage/coverage/src/index-sort-b.html | 2 +-
doc/coverage/coverage/src/index-sort-f.html | 2 +-
doc/coverage/coverage/src/index-sort-l.html | 2 +-
doc/coverage/coverage/src/index.html | 2 +-
.../RuleEngineOperation.sol.func-sort-c.html | 6 +-
.../modules/RuleEngineOperation.sol.func.html | 6 +-
.../modules/RuleEngineOperation.sol.gcov.html | 18 +-
.../RuleEngineValidation.sol.func-sort-c.html | 2 +-
.../RuleEngineValidation.sol.func.html | 2 +-
.../RuleEngineValidation.sol.gcov.html | 12 +-
...ngineValidationCommon.sol.func-sort-c.html | 2 +-
.../RuleEngineValidationCommon.sol.func.html | 2 +-
.../RuleEngineValidationCommon.sol.gcov.html | 2 +-
.../modules/RuleInternal.sol.func-sort-c.html | 4 +-
.../src/modules/RuleInternal.sol.func.html | 4 +-
.../src/modules/RuleInternal.sol.gcov.html | 8 +-
.../coverage/src/modules/index-sort-b.html | 14 +-
.../coverage/src/modules/index-sort-f.html | 2 +-
.../coverage/src/modules/index-sort-l.html | 2 +-
doc/coverage/coverage/src/modules/index.html | 2 +-
...leConditionalTransfer.sol.func-sort-c.html | 42 +-
.../RuleConditionalTransfer.sol.func.html | 36 +-
.../RuleConditionalTransfer.sol.gcov.html | 211 ++++----
...ionalTransferOperator.sol.func-sort-c.html | 36 +-
...eConditionalTransferOperator.sol.func.html | 32 +-
...eConditionalTransferOperator.sol.gcov.html | 344 +++++++------
.../operation/abstract/index-sort-b.html | 2 +-
.../operation/abstract/index-sort-f.html | 2 +-
.../operation/abstract/index-sort-l.html | 2 +-
.../src/rules/operation/abstract/index.html | 2 +-
.../src/rules/operation/index-sort-b.html | 20 +-
.../src/rules/operation/index-sort-f.html | 20 +-
.../src/rules/operation/index-sort-l.html | 20 +-
.../coverage/src/rules/operation/index.html | 20 +-
.../RuleBlacklist.sol.func-sort-c.html | 2 +-
.../validation/RuleBlacklist.sol.func.html | 2 +-
.../validation/RuleBlacklist.sol.gcov.html | 2 +-
.../RuleSanctionList.sol.func-sort-c.html | 2 +-
.../validation/RuleSanctionList.sol.func.html | 2 +-
.../validation/RuleSanctionList.sol.gcov.html | 2 +-
.../RuleWhitelist.sol.func-sort-c.html | 2 +-
.../validation/RuleWhitelist.sol.func.html | 2 +-
.../validation/RuleWhitelist.sol.gcov.html | 2 +-
.../RuleWhitelistWrapper.sol.func-sort-c.html | 2 +-
.../RuleWhitelistWrapper.sol.func.html | 2 +-
.../RuleWhitelistWrapper.sol.gcov.html | 2 +-
.../RuleAddressList.sol.func-sort-c.html | 4 +-
.../RuleAddressList.sol.func.html | 4 +-
.../RuleAddressList.sol.gcov.html | 4 +-
...leAddressListInternal.sol.func-sort-c.html | 4 +-
.../RuleAddressListInternal.sol.func.html | 4 +-
.../RuleAddressListInternal.sol.gcov.html | 4 +-
.../RuleAddressList/index-sort-b.html | 2 +-
.../RuleAddressList/index-sort-f.html | 2 +-
.../RuleAddressList/index-sort-l.html | 2 +-
.../abstract/RuleAddressList/index.html | 2 +-
.../RuleValidateTransfer.sol.func-sort-c.html | 4 +-
.../RuleValidateTransfer.sol.func.html | 4 +-
.../RuleValidateTransfer.sol.gcov.html | 6 +-
.../RuleWhitelistCommon.sol.func-sort-c.html | 2 +-
.../RuleWhitelistCommon.sol.func.html | 2 +-
.../RuleWhitelistCommon.sol.gcov.html | 2 +-
.../validation/abstract/index-sort-b.html | 2 +-
.../validation/abstract/index-sort-f.html | 2 +-
.../validation/abstract/index-sort-l.html | 2 +-
.../src/rules/validation/abstract/index.html | 2 +-
.../src/rules/validation/index-sort-b.html | 2 +-
.../src/rules/validation/index-sort-f.html | 2 +-
.../src/rules/validation/index-sort-l.html | 18 +-
.../coverage/src/rules/validation/index.html | 2 +-
.../RuleCTDeployment.sol.func-sort-c.html | 20 +-
.../RuleCTDeployment.sol.func.html | 20 +-
.../RuleCTDeployment.sol.gcov.html | 18 +-
.../{ => utils}/index-sort-b.html | 26 +-
.../{ => utils}/index-sort-f.html | 26 +-
.../{ => utils}/index-sort-l.html | 26 +-
.../{ => utils}/index.html | 26 +-
.../CMTATDeployment.sol.func-sort-c.html | 4 +-
.../test/utils/CMTATDeployment.sol.func.html | 4 +-
.../test/utils/CMTATDeployment.sol.gcov.html | 10 +-
.../SanctionListOracle.sol.func-sort-c.html | 2 +-
.../utils/SanctionListOracle.sol.func.html | 2 +-
.../utils/SanctionListOracle.sol.gcov.html | 2 +-
.../coverage/test/utils/index-sort-b.html | 26 +-
.../coverage/test/utils/index-sort-f.html | 2 +-
.../coverage/test/utils/index-sort-l.html | 2 +-
doc/coverage/coverage/test/utils/index.html | 2 +-
doc/coverage/lcov.info | 475 ++++++++---------
doc/schema/rule/conditionalTransfer.drawio | 2 +-
.../surya_graph_RuleAddressList.sol.png | Bin 193435 -> 258533 bytes
...urya_graph_RuleConditionalTransfer.sol.png | Bin 405862 -> 446424 bytes
...ph_RuleConditionalTransferOperator.sol.png | Bin 343009 -> 360699 bytes
.../surya_graph_RuleEngine.sol.png | Bin 187844 -> 193554 bytes
.../surya_graph_RuleEngineOperation.sol.png | Bin 140982 -> 127575 bytes
...a_graph_RuleEngineValidationCommon.sol.png | Bin 119785 -> 132775 bytes
.../surya_graph_RuleInternal.sol.png | Bin 87247 -> 87221 bytes
.../surya_graph_RuleSanctionList.sol.png | Bin 154348 -> 203676 bytes
.../surya_graph_RuleWhitelistWrapper.sol.png | Bin 97956 -> 132320 bytes
.../surya_report_RuleAddressList.sol.md | 3 +-
...urya_report_RuleAddressListInternal.sol.md | 2 +-
...ort_RuleAddressListInvariantStorage.sol.md | 2 +-
...eport_RuleBlacklistInvariantStorage.sol.md | 2 +-
...urya_report_RuleConditionalTransfer.sol.md | 7 +-
...ConditionalTransferInvariantStorage.sol.md | 2 +-
...ort_RuleConditionalTransferOperator.sol.md | 5 +-
.../surya_report_RuleEngine.sol.md | 3 +-
.../surya_report_RuleEngineOperation.sol.md | 2 +-
...a_report_RuleEngineValidationCommon.sol.md | 6 +-
.../surya_report_RuleInternal.sol.md | 4 +-
.../surya_report_RuleSanctionList.sol.md | 4 +-
...rt_RuleSanctionListInvariantStorage.sol.md | 2 +-
.../surya_report_RuleWhitelist.sol.md | 2 +-
.../surya_report_RuleWhitelistCommon.sol.md | 2 +-
...eport_RuleWhitelistInvariantStorage.sol.md | 2 +-
.../surya_report_RuleWhitelistWrapper.sol.md | 3 +-
src/RuleEngine.sol | 2 +-
.../operation/RuleConditionalTransfer.sol | 25 +-
.../RuleConditionalTransferOperator.sol | 6 +-
.../CMTATIntegration.t.sol | 413 +--------------
.../CMTATIntegrationConditionalTransfer.t.sol | 390 +-------------
.../CMTATIntegrationTest2.t.sol | 182 +++++++
.../RuleConditionalTransfer.t.sol | 5 +-
...RuleConditionalTransferAccessControl.t.sol | 2 +-
.../RuleConditionalTransferDeployment.t.sol | 2 +-
.../RuleConditionalTransferRestriction.t.sol | 9 +
.../utils/CMTATIntegrationShare.sol | 483 ++++++++++++++++++
.../{ => utils}/RuleCTDeployment.sol | 2 +-
145 files changed, 1742 insertions(+), 1742 deletions(-)
rename doc/coverage/coverage/test/RuleConditionalTransfer/{ => utils}/RuleCTDeployment.sol.func-sort-c.html (69%)
rename doc/coverage/coverage/test/RuleConditionalTransfer/{ => utils}/RuleCTDeployment.sol.func.html (68%)
rename doc/coverage/coverage/test/RuleConditionalTransfer/{ => utils}/RuleCTDeployment.sol.gcov.html (90%)
rename doc/coverage/coverage/test/RuleConditionalTransfer/{ => utils}/index-sort-b.html (68%)
rename doc/coverage/coverage/test/RuleConditionalTransfer/{ => utils}/index-sort-f.html (68%)
rename doc/coverage/coverage/test/RuleConditionalTransfer/{ => utils}/index-sort-l.html (68%)
rename doc/coverage/coverage/test/RuleConditionalTransfer/{ => utils}/index.html (68%)
create mode 100644 test/RuleConditionalTransfer/CMTATIntegrationTest2.t.sol
create mode 100644 test/RuleConditionalTransfer/utils/CMTATIntegrationShare.sol
rename test/RuleConditionalTransfer/{ => utils}/RuleCTDeployment.sol (97%)
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 @@
-7VvbcuI4EP0aqrIPoWzJNx4TkrnsTDaZJLPJzsuUwQJcMRYjiwTm61ey5ZtkwBAbSHZTUzV2Y2Tcffr0UUvuwP508ZG4s8kV9lDQAZq36MCLDgC6AUCH/9O8ZWqBTmIZE98Tttxw5/9GwqgJ69z3UFS6kGIcUH9WNg5xGKIhLdlcQvBL+bIRDsp3nbljpBjuhm6gWh98j06EVde0/INPyB9PxK0dU3wwddOLhSGauB5+KZjgZQf2CcY0OZou+ijg3kv9knzvw4pPsx9GUEjrfOHHT9z78vcXf0xurxD03UfPHJ+KUZ7dYC4e+B4/oZCZJsxTiIifTpepP9hTzPjhfBqcDSkmHXj+jAj1mce+ugMU3ODIpz4O2SUDTCmeFi44C/wx/4DiGbNO6DRgJzo7xHMa+CHqZzHUmHGEQyrwoBvsXH3e9Mez4dGiYBLP/xHhKaJkyS5JP01jIdB4CsX5Sx7a1DQpBNUSNleAaZyNnPubHQiXb+F+oLj/ds48DTTmCi/2oxvcEzeMRhWhIHgeesgT7nqZ+BTdzdwh//SFZWPZxS14E/Y2e1O3K9zZnj+h4k+q+g2F3hlnBnY2DNwo8odlV5X9yvxDlo/8pKvpemr4JzbolpUaLhbF6y+WxbMbRHz2fCyEWyKbumSM6Gb8IK9EYmrEChExKwKS2ggKXOo/l6mvKkjiDjfYZ784Ty+zDAhdCnOE52SIxJeKTCWNIwMLSOMkblHGiRGTPfTuIDIUEOldXmEIcilKs/EW/ZqjiJ5Q3AH99Oo/VKyxyMS8WIaYK5hwyCKOSAVFTn3P42OcExT5v91BPB7Hzow/dewH87xjXtRC09pUkdM9K6XipqVqVUUDpywPgAnKVKC/DlDpJXg0ilArQTZXMK8VMKedD0gpjNavOa/SsatPo9jXZ+wC3ZgtYoenn7OjMf//jhVGritWFc/hkpU7Vl3hZt4eJGT0dZAZ3OHTOKao66RqCnskIGC2Q/aOLuUk6Joq21eRi26aLbG9pSbqIEtUdoB5FOczLzkjScY2Vg5KpWBNGYgjUlkH0MKnj+Iu/DgpKsAUp/lY/CStKLVjm7Dt5uKxsciYR1VkbCgVGVlM1K0ytiMNJJerlstMb5X2u54h4nJp/b609yp3H0p7p/cvBOC13CDyWeuapYxen9D8ZGeFuDHJe0eVvKCp5JUlom7sN3l1VT+ArjubEfwsS8QHn04+X5yI8vPZe0siMcuRV6tEVteMVAi8GZGo241TRGE2qWWTx4QmDPPQs8njIosspwVeTHNXspAGMpw9k4WjwAjyGSUVRPF2J5FZgjQxi7Q0aJfiBBqBkTT7aI8tgMoWTMmNMJkWYq0E99BdPFOqpBZQdVnWN91PU1RVxv2r+7P7o3OdoUm8cgQNUKBSjcu4xnKn3B/hIJolfYq4zRHNXN7qj+tWp9jomAWnT8W2xit6ITiezaDrMO9jJzdnz5fcP7nuZETYhCWmwU10uJsoL0ry9YK8eorfzebxK6pzgzPznlqxH89/O3TS//b99sP85/mnq8sv8M9UQW0s2DnJAkfiWBWyLZZ0A4KuBXv5X+m3QMvp2lrhT6LuuvXekPvHvXr1fp/SEqpLFZBP/k8oYecx/EduELUCf70e/MuLHW2Afx2m35palUEHd139MG1pIHu/ahWq6x+5eNHEHNdjhx34QS3JEzwdzKODlGNbWt01q5SMVoGAzNh8OVZb1GMUxgWR344XX8Ry+fhUoSNNmSy9ottfpQrlOVpzrlTV9V+4IXIsN+A3tOvyGbzZOkGuTdCNDJmi70gY0pHzU56G12XInqS7TTl/VzAkQ4a7LFwmpsErf7ByH7u0w4YdJCM2S79qs2CJohZUwDsCejrzPhagy7iBOwLdMqsB2DTQV92nVaCnFaaogEfrcB5ivthdg827ml5egIEG2HoJ5vDwr5oFrs2TI4G/3FFS6Lk2/OW+rSwu2t4IpDZTauDTc6NJjEm9DFZuv3EpQ1gYW4DGt39ElOCnbGspUEDdXHe/bq/gjTX3dWm61OIy/rrpqrSMfxmO+dacY5P1tkT0ME3NoqzvVURd7qDsIusr3aemGBx0lZ5h683BLl97yEvGKV+e275mNN4EOZJkVTZ/7SpoTEsaKGXUPSWr2nR7LYBylWBvJROqp572Afd+vQEcWtIMEsh6uLaysGUc7rdoqC026HVqNX+PYSl4bWo1shJsAqdc1F8Hn0bb+b+08Kx3cx8svjvgx8PgOlxcPVSogOtbJXjMMbQct0T99XHAN/OlAnLkB4Fkqh/fKk2xo6KsLyuAvLfPcBRZYVXQglxGdlEVleHYTrhvw/OxMrDLC4OODjax/X/pNRAgiUx91z6fvG9HGag5lq5EkcrSq/b41den75cDJGmXTSMOxQHq0gvgbwfs532AjZsFtngh4P/3AdZ2myQpZ+y4aUBenTDsrjRSy2yjrm/BYZt4ZXUMljFrO/arUMtGdErItaxDbn1/H3hW+lm7Arq5xhg7zV9bTy7P3/6Hl/8C7Vtdc9o4FP01zGQfYCz5k8cE0m6z202mzW7bR4EFeGos1xYJ9NdXsuUPSaYYB7Nk2kxmYl1kGV8dnXPvlTIwJ+vt2wTFq/fEx+EAGv52YE4HEAILwgH/NfxdbrE9Lzcsk8AXnSrDx+A7FkZDWDeBj1OpIyUkpEEsG+ckivCcSjaUJORZ7rYgofzUGC2xZvg4R6Fu/RT4dCWswDCqD/7EwXIlHu3Z4oM1KjoLQ7pCPnmumczbgTlJCKH51Xo7wSF3XuEX+j3ZzSbI/2Tehfffhnd3/63fDvPB3hxzS/kKCY7oaYcWk/uEwo3w1yP5iiNmWjFH40S8Od0V7mROiPnlZh1ezylJBubNE05owBz+N5rh8IGkAQ1IxLrMCKVkXetwHQZL/gElMbOu6DpkDcAuyYaGQYQnJQQMZlyQiAo4AZu1WzpBOIs/E29rEBBOeYvJGtNkx7psSyjktwiAm6L5XKGlMK1qOHGEDQl8LsuBqzlgF2IajpgSU5uSDxvmfWgw9/iZb1H4mKAoXTRMT0I2kY994cLnVUDxxxjN+afPbH3Lbj+Xhy140MPAa3Bxfz62NB9T3Zc48q85AbHWPERpGsxl98m+Zj5Ldp95Y2QAUBi+ZAbgOIVhuq33n+7qrQecBOz92LSeYgVQlCzxz/oJoGFfIlB9FmvTZDfMUmFLcIho8CTTbtPMiSc8kIC9RrUMbRkkrjL3KdkkcyxuqtOcMo45lsfxlHFyt2jjZDAqX7o7smwNWWDE1S3BiOJi2X7A3zY4pVeUDOCk6P2HDkA2MxmpyrhDgkbnDAY4aeDXdeD7fIybBKfBdzTLxuOAivlbZ36wbwb2tDvEivWjUkAp4+KhklI2UcOQLQ5oQ2nGCgB3BVTRhSwWKe5lkr19FH0f4wRxVfwFZNOT1xlw/2fdHGuT8lJG3wY0J3RbtL5IrYrKeWNXaxwi8lIrhlwsZK1wHNhFK46b5pxMDyP8lWlICTiByTJ0f6mIQOO8KlKEpDUwwxGK44Q8qSLyKaCrd9OrJG+981+TjBRL9sUyYoygZdsnVZFCoCwgD+tAeYj+VAYADQQvZbQyRpU5xz7AOD0HosC6KBYBSrriqpLVmkUUOrLVgfpmET27N3kwSgWDvN74E+wLV7oEoI5hujLbnwRG9tl4Qq8YsDB0QZJ1ba61yb3ISoGjLD2voIZ6qQCeM6oEeqlg8v7x+vF1+FOtvDhNpRe3wZ89OlTPkE3EWMlBa+6kaJbGmUOckH2VmzRGvBiZaVvW2fm24fXWmzgcfq1a0lQURu7kYZp5+Zp1AHa8zUcub3KW/C/JkjZ8H1VVtfzh7P3y5+f9rhYJy8sywjxEnB3zDDCGtUyDJwfGy5ON47B1MDNoLdZlaGZ4Y0dC4djUQNijnFuKCjtw3E3OLduU5dxqJ+fnrEwAR19dPmtf0YS1M8wuUJi+HLNFJClnr7/jyHoAoCSRGl7aAs9W40hLQXDfcaSrgaoKKwyRlnKUDcw3ui6uyHq2SS9HEx2lcFW265roNMCi3Cg6vSbqBcUljjJV4o/jCojZ2nwlQZyrONiDLYM4uzf/6rXBf8iJVBscURvcWwespeBtePTUku62JVjvogjWU7aMPKOjsnuWMpC6+bSHYBlc0K7WTeS3+7+w+hwobdmzi3zEk7J3sdJq4N/h9EToN45Af1e09x3Qtkb/ZRW7PUMGkzvuiH5HXUZmu/DiWPSrwuuBc6BfL6Ka+Gfgj0iEW/F+sc1foh+Mz4P/pqTv1GvCarsm3ItaE2rI7RpKFa71mlCY2gXnDbkh1GDbArQ+SlcZUIGMYG5/QJTBJcos0DB5bYUm5Gt5KA5qSO85W4MXhRyt6G92TNbKclqxL65mDX0jp/n82G20DCKd+C4ygVCrlpbdkKE1HRgb95VAwIai5by3mooxco8SiKqA6NZPKoCfqlHPUZXZlgUuK6hylKDKdK2OAqLQgKVWHfumAb1mc/9BAyhbkFSGZC4KExLyM0qFriyCMFRM7TcBm0jllELTnldYxDkqdLzY6mvYEGmq/ahqcDpm0Us/L6SRpnAxZwfYnh2kE0qGI7HRaGxYhxjpDEeUYNu87bIYBto6CNUzJa13JJSj69qh2b5JRq+r7Tum1H7z7BfjJGvPFJ6BkG5n27+i6d3nqfGw+PfmDQrgJhrq1SJz9nt7NuM9IBEoZ0ZoHVfv7T9zbx1PVedfoKkcwAYG0DDY5watDUeOOa5+pC9jO97I7UiP6tpS84ODG7a7xlfqsn3LmtV/iuXdq/+3M29/AA==5VvbcuI4EP0aqjIPUJZ8wTwSksymZlKZTbLJ7r4ZW4BrjOWR5QTm61fC8kWSCTdDmFkqVbHaomV3t053H5uOOZovPhMvmd3hAEUdaASLjnnVgRBYEHb4nxEsC4np5pIpCQMhqwSP4U8khIaQZmGAUmkixTiiYSILfRzHyKeSzCMEv8nTJjiSV028KdIEj74X6dKXMKAzIQWGUZ34A4XTmVjatcWJuVdMFoJ05gX4rSYyrzvmiGBM86P5YoQibr3CLqOHv56/XN0Oh2Dche794vmr73dzZTe7fKW8BYJi2q5q4d1XL8qEvfBbjIi4YbosrMjuPeGH2Twa+hSTjnn5iggNmZ2/emMUfcNpSEMcsyljTCme1yYMo3DKT1CcMOmMziM2AOwQZzQKYzQqPW8w4QTHVEQRsNl4y3sXNuJrokXN88IWnxGeI0qWbIo4OxBeFXHdBUXAvlVRYgrRrBYfjpB5Ii6npebK9uxAmH8HV5iaKx4yZn5oMPsEK+N60RPx4nTS4B+CszhAgbDh2yyk6DHxfH72jW1s2e6nMrEFZRubuoWB22Di49nY0mxMdVuiOBhy4GEjP/LSNPRl88m2PsyYKJDQSzdlzVZ2g6kKGUGRR8NXGfOazCdW+IZDdnmlp4Cl7AZb8UCKM+Ij8a06yCiKVJf3FT3UI1NENT0rZ5Z3vb9/bc2/YNzjyYUgj6Ji9zygHxlK6QXFHTgqpn/S44D5ZgVusvs9AWc+czAiDTg3D4OA67gkKA1/euOVPh4qCb/tlSHsy459tX/wFGGs7sQyi4pFpUTVtEO7Rg9AGypI2E5IyUotKCvAk0mKjhIDzjocvU8Q8Xju+v2TW1ndFFVb/4OTW19zyoGwixYh/Zsf92wx+kcaXS1qE6+WtcE3REJ2U3zrNvqEuYIsuWq2OQxQCHLtjgMLQbXAarSsj9QldnNzjrWbIzzH0s0VxZnkmDLgREyWdfWuOcZUSjdonDbJuFosw2HPSxKCX9UU8xLS2e3VBclHt8GvlGSKLXtwkjF60LLtY+SYrvVhWWbQNqBpMFQCXF9CuPfxrcCu4lsFdIENsDUJo2iEI5772KWbgYfcCb/clBL8HdXOOL6LxpP2Mc3cEtMAPCtQ69tqG6mC0baoZqtweGQUK9rdOoytamUqIOyG4PmFFwQMYNILOgvTT3m1LAiC0YrI+UUL6GL3tlFAO4bZl/NRK5FlnwrJih1VC4TR3dPwSXPneXIMSlXRNWEDy9A/KctQOFtpQa7jKWsIfg2zuqpZYZNZm8ibwdGsqscp9BlgOd6cGykep8nKIE5EeeJKvJhvZ554V5OdHxknai+TqPu9GrGjKf+PV70huo8rhi3Xwy41V5XPu5gwVNwO/HZrZ8rELTcc9qa8vaZqAFJT1H+/K/rw5F9A0MbsD8+LNnOVNtvdM/c7fVmPBQcnrQWgzj3fP2gRzaCDyjEsB0iMY6REkxBtn/Gb4K9NvnUHCkVhMmHD84HGvGIeDQB19vpA1Fnfc8B6zwHeRQ+JLzEcGb8GhnUGhAnctrs4M8bEBj0wkKPQUTrcrYl5oITziZl5qFPz8HINa7J9kv1/QRK01viwFo7OSRFJ59oPrYNKBAISBHFsgdb7VUwDmKm4UmKVwuvCjXXWR5dI5bsTrREktUdAJpRRpmtbWmAdEecsG/Ycc1B9pIuxHbfX3xP01A2jNidrQK9S1Gr7/WWJ8L/WrX/z+Gz5d3cvhATLhsf+cNJ7IpneKJ6YTrG2D+ISB1rgis2B5chOOyzGju9BvdsH40NhcE07uBmntmSRextqugbsbBvQ2sazE70p4ciQAgxe9VYfoGjcGqpM0Bu4imqzx5arPu6xKrbGsNbpFuB94svnNdsFySL0HMbfsyhEJIun508Fv7t7z/JdiuODl95TwoA/BdAIsaMxX/v0nLuXY3tmttbLs207zDIfGq5SD5U8wImecCk8CNj31bB+X0POsyvG9Ca1pejeiY/9/Z/inhuP66qvJ+z7boqj0CwDt2cNTLZnHJf/N4+WwoMvNy8LAIM/7eHXFI7S+C6FTeCOOLifb3vx7q5sI0VDW2kvijrnI1I0G1Y/H8inV7/CMK//Aw==3Vpbc9o6EP41PCZjWbYxjxDoZaYnzcnlNHk6o2ABbo1FhQjQX18ZyxdJBgwxttuZTMZaryV599tPu4s78Ga++UjRYvYP8XDQMQ1v04HDjmkCyzQ70Z/hbWOJ7bqxYEp9Tyhlggf/FxZCQ0hXvoeXkiIjJGD+QhaOSRjiMZNkiFKyltUmJJBXXaAp1gQPYxTo0m++x2ax1ITQyW58wv50lizt2FZ8Z44SbfEqyxnyyDongqMOvKGEsPhqvrnBQWS9xDDxcx/23E13RnHIyjzw6RaN+1NGB4sNotPp0+I7fbkSs7yhYCXe+Fv/86PYMNsmZuAzcYvzwWA98xl+WKBxdGfNnc5lMzYP+AjwS31TyQqYMrzJicQmP2Iyx4xuuYq4axnCYAIywBbjdeYAkBh1lrO9K2RI+HyaTp1ZhV8Iw5xgJFszElosKHnDHpe+RlsnC0wRI1Q3XOj1Ixjy0ThAy6U/lu1FySr0cLS4wUd447NncSe6fonk17YYDTc5teFWDPZafElWdIyP+x57UgjofsnZ3S4weyKjOEDMf5MDp8gXYoU74vMdp263u7LbUwpIpojfRzyVx7kykeMq+OkpEzFuAsy0iXbQSF/7fLQ4Glr6d3f3X/8bDRsNK8dpW1h1NUM1ED7coHT7nB/knoqG2WO70fvDTuAjRuEBPbdV4QktGT5QhUXZ8HS7zYZnT0MdoyhcTjDd0Tne4PGKZczOyA8cRiblmQMu4HfunS/olWc9Ei5R4E/DCLQcHfwpOIji1OdpRV/cmPueF80xoHjp/0Kvu/kiXC2i995Zwh507GEh0g5Gk0oIaW4kFpGyjyKiuDKuoeSh5KB4L4KAPCtUZiCTyRJfxOWu5vLR8+jm6bFhRu7ZbWPk5MitkJIL6RUcIddK86CjROu0imjNnkK0wD6PaC2FaFMGr4logV5beD7lRBRExhxTjGKaReHuf+mMujWMm0ZLFZQLelZP5kfrfXC6PK0CvS46xBbco+Eu0r0PfpC4jY9E0Q/MMqldxgIveRKoJ7U7yiRnVFTAqYg2urYc7caZ+RlU6gSzZH7G3Yy2OTURVvs3rJRpUG1fHNFP8sYM1PEOKoW4CTWIx8TFZY8ibeSX9/jnCi9Zm7kqidVKuMo2e60nJ70Mr5mcQElyyvioTGq0l5yO1p1uSRI7o+6sisRcqHBPVUUmhDXnPqf1NipBH2juYCzbajx+gDYIPlsBH1Dz5XMbkE7N2NM7HB4O/T8rta6sm2FcW9CyZDJo/dmlNyyGo9vPTTeQlQ5g490KU+9W3JIQN2qk9FcLJatt0EpWjUdRltR0bVc+XHq2c6zrE43uMPX5i0c8U39bp6qjBBgKDEw1/yjdxDHqqca0HUNwuBzr2uCQ/oXKMb3j8He1lNJgreDcg4bTlVx0ZVYCbuU0TU+ry5+LZuM1Xdm8Wq7pjCPEt5fjKqvpGmxMuXvShlOZEBjG4YkuxYTWMSI8Sd1yDqlfiDb1avTP7GKlBFDJj5zAkTvu76THGvhPrwsuxn97OakJDlFLDzUJKsshWnZesjQ/ubcNCvdbdlugDlJIMtIcmO5xAtyWhn+C/yqyI1POYtoU/P7Xf//Hs6enB2v0vftK3NvZzy8FX2peLPYnJGSJopXPa0Cnpn5h2W+kkkq6DaSkkUnpZrVRDyt1zeJ1qqKZQtiaGmwpnvOqLK3PUNAE46gQ16F6MAgrICBD+b22Of7hw+wr9Fg9+5gfjn4DzVdLj9owEP41OVIlcRLocXl0e9iqaEFtOa3cZCAuTswah0d/fW3ihDiGLkVlBeLgeXic+ebz2HbQINs9crxKv7AEqOO7yc5BQ8f3vcD3HfV3k32p8f1AaxacJNrrqJiQ36CVrtYWJIG14SgYo4KsTGXM8hxiYegw52xrus0ZNVdd4QVYikmMqa39ThKR6jQQio6Gz0AWabV0FAalJcOVt05lneKEbRsqNHLQgDMmylG2GwBV8FXAlPM+nbHWX8YhF5dMYC9k+Dr4VWyG7tNr2psul0Gno6NsMC10xkMswFGhIpytHNSnMnj/YHKnJIMnkhExZVOO8/UcuE5N7CvAeMqyn4VEvb9NiYDJCsfKspX8kLpUZFRKnhzOWS50vb1QLWGlU30bcAG7hkqn9wgsA8H30kVbg0BDrdnmIS1vG6WrfNJG1eoaYU2XRR37CKgcaEz/AV/fwncisJD4yBWleID1YTx+/vptNLwvLLuhgWXH82wwve4JML3wVmAiC0wLMsiTB7XtpRRTvF6T2ESKsyJPQC3insBNwsX3P5TxQy3OtO9BGO4MaV9JOyIa06Q00+up8XGSEqo5Z2u0ZgWP4S8w9HQfxHwB4m3uQWK0OLvijYKGJ+pZ6ThQLMjGbIynaqxXGDMiM6sJFUZui1BBiydl4npas5G1I3ntSKgVqYTGinQgXZ349TwMLB7O5Bn1n6n4rpTyL6SUd1eUilr9vnsloaKPZpz2aXBjOoU3b2tXcOnaVng9B6vr3VscjO6Lg6HJnaBNnou7Wqs/Bu1j9MYsjCwWPoMoeK5KwqXKupwYlHv/C0rongG+eT/xTxQ+utX1pHfBPqZUvlzABEc+DFbKLje5uhwq65xQOmCU8cM05B5+ylVwtoSGZT7XllsgHLSvgD0bYnQC4fZxfAHCUjy+hEpKH1+UaPQHzVhZc9owEP41nmkfwtiSLx7J1XammR40SfPUEbbAmtiWR5YD9NdXsmV8CBpgIM4Dg7Ta1fHtt7uSDXiVrD4xlEV3NMSxAcxwZcBrAwALOkD8Scm6kji+XwkWjIRKqRFMyV+shKaSFiTEeUeRUxpzknWFAU1THPCODDFGl121OY27q2ZogTXBNECxLn0kIY8qKYDQbQY+Y7KI6qVdx65GElRrq6PkEQrpsiWCNwa8YpTyqpWsrnAs0auBqexud4xudsZwyvcxKH78eXjMp/j+FpFJ9pCy2Ty7ULO8oLhQJ54WiRDQuQSwtC/HcnkATkpBTINnHKpD8XUNFaNFGmK5mGXAy2VEOJ5mKJCjS0EOIYt4EqthtSxmHK92nsfaoCT4hWmCOVsLFWUAXQVsTS3VXTZ+ssZKFrVdVHMLKW4sNlM36ImGAvAAMIEGpgYSTsOJpKXoBTHKcxJ0cWlANEVPIMHWv2Vn5NTdp/bY9arTW9e9FeEtM9F7UvPLdmMkO7VNtVUcavHQ84c4Di1YgF8nFUdsgfl/9Ozt/m050Nniv1rGcIw4eelud5tP1QrfKREH2dDHGXfpA0GPFtUxlVU7rnoTuU53IuD1Jqpw0CYqKbY59vGsgxrrfmJesFR6gAnR0HFq9YC2/T0D1TlXnNoaYpcoRqmAAJgX4jdJBETSwwZwUSIRWXCJhVQ1p/d3Hy6rFPhRxzaiyazI3yb/wR7vLB3XrQFk+ecC1jl5AqwTWSuNNUnt7InM3jORwSETmd2rg3B8ZCID/o5AfSWRCX+idUstkwr57g0D3+lu2OxcXESjmvGkWdI9FzWtA6h5bD0fgNLekJR2QY+JR9dmrxcbe9bmQyntmgNQ2ttd+Ocozoev/I713ir/WIPsi3zo/GrX+rip9TNZ50ecJDjn5eBEaJXjMyZa5a0gL99LBlAmqLw7fBV2XMNfvAAz2cwYDXC+xy1hhoLnRem1bwWPSYpP5xvP7vrG2uIbYG7xjXsu39RkGTZFnzDV7vsMsnZ46o1ybS9ILXhkrvXM7kT9a8iZn0GW/injljKj/oox2cTl+w7LXuVzvJGjx6W9hQ5j51xxqT+XThSXh3yeeAdXJ2vfgB4PGc++tyOxHxrPfu/dbplg1OPY0SEtus2Hz0q9+X4Mb/4B
\ No newline at end of file
+7VvbcuI4EP0aqrIPoWzJNx4TkrnsTDaZJLPJzsuUwQJcMRYjiwTm61ey5ZtkwBAbSHZTUzV2Y2Tcffr0UUvuwP508ZG4s8kV9lDQAZq36MCLDgC6AUCH/9O8ZWqBTmIZE98Tttxw5/9GwqgJ69z3UFS6kGIcUH9WNg5xGKIhLdlcQvBL+bIRDsp3nbljpBjuhm6gWh98j06EVde0/INPyB9PxK0dU3wwddOLhSGauB5+KZjgZQf2CcY0OZou+ijg3kv9knzvw4pPsx9GUEjrfOHHT9z78vcXf0xurxD03UfPHJ+KUZ7dYC4e+B4/oZCZJsxTiIifTpepP9hTzPjhfBqcDSkmHXj+jAj1mce+ugMU3ODIpz4O2SUDTCmeFi44C/wx/4DiGbNO6DRgJzo7xHMa+CHqZzHUmHGEQyrwoBvsXH3e9Mez4dGiYBLP/xHhKaJkyS5JP01jIdB4CsX5Sx7a1DQpBNUSNleAaZyNnPubHQiXb+F+oLj/ds48DTTmCi/2oxvcEzeMRhWhIHgeesgT7nqZ+BTdzdwh//SFZWPZxS14E/Y2e1O3K9zZnj+h4k+q+g2F3hlnBnY2DNwo8odlV5X9yvxDlo/8pKvpemr4JzbolpUaLhbF6y+WxbMbRHz2fCyEWyKbumSM6Gb8IK9EYmrEChExKwKS2ggKXOo/l6mvKkjiDjfYZ784Ty+zDAhdCnOE52SIxJeKTCWNIwMLSOMkblHGiRGTPfTuIDIUEOldXmEIcilKs/EW/ZqjiJ5Q3AH99Oo/VKyxyMS8WIaYK5hwyCKOSAVFTn3P42OcExT5v91BPB7Hzow/dewH87xjXtRC09pUkdM9K6XipqVqVUUDpywPgAnKVKC/DlDpJXg0ilArQTZXMK8VMKedD0gpjNavOa/SsatPo9jXZ+wC3ZgtYoenn7OjMf//jhVGritWFc/hkpU7Vl3hZt4eJGT0dZAZ3OHTOKao66RqCnskIGC2Q/aOLuUk6Joq21eRi26aLbG9pSbqIEtUdoB5FOczLzkjScY2Vg5KpWBNGYgjUlkH0MKnj+Iu/DgpKsAUp/lY/CStKLVjm7Dt5uKxsciYR1VkbCgVGVlM1K0ytiMNJJerlstMb5X2u54h4nJp/b609yp3H0p7p/cvBOC13CDyWeuapYxen9D8ZGeFuDHJe0eVvKCp5JUlom7sN3l1VT+ArjubEfwsS8QHn04+X5yI8vPZe0siMcuRV6tEVteMVAi8GZGo241TRGE2qWWTx4QmDPPQs8njIosspwVeTHNXspAGMpw9k4WjwAjyGSUVRPF2J5FZgjQxi7Q0aJfiBBqBkTT7aI8tgMoWTMmNMJkWYq0E99BdPFOqpBZQdVnWN91PU1RVxv2r+7P7o3OdoUm8cgQNUKBSjcu4xnKn3B/hIJolfYq4zRHNXN7qj+tWp9jomAWnT8W2xit6ITiezaDrMO9jJzdnz5fcP7nuZETYhCWmwU10uJsoL0ry9YK8eorfzebxK6pzgzPznlqxH89/O3TS//b99sP85/mnq8sv8M9UQW0s2DnJAkfiWBWyLZZ0A4KuBXv5X+m3QMvp2lrhT6LuuvXekPvHvXr1fp/SEqpLFZBP/k8oYecx/EduELUCf70e/MuLHW2Afx2m35palUEHd139MG1pIHu/ahWq6x+5eNHEHNdjhx34QS3JEzwdzKODlGNbWt01q5SMVoGAzNh8OVZb1GMUxgWR344XX8Ry+fhUoSNNmSy9ottfpQrlOVpzrlTV9V+4IXIsN+A3tOvyGbzZOkGuTdCNDJmi70gY0pHzU56G12XInqS7TTl/VzAkQ4a7LFwmpsErf7ByH7u0w4YdJCM2S79qs2CJohZUwDsCejrzPhagy7iBOwLdMqsB2DTQV92nVaCnFaaogEfrcB5ivthdg827ml5egIEG2HoJ5vDwr5oFrs2TI4G/3FFS6Lk2/OW+rSwu2t4IpDZTauDTc6NJjEm9DFZuv3EpQ1gYW4DGt39ElOCnbGspUEDdXHe/bq/gjTX3dWm61OIy/rrpqrSMfxmO+dacY5P1tkT0ME3NoqzvVURd7qDsIusr3aemGBx0lZ5h683BLl97yEvGKV+e275mNN4EOZJkVTZ/7SpoTEsaKGXUPSWr2nR7LYBylWBvJROqp572Afd+vQEcWtIMEsh6uLaysGUc7rdoqC026HVqNX+PYSl4bWo1shJsAqdc1F8Hn0bb+b+08Kx3cx8svjvgx8PgOlxcPVSogOtbJXjMMbQct0T99XHAN/OlAnLkB4Fkqh/fKk2xo6KsLyuAvLfPcBRZYVXQglxGdlEVleHYTrhvw/OxMrDLC4OODjax/X/pNRAgiUx91z6fvG9HGag5lq5EkcrSq/b41den75cDJGmXTSMOxQHq0gvgbwfs532AjZsFtngh4P/3AdZ2myQpZ+y4aUBenTDsrjRSy2yjrm/BYZt4ZXUMljFrO/arUMtGdErItaxDbn1/H3hW+lm7Arq5xhg7zV9bTy7P3/6Hl/8C7Vtdc9o4FP01zGQfYCz5k8cE0m6z202mzW7bR4EFeGos1xYJ9NdXsuUPSaYYB7Nk2kxmYl1kGV8dnXPvlTIwJ+vt2wTFq/fEx+EAGv52YE4HEAILwgH/NfxdbrE9Lzcsk8AXnSrDx+A7FkZDWDeBj1OpIyUkpEEsG+ckivCcSjaUJORZ7rYgofzUGC2xZvg4R6Fu/RT4dCWswDCqD/7EwXIlHu3Z4oM1KjoLQ7pCPnmumczbgTlJCKH51Xo7wSF3XuEX+j3ZzSbI/2Tehfffhnd3/63fDvPB3hxzS/kKCY7oaYcWk/uEwo3w1yP5iiNmWjFH40S8Od0V7mROiPnlZh1ezylJBubNE05owBz+N5rh8IGkAQ1IxLrMCKVkXetwHQZL/gElMbOu6DpkDcAuyYaGQYQnJQQMZlyQiAo4AZu1WzpBOIs/E29rEBBOeYvJGtNkx7psSyjktwiAm6L5XKGlMK1qOHGEDQl8LsuBqzlgF2IajpgSU5uSDxvmfWgw9/iZb1H4mKAoXTRMT0I2kY994cLnVUDxxxjN+afPbH3Lbj+Xhy140MPAa3Bxfz62NB9T3Zc48q85AbHWPERpGsxl98m+Zj5Ldp95Y2QAUBi+ZAbgOIVhuq33n+7qrQecBOz92LSeYgVQlCzxz/oJoGFfIlB9FmvTZDfMUmFLcIho8CTTbtPMiSc8kIC9RrUMbRkkrjL3KdkkcyxuqtOcMo45lsfxlHFyt2jjZDAqX7o7smwNWWDE1S3BiOJi2X7A3zY4pVeUDOCk6P2HDkA2MxmpyrhDgkbnDAY4aeDXdeD7fIybBKfBdzTLxuOAivlbZ36wbwb2tDvEivWjUkAp4+KhklI2UcOQLQ5oQ2nGCgB3BVTRhSwWKe5lkr19FH0f4wRxVfwFZNOT1xlw/2fdHGuT8lJG3wY0J3RbtL5IrYrKeWNXaxwi8lIrhlwsZK1wHNhFK46b5pxMDyP8lWlICTiByTJ0f6mIQOO8KlKEpDUwwxGK44Q8qSLyKaCrd9OrJG+981+TjBRL9sUyYoygZdsnVZFCoCwgD+tAeYj+VAYADQQvZbQyRpU5xz7AOD0HosC6KBYBSrriqpLVmkUUOrLVgfpmET27N3kwSgWDvN74E+wLV7oEoI5hujLbnwRG9tl4Qq8YsDB0QZJ1ba61yb3ISoGjLD2voIZ6qQCeM6oEeqlg8v7x+vF1+FOtvDhNpRe3wZ89OlTPkE3EWMlBa+6kaJbGmUOckH2VmzRGvBiZaVvW2fm24fXWmzgcfq1a0lQURu7kYZp5+Zp1AHa8zUcub3KW/C/JkjZ8H1VVtfzh7P3y5+f9rhYJy8sywjxEnB3zDDCGtUyDJwfGy5ON47B1MDNoLdZlaGZ4Y0dC4djUQNijnFuKCjtw3E3OLduU5dxqJ+fnrEwAR19dPmtf0YS1M8wuUJi+HLNFJClnr7/jyHoAoCSRGl7aAs9W40hLQXDfcaSrgaoKKwyRlnKUDcw3ui6uyHq2SS9HEx2lcFW265roNMCi3Cg6vSbqBcUljjJV4o/jCojZ2nwlQZyrONiDLYM4uzf/6rXBf8iJVBscURvcWwespeBtePTUku62JVjvogjWU7aMPKOjsnuWMpC6+bSHYBlc0K7WTeS3+7+w+hwobdmzi3zEk7J3sdJq4N/h9EToN45Af1e09x3Qtkb/ZRW7PUMGkzvuiH5HXUZmu/DiWPSrwuuBc6BfL6Ka+Gfgj0iEW/F+sc1foh+Mz4P/pqTv1GvCarsm3ItaE2rI7RpKFa71mlCY2gXnDbkh1GDbArQ+SlcZUIGMYG5/QJTBJcos0DB5bYUm5Gt5KA5qSO85W4MXhRyt6G92TNbKclqxL65mDX0jp/n82G20DCKd+C4ygVCrlpbdkKE1HRgb95VAwIai5by3mooxco8SiKqA6NZPKoCfqlHPUZXZlgUuK6hylKDKdK2OAqLQgKVWHfumAb1mc/9BAyhbkFSGZC4KExLyM0qFriyCMFRM7TcBm0jllELTnldYxDkqdLzY6mvYEGmq/ahqcDpm0Us/L6SRpnAxZwfYnh2kE0qGI7HRaGxYhxjpDEeUYNu87bIYBto6CNUzJa13JJSj69qh2b5JRq+r7Tum1H7z7BfjJGvPFJ6BkG5n27+i6d3nqfGw+PfmDQrgJhrq1SJz9nt7NuM9IBEoZ0ZoHVfv7T9zbx1PVedfoKkcwAYG0DDY5watDUeOOa5+pC9jO97I7UiP6tpS84ODG7a7xlfqsn3LmtV/iuXdq/+3M29/AA==5VvbcuI4EP0aqjIPuCz5gnkkJJlNzaQym2ST3X0ztgDXGMsjywnM168E8kWSCTdDmFkqVbHaomV3t053H5uONZzNPxM/nd7hEMUdaIbzjnXVgRDYEHb4nxkuConlrSQTEoVCVgkeo59ICE0hzaMQZdJEinFMo1QWBjhJUEAlmU8IfpOnjXEsr5r6E6QJHgM/1qUvUUinQgpMszrxB4omU7G054gTM7+YLATZ1A/xW01kXXesIcGYro5m8yGKufUKuwwf/nr+cnU7GIBRF3r38+evQdBdKbvZ5SvlLRCU0HZVC++++nEu7IXfEkTEDdNFYUV27yk/zGfxIKCYdKzLV0RoxOz81R+h+BvOIhrhhE0ZYUrxrDZhEEcTfoLilEmndBazAWCHOKdxlKBh6XmTCcc4oSKKgMPGW967sBFfE81rnhe2+IzwDFGyYFPE2b7wqojrLigC9q2KEkuIprX4cIXMF3E5KTVXtmcHwvw7uMLSXPGQM/NDk9knXBrXj5+In2TjBv8QnCchCoUN36YRRY+pH/Czb2xjy3Y/lYltKNvY0i0MvAYTH8/GtmZjqtsSJeGAAw8bBbGfZVEgm0+29WHGRKGEXropa7ZyGkxVyAiKfRq9ypjXZD6xwjccscsrPQVsZTc4igcynJMAiW/VQUZRpLq8p+ihPpkgqulZOrO86/3962j+BSODJxeCfIqK3fOAfuQooxcUd+CwmP5JjwPmmyW4ye73BZwFzMGINODcLApDruOSoCz66Y+W+niopPy2l4ZwLjvO1f7BU4SxuhPLLCoWlRJV0w7tmgaADlSQsJ2QkpXaUFaAx+MMHSUG3HU4ep8i4vPc9fsnt7K6Kaq23gcnt57mlANhF80j+jc/Nhwx+kcaXc1rE68WtcE3RCJ2U3zrNvqEuYIsuGq2OUxQCFbaXRcWgmqB5WhRH6lL7ObmFdZujvAVlm6uKM4kx5QBJ2KyrKt3zTGWUrpB87RJxtNiGQ4MP00JflVTzEtEp7dXF2Q1ug1/pSRTbNmDk4xpQNtxjpFjuvaHZZl+24CmwVAJcD0J4d7HtwK7im8V0AU2wNY4iuMhjnnuY5duhT7yxvxyM0rwd1Q74wYeGo3bxzRrS0wD8KxAreeobaQKRtuimqPC4ZFRrGh36zC2rJWpgLAbgmcXfhgygMku6DTKPq2qZUEQDJdEzi9aQBe7t40C2jWtnpyPWoks51RIVuyoWiAM754GT5o7z5NjUKqKrgUbWIbeSVmGwtlKC3KdTFhD8GuY1VPNCpvM2kTe9I9mVT1OYcAAy/Vn3EjJKEuXBnFjyhNX6id8O/PEu5zs/sg5UXuZxt3v1YgdTfh/vOwN0X1SMWwrPexSV6pW8y7GDBW3A7/d2pkyccsNh7Mpb6+pGoDUFPXe74o+PPkXELQx+8Pzos08pc329sz9bk/WY8P+SWsBqHPP9w9aRDPooHIMywGS4AQp0SRE22f8Jvhrk2/dgUJRmEzY8HygMa9YRwNAnb0+EHXW9xyw3nOAd9FD4ktMV8avvmmfAWECt+0uzowxcYAB+nIUukqHuzUxD5RwPjEzD3VqHl6uYU22T7L/L0iC9hof1sLRPSki6Vz7oXVQiUBAgiCOLdB+v4ppADMVV0qsUnhduLHO+ugSqXx3ojWCpPYIyIIyynQdWwusI+Kc7UDDtfrVR7oYx/WM3p6gp24YtTlZA3qVolbb7y8LhP+1b4Obx2c7uLt7ISRcNDz2h2PjieR6o3hiOsXePohLHGiBK7b6tis77bAYO74H9W4fjA6FwTXt4Gac2pJFNjbUdA3Y2TagtY1nJ3pTwpUhBZi86q0+QNG4NVRZwOh7imrLYMtVH+9YFVtjWOt0C/A5PyxqtguSx+g5Sr7ncYRInkzOnwp+d/ee5bsUxwcvvaeEIfeyRogdjfnap+fcvRzbM7O1Xp5t22GW+dD0lHqo5AFO9IRL4UHAvq+G9Xoacp5dMaY3qS1F90587O//FPfceFxPfT1h33dTXIVm6XuG3bfYnnE9/t86WgoPv9y8zAEM/3QGXzM4zJK7DDaBO+Lgfr7txbu7so0UDR2lvSjqnI9I0WxY/XxgNb36FYZ1/R8=3Vpbc9o6EP41PCZjWbYxjxDoZaYnzcnlNHk6o2ABbo1FhQjQX18ZyxdJBgwxttuZTMZaryV599tPu4s78Ga++UjRYvYP8XDQMQ1v04HDjmkCyzQ70Z/hbWOJ7bqxYEp9Tyhlggf/FxZCQ0hXvoeXkiIjJGD+QhaOSRjiMZNkiFKyltUmJJBXXaAp1gQPYxTo0m++x2ax1ITQyW58wv50lizt2FZ8Z44SbfEqyxnyyDongqMOvKGEsPhqvrnBQWS9xDDxcx/23E13RnHIyjzw6RaN+1NGB4sNotPp0+I7fbkSs7yhYCXe+Fv/86PYMNsmZuAzcYvzwWA98xl+WKBxdGfNnc5lMzYP+AjwS31TyQqYMrzJicQmP2Iyx4xuuYq4axnCYAIywBbjdeYAkBh1lrO9K2RI+HyaTp1ZhV8Iw5xgJFszElosKHnDHpe+RlsnC0wRI1Q3XOj1Ixjy0ThAy6U/lu1FySr0cLS4wUd447NncSe6fonk17YYDTc5teFWDPZafElWdIyP+x57UgjofsnZ3S4weyKjOEDMf5MDp8gXYoU74vMdp263u7LbUwpIpojfRzyVx7kykeMq+OkpEzFuAsy0iXbQSF/7fLQ4Glr6d3f3X/8bDRsNK8dpW1h1NUM1ED7coHT7nB/knoqG2WO70fvDTuAjRuEBPbdV4QktGT5QhUXZ8HS7zYZnT0MdoyhcTjDd0Tne4PGKZczOyA8cRiblmQMu4HfunS/olWc9Ei5R4E/DCLQcHfwpOIji1OdpRV/cmPueF80xoHjp/0Kvu/kiXC2i995Zwh507GEh0g5Gk0oIaW4kFpGyjyKiuDKuoeSh5KB4L4KAPCtUZiCTyRJfxOWu5vLR8+jm6bFhRu7ZbWPk5MitkJIL6RUcIddK86CjROu0imjNnkK0wD6PaC2FaFMGr4logV5beD7lRBRExhxTjGKaReHuf+mMujWMm0ZLFZQLelZP5kfrfXC6PK0CvS46xBbco+Eu0r0PfpC4jY9E0Q/MMqldxgIveRKoJ7U7yiRnVFTAqYg2urYc7caZ+RlU6gSzZH7G3Yy2OTURVvs3rJRpUG1fHNFP8sYM1PEOKoW4CTWIx8TFZY8ibeSX9/jnCi9Zm7kqidVKuMo2e60nJ70Mr5mcQElyyvioTGq0l5yO1p1uSRI7o+6sisRcqHBPVUUmhDXnPqf1NipBH2juYCzbajx+gDYIPlsBH1Dz5XMbkE7N2NM7HB4O/T8rta6sm2FcW9CyZDJo/dmlNyyGo9vPTTeQlQ5g490KU+9W3JIQN2qk9FcLJatt0EpWjUdRltR0bVc+XHq2c6zrE43uMPX5i0c8U39bp6qjBBgKDEw1/yjdxDHqqca0HUNwuBzr2uCQ/oXKMb3j8He1lNJgreDcg4bTlVx0ZVYCbuU0TU+ry5+LZuM1Xdm8Wq7pjCPEt5fjKqvpGmxMuXvShlOZEBjG4YkuxYTWMSI8Sd1yDqlfiDb1avTP7GKlBFDJj5zAkTvu76THGvhPrwsuxn97OakJDlFLDzUJKsshWnZesjQ/ubcNCvdbdlugDlJIMtIcmO5xAtyWhn+C/yqyI1POYtoU/P7Xf//Hs6enB2v0vftK3NvZzy8FX2peLPYnJGSJopXPa0Cnpn5h2W+kkkq6DaSkkUnpZrVRDyt1zeJ1qqKZQtiaGmwpnvOqLK3PUNAE46gQ16F6MAgrICBD+b22Of7hw+wr9Fg9+5gfjn4DzVdLj9owEP41OVIlcRLocXl0e9iqaEFtOa3cZCAuTswah0d/fW3ihDiGLkVlBeLgeXic+ebz2HbQINs9crxKv7AEqOO7yc5BQ8f3vcD3HfV3k32p8f1AaxacJNrrqJiQ36CVrtYWJIG14SgYo4KsTGXM8hxiYegw52xrus0ZNVdd4QVYikmMqa39ThKR6jQQio6Gz0AWabV0FAalJcOVt05lneKEbRsqNHLQgDMmylG2GwBV8FXAlPM+nbHWX8YhF5dMYC9k+Dr4VWyG7tNr2psul0Gno6NsMC10xkMswFGhIpytHNSnMnj/YHKnJIMnkhExZVOO8/UcuE5N7CvAeMqyn4VEvb9NiYDJCsfKspX8kLpUZFRKnhzOWS50vb1QLWGlU30bcAG7hkqn9wgsA8H30kVbg0BDrdnmIS1vG6WrfNJG1eoaYU2XRR37CKgcaEz/AV/fwncisJD4yBWleID1YTx+/vptNLwvLLuhgWXH82wwve4JML3wVmAiC0wLMsiTB7XtpRRTvF6T2ESKsyJPQC3insBNwsX3P5TxQy3OtO9BGO4MaV9JOyIa06Q00+up8XGSEqo5Z2u0ZgWP4S8w9HQfxHwB4m3uQWK0OLvijYKGJ+pZ6ThQLMjGbIynaqxXGDMiM6sJFUZui1BBiydl4npas5G1I3ntSKgVqYTGinQgXZ349TwMLB7O5Bn1n6n4rpTyL6SUd1eUilr9vnsloaKPZpz2aXBjOoU3b2tXcOnaVng9B6vr3VscjO6Lg6HJnaBNnou7Wqs/Bu1j9MYsjCwWPoMoeK5KwqXKupwYlHv/C0rongG+eT/xTxQ+utX1pHfBPqZUvlzABEc+DFbKLje5uhwq65xQOmCU8cM05B5+ylVwtoSGZT7XllsgHLSvgD0bYnQC4fZxfAHCUjy+hEpKH1+UaPQHzVhZc9owEP41nmkfwtiSLx7J1XammR40SfPUEbbAmtiWR5YD9NdXsmV8CBpgIM4Dg7Ta1fHtt7uSDXiVrD4xlEV3NMSxAcxwZcBrAwALOkD8Scm6kji+XwkWjIRKqRFMyV+shKaSFiTEeUeRUxpzknWFAU1THPCODDFGl121OY27q2ZogTXBNECxLn0kIY8qKYDQbQY+Y7KI6qVdx65GElRrq6PkEQrpsiWCNwa8YpTyqpWsrnAs0auBqexud4xudsZwyvcxKH78eXjMp/j+FpFJ9pCy2Ty7ULO8oLhQJ54WiRDQuQSwtC/HcnkATkpBTINnHKpD8XUNFaNFGmK5mGXAy2VEOJ5mKJCjS0EOIYt4EqthtSxmHK92nsfaoCT4hWmCOVsLFWUAXQVsTS3VXTZ+ssZKFrVdVHMLKW4sNlM36ImGAvAAMIEGpgYSTsOJpKXoBTHKcxJ0cWlANEVPIMHWv2Vn5NTdp/bY9arTW9e9FeEtM9F7UvPLdmMkO7VNtVUcavHQ84c4Di1YgF8nFUdsgfl/9Ozt/m050Nniv1rGcIw4eelud5tP1QrfKREH2dDHGXfpA0GPFtUxlVU7rnoTuU53IuD1Jqpw0CYqKbY59vGsgxrrfmJesFR6gAnR0HFq9YC2/T0D1TlXnNoaYpcoRqmAAJgX4jdJBETSwwZwUSIRWXCJhVQ1p/d3Hy6rFPhRxzaiyazI3yb/wR7vLB3XrQFk+ecC1jl5AqwTWSuNNUnt7InM3jORwSETmd2rg3B8ZCID/o5AfSWRCX+idUstkwr57g0D3+lu2OxcXESjmvGkWdI9FzWtA6h5bD0fgNLekJR2QY+JR9dmrxcbe9bmQyntmgNQ2ttd+Ocozoev/I713ir/WIPsi3zo/GrX+rip9TNZ50ecJDjn5eBEaJXjMyZa5a0gL99LBlAmqLw7fBV2XMNfvAAz2cwYDXC+xy1hhoLnRem1bwWPSYpP5xvP7vrG2uIbYG7xjXsu39RkGTZFnzDV7vsMsnZ46o1ybS9ILXhkrvXM7kT9a8iZn0GW/injljKj/oox2cTl+w7LXuVzvJGjx6W9hQ5j51xxqT+XThSXh3yeeAdXJ2vfgB4PGc++tyOxHxrPfu/dbplg1OPY0SEtus2Hz0q9+X4Mb/4B
\ 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 e43eaeb14d73b5e5398fa452c65cc4581faf64c9..3344dd48d6651c379a9fc3c1a14b29d21adacd9e 100644
GIT binary patch
literal 258533
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