| Public ❗️ | 🛑 | MetaTxModuleStandalone |
+| └ | detectTransferRestriction | Public ❗️ | |NO❗️ |
+| └ | canReturnTransferRestrictionCode | External ❗️ | |NO❗️ |
+| └ | messageForTransferRestriction | External ❗️ | |NO❗️ |
+| └ | _msgSender | Internal 🔒 | | |
+| └ | _msgData | Internal 🔒 | | |
+| └ | _contextSuffixLength | Internal 🔒 | | |
+
+
+### Legend
+
+| Symbol | Meaning |
+|:--------:|-----------|
+| 🛑 | Function can modify state |
+| 💵 | Function is payable |
diff --git a/doc/technical/RuleBlacklist.md b/doc/technical/RuleBlacklist.md
index 6028c04..59ebb3c 100644
--- a/doc/technical/RuleBlacklist.md
+++ b/doc/technical/RuleBlacklist.md
@@ -11,7 +11,9 @@ A part of the code is shared with Rule Whitelist
![surya_graph_Blacklist](../surya/surya_graph/surya_graph_RuleBlacklist.sol.png)
+### Inheritance
+![surya_inheritance_RuleWhitelistWrapper.sol](../surya/surya_inheritance/surya_inheritance_RuleBlacklist.sol.png)
## Access Control
diff --git a/doc/technical/RuleConditionalTransfer.md b/doc/technical/RuleConditionalTransfer.md
index a9f1d85..fcea617 100644
--- a/doc/technical/RuleConditionalTransfer.md
+++ b/doc/technical/RuleConditionalTransfer.md
@@ -71,7 +71,9 @@ To perform the transfer, the token holder has to `approve` the rule to spend tok
![surya_graph_Blacklist](../surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png)
+### Inheritance
+![surya_inheritance_RuleWhitelistWrapper.sol](../surya/surya_inheritance/surya_inheritance_RuleConditionalTransfer.sol.png)
### Workflow
diff --git a/doc/technical/RuleSanctionList.md b/doc/technical/RuleSanctionList.md
index 06fb607..3ce697e 100644
--- a/doc/technical/RuleSanctionList.md
+++ b/doc/technical/RuleSanctionList.md
@@ -18,6 +18,10 @@ The documentation and the contracts addresses are available here: [Chainalysis o
![surya_graph_Whitelist](../surya/surya_graph/surya_graph_RuleSanctionList.sol.png)
+### Inheritance
+
+![surya_inheritance_RuleWhitelistWrapper.sol](../surya/surya_inheritance/surya_inheritance_RuleSanctionList.sol.png)
+
## Access Control
### Admin
diff --git a/doc/technical/RuleWhitelist.md b/doc/technical/RuleWhitelist.md
index 5360520..d74b8aa 100644
--- a/doc/technical/RuleWhitelist.md
+++ b/doc/technical/RuleWhitelist.md
@@ -10,7 +10,9 @@ This rule can be used to restrict transfers from/to only addresses inside a whit
![surya_graph_Whitelist](../surya/surya_graph/surya_graph_RuleWhitelist.sol.png)
+### Inheritance
+![surya_inheritance_RuleWhitelistWrapper.sol](../surya/surya_inheritance/surya_inheritance_RuleWhitelist.sol.png)
## Access Control
@@ -21,7 +23,7 @@ The default admin is the address put in argument(`admin`) inside the constructor
### Schema
Here a schema of the Access Control.
-![alt text](../accessControl/access-control-RuleWhitelist.png)
+![alt text](../security/accessControl/access-control-RuleWhitelist.png)
diff --git a/doc/technical/RuleWhitelistWrapper.md b/doc/technical/RuleWhitelistWrapper.md
new file mode 100644
index 0000000..4895bf1
--- /dev/null
+++ b/doc/technical/RuleWhitelistWrapper.md
@@ -0,0 +1,32 @@
+# Rule Whitelist Wrapper
+
+[TOC]
+
+This rule allows to have several different whitelist rules, managed by different operators.
+
+The rule will call each whitelist rule to know if during a transfer the address `from`or the address `to`is in the whitelist.
+If this is the case, the rule return 0 (transfer valid) or an error otherwise.
+
+## Schema
+
+### Architecture
+
+![ruleWhitelistWrapper.drawio](../schema/rule/ruleWhitelistWrapper.drawio.png)
+
+### Graph
+
+![surya_graph_Whitelist](../surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png)
+
+### Inheritance
+
+![surya_inheritance_RuleWhitelistWrapper.sol](../surya/surya_inheritance/surya_inheritance_RuleWhitelistWrapper.sol.png)
+
+## Details
+
+### Architecture
+
+This rule inherits from `RuleEngineValidationCommon`. Thus the whitelist rules are managed with the same architecture and code than for the ruleEngine. For example, rules are added with the functions `setRulesValidation` or `addRuleValidation`.
+
+### Admin
+
+The default admin is the address put in argument(`admin`) inside the constructor. It is set in the constructor when the contract is deployed.
diff --git a/doc/test/coverage/index-sort-b.html b/doc/test/coverage/index-sort-b.html
index a8ed6d6..922799d 100644
--- a/doc/test/coverage/index-sort-b.html
+++ b/doc/test/coverage/index-sort-b.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
|
@@ -96,22 +96,22 @@
src/rules/validation/abstract/RuleAddressList |
-
+
|
- 96.8 % |
- 30 / 31 |
- 93.3 % |
- 14 / 15 |
+ 97.1 % |
+ 34 / 35 |
+ 93.8 % |
+ 15 / 16 |
75.0 % |
6 / 8 |
src |
-
+
|
- 96.3 % |
- 26 / 27 |
+ 96.6 % |
+ 28 / 29 |
85.7 % |
6 / 7 |
80.0 % |
@@ -123,19 +123,31 @@
98.8 % |
- 84 / 85 |
+ 85 / 86 |
93.8 % |
15 / 16 |
90.5 % |
38 / 42 |
+
+ src/rules/validation |
+
+
+ |
+ 95.8 % |
+ 69 / 72 |
+ 89.5 % |
+ 17 / 19 |
+ 92.1 % |
+ 35 / 38 |
+
src/modules |
|
100.0 % |
- 80 / 80 |
+ 82 / 82 |
100.0 % |
27 / 27 |
95.8 % |
@@ -147,7 +159,7 @@
100.0 % |
- 96 / 96 |
+ 99 / 99 |
94.7 % |
18 / 19 |
98.1 % |
@@ -177,18 +189,6 @@
- |
0 / 0 |
-
- src/rules/validation |
-
-
- |
- 97.7 % |
- 43 / 44 |
- 92.3 % |
- 12 / 13 |
- 100.0 % |
- 26 / 26 |
-
diff --git a/doc/test/coverage/index-sort-f.html b/doc/test/coverage/index-sort-f.html
index 6d4fae1..d45e811 100644
--- a/doc/test/coverage/index-sort-f.html
+++ b/doc/test/coverage/index-sort-f.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
|
@@ -108,10 +108,10 @@
src |
-
+
|
- 96.3 % |
- 26 / 27 |
+ 96.6 % |
+ 28 / 29 |
85.7 % |
6 / 7 |
80.0 % |
@@ -120,24 +120,24 @@
src/rules/validation |
-
+
|
- 97.7 % |
- 43 / 44 |
- 92.3 % |
- 12 / 13 |
- 100.0 % |
- 26 / 26 |
+ 95.8 % |
+ 69 / 72 |
+ 89.5 % |
+ 17 / 19 |
+ 92.1 % |
+ 35 / 38 |
src/rules/validation/abstract/RuleAddressList |
-
+
|
- 96.8 % |
- 30 / 31 |
- 93.3 % |
- 14 / 15 |
+ 97.1 % |
+ 34 / 35 |
+ 93.8 % |
+ 15 / 16 |
75.0 % |
6 / 8 |
@@ -147,7 +147,7 @@
98.8 % |
- 84 / 85 |
+ 85 / 86 |
93.8 % |
15 / 16 |
90.5 % |
@@ -159,7 +159,7 @@
100.0 % |
- 96 / 96 |
+ 99 / 99 |
94.7 % |
18 / 19 |
98.1 % |
@@ -183,7 +183,7 @@
100.0 % |
- 80 / 80 |
+ 82 / 82 |
100.0 % |
27 / 27 |
95.8 % |
diff --git a/doc/test/coverage/index-sort-l.html b/doc/test/coverage/index-sort-l.html
index c955df1..608336a 100644
--- a/doc/test/coverage/index-sort-l.html
+++ b/doc/test/coverage/index-sort-l.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
|
@@ -105,13 +105,25 @@
- |
0 / 0 |
+
+ src/rules/validation |
+
+
+ |
+ 95.8 % |
+ 69 / 72 |
+ 89.5 % |
+ 17 / 19 |
+ 92.1 % |
+ 35 / 38 |
+
src |
-
+
|
- 96.3 % |
- 26 / 27 |
+ 96.6 % |
+ 28 / 29 |
85.7 % |
6 / 7 |
80.0 % |
@@ -120,34 +132,22 @@
src/rules/validation/abstract/RuleAddressList |
-
+
|
- 96.8 % |
- 30 / 31 |
- 93.3 % |
- 14 / 15 |
+ 97.1 % |
+ 34 / 35 |
+ 93.8 % |
+ 15 / 16 |
75.0 % |
6 / 8 |
-
- src/rules/validation |
-
-
- |
- 97.7 % |
- 43 / 44 |
- 92.3 % |
- 12 / 13 |
- 100.0 % |
- 26 / 26 |
-
src/rules/operation |
|
98.8 % |
- 84 / 85 |
+ 85 / 86 |
93.8 % |
15 / 16 |
90.5 % |
@@ -171,7 +171,7 @@
100.0 % |
- 80 / 80 |
+ 82 / 82 |
100.0 % |
27 / 27 |
95.8 % |
@@ -183,7 +183,7 @@
100.0 % |
- 96 / 96 |
+ 99 / 99 |
94.7 % |
18 / 19 |
98.1 % |
diff --git a/doc/test/coverage/index.html b/doc/test/coverage/index.html
index 960324e..db93b03 100644
--- a/doc/test/coverage/index.html
+++ b/doc/test/coverage/index.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
|
@@ -96,10 +96,10 @@
src |
-
+
|
- 96.3 % |
- 26 / 27 |
+ 96.6 % |
+ 28 / 29 |
85.7 % |
6 / 7 |
80.0 % |
@@ -111,7 +111,7 @@
100.0 % |
- 80 / 80 |
+ 82 / 82 |
100.0 % |
27 / 27 |
95.8 % |
@@ -123,7 +123,7 @@
98.8 % |
- 84 / 85 |
+ 85 / 86 |
93.8 % |
15 / 16 |
90.5 % |
@@ -135,7 +135,7 @@
100.0 % |
- 96 / 96 |
+ 99 / 99 |
94.7 % |
18 / 19 |
98.1 % |
@@ -144,14 +144,14 @@
src/rules/validation |
-
+
|
- 97.7 % |
- 43 / 44 |
- 92.3 % |
- 12 / 13 |
- 100.0 % |
- 26 / 26 |
+ 95.8 % |
+ 69 / 72 |
+ 89.5 % |
+ 17 / 19 |
+ 92.1 % |
+ 35 / 38 |
src/rules/validation/abstract |
@@ -168,12 +168,12 @@
src/rules/validation/abstract/RuleAddressList |
-
+
|
- 96.8 % |
- 30 / 31 |
- 93.3 % |
- 14 / 15 |
+ 97.1 % |
+ 34 / 35 |
+ 93.8 % |
+ 15 / 16 |
75.0 % |
6 / 8 |
diff --git a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html b/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html
index 104e111..78d135d 100644
--- a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html
+++ b/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,7 +69,7 @@
Hit count |
- CMTATWithRuleEngineScript.run |
+ CMTATWithRuleEngineScript.run |
0 |
diff --git a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html b/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html
index 6955f40..7974e50 100644
--- a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html
+++ b/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,7 +69,7 @@
Hit count |
- CMTATWithRuleEngineScript.run |
+ CMTATWithRuleEngineScript.run |
0 |
diff --git a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html b/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html
index fd8f994..f3ff3ee 100644
--- a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html
+++ b/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -78,48 +78,53 @@
7 : : import "CMTAT/CMTAT_STANDALONE.sol";
8 : : import "src/RuleEngine.sol";
9 : : import "src/rules/validation/RuleWhitelist.sol";
- 10 : : /**
- 11 : : @title Deploy a CMTAT, a RuleWhitelist and a RuleEngine
- 12 : : */
- 13 : : contract CMTATWithRuleEngineScript is Script {
- 14 : : function run() external {
- 15 : : // Get env variable
- 16 : 0 : uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
- 17 : 0 : address ADMIN = vm.addr(deployerPrivateKey);
- 18 : 0 : address trustedForwarder = address(0x0);
- 19 : 0 : vm.startBroadcast(deployerPrivateKey);
- 20 : 0 : uint256 flag = 5;
- 21 : 0 : uint8 decimals = 0;
- 22 : : // CMTAT
- 23 : 0 : CMTAT_STANDALONE CMTAT_CONTRACT = new CMTAT_STANDALONE(
- 24 : : trustedForwarder,
- 25 : : ADMIN,
- 26 : : IAuthorizationEngine(address(0)),
- 27 : : "CMTA Token",
- 28 : : "CMTAT",
- 29 : : decimals,
- 30 : : "CMTAT_ISIN",
- 31 : : "https://cmta.ch",
- 32 : : IRuleEngine(address(0)),
- 33 : : "CMTAT_info",
- 34 : : flag
- 35 : : );
- 36 : 0 : console.log("CMTAT CMTAT_CONTRACT : ", address(CMTAT_CONTRACT));
- 37 : : // whitelist
- 38 : 0 : RuleWhitelist ruleWhitelist = new RuleWhitelist(
- 39 : : ADMIN,
- 40 : : trustedForwarder
- 41 : : );
- 42 : 0 : console.log("whitelist: ", address(ruleWhitelist));
- 43 : : // ruleEngine
- 44 : 0 : RuleEngine RULE_ENGINE = new RuleEngine(ADMIN, trustedForwarder, address(CMTAT_CONTRACT));
- 45 : 0 : console.log("RuleEngine : ", address(RULE_ENGINE));
- 46 : 0 : RULE_ENGINE.addRuleValidation(ruleWhitelist);
- 47 : 0 : CMTAT_CONTRACT.setRuleEngine(RULE_ENGINE);
- 48 : :
- 49 : 0 : vm.stopBroadcast();
- 50 : : }
- 51 : : }
+ 10 : :
+ 11 : : /**
+ 12 : : @title Deploy a CMTAT, a RuleWhitelist and a RuleEngine
+ 13 : : */
+ 14 : : contract CMTATWithRuleEngineScript is Script {
+ 15 : : function run() external {
+ 16 : : // Get env variable
+ 17 : 0 : uint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");
+ 18 : 0 : address ADMIN = vm.addr(deployerPrivateKey);
+ 19 : 0 : address trustedForwarder = address(0x0);
+ 20 : 0 : vm.startBroadcast(deployerPrivateKey);
+ 21 : 0 : uint256 flag = 5;
+ 22 : 0 : uint8 decimals = 0;
+ 23 : : // CMTAT
+ 24 : 0 : CMTAT_STANDALONE CMTAT_CONTRACT = new CMTAT_STANDALONE(
+ 25 : : trustedForwarder,
+ 26 : : ADMIN,
+ 27 : : IAuthorizationEngine(address(0)),
+ 28 : : "CMTA Token",
+ 29 : : "CMTAT",
+ 30 : : decimals,
+ 31 : : "CMTAT_ISIN",
+ 32 : : "https://cmta.ch",
+ 33 : : IRuleEngine(address(0)),
+ 34 : : "CMTAT_info",
+ 35 : : flag
+ 36 : : );
+ 37 : 0 : console.log("CMTAT CMTAT_CONTRACT : ", address(CMTAT_CONTRACT));
+ 38 : : // whitelist
+ 39 : 0 : RuleWhitelist ruleWhitelist = new RuleWhitelist(
+ 40 : : ADMIN,
+ 41 : : trustedForwarder
+ 42 : : );
+ 43 : 0 : console.log("whitelist: ", address(ruleWhitelist));
+ 44 : : // ruleEngine
+ 45 : 0 : RuleEngine RULE_ENGINE = new RuleEngine(
+ 46 : : ADMIN,
+ 47 : : trustedForwarder,
+ 48 : : address(CMTAT_CONTRACT)
+ 49 : : );
+ 50 : 0 : console.log("RuleEngine : ", address(RULE_ENGINE));
+ 51 : 0 : RULE_ENGINE.addRuleValidation(ruleWhitelist);
+ 52 : 0 : CMTAT_CONTRACT.setRuleEngine(RULE_ENGINE);
+ 53 : :
+ 54 : 0 : vm.stopBroadcast();
+ 55 : : }
+ 56 : : }
diff --git a/doc/test/coverage/script/RuleEngineScript.s.sol.func-sort-c.html b/doc/test/coverage/script/RuleEngineScript.s.sol.func-sort-c.html
index 0be87b7..959b08b 100644
--- a/doc/test/coverage/script/RuleEngineScript.s.sol.func-sort-c.html
+++ b/doc/test/coverage/script/RuleEngineScript.s.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/script/RuleEngineScript.s.sol.func.html b/doc/test/coverage/script/RuleEngineScript.s.sol.func.html
index f91ca3b..0433035 100644
--- a/doc/test/coverage/script/RuleEngineScript.s.sol.func.html
+++ b/doc/test/coverage/script/RuleEngineScript.s.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/script/RuleEngineScript.s.sol.gcov.html b/doc/test/coverage/script/RuleEngineScript.s.sol.gcov.html
index 4eb457e..48afae6 100644
--- a/doc/test/coverage/script/RuleEngineScript.s.sol.gcov.html
+++ b/doc/test/coverage/script/RuleEngineScript.s.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/script/index-sort-b.html b/doc/test/coverage/script/index-sort-b.html
index 7e3a773..4495e7c 100644
--- a/doc/test/coverage/script/index-sort-b.html
+++ b/doc/test/coverage/script/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/script/index-sort-f.html b/doc/test/coverage/script/index-sort-f.html
index afd417e..12cfb5b 100644
--- a/doc/test/coverage/script/index-sort-f.html
+++ b/doc/test/coverage/script/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
|
@@ -82,28 +82,28 @@
Branches |
- RuleEngineScript.s.sol |
+ CMTATWithRuleEngineScript.s.sol |
|
0.0 % |
- 0 / 12 |
+ 0 / 15 |
0.0 % |
0 / 1 |
- 0.0 % |
- 0 / 2 |
+ - |
+ 0 / 0 |
- CMTATWithRuleEngineScript.s.sol |
+ RuleEngineScript.s.sol |
|
0.0 % |
- 0 / 15 |
+ 0 / 12 |
0.0 % |
0 / 1 |
- - |
- 0 / 0 |
+ 0.0 % |
+ 0 / 2 |
diff --git a/doc/test/coverage/script/index-sort-l.html b/doc/test/coverage/script/index-sort-l.html
index 0366127..a1602b6 100644
--- a/doc/test/coverage/script/index-sort-l.html
+++ b/doc/test/coverage/script/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/script/index.html b/doc/test/coverage/script/index.html
index 38a89dc..647bf4f 100644
--- a/doc/test/coverage/script/index.html
+++ b/doc/test/coverage/script/index.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/src/RuleEngine.sol.func-sort-c.html b/doc/test/coverage/src/RuleEngine.sol.func-sort-c.html
index a8539b5..405200a 100644
--- a/doc/test/coverage/src/RuleEngine.sol.func-sort-c.html
+++ b/doc/test/coverage/src/RuleEngine.sol.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -69,32 +69,32 @@
Hit count |
- RuleEngine._msgData |
+ RuleEngine._msgData |
0 |
- RuleEngine.validateTransfer |
+ RuleEngine.validateTransfer |
9 |
- RuleEngine.detectTransferRestriction |
- 13 |
+ RuleEngine.detectTransferRestriction |
+ 17 |
- RuleEngine.messageForTransferRestriction |
- 14 |
+ RuleEngine.messageForTransferRestriction |
+ 18 |
- RuleEngine.operateOnTransfer |
- 45 |
+ RuleEngine.operateOnTransfer |
+ 52 |
- RuleEngine._contextSuffixLength |
- 244 |
+ RuleEngine._contextSuffixLength |
+ 263 |
- RuleEngine._msgSender |
- 244 |
+ RuleEngine._msgSender |
+ 263 |
diff --git a/doc/test/coverage/src/RuleEngine.sol.func.html b/doc/test/coverage/src/RuleEngine.sol.func.html
index 2250ee1..fe0b6bf 100644
--- a/doc/test/coverage/src/RuleEngine.sol.func.html
+++ b/doc/test/coverage/src/RuleEngine.sol.func.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -69,31 +69,31 @@
Hit count |
- RuleEngine._contextSuffixLength |
- 244 |
+ RuleEngine._contextSuffixLength |
+ 263 |
- RuleEngine._msgData |
+ RuleEngine._msgData |
0 |
- RuleEngine._msgSender |
- 244 |
+ RuleEngine._msgSender |
+ 263 |
- RuleEngine.detectTransferRestriction |
- 13 |
+ RuleEngine.detectTransferRestriction |
+ 17 |
- RuleEngine.messageForTransferRestriction |
- 14 |
+ RuleEngine.messageForTransferRestriction |
+ 18 |
- RuleEngine.operateOnTransfer |
- 45 |
+ RuleEngine.operateOnTransfer |
+ 52 |
- RuleEngine.validateTransfer |
+ RuleEngine.validateTransfer |
9 |
diff --git a/doc/test/coverage/src/RuleEngine.sol.gcov.html b/doc/test/coverage/src/RuleEngine.sol.gcov.html
index a5ae197..4d28c47 100644
--- a/doc/test/coverage/src/RuleEngine.sol.gcov.html
+++ b/doc/test/coverage/src/RuleEngine.sol.gcov.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -78,152 +78,177 @@
7 : : import "./modules/RuleEngineOperation.sol";
8 : : import "./modules/RuleEngineValidation.sol";
9 : :
- 10 : :
- 11 : : /**
- 12 : : * @title Implementation of a ruleEngine as defined by the CMTAT
- 13 : : */
- 14 : : contract RuleEngine is IRuleEngine, RuleEngineOperation, RuleEngineValidation, MetaTxModuleStandalone {
- 15 : : error RuleEngine_TransferInvalid();
- 16 : : /**
- 17 : : * @param admin Address of the contract (Access Control)
- 18 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 19 : : */
- 20 : : constructor(
- 21 : : address admin,
- 22 : : address forwarderIrrevocable,
- 23 : : address tokenContract
- 24 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 25 : : if(admin == address(0))
- 26 : : {
- 27 : : revert RuleEngine_AdminWithAddressZeroNotAllowed();
- 28 : : }
- 29 : : if(tokenContract != address(0)){
- 30 : : _grantRole(TOKEN_CONTRACT_ROLE, tokenContract);
- 31 : : }
- 32 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 33 : : _grantRole(RULE_ENGINE_ROLE, admin);
- 34 : : }
- 35 : :
- 36 : :
- 37 : : /**
- 38 : : * @notice Go through all the rule to know if a restriction exists on the transfer
- 39 : : * @param _from the origin address
- 40 : : * @param _to the destination address
- 41 : : * @param _amount to transfer
- 42 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 43 : : **/
- 44 : : function detectTransferRestriction(
- 45 : : address _from,
- 46 : : address _to,
- 47 : : uint256 _amount
- 48 : : ) public view override returns (uint8) {
- 49 : : // Validation
- 50 : 66 : uint8 code = RuleEngineValidation.detectTransferRestrictionValidation(_from, _to, _amount);
- 51 [ + + ]: 66 : if(code != uint8(REJECTED_CODE_BASE.TRANSFER_OK) ){
- 52 : 24 : return code;
- 53 : : }
- 54 : :
- 55 : : // Operation
- 56 : 20 : uint256 rulesLength = _rulesOperation.length;
- 57 : 32 : for (uint256 i = 0; i < rulesLength; ++i ) {
- 58 : 18 : uint8 restriction = IRuleValidation(_rulesOperation[i]).detectTransferRestriction(
- 59 : : _from,
- 60 : : _to,
- 61 : : _amount
- 62 : : );
- 63 [ + + ]: 12 : if (restriction > 0) {
- 64 : 10 : return restriction;
- 65 : : }
- 66 : : }
- 67 : :
- 68 : 15 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 69 : : }
- 70 : :
- 71 : : /**
- 72 : : * @notice Validate a transfer
- 73 : : * @param _from the origin address
- 74 : : * @param _to the destination address
- 75 : : * @param _amount to transfer
- 76 : : * @return True if the transfer is valid, false otherwise
- 77 : : **/
- 78 : : function validateTransfer(
- 79 : : address _from,
- 80 : : address _to,
- 81 : : uint256 _amount
- 82 : : ) public view override returns (bool) {
- 83 : 45 : return detectTransferRestriction(_from, _to, _amount) == uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 84 : : }
- 85 : :
- 86 : : /**
- 87 : : * @notice Return the message corresponding to the code
- 88 : : * @param _restrictionCode The target restriction code
- 89 : : * @return True if the transfer is valid, false otherwise
- 90 : : **/
- 91 : : function messageForTransferRestriction(
- 92 : : uint8 _restrictionCode
- 93 : : ) external view override returns (string memory) {
- 94 : : // Validation
- 95 : 28 : uint256 rulesLength = _rulesValidation.length;
- 96 : 46 : for (uint256 i = 0; i < rulesLength; ++i) {
- 97 [ # + ]: 18 : if (IRuleValidation(_rulesValidation[i]).canReturnTransferRestrictionCode(_restrictionCode)) {
- 98 : 14 : return
- 99 : 14 : IRuleValidation(_rulesValidation[i]).messageForTransferRestriction(_restrictionCode);
- 100 : : }
- 101 : : }
- 102 : : // operation
- 103 : 14 : rulesLength = _rulesOperation.length;
- 104 : 23 : for (uint256 i = 0; i < rulesLength; ++i) {
- 105 [ # + ]: 4 : if (IRuleValidation(_rulesOperation[i]).canReturnTransferRestrictionCode(_restrictionCode)) {
- 106 : 2 : return
- 107 : 2 : IRuleValidation(_rulesOperation[i]).messageForTransferRestriction(_restrictionCode);
- 108 : : }
- 109 : : }
- 110 : 12 : return "Unknown restriction code";
- 111 : : }
- 112 : :
- 113 : : /*
- 114 : : * @notice function protected by access control
- 115 : : */
- 116 : : function operateOnTransfer(address from, address to, uint256 amount) external override onlyRole(TOKEN_CONTRACT_ROLE) returns (bool isValid) {
- 117 : : // Validate the transfer
- 118 [ + + ]: 88 : if(!RuleEngineValidation.validateTransferValidation(from, to, amount)){
- 119 : 14 : return false;
- 120 : : }
- 121 : : // Apply operation on RuleEngine
- 122 : 111 : return RuleEngineOperation._operateOnTransfer(from, to, amount);
- 123 : : }
- 124 : :
- 125 : : /**
- 126 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 127 : : */
- 128 : : function _msgSender()
- 129 : : internal
- 130 : : view
- 131 : : override(ERC2771Context, Context)
- 132 : : returns (address sender)
- 133 : : {
- 134 : 732 : return ERC2771Context._msgSender();
- 135 : : }
- 136 : :
- 137 : : /**
- 138 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 139 : : */
- 140 : : function _msgData()
- 141 : : internal
- 142 : : view
- 143 : : override(ERC2771Context, Context)
- 144 : : returns (bytes calldata)
- 145 : : {
- 146 : 0 : return ERC2771Context._msgData();
- 147 : : }
- 148 : :
- 149 : : /**
- 150 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 151 : : */
- 152 : : function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
- 153 : 732 : return ERC2771Context._contextSuffixLength();
- 154 : : }
- 155 : : }
+ 10 : : /**
+ 11 : : * @title Implementation of a ruleEngine as defined by the CMTAT
+ 12 : : */
+ 13 : : contract RuleEngine is
+ 14 : : IRuleEngine,
+ 15 : : RuleEngineOperation,
+ 16 : : RuleEngineValidation,
+ 17 : : MetaTxModuleStandalone
+ 18 : : {
+ 19 : : error RuleEngine_TransferInvalid();
+ 20 : :
+ 21 : : /**
+ 22 : : * @param admin Address of the contract (Access Control)
+ 23 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ 24 : : */
+ 25 : : constructor(
+ 26 : : address admin,
+ 27 : : address forwarderIrrevocable,
+ 28 : : address tokenContract
+ 29 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
+ 30 : : if (admin == address(0)) {
+ 31 : : revert RuleEngine_AdminWithAddressZeroNotAllowed();
+ 32 : : }
+ 33 : : if (tokenContract != address(0)) {
+ 34 : : _grantRole(TOKEN_CONTRACT_ROLE, tokenContract);
+ 35 : : }
+ 36 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ 37 : : _grantRole(RULE_ENGINE_OPERATOR_ROLE, admin);
+ 38 : : }
+ 39 : :
+ 40 : : /**
+ 41 : : * @notice Go through all the rule to know if a restriction exists on the transfer
+ 42 : : * @param _from the origin address
+ 43 : : * @param _to the destination address
+ 44 : : * @param _amount to transfer
+ 45 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ 46 : : **/
+ 47 : : function detectTransferRestriction(
+ 48 : : address _from,
+ 49 : : address _to,
+ 50 : : uint256 _amount
+ 51 : : ) public view override returns (uint8) {
+ 52 : : // Validation
+ 53 : 78 : uint8 code = RuleEngineValidation.detectTransferRestrictionValidation(
+ 54 : : _from,
+ 55 : : _to,
+ 56 : : _amount
+ 57 : : );
+ 58 [ + + ]: 78 : if (code != uint8(REJECTED_CODE_BASE.TRANSFER_OK)) {
+ 59 : 30 : return code;
+ 60 : : }
+ 61 : :
+ 62 : : // Operation
+ 63 : 22 : uint256 rulesLength = _rulesOperation.length;
+ 64 : 35 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 65 : 18 : uint8 restriction = IRuleValidation(_rulesOperation[i])
+ 66 : : .detectTransferRestriction(_from, _to, _amount);
+ 67 [ + + ]: 12 : if (restriction > 0) {
+ 68 : 10 : return restriction;
+ 69 : : }
+ 70 : : }
+ 71 : :
+ 72 : 18 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 73 : : }
+ 74 : :
+ 75 : : /**
+ 76 : : * @notice Validate a transfer
+ 77 : : * @param _from the origin address
+ 78 : : * @param _to the destination address
+ 79 : : * @param _amount to transfer
+ 80 : : * @return True if the transfer is valid, false otherwise
+ 81 : : **/
+ 82 : : function validateTransfer(
+ 83 : : address _from,
+ 84 : : address _to,
+ 85 : : uint256 _amount
+ 86 : : ) public view override returns (bool) {
+ 87 : 18 : return
+ 88 : 27 : detectTransferRestriction(_from, _to, _amount) ==
+ 89 : 18 : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 90 : : }
+ 91 : :
+ 92 : : /**
+ 93 : : * @notice Return the message corresponding to the code
+ 94 : : * @param _restrictionCode The target restriction code
+ 95 : : * @return True if the transfer is valid, false otherwise
+ 96 : : **/
+ 97 : : function messageForTransferRestriction(
+ 98 : : uint8 _restrictionCode
+ 99 : : ) external view override returns (string memory) {
+ 100 : : // Validation
+ 101 : 36 : uint256 rulesLength = _rulesValidation.length;
+ 102 : 60 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 103 [ # + ]: : if (
+ 104 : 26 : IRuleValidation(_rulesValidation[i])
+ 105 : : .canReturnTransferRestrictionCode(_restrictionCode)
+ 106 : : ) {
+ 107 : 20 : return
+ 108 : 20 : IRuleValidation(_rulesValidation[i])
+ 109 : : .messageForTransferRestriction(_restrictionCode);
+ 110 : : }
+ 111 : : }
+ 112 : : // operation
+ 113 : 16 : rulesLength = _rulesOperation.length;
+ 114 : 26 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 115 [ # + ]: : if (
+ 116 : 4 : IRuleValidation(_rulesOperation[i])
+ 117 : : .canReturnTransferRestrictionCode(_restrictionCode)
+ 118 : : ) {
+ 119 : 2 : return
+ 120 : 2 : IRuleValidation(_rulesOperation[i])
+ 121 : : .messageForTransferRestriction(_restrictionCode);
+ 122 : : }
+ 123 : : }
+ 124 : 14 : return "Unknown restriction code";
+ 125 : : }
+ 126 : :
+ 127 : : /*
+ 128 : : * @notice function protected by access control
+ 129 : : */
+ 130 : : function operateOnTransfer(
+ 131 : : address from,
+ 132 : : address to,
+ 133 : : uint256 amount
+ 134 : : ) external override onlyRole(TOKEN_CONTRACT_ROLE) returns (bool isValid) {
+ 135 : : // Validate the transfer
+ 136 [ + + ]: : if (
+ 137 : 102 : !RuleEngineValidation.validateTransferValidation(from, to, amount)
+ 138 : : ) {
+ 139 : 20 : return false;
+ 140 : : }
+ 141 : : // Apply operation on RuleEngine
+ 142 : 123 : return RuleEngineOperation._operateOnTransfer(from, to, amount);
+ 143 : : }
+ 144 : :
+ 145 : : /**
+ 146 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 147 : : */
+ 148 : : function _msgSender()
+ 149 : : internal
+ 150 : : view
+ 151 : : override(ERC2771Context, Context)
+ 152 : : returns (address sender)
+ 153 : : {
+ 154 : 789 : return ERC2771Context._msgSender();
+ 155 : : }
+ 156 : :
+ 157 : : /**
+ 158 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 159 : : */
+ 160 : : function _msgData()
+ 161 : : internal
+ 162 : : view
+ 163 : : override(ERC2771Context, Context)
+ 164 : : returns (bytes calldata)
+ 165 : : {
+ 166 : 0 : return ERC2771Context._msgData();
+ 167 : : }
+ 168 : :
+ 169 : : /**
+ 170 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 171 : : */
+ 172 : : function _contextSuffixLength()
+ 173 : : internal
+ 174 : : view
+ 175 : : override(ERC2771Context, Context)
+ 176 : : returns (uint256)
+ 177 : : {
+ 178 : 789 : return ERC2771Context._contextSuffixLength();
+ 179 : : }
+ 180 : : }
diff --git a/doc/test/coverage/src/index-sort-b.html b/doc/test/coverage/src/index-sort-b.html
index 7c7d1c2..69c094d 100644
--- a/doc/test/coverage/src/index-sort-b.html
+++ b/doc/test/coverage/src/index-sort-b.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -84,10 +84,10 @@
RuleEngine.sol |
-
+
|
- 96.3 % |
- 26 / 27 |
+ 96.6 % |
+ 28 / 29 |
85.7 % |
6 / 7 |
80.0 % |
diff --git a/doc/test/coverage/src/index-sort-f.html b/doc/test/coverage/src/index-sort-f.html
index 6a6bcc1..a0c5e56 100644
--- a/doc/test/coverage/src/index-sort-f.html
+++ b/doc/test/coverage/src/index-sort-f.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -84,10 +84,10 @@
RuleEngine.sol |
-
+
|
- 96.3 % |
- 26 / 27 |
+ 96.6 % |
+ 28 / 29 |
85.7 % |
6 / 7 |
80.0 % |
diff --git a/doc/test/coverage/src/index-sort-l.html b/doc/test/coverage/src/index-sort-l.html
index 876daf1..7392b50 100644
--- a/doc/test/coverage/src/index-sort-l.html
+++ b/doc/test/coverage/src/index-sort-l.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -84,10 +84,10 @@
RuleEngine.sol |
-
+
|
- 96.3 % |
- 26 / 27 |
+ 96.6 % |
+ 28 / 29 |
85.7 % |
6 / 7 |
80.0 % |
diff --git a/doc/test/coverage/src/index.html b/doc/test/coverage/src/index.html
index 3326585..c192026 100644
--- a/doc/test/coverage/src/index.html
+++ b/doc/test/coverage/src/index.html
@@ -31,13 +31,13 @@
|
-
-
-
+
+
+
-
+
|
@@ -84,10 +84,10 @@
RuleEngine.sol |
-
+
|
- 96.3 % |
- 26 / 27 |
+ 96.6 % |
+ 28 / 29 |
85.7 % |
6 / 7 |
80.0 % |
diff --git a/doc/test/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html b/doc/test/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html
index 60b6676..0fd50ed 100644
--- a/doc/test/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html
+++ b/doc/test/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,47 +69,47 @@
Hit count |
- RuleEngineOperation.ruleOperation |
+ RuleEngineOperation.ruleOperation |
1 |
- RuleEngineOperation.getRuleIndexOperation |
+ RuleEngineOperation.getRuleIndexOperation |
3 |
- RuleEngineOperation.clearRulesOperation |
+ RuleEngineOperation.clearRulesOperation |
4 |
- RuleEngineOperation.removeRuleOperation |
+ RuleEngineOperation.removeRuleOperation |
5 |
- RuleEngineOperation.rulesOperation |
+ RuleEngineOperation.rulesOperation |
5 |
- RuleEngineOperation.setRulesOperation |
+ RuleEngineOperation.setRulesOperation |
11 |
- RuleEngineOperation._clearRulesOperation |
+ RuleEngineOperation._clearRulesOperation |
14 |
- RuleEngineOperation._removeRuleOperation |
+ RuleEngineOperation._removeRuleOperation |
22 |
- RuleEngineOperation._operateOnTransfer |
- 37 |
+ RuleEngineOperation._operateOnTransfer |
+ 41 |
- RuleEngineOperation.rulesCountOperation |
+ RuleEngineOperation.rulesCountOperation |
41 |
- RuleEngineOperation.addRuleOperation |
+ RuleEngineOperation.addRuleOperation |
68 |
diff --git a/doc/test/coverage/src/modules/RuleEngineOperation.sol.func.html b/doc/test/coverage/src/modules/RuleEngineOperation.sol.func.html
index d1a961d..4034157 100644
--- a/doc/test/coverage/src/modules/RuleEngineOperation.sol.func.html
+++ b/doc/test/coverage/src/modules/RuleEngineOperation.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,47 +69,47 @@
Hit count |
- RuleEngineOperation._clearRulesOperation |
+ RuleEngineOperation._clearRulesOperation |
14 |
- RuleEngineOperation._operateOnTransfer |
- 37 |
+ RuleEngineOperation._operateOnTransfer |
+ 41 |
- RuleEngineOperation._removeRuleOperation |
+ RuleEngineOperation._removeRuleOperation |
22 |
- RuleEngineOperation.addRuleOperation |
+ RuleEngineOperation.addRuleOperation |
68 |
- RuleEngineOperation.clearRulesOperation |
+ RuleEngineOperation.clearRulesOperation |
4 |
- RuleEngineOperation.getRuleIndexOperation |
+ RuleEngineOperation.getRuleIndexOperation |
3 |
- RuleEngineOperation.removeRuleOperation |
+ RuleEngineOperation.removeRuleOperation |
5 |
- RuleEngineOperation.ruleOperation |
+ RuleEngineOperation.ruleOperation |
1 |
- RuleEngineOperation.rulesCountOperation |
+ RuleEngineOperation.rulesCountOperation |
41 |
- RuleEngineOperation.rulesOperation |
+ RuleEngineOperation.rulesOperation |
5 |
- RuleEngineOperation.setRulesOperation |
+ RuleEngineOperation.setRulesOperation |
11 |
diff --git a/doc/test/coverage/src/modules/RuleEngineOperation.sol.gcov.html b/doc/test/coverage/src/modules/RuleEngineOperation.sol.gcov.html
index 157fff9..4a3b270 100644
--- a/doc/test/coverage/src/modules/RuleEngineOperation.sol.gcov.html
+++ b/doc/test/coverage/src/modules/RuleEngineOperation.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -77,156 +77,168 @@
6 : : import "../interfaces/IRuleEngineOperation.sol";
7 : : import "../interfaces/IRuleOperation.sol";
8 : : import "OZ/access/AccessControl.sol";
- 9 : : /**
- 10 : : * @title Implementation of a ruleEngine defined by the CMTAT
- 11 : : */
- 12 : : abstract contract RuleEngineOperation is AccessControl, RuleInternal, IRuleEngineOperation {
- 13 : : /// @dev Array of rules
- 14 : : address[] internal _rulesOperation;
- 15 : :
- 16 : : /**
- 17 : : * @notice Set all the rules, will overwrite all the previous rules. \n
- 18 : : * Revert if one rule is a zero address or if the rule is already present
- 19 : : *
- 20 : : */
- 21 : : function setRulesOperation(
- 22 : : address[] calldata rules_
- 23 : : ) public onlyRole(RULE_ENGINE_ROLE) {
- 24 [ + + ]: 22 : if(_rulesOperation.length > 0){
- 25 : 20 : _clearRulesOperation();
- 26 : : }
- 27 : 22 : _setRules(rules_);
- 28 : 16 : _rulesOperation = rules_;
- 29 : : }
- 30 : :
- 31 : : /**
- 32 : : * @notice Clear all the rules of the array of rules
- 33 : : *
- 34 : : */
- 35 : : function clearRulesOperation() public onlyRole(RULE_ENGINE_ROLE) {
- 36 : 8 : _clearRulesOperation();
- 37 : : }
- 38 : :
- 39 : : /**
- 40 : : * @notice Clear all the rules of the array of rules
- 41 : : *
- 42 : : */
- 43 : : function _clearRulesOperation() internal {
- 44 : 28 : uint256 index;
- 45 : : // we remove the last element first since it is more optimized.
- 46 : 76 : for(uint256 i = _rulesOperation.length; i > 0; --i){
- 47 : : unchecked {
- 48 : : // don't underflow since i > 0
- 49 : 34 : index = i - 1;
- 50 : : }
- 51 : 34 : _removeRuleOperation(_rulesOperation[index], index);
- 52 : : }
- 53 : 28 : emit ClearRules(_rulesOperation);
- 54 : : }
- 55 : :
- 56 : : /**
- 57 : : * @notice Add a rule to the array of rules
- 58 : : * Revert if one rule is a zero address or if the rule is already present
- 59 : : *
- 60 : : */
- 61 : : function addRuleOperation(IRuleOperation rule_) public onlyRole(RULE_ENGINE_ROLE) {
- 62 : 136 : RuleInternal._addRule( _rulesOperation, address(rule_));
- 63 : 132 : emit AddRule(address(rule_));
- 64 : : }
- 65 : :
- 66 : : /**
- 67 : : * @notice Remove a rule from the array of rules
- 68 : : * Revert if the rule found at the specified index does not match the rule in argument
- 69 : : * @param rule_ address of the target rule
- 70 : : * @param index the position inside the array of rule
- 71 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 72 : : * by the rule to remove
- 73 : : *
- 74 : : *
- 75 : : */
- 76 : : function removeRuleOperation(
- 77 : : IRuleOperation rule_,
- 78 : : uint256 index
- 79 : : ) public onlyRole(RULE_ENGINE_ROLE) {
- 80 : 10 : _removeRuleOperation(address(rule_), index);
- 81 : : }
- 82 : :
- 83 : : /**
- 84 : : * @notice Remove a rule from the array of rules
- 85 : : * Revert if the rule found at the specified index does not match the rule in argument
- 86 : : * @param rule_ address of the target rule
- 87 : : * @param index the position inside the array of rule
- 88 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 89 : : * by the rule to remove
- 90 : : *
- 91 : : *
- 92 : : */
- 93 : : function _removeRuleOperation(
- 94 : : address rule_,
- 95 : : uint256 index
- 96 : : ) internal {
- 97 : 44 : RuleInternal._removeRule(_rulesOperation, rule_, index);
- 98 : 42 : emit RemoveRule(address(rule_));
- 99 : : }
- 100 : :
- 101 : : /**
- 102 : : * @return The number of rules inside the array
- 103 : : */
- 104 : : function rulesCountOperation() external view override returns (uint256) {
- 105 : 82 : return _rulesOperation.length;
- 106 : : }
- 107 : :
- 108 : : /**
- 109 : : * @notice Get the index of a rule inside the list
- 110 : : * @return index if the rule is found, _rulesOperation.length otherwise
- 111 : : */
- 112 : : function getRuleIndexOperation(IRuleOperation rule_) external view returns (uint256 index) {
- 113 : 9 : return RuleInternal.getRuleIndex(_rulesOperation, address(rule_));
- 114 : : }
- 115 : :
- 116 : : /**
- 117 : : * @notice Get the rule at the position specified by ruleId
- 118 : : * @param ruleId index of the rule
- 119 : : * @return a rule address
- 120 : : */
- 121 : : function ruleOperation(uint256 ruleId) external view override returns (address) {
- 122 : 2 : return _rulesOperation[ruleId];
- 123 : : }
- 124 : :
- 125 : : /**
- 126 : : * @notice Get all the rules
- 127 : : * @return An array of rules
- 128 : : */
- 129 : : function rulesOperation() external view override returns (address[] memory) {
- 130 : 10 : return _rulesOperation;
+ 9 : :
+ 10 : : /**
+ 11 : : * @title Implementation of a ruleEngine defined by the CMTAT
+ 12 : : */
+ 13 : : abstract contract RuleEngineOperation is
+ 14 : : AccessControl,
+ 15 : : RuleInternal,
+ 16 : : IRuleEngineOperation
+ 17 : : {
+ 18 : : /// @dev Array of rules
+ 19 : : address[] internal _rulesOperation;
+ 20 : :
+ 21 : : /**
+ 22 : : * @notice Set all the rules, will overwrite all the previous rules. \n
+ 23 : : * Revert if one rule is a zero address or if the rule is already present
+ 24 : : *
+ 25 : : */
+ 26 : : function setRulesOperation(
+ 27 : : address[] calldata rules_
+ 28 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ 29 [ + + ]: 22 : if (_rulesOperation.length > 0) {
+ 30 : 20 : _clearRulesOperation();
+ 31 : : }
+ 32 : 22 : _setRules(rules_);
+ 33 : 16 : _rulesOperation = rules_;
+ 34 : : }
+ 35 : :
+ 36 : : /**
+ 37 : : * @notice Clear all the rules of the array of rules
+ 38 : : *
+ 39 : : */
+ 40 : : function clearRulesOperation() public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ 41 : 8 : _clearRulesOperation();
+ 42 : : }
+ 43 : :
+ 44 : : /**
+ 45 : : * @notice Clear all the rules of the array of rules
+ 46 : : *
+ 47 : : */
+ 48 : : function _clearRulesOperation() internal {
+ 49 : 28 : uint256 index;
+ 50 : : // we remove the last element first since it is more optimized.
+ 51 : 76 : for (uint256 i = _rulesOperation.length; i > 0; --i) {
+ 52 : : unchecked {
+ 53 : : // don't underflow since i > 0
+ 54 : 34 : index = i - 1;
+ 55 : : }
+ 56 : 34 : _removeRuleOperation(_rulesOperation[index], index);
+ 57 : : }
+ 58 : 28 : emit ClearRules(_rulesOperation);
+ 59 : : }
+ 60 : :
+ 61 : : /**
+ 62 : : * @notice Add a rule to the array of rules
+ 63 : : * Revert if one rule is a zero address or if the rule is already present
+ 64 : : *
+ 65 : : */
+ 66 : : function addRuleOperation(
+ 67 : : IRuleOperation rule_
+ 68 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ 69 : 136 : RuleInternal._addRule(_rulesOperation, address(rule_));
+ 70 : 132 : emit AddRule(address(rule_));
+ 71 : : }
+ 72 : :
+ 73 : : /**
+ 74 : : * @notice Remove a rule from the array of rules
+ 75 : : * Revert if the rule found at the specified index does not match the rule in argument
+ 76 : : * @param rule_ address of the target rule
+ 77 : : * @param index the position inside the array of rule
+ 78 : : * @dev To reduce the array size, the last rule is moved to the location occupied
+ 79 : : * by the rule to remove
+ 80 : : *
+ 81 : : *
+ 82 : : */
+ 83 : : function removeRuleOperation(
+ 84 : : IRuleOperation rule_,
+ 85 : : uint256 index
+ 86 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ 87 : 10 : _removeRuleOperation(address(rule_), index);
+ 88 : : }
+ 89 : :
+ 90 : : /**
+ 91 : : * @notice Remove a rule from the array of rules
+ 92 : : * Revert if the rule found at the specified index does not match the rule in argument
+ 93 : : * @param rule_ address of the target rule
+ 94 : : * @param index the position inside the array of rule
+ 95 : : * @dev To reduce the array size, the last rule is moved to the location occupied
+ 96 : : * by the rule to remove
+ 97 : : *
+ 98 : : *
+ 99 : : */
+ 100 : : function _removeRuleOperation(address rule_, uint256 index) internal {
+ 101 : 44 : RuleInternal._removeRule(_rulesOperation, rule_, index);
+ 102 : 42 : emit RemoveRule(address(rule_));
+ 103 : : }
+ 104 : :
+ 105 : : /**
+ 106 : : * @return The number of rules inside the array
+ 107 : : */
+ 108 : : function rulesCountOperation() external view override returns (uint256) {
+ 109 : 82 : return _rulesOperation.length;
+ 110 : : }
+ 111 : :
+ 112 : : /**
+ 113 : : * @notice Get the index of a rule inside the list
+ 114 : : * @return index if the rule is found, _rulesOperation.length otherwise
+ 115 : : */
+ 116 : : function getRuleIndexOperation(
+ 117 : : IRuleOperation rule_
+ 118 : : ) external view returns (uint256 index) {
+ 119 : 9 : return RuleInternal.getRuleIndex(_rulesOperation, address(rule_));
+ 120 : : }
+ 121 : :
+ 122 : : /**
+ 123 : : * @notice Get the rule at the position specified by ruleId
+ 124 : : * @param ruleId index of the rule
+ 125 : : * @return a rule address
+ 126 : : */
+ 127 : : function ruleOperation(
+ 128 : : uint256 ruleId
+ 129 : : ) external view override returns (address) {
+ 130 : 2 : return _rulesOperation[ruleId];
131 : : }
132 : :
- 133 : :
- 134 : : /**
- 135 : : * @notice Go through all the rule to know if a restriction exists on the transfer
- 136 : : * @param _from the origin address
- 137 : : * @param _to the destination address
- 138 : : * @param _amount to transfer
- 139 : : **/
- 140 : : function _operateOnTransfer(
- 141 : : address _from,
- 142 : : address _to,
- 143 : : uint256 _amount
- 144 : : ) internal returns (bool isValid){
- 145 : 74 : uint256 rulesLength = _rulesOperation.length;
- 146 : 143 : for (uint256 i = 0; i < rulesLength; ++i ) {
- 147 : 99 : bool result = IRuleOperation(_rulesOperation[i]).operateOnTransfer(
- 148 : : _from,
- 149 : : _to,
- 150 : : _amount
- 151 : : );
- 152 [ + + ]: 66 : if(!result){
- 153 : 34 : return false;
- 154 : : }
- 155 : : }
- 156 : 40 : return true;
- 157 : : }
- 158 : : }
+ 133 : : /**
+ 134 : : * @notice Get all the rules
+ 135 : : * @return An array of rules
+ 136 : : */
+ 137 : : function rulesOperation()
+ 138 : : external
+ 139 : : view
+ 140 : : override
+ 141 : : returns (address[] memory)
+ 142 : : {
+ 143 : 10 : return _rulesOperation;
+ 144 : : }
+ 145 : :
+ 146 : : /**
+ 147 : : * @notice Go through all the rule to know if a restriction exists on the transfer
+ 148 : : * @param _from the origin address
+ 149 : : * @param _to the destination address
+ 150 : : * @param _amount to transfer
+ 151 : : **/
+ 152 : : function _operateOnTransfer(
+ 153 : : address _from,
+ 154 : : address _to,
+ 155 : : uint256 _amount
+ 156 : : ) internal returns (bool isValid) {
+ 157 : 82 : uint256 rulesLength = _rulesOperation.length;
+ 158 : 155 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 159 : 99 : bool result = IRuleOperation(_rulesOperation[i]).operateOnTransfer(
+ 160 : : _from,
+ 161 : : _to,
+ 162 : : _amount
+ 163 : : );
+ 164 [ + + ]: 66 : if (!result) {
+ 165 : 34 : return false;
+ 166 : : }
+ 167 : : }
+ 168 : 48 : return true;
+ 169 : : }
+ 170 : : }
diff --git a/doc/test/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html b/doc/test/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html
index 25488e0..ab7d535 100644
--- a/doc/test/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html
+++ b/doc/test/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,8 +49,8 @@
|
|
-
-
+
+
|
@@ -69,53 +69,13 @@
Hit count |
- RuleEngineValidation.ruleValidation |
- 1 |
-
-
- RuleEngineValidation.validateTransferValidation |
+ RuleEngineValidation.validateTransferValidation |
2 |
- RuleEngineValidation.detectTransferRestrictionValidation |
- 3 |
-
-
- RuleEngineValidation.getRuleIndexValidation |
+ RuleEngineValidation.detectTransferRestrictionValidation |
3 |
-
- RuleEngineValidation.rulesValidation |
- 5 |
-
-
- RuleEngineValidation.clearRulesValidation |
- 6 |
-
-
- RuleEngineValidation.removeRuleValidation |
- 6 |
-
-
- RuleEngineValidation.setRulesValidation |
- 22 |
-
-
- RuleEngineValidation._clearRulesValidation |
- 25 |
-
-
- RuleEngineValidation._removeRuleValidation |
- 33 |
-
-
- RuleEngineValidation.addRuleValidation |
- 67 |
-
-
- RuleEngineValidation.rulesCountValidation |
- 69 |
-
diff --git a/doc/test/coverage/src/modules/RuleEngineValidation.sol.func.html b/doc/test/coverage/src/modules/RuleEngineValidation.sol.func.html
index 0e25146..9008852 100644
--- a/doc/test/coverage/src/modules/RuleEngineValidation.sol.func.html
+++ b/doc/test/coverage/src/modules/RuleEngineValidation.sol.func.html
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,8 +49,8 @@
|
|
-
-
+
+
|
@@ -69,51 +69,11 @@
Hit count |
- RuleEngineValidation._clearRulesValidation |
- 25 |
-
-
- RuleEngineValidation._removeRuleValidation |
- 33 |
-
-
- RuleEngineValidation.addRuleValidation |
- 67 |
-
-
- RuleEngineValidation.clearRulesValidation |
- 6 |
-
-
- RuleEngineValidation.detectTransferRestrictionValidation |
- 3 |
-
-
- RuleEngineValidation.getRuleIndexValidation |
+ RuleEngineValidation.detectTransferRestrictionValidation |
3 |
- RuleEngineValidation.removeRuleValidation |
- 6 |
-
-
- RuleEngineValidation.ruleValidation |
- 1 |
-
-
- RuleEngineValidation.rulesCountValidation |
- 69 |
-
-
- RuleEngineValidation.rulesValidation |
- 5 |
-
-
- RuleEngineValidation.setRulesValidation |
- 22 |
-
-
- RuleEngineValidation.validateTransferValidation |
+ RuleEngineValidation.validateTransferValidation |
2 |
diff --git a/doc/test/coverage/src/modules/RuleEngineValidation.sol.gcov.html b/doc/test/coverage/src/modules/RuleEngineValidation.sol.gcov.html
index d78351a..6a7a5f3 100644
--- a/doc/test/coverage/src/modules/RuleEngineValidation.sol.gcov.html
+++ b/doc/test/coverage/src/modules/RuleEngineValidation.sol.gcov.html
@@ -31,17 +31,17 @@
|
-
-
+
+
-
+
|
-
-
+
+
@@ -49,8 +49,8 @@
|
|
-
-
+
+
|
@@ -75,177 +75,62 @@
4 : :
5 : : import "OZ/access/AccessControl.sol";
6 : : import "./RuleInternal.sol";
- 7 : : import "../interfaces/IRuleEngineValidation.sol";
- 8 : : import "../interfaces/IRuleValidation.sol";
- 9 : : import "CMTAT/interfaces/draft-IERC1404/draft-IERC1404EnumCode.sol";
- 10 : : /**
- 11 : : * @title Implementation of a ruleEngine defined by the CMTAT
- 12 : : */
- 13 : : abstract contract RuleEngineValidation is AccessControl, RuleInternal, IRuleEngineValidation, IERC1404EnumCode {
- 14 : : /// @dev Array of rules
- 15 : : address[] internal _rulesValidation;
- 16 : :
- 17 : :
- 18 : : /**
- 19 : : * @notice Set all the rules, will overwrite all the previous rules. \n
- 20 : : * Revert if one rule is a zero address or if the rule is already present
- 21 : : * @dev take address[] instead of IRuleEngineValidation[] since it is not possible to cast IRuleEngineValidation[] -> address[]
- 22 : : *
- 23 : : */
- 24 : : function setRulesValidation(
- 25 : : address[] calldata rules_
- 26 : : ) public override onlyRole(RULE_ENGINE_ROLE) {
- 27 [ + + ]: 42 : if(_rulesValidation.length > 0){
- 28 : 40 : _clearRulesValidation();
- 29 : : }
- 30 : 42 : _setRules(rules_);
- 31 : 36 : _rulesValidation = rules_;
- 32 : : }
- 33 : :
- 34 : : /**
- 35 : : * @notice Clear all the rules of the array of rules
- 36 : : *
- 37 : : */
- 38 : : function clearRulesValidation() public onlyRole(RULE_ENGINE_ROLE) {
- 39 : 10 : _clearRulesValidation();
- 40 : : }
- 41 : :
- 42 : : /**
- 43 : : * @notice Clear all the rules of the array of rules
- 44 : : *
- 45 : : */
- 46 : : function _clearRulesValidation() internal {
- 47 : 50 : uint256 index;
- 48 : : // we remove the last element first since it is more optimized.
- 49 : 131 : for(uint256 i = _rulesValidation.length; i > 0; --i){
- 50 : : unchecked {
- 51 : : // don't underflow since i > 0
- 52 : 56 : index = i - 1;
- 53 : : }
- 54 : 56 : _removeRuleValidation(_rulesValidation[index], index);
- 55 : : }
- 56 : 50 : emit ClearRules(_rulesValidation);
- 57 : : }
- 58 : :
- 59 : : /**
- 60 : : * @notice Add a rule to the array of rules
- 61 : : * Revert if one rule is a zero address or if the rule is already present
- 62 : : *
- 63 : : */
- 64 : : function addRuleValidation(IRuleValidation rule_) public onlyRole(RULE_ENGINE_ROLE) {
- 65 : 132 : RuleInternal._addRule( _rulesValidation, address(rule_));
- 66 : 128 : emit AddRule(address(rule_));
- 67 : : }
- 68 : :
- 69 : : /**
- 70 : : * @notice Remove a rule from the array of rules
- 71 : : * Revert if the rule found at the specified index does not match the rule in argument
- 72 : : * @param rule_ address of the target rule
- 73 : : * @param index the position inside the array of rule
- 74 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 75 : : * by the rule to remove
- 76 : : *
- 77 : : *
- 78 : : */
- 79 : : function removeRuleValidation(
- 80 : : IRuleValidation rule_,
- 81 : : uint256 index
- 82 : : ) public onlyRole(RULE_ENGINE_ROLE) {
- 83 : 10 : _removeRuleValidation(address(rule_), index);
- 84 : : }
- 85 : :
- 86 : : /**
- 87 : : * @notice Remove a rule from the array of rules
- 88 : : * Revert if the rule found at the specified index does not match the rule in argument
- 89 : : * @param rule_ address of the target rule
- 90 : : * @param index the position inside the array of rule
- 91 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 92 : : * by the rule to remove
- 93 : : *
- 94 : : *
- 95 : : */
- 96 : : function _removeRuleValidation(
- 97 : : address rule_,
- 98 : : uint256 index
- 99 : : ) internal {
- 100 : 66 : RuleInternal._removeRule(_rulesValidation, rule_, index);
- 101 : 64 : emit RemoveRule(address(rule_));
- 102 : : }
- 103 : :
- 104 : : /**
- 105 : : * @return The number of rules inside the array
- 106 : : */
- 107 : : function rulesCountValidation() external view override returns (uint256) {
- 108 : 138 : return _rulesValidation.length;
- 109 : : }
- 110 : :
- 111 : : /**
- 112 : : * @notice Get the index of a rule inside the list
- 113 : : * @return index if the rule is found, _rulesValidation.length otherwise
- 114 : : */
- 115 : : function getRuleIndexValidation(IRuleValidation rule_) external view returns (uint256 index) {
- 116 : 9 : return RuleInternal.getRuleIndex(_rulesValidation, address(rule_));
- 117 : : }
- 118 : :
- 119 : : /**
- 120 : : * @notice Get the rule at the position specified by ruleId
- 121 : : * @param ruleId index of the rule
- 122 : : * @return a rule address
- 123 : : */
- 124 : : function ruleValidation(uint256 ruleId) external view override returns (address) {
- 125 : 2 : return _rulesValidation[ruleId];
- 126 : : }
- 127 : :
- 128 : : /**
- 129 : : * @notice Get all the rules
- 130 : : * @return An array of rules
- 131 : : */
- 132 : : function rulesValidation() external view override returns (address[] memory) {
- 133 : 10 : return _rulesValidation;
- 134 : : }
- 135 : :
- 136 : : /**
- 137 : : * @notice Go through all the rule to know if a restriction exists on the transfer
- 138 : : * @param _from the origin address
- 139 : : * @param _to the destination address
- 140 : : * @param _amount to transfer
- 141 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 142 : : **/
- 143 : : function detectTransferRestrictionValidation(
- 144 : : address _from,
- 145 : : address _to,
- 146 : : uint256 _amount
- 147 : : ) public view override returns (uint8) {
- 148 : 142 : uint256 rulesLength = _rulesValidation.length;
- 149 : 233 : for (uint256 i = 0; i < rulesLength; ++i ) {
- 150 : 96 : uint8 restriction = IRuleValidation(_rulesValidation[i]).detectTransferRestriction(
- 151 : : _from,
- 152 : : _to,
- 153 : : _amount
- 154 : : );
- 155 [ + + ]: 64 : if (restriction > 0) {
- 156 : 44 : return restriction;
- 157 : : }
- 158 : : }
- 159 : :
- 160 : 147 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 161 : : }
- 162 : :
- 163 : : /**
- 164 : : * @notice Validate a transfer
- 165 : : * @param _from the origin address
- 166 : : * @param _to the destination address
- 167 : : * @param _amount to transfer
- 168 : : * @return True if the transfer is valid, false otherwise
- 169 : : **/
- 170 : : function validateTransferValidation(
- 171 : : address _from,
- 172 : : address _to,
- 173 : : uint256 _amount
- 174 : : ) public view override returns (bool) {
- 175 : 230 : return detectTransferRestrictionValidation(_from, _to, _amount) == uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 176 : : }
- 177 : : }
+ 7 : : import "./RuleEngineValidationCommon.sol";
+ 8 : : import "../interfaces/IRuleEngineValidation.sol";
+ 9 : : import "../interfaces/IRuleValidation.sol";
+ 10 : : import "CMTAT/interfaces/draft-IERC1404/draft-IERC1404EnumCode.sol";
+ 11 : :
+ 12 : : /**
+ 13 : : * @title Implementation of a ruleEngine defined by the CMTAT
+ 14 : : */
+ 15 : : abstract contract RuleEngineValidation is
+ 16 : : AccessControl,
+ 17 : : RuleInternal,
+ 18 : : RuleEngineValidationCommon,
+ 19 : : IRuleEngineValidation,
+ 20 : : IERC1404EnumCode
+ 21 : : {
+ 22 : : /**
+ 23 : : * @notice Go through all the rule to know if a restriction exists on the transfer
+ 24 : : * @param _from the origin address
+ 25 : : * @param _to the destination address
+ 26 : : * @param _amount to transfer
+ 27 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ 28 : : **/
+ 29 : : function detectTransferRestrictionValidation(
+ 30 : : address _from,
+ 31 : : address _to,
+ 32 : : uint256 _amount
+ 33 : : ) public view override returns (uint8) {
+ 34 : 164 : uint256 rulesLength = _rulesValidation.length;
+ 35 : 276 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 36 : 129 : uint8 restriction = IRuleValidation(_rulesValidation[i])
+ 37 : : .detectTransferRestriction(_from, _to, _amount);
+ 38 [ + + ]: 86 : if (restriction > 0) {
+ 39 : 56 : return restriction;
+ 40 : : }
+ 41 : : }
+ 42 : :
+ 43 : 162 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 44 : : }
+ 45 : :
+ 46 : : /**
+ 47 : : * @notice Validate a transfer
+ 48 : : * @param _from the origin address
+ 49 : : * @param _to the destination address
+ 50 : : * @param _amount to transfer
+ 51 : : * @return True if the transfer is valid, false otherwise
+ 52 : : **/
+ 53 : : function validateTransferValidation(
+ 54 : : address _from,
+ 55 : : address _to,
+ 56 : : uint256 _amount
+ 57 : : ) public view override returns (bool) {
+ 58 : 106 : return
+ 59 : 159 : detectTransferRestrictionValidation(_from, _to, _amount) ==
+ 60 : 106 : uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 61 : : }
+ 62 : : }
diff --git a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html b/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html
new file mode 100644
index 0000000..2cc84b0
--- /dev/null
+++ b/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/modules/RuleEngineValidationCommon.sol - functions
+
+
+
+
+
+
+ LCOV - code coverage report |
+ |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func.html b/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func.html
new file mode 100644
index 0000000..cc2d19e
--- /dev/null
+++ b/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func.html
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/modules/RuleEngineValidationCommon.sol - functions
+
+
+
+
+
+
+ LCOV - code coverage report |
+ |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html b/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html
new file mode 100644
index 0000000..c291df0
--- /dev/null
+++ b/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html
@@ -0,0 +1,231 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/modules/RuleEngineValidationCommon.sol
+
+
+
+
+
+
+ LCOV - code coverage report |
+ |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+
+
+
|
+
+
+
+ Branch data Line data Source code
+
+ 1 : : // SPDX-License-Identifier: MPL-2.0
+ 2 : :
+ 3 : : pragma solidity ^0.8.20;
+ 4 : :
+ 5 : : import "OZ/access/AccessControl.sol";
+ 6 : : import "./RuleInternal.sol";
+ 7 : : import "../interfaces/IRuleEngineValidation.sol";
+ 8 : : import "../interfaces/IRuleValidation.sol";
+ 9 : :
+ 10 : : /**
+ 11 : : * @title Implementation of a ruleEngine defined by the CMTAT
+ 12 : : */
+ 13 : : abstract contract RuleEngineValidationCommon is
+ 14 : : AccessControl,
+ 15 : : RuleInternal,
+ 16 : : IRuleEngineValidationCommon
+ 17 : : {
+ 18 : : /// @dev Array of rules
+ 19 : : address[] internal _rulesValidation;
+ 20 : :
+ 21 : : /**
+ 22 : : * @notice Set all the rules, will overwrite all the previous rules. \n
+ 23 : : * Revert if one rule is a zero address or if the rule is already present
+ 24 : : * @dev take address[] instead of IRuleEngineValidation[] since it is not possible to cast IRuleEngineValidation[] -> address[]
+ 25 : : *
+ 26 : : */
+ 27 : : function setRulesValidation(
+ 28 : : address[] calldata rules_
+ 29 : : ) public override onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ 30 [ + + ]: 42 : if (_rulesValidation.length > 0) {
+ 31 : 40 : _clearRulesValidation();
+ 32 : : }
+ 33 : 42 : _setRules(rules_);
+ 34 : 36 : _rulesValidation = rules_;
+ 35 : : }
+ 36 : :
+ 37 : : /**
+ 38 : : * @notice Clear all the rules of the array of rules
+ 39 : : *
+ 40 : : */
+ 41 : : function clearRulesValidation() public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ 42 : 10 : _clearRulesValidation();
+ 43 : : }
+ 44 : :
+ 45 : : /**
+ 46 : : * @notice Clear all the rules of the array of rules
+ 47 : : *
+ 48 : : */
+ 49 : : function _clearRulesValidation() internal {
+ 50 : 50 : uint256 index;
+ 51 : : // we remove the last element first since it is more optimized.
+ 52 : 131 : for (uint256 i = _rulesValidation.length; i > 0; --i) {
+ 53 : : unchecked {
+ 54 : : // don't underflow since i > 0
+ 55 : 56 : index = i - 1;
+ 56 : : }
+ 57 : 56 : _removeRuleValidation(_rulesValidation[index], index);
+ 58 : : }
+ 59 : 50 : emit ClearRules(_rulesValidation);
+ 60 : : }
+ 61 : :
+ 62 : : /**
+ 63 : : * @notice Add a rule to the array of rules
+ 64 : : * Revert if one rule is a zero address or if the rule is already present
+ 65 : : *
+ 66 : : */
+ 67 : : function addRuleValidation(
+ 68 : : IRuleValidation rule_
+ 69 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ 70 : 228 : RuleInternal._addRule(_rulesValidation, address(rule_));
+ 71 : 224 : emit AddRule(address(rule_));
+ 72 : : }
+ 73 : :
+ 74 : : /**
+ 75 : : * @notice Remove a rule from the array of rules
+ 76 : : * Revert if the rule found at the specified index does not match the rule in argument
+ 77 : : * @param rule_ address of the target rule
+ 78 : : * @param index the position inside the array of rule
+ 79 : : * @dev To reduce the array size, the last rule is moved to the location occupied
+ 80 : : * by the rule to remove
+ 81 : : *
+ 82 : : *
+ 83 : : */
+ 84 : : function removeRuleValidation(
+ 85 : : IRuleValidation rule_,
+ 86 : : uint256 index
+ 87 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ 88 : 10 : _removeRuleValidation(address(rule_), index);
+ 89 : : }
+ 90 : :
+ 91 : : /**
+ 92 : : * @notice Remove a rule from the array of rules
+ 93 : : * Revert if the rule found at the specified index does not match the rule in argument
+ 94 : : * @param rule_ address of the target rule
+ 95 : : * @param index the position inside the array of rule
+ 96 : : * @dev To reduce the array size, the last rule is moved to the location occupied
+ 97 : : * by the rule to remove
+ 98 : : *
+ 99 : : *
+ 100 : : */
+ 101 : : function _removeRuleValidation(address rule_, uint256 index) internal {
+ 102 : 66 : RuleInternal._removeRule(_rulesValidation, rule_, index);
+ 103 : 64 : emit RemoveRule(address(rule_));
+ 104 : : }
+ 105 : :
+ 106 : : /**
+ 107 : : * @return The number of rules inside the array
+ 108 : : */
+ 109 : : function rulesCountValidation() external view override returns (uint256) {
+ 110 : 138 : return _rulesValidation.length;
+ 111 : : }
+ 112 : :
+ 113 : : /**
+ 114 : : * @notice Get the index of a rule inside the list
+ 115 : : * @return index if the rule is found, _rulesValidation.length otherwise
+ 116 : : */
+ 117 : : function getRuleIndexValidation(
+ 118 : : IRuleValidation rule_
+ 119 : : ) external view returns (uint256 index) {
+ 120 : 9 : return RuleInternal.getRuleIndex(_rulesValidation, address(rule_));
+ 121 : : }
+ 122 : :
+ 123 : : /**
+ 124 : : * @notice Get the rule at the position specified by ruleId
+ 125 : : * @param ruleId index of the rule
+ 126 : : * @return a rule address
+ 127 : : */
+ 128 : : function ruleValidation(
+ 129 : : uint256 ruleId
+ 130 : : ) external view override returns (address) {
+ 131 : 2 : return _rulesValidation[ruleId];
+ 132 : : }
+ 133 : :
+ 134 : : /**
+ 135 : : * @notice Get all the rules
+ 136 : : * @return An array of rules
+ 137 : : */
+ 138 : : function rulesValidation()
+ 139 : : external
+ 140 : : view
+ 141 : : override
+ 142 : : returns (address[] memory)
+ 143 : : {
+ 144 : 10 : return _rulesValidation;
+ 145 : : }
+ 146 : : }
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/doc/test/coverage/src/modules/RuleInternal.sol.func-sort-c.html b/doc/test/coverage/src/modules/RuleInternal.sol.func-sort-c.html
index 7f87299..388b450 100644
--- a/doc/test/coverage/src/modules/RuleInternal.sol.func-sort-c.html
+++ b/doc/test/coverage/src/modules/RuleInternal.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,20 +69,20 @@
Hit count |
- RuleInternal.getRuleIndex |
+ RuleInternal.getRuleIndex |
6 |
- RuleInternal._setRules |
+ RuleInternal._setRules |
32 |
- RuleInternal._removeRule |
+ RuleInternal._removeRule |
55 |
- RuleInternal._addRule |
- 134 |
+ RuleInternal._addRule |
+ 182 |
diff --git a/doc/test/coverage/src/modules/RuleInternal.sol.func.html b/doc/test/coverage/src/modules/RuleInternal.sol.func.html
index 3682d83..c96cc29 100644
--- a/doc/test/coverage/src/modules/RuleInternal.sol.func.html
+++ b/doc/test/coverage/src/modules/RuleInternal.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,19 +69,19 @@
Hit count |
- RuleInternal._addRule |
- 134 |
+ RuleInternal._addRule |
+ 182 |
- RuleInternal._removeRule |
+ RuleInternal._removeRule |
55 |
- RuleInternal._setRules |
+ RuleInternal._setRules |
32 |
- RuleInternal.getRuleIndex |
+ RuleInternal.getRuleIndex |
6 |
diff --git a/doc/test/coverage/src/modules/RuleInternal.sol.gcov.html b/doc/test/coverage/src/modules/RuleInternal.sol.gcov.html
index 56428d7..c533201 100644
--- a/doc/test/coverage/src/modules/RuleInternal.sol.gcov.html
+++ b/doc/test/coverage/src/modules/RuleInternal.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -75,102 +75,99 @@
4 : : import "./RuleEngineInvariantStorage.sol";
5 : :
6 : : /**
- 7 : : * @title Implementation of a ruleEngine defined by the CMTAT
- 8 : : */
+ 7 : : * @title Implementation of a ruleEngine defined by the CMTAT
+ 8 : : */
9 : : abstract contract RuleInternal is RuleEngineInvariantStorage {
- 10 : :
- 11 : : /// @dev Indicate if a rule already exists
- 12 : : // Can be shared betwen RuleOperation and RuleValidation since it is a mapping
- 13 : : mapping(address => bool) _ruleIsPresent;
- 14 : :
- 15 : : /**
- 16 : : * @notice Set all the rules, will overwrite all the previous rules. \n
- 17 : : * Revert if one rule is a zero address or if the rule is already present
- 18 : : *
- 19 : : */
- 20 : : function _setRules(
- 21 : : address[] calldata rules_
- 22 : : ) internal {
- 23 [ + + ]: 64 : if(rules_.length == 0){
- 24 : 4 : revert RuleEngine_ArrayIsEmpty();
- 25 : : }
- 26 : 134 : for (uint256 i = 0; i < rules_.length; ) {
- 27 [ + + ]: 192 : if( address(rules_[i]) == address(0x0)){
- 28 : 4 : revert RuleEngine_RuleAddressZeroNotAllowed();
+ 10 : : /// @dev Indicate if a rule already exists
+ 11 : : // Can be shared betwen RuleOperation and RuleValidation since it is a mapping
+ 12 : : mapping(address => bool) _ruleIsPresent;
+ 13 : :
+ 14 : : /**
+ 15 : : * @notice Set all the rules, will overwrite all the previous rules. \n
+ 16 : : * Revert if one rule is a zero address or if the rule is already present
+ 17 : : *
+ 18 : : */
+ 19 : : function _setRules(address[] calldata rules_) internal {
+ 20 [ + + ]: 64 : if (rules_.length == 0) {
+ 21 : 4 : revert RuleEngine_ArrayIsEmpty();
+ 22 : : }
+ 23 : 134 : for (uint256 i = 0; i < rules_.length; ) {
+ 24 [ + + ]: 192 : if (address(rules_[i]) == address(0x0)) {
+ 25 : 4 : revert RuleEngine_RuleAddressZeroNotAllowed();
+ 26 : : }
+ 27 [ + + ]: 46 : if (_ruleIsPresent[rules_[i]]) {
+ 28 : 4 : revert RuleEngine_RuleAlreadyExists();
29 : : }
- 30 [ + + ]: 46 : if(_ruleIsPresent[rules_[i]]){
- 31 : 4 : revert RuleEngine_RuleAlreadyExists();
- 32 : : }
- 33 : 88 : _ruleIsPresent[rules_[i]] = true;
- 34 : 88 : emit AddRule(rules_[i]);
- 35 : : unchecked {
- 36 : 88 : ++i;
- 37 : : }
- 38 : : }
- 39 : : }
- 40 : :
- 41 : : /**
- 42 : : * @notice Add a rule to the array of rules
- 43 : : * Revert if one rule is a zero address or if the rule is already present
- 44 : : *
- 45 : : */
- 46 : : function _addRule(address[] storage _rules, address rule_) internal {
- 47 [ + + ]: 536 : if( address(rule_) == address(0x0))
- 48 : : {
- 49 : 4 : revert RuleEngine_RuleAddressZeroNotAllowed();
- 50 : : }
- 51 [ + + ]: 132 : if( _ruleIsPresent[rule_])
- 52 : : {
- 53 : 4 : revert RuleEngine_RuleAlreadyExists();
- 54 : : }
- 55 : 260 : _rules.push(rule_);
- 56 : 260 : _ruleIsPresent[rule_] = true;
- 57 : : }
- 58 : :
- 59 : : /**
- 60 : : * @notice Remove a rule from the array of rules
- 61 : : * Revert if the rule found at the specified index does not match the rule in argument
- 62 : : * @param rule_ address of the target rule
- 63 : : * @param index the position inside the array of rule
- 64 : : * @dev To reduce the array size, the last rule is moved to the location occupied
- 65 : : * by the rule to remove
- 66 : : *
- 67 : : *
- 68 : : */
- 69 : : function _removeRule(
- 70 : : address[] storage _rules,
- 71 : : address rule_,
- 72 : : uint256 index
- 73 : : ) internal {
- 74 [ + + ]: 110 : if(_rules[index] != rule_)
- 75 : : {
- 76 : 4 : revert RuleEngine_RuleDoNotMatch();
- 77 : : }
- 78 [ # + ]: 159 : if (index != _rules.length - 1) {
- 79 : 8 : _rules[index] = _rules[_rules.length - 1];
- 80 : : }
- 81 : 106 : _rules.pop();
- 82 : 106 : _ruleIsPresent[rule_] = false;
- 83 : 106 : emit RemoveRule(rule_);
- 84 : : }
- 85 : :
- 86 : : /**
- 87 : : * @notice Get the index of a rule inside the list
- 88 : : * @return index if the rule is found, _rules.length otherwise
- 89 : : */
- 90 : : function getRuleIndex(address[] storage _rules, address rule_) internal view returns (uint256 index) {
- 91 : 12 : uint256 rulesLength = _rules.length;
- 92 : 24 : for (index = 0; index < rulesLength;) {
- 93 [ + + ]: 20 : if (_rules[index] == rule_) {
- 94 : 8 : return index;
+ 30 : 88 : _ruleIsPresent[rules_[i]] = true;
+ 31 : 88 : emit AddRule(rules_[i]);
+ 32 : : unchecked {
+ 33 : 88 : ++i;
+ 34 : : }
+ 35 : : }
+ 36 : : }
+ 37 : :
+ 38 : : /**
+ 39 : : * @notice Add a rule to the array of rules
+ 40 : : * Revert if one rule is a zero address or if the rule is already present
+ 41 : : *
+ 42 : : */
+ 43 : : function _addRule(address[] storage _rules, address rule_) internal {
+ 44 [ + + ]: 728 : if (address(rule_) == address(0x0)) {
+ 45 : 4 : revert RuleEngine_RuleAddressZeroNotAllowed();
+ 46 : : }
+ 47 [ + + ]: 180 : if (_ruleIsPresent[rule_]) {
+ 48 : 4 : revert RuleEngine_RuleAlreadyExists();
+ 49 : : }
+ 50 : 356 : _rules.push(rule_);
+ 51 : 356 : _ruleIsPresent[rule_] = true;
+ 52 : : }
+ 53 : :
+ 54 : : /**
+ 55 : : * @notice Remove a rule from the array of rules
+ 56 : : * Revert if the rule found at the specified index does not match the rule in argument
+ 57 : : * @param rule_ address of the target rule
+ 58 : : * @param index the position inside the array of rule
+ 59 : : * @dev To reduce the array size, the last rule is moved to the location occupied
+ 60 : : * by the rule to remove
+ 61 : : *
+ 62 : : *
+ 63 : : */
+ 64 : : function _removeRule(
+ 65 : : address[] storage _rules,
+ 66 : : address rule_,
+ 67 : : uint256 index
+ 68 : : ) internal {
+ 69 [ + + ]: 110 : if (_rules[index] != rule_) {
+ 70 : 4 : revert RuleEngine_RuleDoNotMatch();
+ 71 : : }
+ 72 [ # + ]: 159 : if (index != _rules.length - 1) {
+ 73 : 8 : _rules[index] = _rules[_rules.length - 1];
+ 74 : : }
+ 75 : 106 : _rules.pop();
+ 76 : 106 : _ruleIsPresent[rule_] = false;
+ 77 : 106 : emit RemoveRule(rule_);
+ 78 : : }
+ 79 : :
+ 80 : : /**
+ 81 : : * @notice Get the index of a rule inside the list
+ 82 : : * @return index if the rule is found, _rules.length otherwise
+ 83 : : */
+ 84 : : function getRuleIndex(
+ 85 : : address[] storage _rules,
+ 86 : : address rule_
+ 87 : : ) internal view returns (uint256 index) {
+ 88 : 12 : uint256 rulesLength = _rules.length;
+ 89 : 24 : for (index = 0; index < rulesLength; ) {
+ 90 [ + + ]: 20 : if (_rules[index] == rule_) {
+ 91 : 8 : return index;
+ 92 : : }
+ 93 : : unchecked {
+ 94 : 12 : ++index;
95 : : }
- 96 : : unchecked {
- 97 : 12 : ++index;
- 98 : : }
- 99 : : }
- 100 : 4 : return _rules.length;
- 101 : : }
- 102 : : }
+ 96 : : }
+ 97 : 4 : return _rules.length;
+ 98 : : }
+ 99 : : }
diff --git a/doc/test/coverage/src/modules/index-sort-b.html b/doc/test/coverage/src/modules/index-sort-b.html
index 85bb87e..014db42 100644
--- a/doc/test/coverage/src/modules/index-sort-b.html
+++ b/doc/test/coverage/src/modules/index-sort-b.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -93,17 +93,29 @@
93.8 % |
15 / 16 |
+
+ RuleEngineValidationCommon.sol |
+
+
+ |
+ 100.0 % |
+ 19 / 19 |
+ 100.0 % |
+ 10 / 10 |
+ 100.0 % |
+ 2 / 2 |
+
RuleEngineValidation.sol |
|
100.0 % |
- 26 / 26 |
+ 9 / 9 |
100.0 % |
- 12 / 12 |
+ 2 / 2 |
100.0 % |
- 4 / 4 |
+ 2 / 2 |
RuleEngineOperation.sol |
diff --git a/doc/test/coverage/src/modules/index-sort-f.html b/doc/test/coverage/src/modules/index-sort-f.html
index a84ef03..4e1c5fa 100644
--- a/doc/test/coverage/src/modules/index-sort-f.html
+++ b/doc/test/coverage/src/modules/index-sort-f.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -81,6 +81,18 @@
Functions |
Branches |
+
+ RuleEngineValidation.sol |
+
+
+ |
+ 100.0 % |
+ 9 / 9 |
+ 100.0 % |
+ 2 / 2 |
+ 100.0 % |
+ 2 / 2 |
+
RuleInternal.sol |
@@ -94,26 +106,26 @@
| 15 / 16 |
- RuleEngineOperation.sol |
+ RuleEngineValidationCommon.sol |
|
100.0 % |
- 25 / 25 |
+ 19 / 19 |
100.0 % |
- 11 / 11 |
+ 10 / 10 |
100.0 % |
- 4 / 4 |
+ 2 / 2 |
- RuleEngineValidation.sol |
+ RuleEngineOperation.sol |
|
100.0 % |
- 26 / 26 |
+ 25 / 25 |
100.0 % |
- 12 / 12 |
+ 11 / 11 |
100.0 % |
4 / 4 |
diff --git a/doc/test/coverage/src/modules/index-sort-l.html b/doc/test/coverage/src/modules/index-sort-l.html
index 49f111f..4306ce9 100644
--- a/doc/test/coverage/src/modules/index-sort-l.html
+++ b/doc/test/coverage/src/modules/index-sort-l.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -82,26 +82,38 @@
Branches |
- RuleEngineOperation.sol |
+ RuleEngineValidation.sol |
|
100.0 % |
- 25 / 25 |
+ 9 / 9 |
100.0 % |
- 11 / 11 |
+ 2 / 2 |
100.0 % |
- 4 / 4 |
+ 2 / 2 |
- RuleEngineValidation.sol |
+ RuleEngineValidationCommon.sol |
|
100.0 % |
- 26 / 26 |
+ 19 / 19 |
+ 100.0 % |
+ 10 / 10 |
100.0 % |
- 12 / 12 |
+ 2 / 2 |
+
+
+ RuleEngineOperation.sol |
+
+
+ |
+ 100.0 % |
+ 25 / 25 |
+ 100.0 % |
+ 11 / 11 |
100.0 % |
4 / 4 |
diff --git a/doc/test/coverage/src/modules/index.html b/doc/test/coverage/src/modules/index.html
index 373a764..953d36c 100644
--- a/doc/test/coverage/src/modules/index.html
+++ b/doc/test/coverage/src/modules/index.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -99,11 +99,23 @@
100.0 % |
- 26 / 26 |
+ 9 / 9 |
100.0 % |
- 12 / 12 |
+ 2 / 2 |
100.0 % |
- 4 / 4 |
+ 2 / 2 |
+
+
+ RuleEngineValidationCommon.sol |
+
+
+ |
+ 100.0 % |
+ 19 / 19 |
+ 100.0 % |
+ 10 / 10 |
+ 100.0 % |
+ 2 / 2 |
RuleInternal.sol |
diff --git a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html b/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html
index 6760052..5abe2e2 100644
--- a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html
+++ b/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
+
-
+
|
@@ -69,67 +69,67 @@
Hit count |
- RuleConditionalTransfer._msgData |
+ RuleConditionalTransfer._msgData |
0 |
- RuleConditionalTransfer.canReturnTransferRestrictionCode |
+ RuleConditionalTransfer.canReturnTransferRestrictionCode |
2 |
- RuleConditionalTransfer.cancelTransferRequestBatch |
+ RuleConditionalTransfer.cancelTransferRequestBatch |
3 |
- RuleConditionalTransfer.createTransferRequestBatch |
+ RuleConditionalTransfer.createTransferRequestBatch |
3 |
- RuleConditionalTransfer.messageForTransferRestriction |
+ RuleConditionalTransfer.messageForTransferRestriction |
3 |
- RuleConditionalTransfer.cancelTransferRequest |
+ RuleConditionalTransfer.cancelTransferRequest |
6 |
- RuleConditionalTransfer._cancelTransferRequest |
+ RuleConditionalTransfer._cancelTransferRequest |
9 |
- RuleConditionalTransfer.detectTransferRestriction |
+ RuleConditionalTransfer.detectTransferRestriction |
11 |
- RuleConditionalTransfer.operateOnTransfer |
+ RuleConditionalTransfer.operateOnTransfer |
33 |
- RuleConditionalTransfer.getRequestByStatus |
+ RuleConditionalTransfer.getRequestByStatus |
35 |
- RuleConditionalTransfer._validateApproval |
+ RuleConditionalTransfer._validateApproval |
37 |
- RuleConditionalTransfer._validateBurnMint |
+ RuleConditionalTransfer._validateBurnMint |
41 |
- RuleConditionalTransfer.getRequestTrade |
+ RuleConditionalTransfer.getRequestTrade |
57 |
- RuleConditionalTransfer.createTransferRequest |
+ RuleConditionalTransfer.createTransferRequest |
102 |
- RuleConditionalTransfer._contextSuffixLength |
+ RuleConditionalTransfer._contextSuffixLength |
452 |
- RuleConditionalTransfer._msgSender |
+ RuleConditionalTransfer._msgSender |
452 |
diff --git a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html b/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html
index 4bb3fe2..9fa83d8 100644
--- a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html
+++ b/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html
@@ -31,13 +31,13 @@
|
-
+
-
+
|
@@ -69,67 +69,67 @@
Hit count |
- RuleConditionalTransfer._cancelTransferRequest |
+ RuleConditionalTransfer._cancelTransferRequest |
9 |
- RuleConditionalTransfer._contextSuffixLength |
+ RuleConditionalTransfer._contextSuffixLength |
452 |
- RuleConditionalTransfer._msgData |
+ RuleConditionalTransfer._msgData |
0 |
- RuleConditionalTransfer._msgSender |
+ RuleConditionalTransfer._msgSender |
452 |
- RuleConditionalTransfer._validateApproval |
+ RuleConditionalTransfer._validateApproval |
37 |
- RuleConditionalTransfer._validateBurnMint |
+ RuleConditionalTransfer._validateBurnMint |
41 |
- RuleConditionalTransfer.canReturnTransferRestrictionCode |
+ RuleConditionalTransfer.canReturnTransferRestrictionCode |
2 |
- RuleConditionalTransfer.cancelTransferRequest |
+ RuleConditionalTransfer.cancelTransferRequest |
6 |
- RuleConditionalTransfer.cancelTransferRequestBatch |
+ RuleConditionalTransfer.cancelTransferRequestBatch |
3 |
- RuleConditionalTransfer.createTransferRequest |
+ RuleConditionalTransfer.createTransferRequest |
102 |
- RuleConditionalTransfer.createTransferRequestBatch |
+ RuleConditionalTransfer.createTransferRequestBatch |
3 |
- RuleConditionalTransfer.detectTransferRestriction |
+ RuleConditionalTransfer.detectTransferRestriction |
11 |
- RuleConditionalTransfer.getRequestByStatus |
+ RuleConditionalTransfer.getRequestByStatus |
35 |
- RuleConditionalTransfer.getRequestTrade |
+ RuleConditionalTransfer.getRequestTrade |
57 |
- RuleConditionalTransfer.messageForTransferRestriction |
+ RuleConditionalTransfer.messageForTransferRestriction |
3 |
- RuleConditionalTransfer.operateOnTransfer |
+ RuleConditionalTransfer.operateOnTransfer |
33 |
diff --git a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html b/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html
index d822f2b..9ad4604 100644
--- a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html
+++ b/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html
@@ -31,13 +31,13 @@
|
-
+
-
+
|
@@ -75,342 +75,375 @@
4 : :
5 : : import "OZ/access/AccessControl.sol";
6 : : import "../../interfaces/IRuleOperation.sol";
- 7 : : import "./../../modules/MetaTxModuleStandalone.sol";
+ 7 : : import "./../../modules/MetaTxModuleStandalone.sol";
8 : : import "./abstract/RuleConditionalTransferInvariantStorage.sol";
9 : : import "./abstract/RuleConditionalTransferOperator.sol";
10 : : import "../validation/abstract/RuleValidateTransfer.sol";
11 : : import "CMTAT/interfaces/engine/IRuleEngine.sol";
12 : :
13 : : /**
- 14 : : * @title a whitelist manager
- 15 : : */
+ 14 : : * @title a whitelist manager
+ 15 : : */
16 : :
- 17 : : contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleConditionalTransferOperator, MetaTxModuleStandalone {
- 18 : : /**
- 19 : : * @param admin Address of the contract (Access Control)
- 20 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 21 : : */
- 22 : : constructor(
- 23 : : address admin,
- 24 : : address forwarderIrrevocable,
- 25 : : IRuleEngine ruleEngineContract,
- 26 : : OPTION memory options_
- 27 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 28 : : if(admin == address(0)){
- 29 : : revert RuleConditionalTransfer_AdminWithAddressZeroNotAllowed();
- 30 : : }
- 31 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 32 : : _grantRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE, admin);
- 33 : : if(address(ruleEngineContract) != address(0x0)){
- 34 : : _grantRole(RULE_ENGINE_CONTRACT_ROLE, address(ruleEngineContract));
+ 17 : : contract RuleConditionalTransfer is
+ 18 : : RuleValidateTransfer,
+ 19 : : IRuleOperation,
+ 20 : : RuleConditionalTransferOperator,
+ 21 : : MetaTxModuleStandalone
+ 22 : : {
+ 23 : : /**
+ 24 : : * @param admin Address of the contract (Access Control)
+ 25 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ 26 : : */
+ 27 : : constructor(
+ 28 : : address admin,
+ 29 : : address forwarderIrrevocable,
+ 30 : : IRuleEngine ruleEngineContract,
+ 31 : : OPTION memory options_
+ 32 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
+ 33 : : if (admin == address(0)) {
+ 34 : : revert RuleConditionalTransfer_AdminWithAddressZeroNotAllowed();
35 : : }
- 36 : : if(options_.timeLimit.timeLimitToApprove == 0){
- 37 : : options_.timeLimit.timeLimitToApprove = type(uint64).max;
- 38 : : }
- 39 : : if(options_.timeLimit.timeLimitToTransfer == 0){
- 40 : : options_.timeLimit.timeLimitToTransfer = type(uint64).max;
- 41 : : }
- 42 : : options = options_;
- 43 : : }
- 44 : :
- 45 : : /**
- 46 : : * @notice Create a request of transfer for yourselves
- 47 : : * @param to recipient of tokens
- 48 : : * @param value amount of tokens to transfer
- 49 : : */
- 50 : : function createTransferRequest(
- 51 : : address to, uint256 value
- 52 : : ) public {
- 53 : : // WAIT => Will set a new delay to approve
- 54 : : // APPROVED => will overwrite previous status
- 55 : : // DENIED => reject
- 56 : 315 : address from = _msgSender();
- 57 : 315 : bytes32 key = keccak256(abi.encode(from, to, value));
- 58 [ + + ]: 210 : if(transferRequests[key].status == STATUS.DENIED){
- 59 : 2 : revert RuleConditionalTransfer_TransferDenied();
- 60 : : }
- 61 [ # + ]: 208 : if(_checkRequestStatus(key)){
- 62 : 202 : uint256 requestIdLocal = requestId;
- 63 : 303 : TransferRequest memory newTransferApproval = TransferRequest({
- 64 : : key:key,
- 65 : : id: requestIdLocal,
- 66 : : from: from,
- 67 : : to:to,
- 68 : : value:value,
- 69 : : askTime: block.timestamp,
- 70 : : maxTime:0,
- 71 : : status: STATUS.WAIT
- 72 : : }
- 73 : : );
- 74 : 202 : transferRequests[key] = newTransferApproval;
- 75 : 202 : IdToKey[requestIdLocal] = key;
- 76 : 202 : emit transferWaiting(key, from, to, value, requestId);
- 77 : 202 : ++requestId;
- 78 : : } else {
- 79 : : // Overwrite previous approval
- 80 : 6 : transferRequests[key].askTime = block.timestamp;
- 81 : 6 : transferRequests[key].status = STATUS.WAIT;
- 82 : 6 : emit transferWaiting(key, from, to, value, transferRequests[key].id);
- 83 : : }
- 84 : : }
- 85 : :
- 86 : : /**
- 87 : : * @notice Batch version of {createTransferRequest}
- 88 : : */
- 89 : : function createTransferRequestBatch(address[] memory tos, uint256[] memory values) public{
- 90 [ + + ]: 6 : if(tos.length == 0){
- 91 : 2 : revert RuleConditionalTransfer_EmptyArray();
- 92 : : }
- 93 [ + + ]: 4 : if(tos.length != values.length){
- 94 : 2 : revert RuleConditionalTransfer_InvalidLengthArray();
- 95 : : }
- 96 : 9 : for(uint256 i = 0; i < tos.length; ++i){
- 97 : 6 : createTransferRequest(tos[i], values[i]);
- 98 : : }
- 99 : : }
- 100 : :
- 101 : : /**
- 102 : : * @notice allow a token holder to cancel/reset his own request
- 103 : : */
- 104 : : function cancelTransferRequest(
- 105 : : uint256 requestId_
- 106 : : ) public {
- 107 : 12 : _cancelTransferRequest(requestId_);
- 108 : : }
- 109 : :
- 110 : : /**
- 111 : : * @notice allow a token holder to cancel/reset his own request
- 112 : : */
- 113 : : function cancelTransferRequestBatch(
- 114 : : uint256[] memory requestIds
- 115 : : ) public {
- 116 [ + + ]: 6 : if(requestIds.length == 0){
- 117 : 2 : revert RuleConditionalTransfer_EmptyArray();
- 118 : : }
- 119 : : // Check id validity before performing actions
- 120 : 14 : for(uint256 i = 0; i < requestIds.length; ++i){
- 121 [ + + ]: 15 : if(requestIds[i] + 1 > requestId) {
- 122 : 2 : revert RuleConditionalTransfer_InvalidId();
- 123 : : }
- 124 : : }
- 125 : 9 : for(uint256 i = 0; i < requestIds.length; ++i){
- 126 : 6 : _cancelTransferRequest(requestIds[i]);
- 127 : : }
- 128 : :
- 129 : : }
- 130 : :
- 131 : : function _cancelTransferRequest(
- 132 : : uint256 requestId_
- 133 : : ) internal {
- 134 [ + + ]: 27 : if(requestId_ + 1 > requestId) {
- 135 : 2 : revert RuleConditionalTransfer_InvalidId();
- 136 : : }
- 137 : 16 : bytes32 key = IdToKey[requestId_];
- 138 : : // Check Sender
- 139 [ + + ]: 24 : if(transferRequests[key].from != _msgSender()){
- 140 : 2 : revert RuleConditionalTransfer_InvalidSender();
- 141 : : }
- 142 : : // Check status
- 143 [ + + ]: 21 : if(transferRequests[key].status != STATUS.WAIT
- 144 : 4 : && transferRequests[key].status != STATUS.APPROVED
- 145 : : ){
- 146 : 2 : revert RuleConditionalTransfer_Wrong_Status();
- 147 : : }
- 148 : 12 : _resetRequestStatus(key);
- 149 : : }
- 150 : :
- 151 : :
- 152 : : function getRequestTrade(address from, address to, uint256 value) public view returns (TransferRequest memory) {
- 153 : 171 : bytes32 key = keccak256(abi.encode(from, to, value));
- 154 : 114 : return transferRequests[key];
- 155 : : }
- 156 : :
- 157 : : /**
- 158 : : * @notice get Trade by status
- 159 : : * @param _targetStatus The status of the transactions you want to retrieve
- 160 : : * @return array with corresponding transactions
- 161 : : */
- 162 : : function getRequestByStatus(STATUS _targetStatus) public view returns (TransferRequest[] memory) {
- 163 : 70 : uint totalRequestCount = requestId;
- 164 : 70 : uint requestCount = 0;
- 165 : 70 : uint currentIndex = 0;
- 166 : :
- 167 : : // We count the number of requests matching the criteria
- 168 : 181 : for (uint i = 0; i < totalRequestCount; ++i) {
- 169 [ + + ]: 76 : if (transferRequests[IdToKey[i]].status == _targetStatus) {
- 170 : 72 : requestCount += 1;
- 171 : : }
- 172 : : }
- 173 : :
- 174 : : // We reserve the memory to store the trade
- 175 : 105 : TransferRequest[] memory requests = new TransferRequest[](requestCount);
+ 36 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ 37 : : _grantRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE, admin);
+ 38 : : if (address(ruleEngineContract) != address(0x0)) {
+ 39 : : _grantRole(RULE_ENGINE_CONTRACT_ROLE, address(ruleEngineContract));
+ 40 : : }
+ 41 : : if (options_.timeLimit.timeLimitToApprove == 0) {
+ 42 : : options_.timeLimit.timeLimitToApprove = type(uint64).max;
+ 43 : : }
+ 44 : : if (options_.timeLimit.timeLimitToTransfer == 0) {
+ 45 : : options_.timeLimit.timeLimitToTransfer = type(uint64).max;
+ 46 : : }
+ 47 : : options = options_;
+ 48 : : }
+ 49 : :
+ 50 : : /**
+ 51 : : * @notice Create a request of transfer for yourselves
+ 52 : : * @param to recipient of tokens
+ 53 : : * @param value amount of tokens to transfer
+ 54 : : */
+ 55 : : function createTransferRequest(address to, uint256 value) public {
+ 56 : : // WAIT => Will set a new delay to approve
+ 57 : : // APPROVED => will overwrite previous status
+ 58 : : // DENIED => reject
+ 59 : 315 : address from = _msgSender();
+ 60 : 315 : bytes32 key = keccak256(abi.encode(from, to, value));
+ 61 [ + + ]: 210 : if (transferRequests[key].status == STATUS.DENIED) {
+ 62 : 2 : revert RuleConditionalTransfer_TransferDenied();
+ 63 : : }
+ 64 [ # + ]: 208 : if (_checkRequestStatus(key)) {
+ 65 : 202 : uint256 requestIdLocal = requestId;
+ 66 : 303 : TransferRequest memory newTransferApproval = TransferRequest({
+ 67 : : key: key,
+ 68 : : id: requestIdLocal,
+ 69 : : from: from,
+ 70 : : to: to,
+ 71 : : value: value,
+ 72 : : askTime: block.timestamp,
+ 73 : : maxTime: 0,
+ 74 : : status: STATUS.WAIT
+ 75 : : });
+ 76 : 202 : transferRequests[key] = newTransferApproval;
+ 77 : 202 : IdToKey[requestIdLocal] = key;
+ 78 : 202 : emit transferWaiting(key, from, to, value, requestId);
+ 79 : 202 : ++requestId;
+ 80 : : } else {
+ 81 : : // Overwrite previous approval
+ 82 : 6 : transferRequests[key].askTime = block.timestamp;
+ 83 : 6 : transferRequests[key].status = STATUS.WAIT;
+ 84 : 6 : emit transferWaiting(
+ 85 : : key,
+ 86 : : from,
+ 87 : : to,
+ 88 : : value,
+ 89 : : transferRequests[key].id
+ 90 : : );
+ 91 : : }
+ 92 : : }
+ 93 : :
+ 94 : : /**
+ 95 : : * @notice Batch version of {createTransferRequest}
+ 96 : : */
+ 97 : : function createTransferRequestBatch(
+ 98 : : address[] memory tos,
+ 99 : : uint256[] memory values
+ 100 : : ) public {
+ 101 [ + + ]: 6 : if (tos.length == 0) {
+ 102 : 2 : revert RuleConditionalTransfer_EmptyArray();
+ 103 : : }
+ 104 [ + + ]: 4 : if (tos.length != values.length) {
+ 105 : 2 : revert RuleConditionalTransfer_InvalidLengthArray();
+ 106 : : }
+ 107 : 9 : for (uint256 i = 0; i < tos.length; ++i) {
+ 108 : 6 : createTransferRequest(tos[i], values[i]);
+ 109 : : }
+ 110 : : }
+ 111 : :
+ 112 : : /**
+ 113 : : * @notice allow a token holder to cancel/reset his own request
+ 114 : : */
+ 115 : : function cancelTransferRequest(uint256 requestId_) public {
+ 116 : 12 : _cancelTransferRequest(requestId_);
+ 117 : : }
+ 118 : :
+ 119 : : /**
+ 120 : : * @notice allow a token holder to cancel/reset his own request
+ 121 : : */
+ 122 : : function cancelTransferRequestBatch(uint256[] memory requestIds) public {
+ 123 [ + + ]: 6 : if (requestIds.length == 0) {
+ 124 : 2 : revert RuleConditionalTransfer_EmptyArray();
+ 125 : : }
+ 126 : : // Check id validity before performing actions
+ 127 : 14 : for (uint256 i = 0; i < requestIds.length; ++i) {
+ 128 [ + + ]: 15 : if (requestIds[i] + 1 > requestId) {
+ 129 : 2 : revert RuleConditionalTransfer_InvalidId();
+ 130 : : }
+ 131 : : }
+ 132 : 9 : for (uint256 i = 0; i < requestIds.length; ++i) {
+ 133 : 6 : _cancelTransferRequest(requestIds[i]);
+ 134 : : }
+ 135 : : }
+ 136 : :
+ 137 : : function _cancelTransferRequest(uint256 requestId_) internal {
+ 138 [ + + ]: 27 : if (requestId_ + 1 > requestId) {
+ 139 : 2 : revert RuleConditionalTransfer_InvalidId();
+ 140 : : }
+ 141 : 16 : bytes32 key = IdToKey[requestId_];
+ 142 : : // Check Sender
+ 143 [ + + ]: 24 : if (transferRequests[key].from != _msgSender()) {
+ 144 : 2 : revert RuleConditionalTransfer_InvalidSender();
+ 145 : : }
+ 146 : : // Check status
+ 147 [ + + ]: : if (
+ 148 : 21 : transferRequests[key].status != STATUS.WAIT &&
+ 149 : 4 : transferRequests[key].status != STATUS.APPROVED
+ 150 : : ) {
+ 151 : 2 : revert RuleConditionalTransfer_Wrong_Status();
+ 152 : : }
+ 153 : 12 : _resetRequestStatus(key);
+ 154 : : }
+ 155 : :
+ 156 : : function getRequestTrade(
+ 157 : : address from,
+ 158 : : address to,
+ 159 : : uint256 value
+ 160 : : ) public view returns (TransferRequest memory) {
+ 161 : 171 : bytes32 key = keccak256(abi.encode(from, to, value));
+ 162 : 114 : return transferRequests[key];
+ 163 : : }
+ 164 : :
+ 165 : : /**
+ 166 : : * @notice get Trade by status
+ 167 : : * @param _targetStatus The status of the transactions you want to retrieve
+ 168 : : * @return array with corresponding transactions
+ 169 : : */
+ 170 : : function getRequestByStatus(
+ 171 : : STATUS _targetStatus
+ 172 : : ) public view returns (TransferRequest[] memory) {
+ 173 : 70 : uint totalRequestCount = requestId;
+ 174 : 70 : uint requestCount = 0;
+ 175 : 70 : uint currentIndex = 0;
176 : :
- 177 : : // We create an array with the list of trade
+ 177 : : // We count the number of requests matching the criteria
178 : 181 : for (uint i = 0; i < totalRequestCount; ++i) {
- 179 [ # + ]: 76 : if (transferRequests[IdToKey[i]].status == _targetStatus) {
- 180 : : //uint currentId = i + 1;
- 181 : 72 : TransferRequest memory currentRequest = transferRequests[IdToKey[i]];
- 182 : 72 : requests[currentIndex] = currentRequest;
- 183 : 72 : currentIndex += 1;
- 184 : : }
- 185 : : }
- 186 : 70 : return requests;
- 187 : : }
- 188 : :
- 189 : : /**
- 190 : : * @dev Returns true if the transfer is valid, and false otherwise.
- 191 : : * Add access control with the RuleEngine
- 192 : : */
- 193 : : function operateOnTransfer(
- 194 : : address _from,
- 195 : : address _to,
- 196 : : uint256 _amount
- 197 : : ) public override onlyRole(RULE_ENGINE_CONTRACT_ROLE) returns(bool isValid){
- 198 : : // No need of approval if from and to are in the whitelist
- 199 [ + + ]: 132 : if(address(whitelistConditionalTransfer) != address(0)){
- 200 [ + + ]: 57 : if(whitelistConditionalTransfer.addressIsListed(_from) && whitelistConditionalTransfer.addressIsListed(_to)){
- 201 : 4 : return true;
- 202 : : }
- 203 : : }
- 204 : :
- 205 : : // Mint & Burn
- 206 [ + + ]: 62 : if(_validateBurnMint(_from, _to)) {
- 207 : 8 : return true;
- 208 : : }
- 209 : 81 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
- 210 [ + + ]: 54 : if(_validateApproval(key)) {
- 211 : 20 : _updateProcessedTransfer(key);
- 212 : 20 : return true;
- 213 : : } else {
- 214 : 34 : return false;
- 215 : : }
- 216 : : }
- 217 : :
- 218 : : /**
- 219 : : * @notice Check if the transfer is valid
- 220 : : * @param _from the origin address
- 221 : : * @param _to the destination address
- 222 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 223 : : **/
- 224 : : function detectTransferRestriction(
- 225 : : address _from,
- 226 : : address _to,
- 227 : : uint256 _amount
- 228 : : ) public view override returns (uint8) {
- 229 : : // No need of approval if from and to are in the whitelist
- 230 [ # + ]: 44 : if(address(whitelistConditionalTransfer) != address(0)){
- 231 [ # + ]: 11 : if(whitelistConditionalTransfer.addressIsListed(_from) && whitelistConditionalTransfer.addressIsListed(_to)){
- 232 : 3 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 233 : : }
- 234 : : }
- 235 : 30 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
- 236 [ + + ]: 40 : if (!_validateBurnMint(_from,_to) && !_validateApproval(key)) {
- 237 : 16 : return CODE_TRANSFER_REQUEST_NOT_APPROVED;
- 238 : : }
- 239 : : else {
- 240 : 6 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 241 : : }
- 242 : : }
- 243 : :
- 244 : : /**
- 245 : : * @notice To know if the restriction code is valid for this rule or not.
- 246 : : * @param _restrictionCode The target restriction code
- 247 : : * @return true if the restriction code is known, false otherwise
- 248 : : **/
- 249 : : function canReturnTransferRestrictionCode(
- 250 : : uint8 _restrictionCode
- 251 : : ) external pure override returns (bool) {
- 252 : 4 : return
- 253 : 4 : _restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED;
- 254 : : }
- 255 : :
- 256 : : /**
- 257 : : * @notice Return the corresponding message
- 258 : : * @param _restrictionCode The target restriction code
- 259 : : * @return true if the transfer is valid, false otherwise
- 260 : : **/
- 261 : : function messageForTransferRestriction(
- 262 : : uint8 _restrictionCode
- 263 : : ) external pure override returns (string memory) {
- 264 [ + + ]: 6 : if (_restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED) {
- 265 : 4 : return TEXT_TRANSFER_REQUEST_NOT_APPROVED;
- 266 : : } else {
- 267 : 2 : return TEXT_CODE_NOT_FOUND;
- 268 : : }
- 269 : : }
- 270 : :
- 271 : : /**
- 272 : : *
- 273 : : * @dev
- 274 : : * Test burn and mint condition
- 275 : : * Returns true if the transfer is valid, and false otherwise.
- 276 : : *
- 277 : : */
- 278 : : function _validateBurnMint(
- 279 : : address _from,
- 280 : : address _to
- 281 : : ) internal view returns(bool isValid){
- 282 : : // Mint & Burn
- 283 [ + + ]: : if(
- 284 : 82 : (_from == address(0) && options.issuance.authorizedMintWithoutApproval)
- 285 : : || (_to == address(0) && options.issuance.authorizedBurnWithoutApproval)
- 286 : : ){
- 287 : 8 : return true;
- 288 : : }
- 289 : 74 : return false;
+ 179 [ + + ]: 76 : if (transferRequests[IdToKey[i]].status == _targetStatus) {
+ 180 : 72 : requestCount += 1;
+ 181 : : }
+ 182 : : }
+ 183 : :
+ 184 : : // We reserve the memory to store the trade
+ 185 : 105 : TransferRequest[] memory requests = new TransferRequest[](requestCount);
+ 186 : :
+ 187 : : // We create an array with the list of trade
+ 188 : 181 : for (uint i = 0; i < totalRequestCount; ++i) {
+ 189 [ # + ]: 76 : if (transferRequests[IdToKey[i]].status == _targetStatus) {
+ 190 : : //uint currentId = i + 1;
+ 191 : 72 : TransferRequest memory currentRequest = transferRequests[
+ 192 : : IdToKey[i]
+ 193 : : ];
+ 194 : 72 : requests[currentIndex] = currentRequest;
+ 195 : 72 : currentIndex += 1;
+ 196 : : }
+ 197 : : }
+ 198 : 70 : return requests;
+ 199 : : }
+ 200 : :
+ 201 : : /**
+ 202 : : * @dev Returns true if the transfer is valid, and false otherwise.
+ 203 : : * Add access control with the RuleEngine
+ 204 : : */
+ 205 : : function operateOnTransfer(
+ 206 : : address _from,
+ 207 : : address _to,
+ 208 : : uint256 _amount
+ 209 : : )
+ 210 : : public
+ 211 : : override
+ 212 : : onlyRole(RULE_ENGINE_CONTRACT_ROLE)
+ 213 : : returns (bool isValid)
+ 214 : : {
+ 215 : : // No need of approval if from and to are in the whitelist
+ 216 [ + + ]: 132 : if (address(whitelistConditionalTransfer) != address(0)) {
+ 217 [ + + ]: : if (
+ 218 : 54 : whitelistConditionalTransfer.addressIsListed(_from) &&
+ 219 : 6 : whitelistConditionalTransfer.addressIsListed(_to)
+ 220 : : ) {
+ 221 : 4 : return true;
+ 222 : : }
+ 223 : : }
+ 224 : :
+ 225 : : // Mint & Burn
+ 226 [ + + ]: 62 : if (_validateBurnMint(_from, _to)) {
+ 227 : 8 : return true;
+ 228 : : }
+ 229 : 81 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
+ 230 [ + + ]: 54 : if (_validateApproval(key)) {
+ 231 : 20 : _updateProcessedTransfer(key);
+ 232 : 20 : return true;
+ 233 : : } else {
+ 234 : 34 : return false;
+ 235 : : }
+ 236 : : }
+ 237 : :
+ 238 : : /**
+ 239 : : * @notice Check if the transfer is valid
+ 240 : : * @param _from the origin address
+ 241 : : * @param _to the destination address
+ 242 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ 243 : : **/
+ 244 : : function detectTransferRestriction(
+ 245 : : address _from,
+ 246 : : address _to,
+ 247 : : uint256 _amount
+ 248 : : ) public view override returns (uint8) {
+ 249 : : // No need of approval if from and to are in the whitelist
+ 250 [ # + ]: 44 : if (address(whitelistConditionalTransfer) != address(0)) {
+ 251 [ # + ]: : if (
+ 252 : 9 : whitelistConditionalTransfer.addressIsListed(_from) &&
+ 253 : 4 : whitelistConditionalTransfer.addressIsListed(_to)
+ 254 : : ) {
+ 255 : 3 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 256 : : }
+ 257 : : }
+ 258 : 30 : bytes32 key = keccak256(abi.encode(_from, _to, _amount));
+ 259 [ + + ]: 40 : if (!_validateBurnMint(_from, _to) && !_validateApproval(key)) {
+ 260 : 16 : return CODE_TRANSFER_REQUEST_NOT_APPROVED;
+ 261 : : } else {
+ 262 : 6 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 263 : : }
+ 264 : : }
+ 265 : :
+ 266 : : /**
+ 267 : : * @notice To know if the restriction code is valid for this rule or not.
+ 268 : : * @param _restrictionCode The target restriction code
+ 269 : : * @return true if the restriction code is known, false otherwise
+ 270 : : **/
+ 271 : : function canReturnTransferRestrictionCode(
+ 272 : : uint8 _restrictionCode
+ 273 : : ) external pure override returns (bool) {
+ 274 : 6 : return _restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED;
+ 275 : : }
+ 276 : :
+ 277 : : /**
+ 278 : : * @notice Return the corresponding message
+ 279 : : * @param _restrictionCode The target restriction code
+ 280 : : * @return true if the transfer is valid, false otherwise
+ 281 : : **/
+ 282 : : function messageForTransferRestriction(
+ 283 : : uint8 _restrictionCode
+ 284 : : ) external pure override returns (string memory) {
+ 285 [ + + ]: 6 : if (_restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED) {
+ 286 : 4 : return TEXT_TRANSFER_REQUEST_NOT_APPROVED;
+ 287 : : } else {
+ 288 : 2 : return TEXT_CODE_NOT_FOUND;
+ 289 : : }
290 : : }
291 : :
292 : : /**
- 293 : : *
- 294 : : * @dev
- 295 : : * Test transfer approval condition
+ 293 : : *
+ 294 : : * @dev
+ 295 : : * Test burn and mint condition
296 : : * Returns true if the transfer is valid, and false otherwise.
- 297 : : */
- 298 : : function _validateApproval(
- 299 : : bytes32 key
- 300 : : ) internal view returns(bool isValid){
- 301 : 111 : bool automaticApprovalCondition = options.automaticApproval.isActivate && ((transferRequests[key].askTime + options.automaticApproval.timeLimitBeforeAutomaticApproval ) >= block.timestamp);
- 302 : 111 : bool isTransferApproved = (transferRequests[key].status == STATUS.APPROVED)
- 303 : : && (transferRequests[key].maxTime >= block.timestamp);
- 304 [ + + ]: 74 : if(automaticApprovalCondition || isTransferApproved)
- 305 : : {
- 306 : 24 : return true;
- 307 : : } else {
- 308 : 50 : return false;
- 309 : : }
- 310 : : }
- 311 : :
- 312 : : /**
- 313 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 314 : : */
- 315 : : function _msgSender()
- 316 : : internal
- 317 : : view
- 318 : : override(ERC2771Context, Context)
- 319 : : returns (address sender)
- 320 : : {
- 321 : 1356 : return ERC2771Context._msgSender();
- 322 : : }
- 323 : :
- 324 : : /**
- 325 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 326 : : */
- 327 : : function _msgData()
- 328 : : internal
- 329 : : view
- 330 : : override(ERC2771Context, Context)
- 331 : : returns (bytes calldata)
- 332 : : {
- 333 : 0 : return ERC2771Context._msgData();
- 334 : : }
- 335 : :
- 336 : : /**
- 337 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 338 : : */
- 339 : : function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
- 340 : 1356 : return ERC2771Context._contextSuffixLength();
- 341 : : }
- 342 : : }
+ 297 : : *
+ 298 : : */
+ 299 : : function _validateBurnMint(
+ 300 : : address _from,
+ 301 : : address _to
+ 302 : : ) internal view returns (bool isValid) {
+ 303 : : // Mint & Burn
+ 304 [ + + ]: : if (
+ 305 : 82 : (_from == address(0) &&
+ 306 : : options.issuance.authorizedMintWithoutApproval) ||
+ 307 : : (_to == address(0) &&
+ 308 : : options.issuance.authorizedBurnWithoutApproval)
+ 309 : : ) {
+ 310 : 8 : return true;
+ 311 : : }
+ 312 : 74 : return false;
+ 313 : : }
+ 314 : :
+ 315 : : /**
+ 316 : : *
+ 317 : : * @dev
+ 318 : : * Test transfer approval condition
+ 319 : : * Returns true if the transfer is valid, and false otherwise.
+ 320 : : */
+ 321 : : function _validateApproval(
+ 322 : : bytes32 key
+ 323 : : ) internal view returns (bool isValid) {
+ 324 : 111 : bool automaticApprovalCondition = options
+ 325 : : .automaticApproval
+ 326 : : .isActivate &&
+ 327 : : ((transferRequests[key].askTime +
+ 328 : : options.automaticApproval.timeLimitBeforeAutomaticApproval) >=
+ 329 : : block.timestamp);
+ 330 : 111 : bool isTransferApproved = (transferRequests[key].status ==
+ 331 : : STATUS.APPROVED) &&
+ 332 : : (transferRequests[key].maxTime >= block.timestamp);
+ 333 [ + + ]: 74 : if (automaticApprovalCondition || isTransferApproved) {
+ 334 : 24 : return true;
+ 335 : : } else {
+ 336 : 50 : return false;
+ 337 : : }
+ 338 : : }
+ 339 : :
+ 340 : : /**
+ 341 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 342 : : */
+ 343 : : function _msgSender()
+ 344 : : internal
+ 345 : : view
+ 346 : : override(ERC2771Context, Context)
+ 347 : : returns (address sender)
+ 348 : : {
+ 349 : 1356 : return ERC2771Context._msgSender();
+ 350 : : }
+ 351 : :
+ 352 : : /**
+ 353 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 354 : : */
+ 355 : : function _msgData()
+ 356 : : internal
+ 357 : : view
+ 358 : : override(ERC2771Context, Context)
+ 359 : : returns (bytes calldata)
+ 360 : : {
+ 361 : 0 : return ERC2771Context._msgData();
+ 362 : : }
+ 363 : :
+ 364 : : /**
+ 365 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 366 : : */
+ 367 : : function _contextSuffixLength()
+ 368 : : internal
+ 369 : : view
+ 370 : : override(ERC2771Context, Context)
+ 371 : : returns (uint256)
+ 372 : : {
+ 373 : 1356 : return ERC2771Context._contextSuffixLength();
+ 374 : : }
+ 375 : : }
diff --git a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html b/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html
index b1117d6..37c914c 100644
--- a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html
+++ b/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -69,79 +69,79 @@
Hit count |
- RuleConditionalTransferOperator._createTransferRequestWithApproval |
+ RuleConditionalTransferOperator._createTransferRequestWithApproval |
0 |
- RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch |
+ RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch |
3 |
- RuleConditionalTransferOperator.resetRequestStatus |
+ RuleConditionalTransferOperator.resetRequestStatus |
3 |
- RuleConditionalTransferOperator.resetRequestStatusBatch |
+ RuleConditionalTransferOperator.resetRequestStatusBatch |
3 |
- RuleConditionalTransferOperator.setAutomaticTransfer |
+ RuleConditionalTransferOperator.setAutomaticTransfer |
3 |
- RuleConditionalTransferOperator.setTimeLimit |
+ RuleConditionalTransferOperator.setTimeLimit |
4 |
- RuleConditionalTransferOperator.approveTransferRequestWithId |
+ RuleConditionalTransferOperator.approveTransferRequestWithId |
5 |
- RuleConditionalTransferOperator.setAutomaticApproval |
+ RuleConditionalTransferOperator.setAutomaticApproval |
5 |
- RuleConditionalTransferOperator.setIssuanceOptions |
+ RuleConditionalTransferOperator.setIssuanceOptions |
5 |
- RuleConditionalTransferOperator.createTransferRequestWithApproval |
+ RuleConditionalTransferOperator.createTransferRequestWithApproval |
6 |
- RuleConditionalTransferOperator.approveTransferRequestBatch |
+ RuleConditionalTransferOperator.approveTransferRequestBatch |
7 |
- RuleConditionalTransferOperator.approveTransferRequestBatchWithId |
+ RuleConditionalTransferOperator.approveTransferRequestBatchWithId |
7 |
- RuleConditionalTransferOperator._resetRequestStatus |
+ RuleConditionalTransferOperator._resetRequestStatus |
10 |
- RuleConditionalTransferOperator._updateProcessedTransfer |
+ RuleConditionalTransferOperator._updateProcessedTransfer |
10 |
- RuleConditionalTransferOperator.setConditionalWhitelist |
+ RuleConditionalTransferOperator.setConditionalWhitelist |
25 |
- RuleConditionalTransferOperator.approveTransferRequest |
+ RuleConditionalTransferOperator.approveTransferRequest |
33 |
- RuleConditionalTransferOperator._approveTransferRequestKeyElement |
+ RuleConditionalTransferOperator._approveTransferRequestKeyElement |
41 |
- RuleConditionalTransferOperator._approveRequest |
+ RuleConditionalTransferOperator._approveRequest |
46 |
- RuleConditionalTransferOperator._checkRequestStatus |
+ RuleConditionalTransferOperator._checkRequestStatus |
119 |
diff --git a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html b/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html
index 7f4ac9d..dc88726 100644
--- a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html
+++ b/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -69,79 +69,79 @@
Hit count |
- RuleConditionalTransferOperator._approveRequest |
+ RuleConditionalTransferOperator._approveRequest |
46 |
- RuleConditionalTransferOperator._approveTransferRequestKeyElement |
+ RuleConditionalTransferOperator._approveTransferRequestKeyElement |
41 |
- RuleConditionalTransferOperator._checkRequestStatus |
+ RuleConditionalTransferOperator._checkRequestStatus |
119 |
- RuleConditionalTransferOperator._createTransferRequestWithApproval |
+ RuleConditionalTransferOperator._createTransferRequestWithApproval |
0 |
- RuleConditionalTransferOperator._resetRequestStatus |
+ RuleConditionalTransferOperator._resetRequestStatus |
10 |
- RuleConditionalTransferOperator._updateProcessedTransfer |
+ RuleConditionalTransferOperator._updateProcessedTransfer |
10 |
- RuleConditionalTransferOperator.approveTransferRequest |
+ RuleConditionalTransferOperator.approveTransferRequest |
33 |
- RuleConditionalTransferOperator.approveTransferRequestBatch |
+ RuleConditionalTransferOperator.approveTransferRequestBatch |
7 |
- RuleConditionalTransferOperator.approveTransferRequestBatchWithId |
+ RuleConditionalTransferOperator.approveTransferRequestBatchWithId |
7 |
- RuleConditionalTransferOperator.approveTransferRequestWithId |
+ RuleConditionalTransferOperator.approveTransferRequestWithId |
5 |
- RuleConditionalTransferOperator.createTransferRequestWithApproval |
+ RuleConditionalTransferOperator.createTransferRequestWithApproval |
6 |
- RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch |
+ RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch |
3 |
- RuleConditionalTransferOperator.resetRequestStatus |
+ RuleConditionalTransferOperator.resetRequestStatus |
3 |
- RuleConditionalTransferOperator.resetRequestStatusBatch |
+ RuleConditionalTransferOperator.resetRequestStatusBatch |
3 |
- RuleConditionalTransferOperator.setAutomaticApproval |
+ RuleConditionalTransferOperator.setAutomaticApproval |
5 |
- RuleConditionalTransferOperator.setAutomaticTransfer |
+ RuleConditionalTransferOperator.setAutomaticTransfer |
3 |
- RuleConditionalTransferOperator.setConditionalWhitelist |
+ RuleConditionalTransferOperator.setConditionalWhitelist |
25 |
- RuleConditionalTransferOperator.setIssuanceOptions |
+ RuleConditionalTransferOperator.setIssuanceOptions |
5 |
- RuleConditionalTransferOperator.setTimeLimit |
+ RuleConditionalTransferOperator.setTimeLimit |
4 |
diff --git a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html b/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html
index 0c436a8..f764155 100644
--- a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html
+++ b/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -75,314 +75,449 @@
4 : :
5 : : import "OZ/access/AccessControl.sol";
6 : : import "./RuleConditionalTransferInvariantStorage.sol";
- 7 : : import "OZ/token/ERC20/utils/SafeERC20.sol";
- 8 : : /**
- 9 : : * @title Restricted functions
- 10 : : */
- 11 : : abstract contract RuleConditionalTransferOperator is AccessControl, RuleConditionalTransferInvariantStorage {
- 12 : : // Security
- 13 : : using SafeERC20 for IERC20;
- 14 : :
- 15 : : // public variable with automatic Getter
- 16 : : OPTION public options;
- 17 : : uint256 public requestId;
- 18 : : mapping(uint256 => bytes32) public IdToKey;
- 19 : : mapping(bytes32 => TransferRequest) public transferRequests;
- 20 : : RuleWhitelist public whitelistConditionalTransfer;
- 21 : :
- 22 : : /**
- 23 : : * @notice set a whitelist. A transfer does not need of an approved request if from and to are in the whitelist
- 24 : : */
- 25 : : function setConditionalWhitelist(RuleWhitelist newWhitelistConditionalTransfer) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 26 : 50 : whitelistConditionalTransfer = newWhitelistConditionalTransfer;
- 27 : 50 : emit WhitelistConditionalTransfer(newWhitelistConditionalTransfer);
- 28 : : }
- 29 : :
- 30 : : /**
- 31 : : set/unset the issuance options (mint & burn)
- 32 : : */
- 33 : : function setIssuanceOptions(ISSUANCE calldata issuance_) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 34 [ + + ]: 8 : if(options.issuance.authorizedMintWithoutApproval != issuance_.authorizedMintWithoutApproval ){
- 35 : 4 : options.issuance.authorizedMintWithoutApproval = issuance_.authorizedMintWithoutApproval;
- 36 : : }
- 37 [ + + ]: 8 : if(options.issuance.authorizedBurnWithoutApproval != issuance_.authorizedBurnWithoutApproval ){
- 38 : 4 : options.issuance.authorizedBurnWithoutApproval = issuance_.authorizedBurnWithoutApproval;
- 39 : : }
- 40 : : }
- 41 : :
- 42 : : /**
- 43 : : * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
- 44 : : * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
- 45 : : * If the allowance is not sufficient, the request will be approved, but without performing the transfer.
- 46 : : */
- 47 : : function setAutomaticTransfer(AUTOMATIC_TRANSFER calldata automaticTransfer_) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 48 [ + + ]: 4 : if(automaticTransfer_.isActivate != options.automaticTransfer.isActivate){
- 49 : 4 : options.automaticTransfer.isActivate = automaticTransfer_.isActivate;
- 50 : : }
- 51 : : // No need to put the cmtat to zero to deactivate automaticTransfer
- 52 [ + + ]: 8 : if(address(automaticTransfer_.cmtat) != address(options.automaticTransfer.cmtat)){
- 53 : 4 : options.automaticTransfer.cmtat = automaticTransfer_.cmtat;
- 54 : : }
- 55 : : }
- 56 : :
- 57 : : /**
- 58 : : * @notice set time limit for new requests (Approval and transfer)
- 59 : : * timeLimitToApprove: time limit for an operator to approve a request
- 60 : : * timeLimitToTransfer: once a request is approved, time limit for the token holder to perform the transfer
- 61 : : */
- 62 : : function setTimeLimit(TIME_LIMIT memory timeLimit_) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 63 [ + + ]: 6 : if(options.timeLimit.timeLimitToApprove != timeLimit_.timeLimitToApprove){
- 64 : 6 : options.timeLimit.timeLimitToApprove = timeLimit_.timeLimitToApprove;
- 65 : : }
- 66 [ + + ]: 6 : if(options.timeLimit.timeLimitToTransfer != timeLimit_.timeLimitToTransfer){
- 67 : 6 : options.timeLimit.timeLimitToTransfer = timeLimit_.timeLimitToTransfer;
- 68 : : }
- 69 : : }
- 70 : : /**
- 71 : : * @notice If the transfer is not approved or denied within {timeLimitBeforeAutomaticApproval},
- 72 : : * the request is considered as approved during a transfer.
- 73 : : *
- 74 : : */
- 75 : : function setAutomaticApproval(AUTOMATIC_APPROVAL memory automaticApproval_) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 76 [ + + ]: 8 : if(options.automaticApproval.isActivate != automaticApproval_.isActivate ){
- 77 : 8 : options.automaticApproval.isActivate = automaticApproval_.isActivate;
- 78 : : }
- 79 [ + + ]: 8 : if(options.automaticApproval.timeLimitBeforeAutomaticApproval != automaticApproval_.timeLimitBeforeAutomaticApproval){
- 80 : 8 : options.automaticApproval.timeLimitBeforeAutomaticApproval = automaticApproval_.timeLimitBeforeAutomaticApproval;
- 81 : : }
- 82 : : }
- 83 : :
- 84 : : /**
- 85 : : * @notice create a transfer request directly approved
- 86 : : */
- 87 : : function createTransferRequestWithApproval(
- 88 : : TransferRequestKeyElement calldata keyElement
- 89 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 90 : 10 : _createTransferRequestWithApproval(keyElement);
- 91 : : }
- 92 : :
- 93 : : /**
- 94 : : @notice approve a transferRequest
- 95 : : @param keyElement contains from, to, value
- 96 : : @param partialValue amount approved. Put 0 if all the amount specified by value is approved.
- 97 : : @param isApproved approved (true) or refused (false). Put true if you use partialApproval
- 98 : : */
- 99 : : function approveTransferRequest(
- 100 : : TransferRequestKeyElement calldata keyElement, uint256 partialValue, bool isApproved
- 101 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 102 : 64 : _approveTransferRequestKeyElement(keyElement, partialValue, isApproved);
- 103 : : }
- 104 : :
- 105 : : /**
- 106 : : * @notice approve a transferRequestby using its id
- 107 : : */
- 108 : : function approveTransferRequestWithId(
- 109 : : uint256 requestId_, bool isApproved
- 110 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 111 [ + + ]: 12 : if(requestId_ + 1 > requestId) {
- 112 : 4 : revert RuleConditionalTransfer_InvalidId();
- 113 : : }
- 114 : 4 : TransferRequest memory transferRequest = transferRequests[IdToKey[requestId_]];
- 115 : 4 : _approveRequest(transferRequest, isApproved);
- 116 : : }
- 117 : :
- 118 : : /**
- 119 : : * @notice reset to None the status of a request
- 120 : : */
- 121 : : function resetRequestStatus(
- 122 : : uint256 requestId_
- 123 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 124 [ + + ]: 6 : if(requestId_ + 1 > requestId) {
- 125 : 2 : revert RuleConditionalTransfer_InvalidId();
- 126 : : }
- 127 : 2 : bytes32 key = IdToKey[requestId_];
- 128 : 2 : _resetRequestStatus(key);
- 129 : : }
- 130 : :
- 131 : : /***** Batch function */
+ 7 : : import "OZ/token/ERC20/utils/SafeERC20.sol";
+ 8 : :
+ 9 : : /**
+ 10 : : * @title Restricted functions
+ 11 : : */
+ 12 : : abstract contract RuleConditionalTransferOperator is
+ 13 : : AccessControl,
+ 14 : : RuleConditionalTransferInvariantStorage
+ 15 : : {
+ 16 : : // Security
+ 17 : : using SafeERC20 for IERC20;
+ 18 : :
+ 19 : : // public variable with automatic Getter
+ 20 : : OPTION public options;
+ 21 : : uint256 public requestId;
+ 22 : : mapping(uint256 => bytes32) public IdToKey;
+ 23 : : mapping(bytes32 => TransferRequest) public transferRequests;
+ 24 : : RuleWhitelist public whitelistConditionalTransfer;
+ 25 : :
+ 26 : : /**
+ 27 : : * @notice set a whitelist. A transfer does not need of an approved request if from and to are in the whitelist
+ 28 : : */
+ 29 : : function setConditionalWhitelist(
+ 30 : : RuleWhitelist newWhitelistConditionalTransfer
+ 31 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 32 : 50 : whitelistConditionalTransfer = newWhitelistConditionalTransfer;
+ 33 : 50 : emit WhitelistConditionalTransfer(newWhitelistConditionalTransfer);
+ 34 : : }
+ 35 : :
+ 36 : : /**
+ 37 : : set/unset the issuance options (mint & burn)
+ 38 : : */
+ 39 : : function setIssuanceOptions(
+ 40 : : ISSUANCE calldata issuance_
+ 41 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 42 [ + + ]: : if (
+ 43 : 8 : options.issuance.authorizedMintWithoutApproval !=
+ 44 : : issuance_.authorizedMintWithoutApproval
+ 45 : : ) {
+ 46 : 4 : options.issuance.authorizedMintWithoutApproval = issuance_
+ 47 : : .authorizedMintWithoutApproval;
+ 48 : : }
+ 49 [ + + ]: : if (
+ 50 : 8 : options.issuance.authorizedBurnWithoutApproval !=
+ 51 : : issuance_.authorizedBurnWithoutApproval
+ 52 : : ) {
+ 53 : 4 : options.issuance.authorizedBurnWithoutApproval = issuance_
+ 54 : : .authorizedBurnWithoutApproval;
+ 55 : : }
+ 56 : : }
+ 57 : :
+ 58 : : /**
+ 59 : : * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
+ 60 : : * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
+ 61 : : * If the allowance is not sufficient, the request will be approved, but without performing the transfer.
+ 62 : : */
+ 63 : : function setAutomaticTransfer(
+ 64 : : AUTOMATIC_TRANSFER calldata automaticTransfer_
+ 65 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 66 [ + + ]: : if (
+ 67 : 4 : automaticTransfer_.isActivate !=
+ 68 : : options.automaticTransfer.isActivate
+ 69 : : ) {
+ 70 : 4 : options.automaticTransfer.isActivate = automaticTransfer_
+ 71 : : .isActivate;
+ 72 : : }
+ 73 : : // No need to put the cmtat to zero to deactivate automaticTransfer
+ 74 [ + + ]: : if (
+ 75 : 6 : address(automaticTransfer_.cmtat) !=
+ 76 : 4 : address(options.automaticTransfer.cmtat)
+ 77 : : ) {
+ 78 : 4 : options.automaticTransfer.cmtat = automaticTransfer_.cmtat;
+ 79 : : }
+ 80 : : }
+ 81 : :
+ 82 : : /**
+ 83 : : * @notice set time limit for new requests (Approval and transfer)
+ 84 : : * timeLimitToApprove: time limit for an operator to approve a request
+ 85 : : * timeLimitToTransfer: once a request is approved, time limit for the token holder to perform the transfer
+ 86 : : */
+ 87 : : function setTimeLimit(
+ 88 : : TIME_LIMIT memory timeLimit_
+ 89 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 90 [ + + ]: : if (
+ 91 : 6 : options.timeLimit.timeLimitToApprove !=
+ 92 : : timeLimit_.timeLimitToApprove
+ 93 : : ) {
+ 94 : 6 : options.timeLimit.timeLimitToApprove = timeLimit_
+ 95 : : .timeLimitToApprove;
+ 96 : : }
+ 97 [ + + ]: : if (
+ 98 : 6 : options.timeLimit.timeLimitToTransfer !=
+ 99 : : timeLimit_.timeLimitToTransfer
+ 100 : : ) {
+ 101 : 6 : options.timeLimit.timeLimitToTransfer = timeLimit_
+ 102 : : .timeLimitToTransfer;
+ 103 : : }
+ 104 : : }
+ 105 : :
+ 106 : : /**
+ 107 : : * @notice If the transfer is not approved or denied within {timeLimitBeforeAutomaticApproval},
+ 108 : : * the request is considered as approved during a transfer.
+ 109 : : *
+ 110 : : */
+ 111 : : function setAutomaticApproval(
+ 112 : : AUTOMATIC_APPROVAL memory automaticApproval_
+ 113 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 114 [ + + ]: : if (
+ 115 : 8 : options.automaticApproval.isActivate !=
+ 116 : : automaticApproval_.isActivate
+ 117 : : ) {
+ 118 : 8 : options.automaticApproval.isActivate = automaticApproval_
+ 119 : : .isActivate;
+ 120 : : }
+ 121 [ + + ]: : if (
+ 122 : 8 : options.automaticApproval.timeLimitBeforeAutomaticApproval !=
+ 123 : : automaticApproval_.timeLimitBeforeAutomaticApproval
+ 124 : : ) {
+ 125 : 8 : options
+ 126 : : .automaticApproval
+ 127 : : .timeLimitBeforeAutomaticApproval = automaticApproval_
+ 128 : : .timeLimitBeforeAutomaticApproval;
+ 129 : : }
+ 130 : : }
+ 131 : :
132 : : /**
- 133 : : * @notice Batch version of {approveTransferRequestWithId}
- 134 : : */
- 135 : : function approveTransferRequestBatchWithId(
- 136 : : uint256[] calldata requestId_, bool[] calldata isApproved
- 137 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 138 [ + + ]: 10 : if(requestId_.length == 0){
- 139 : 2 : revert RuleConditionalTransfer_EmptyArray();
- 140 : : }
- 141 [ + + ]: 8 : if(requestId_.length != isApproved.length){
- 142 : 2 : revert RuleConditionalTransfer_InvalidLengthArray();
- 143 : : }
- 144 : : // Check id validity before performing actions
- 145 : 29 : for(uint256 i = 0; i < requestId_.length; ++i){
- 146 [ + + ]: 33 : if(requestId_[i] + 1 > requestId) {
- 147 : 2 : revert RuleConditionalTransfer_InvalidId();
- 148 : : }
- 149 : : }
- 150 : 14 : for(uint256 i = 0; i < requestId_.length; ++i){
- 151 : 10 : TransferRequest memory transferRequest = transferRequests[IdToKey[requestId_[i]]];
- 152 : 10 : _approveRequest(transferRequest, isApproved[i]);
- 153 : : }
- 154 : : }
- 155 : :
- 156 : : /**
- 157 : : * @notice Batch version of {approveTransferRequest}
- 158 : : */
- 159 : : function approveTransferRequestBatch(
- 160 : : TransferRequestKeyElement[] calldata keyElements, uint256[] calldata partialValues, bool[] calldata isApproved
+ 133 : : * @notice create a transfer request directly approved
+ 134 : : */
+ 135 : : function createTransferRequestWithApproval(
+ 136 : : TransferRequestKeyElement calldata keyElement
+ 137 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 138 : 10 : _createTransferRequestWithApproval(keyElement);
+ 139 : : }
+ 140 : :
+ 141 : : /**
+ 142 : : @notice approve a transferRequest
+ 143 : : @param keyElement contains from, to, value
+ 144 : : @param partialValue amount approved. Put 0 if all the amount specified by value is approved.
+ 145 : : @param isApproved approved (true) or refused (false). Put true if you use partialApproval
+ 146 : : */
+ 147 : : function approveTransferRequest(
+ 148 : : TransferRequestKeyElement calldata keyElement,
+ 149 : : uint256 partialValue,
+ 150 : : bool isApproved
+ 151 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 152 : 64 : _approveTransferRequestKeyElement(keyElement, partialValue, isApproved);
+ 153 : : }
+ 154 : :
+ 155 : : /**
+ 156 : : * @notice approve a transferRequestby using its id
+ 157 : : */
+ 158 : : function approveTransferRequestWithId(
+ 159 : : uint256 requestId_,
+ 160 : : bool isApproved
161 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- 162 [ + + ]: 12 : if(keyElements.length == 0){
- 163 : 2 : revert RuleConditionalTransfer_EmptyArray();
+ 162 [ + + ]: 12 : if (requestId_ + 1 > requestId) {
+ 163 : 4 : revert RuleConditionalTransfer_InvalidId();
164 : : }
- 165 [ + + ]: 10 : if((keyElements.length != partialValues.length) || (partialValues.length != isApproved.length)){
- 166 : 6 : revert RuleConditionalTransfer_InvalidLengthArray();
- 167 : : }
- 168 : 24 : for(uint256 i = 0; i < keyElements.length; ++i){
- 169 : 18 : _approveTransferRequestKeyElement(keyElements[i], partialValues[i], isApproved[i]);
- 170 : : }
- 171 : : }
- 172 : :
- 173 : : /**
- 174 : : * @notice Batch version of {createTransferRequestWithApproval}
- 175 : : */
- 176 : : function createTransferRequestWithApprovalBatch(
- 177 : : TransferRequestKeyElement[] calldata keyElements
- 178 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 179 [ + + ]: 4 : if(keyElements.length == 0){
- 180 : 2 : revert RuleConditionalTransfer_EmptyArray();
- 181 : : }
- 182 : 11 : for(uint256 i = 0; i < keyElements.length; ++i){
- 183 : 8 : _createTransferRequestWithApproval(keyElements[i]);
- 184 : : }
- 185 : : }
- 186 : :
- 187 : : /**
- 188 : : * @notice Batch version of {resetRequestStatus}
- 189 : : */
- 190 : : function resetRequestStatusBatch(
- 191 : : uint256[] memory requestIds
- 192 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 193 [ + + ]: 6 : if(requestIds.length == 0){
- 194 : 2 : revert RuleConditionalTransfer_EmptyArray();
- 195 : : }
- 196 : : // Check id validity before performing actions
- 197 : 12 : for(uint256 i = 0; i < requestIds.length; ++i){
- 198 [ + + ]: 12 : if(requestIds[i] + 1 > requestId) {
- 199 : 2 : revert RuleConditionalTransfer_InvalidId();
- 200 : : }
- 201 : : }
- 202 : 9 : for(uint256 i = 0; i < requestIds.length; ++i){
- 203 : 6 : bytes32 key = IdToKey[requestIds[i]];
- 204 : 6 : _resetRequestStatus(key);
- 205 : : }
- 206 : : }
- 207 : :
- 208 : :
- 209 : : /*** Internal functions ****/
- 210 : : function _approveTransferRequestKeyElement(
- 211 : : TransferRequestKeyElement calldata keyElement, uint256 partialValue, bool isApproved
- 212 : : ) internal {
- 213 [ + + ]: 82 : if(partialValue > keyElement.value){
- 214 : 2 : revert RuleConditionalTransfer_InvalidValueApproved();
- 215 : : }
- 216 : 120 : bytes32 key = keccak256(abi.encode(keyElement.from, keyElement.to, keyElement.value));
- 217 : 80 : TransferRequest memory transferRequest = transferRequests[key];
- 218 [ + + ]: 80 : if(partialValue > 0 ){
- 219 [ + + ]: 14 : if(! isApproved){
- 220 : 2 : revert RuleConditionalTransfer_CannotDeniedPartially();
- 221 : : }
- 222 : : // Denied the first request
- 223 : 12 : _approveRequest(transferRequest, false);
- 224 : : // Create new request
- 225 : 12 : _createTransferRequestWithApproval(TransferRequestKeyElement({from: keyElement.from, to: keyElement.to, value: partialValue}));
- 226 : : }else{
- 227 : 66 : _approveRequest(transferRequest, isApproved);
+ 165 : 4 : TransferRequest memory transferRequest = transferRequests[
+ 166 : : IdToKey[requestId_]
+ 167 : : ];
+ 168 : 4 : _approveRequest(transferRequest, isApproved);
+ 169 : : }
+ 170 : :
+ 171 : : /**
+ 172 : : * @notice reset to None the status of a request
+ 173 : : */
+ 174 : : function resetRequestStatus(
+ 175 : : uint256 requestId_
+ 176 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 177 [ + + ]: 6 : if (requestId_ + 1 > requestId) {
+ 178 : 2 : revert RuleConditionalTransfer_InvalidId();
+ 179 : : }
+ 180 : 2 : bytes32 key = IdToKey[requestId_];
+ 181 : 2 : _resetRequestStatus(key);
+ 182 : : }
+ 183 : :
+ 184 : : /***** Batch function */
+ 185 : : /**
+ 186 : : * @notice Batch version of {approveTransferRequestWithId}
+ 187 : : */
+ 188 : : function approveTransferRequestBatchWithId(
+ 189 : : uint256[] calldata requestId_,
+ 190 : : bool[] calldata isApproved
+ 191 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 192 [ + + ]: 10 : if (requestId_.length == 0) {
+ 193 : 2 : revert RuleConditionalTransfer_EmptyArray();
+ 194 : : }
+ 195 [ + + ]: 8 : if (requestId_.length != isApproved.length) {
+ 196 : 2 : revert RuleConditionalTransfer_InvalidLengthArray();
+ 197 : : }
+ 198 : : // Check id validity before performing actions
+ 199 : 29 : for (uint256 i = 0; i < requestId_.length; ++i) {
+ 200 [ + + ]: 33 : if (requestId_[i] + 1 > requestId) {
+ 201 : 2 : revert RuleConditionalTransfer_InvalidId();
+ 202 : : }
+ 203 : : }
+ 204 : 14 : for (uint256 i = 0; i < requestId_.length; ++i) {
+ 205 : 10 : TransferRequest memory transferRequest = transferRequests[
+ 206 : : IdToKey[requestId_[i]]
+ 207 : : ];
+ 208 : 10 : _approveRequest(transferRequest, isApproved[i]);
+ 209 : : }
+ 210 : : }
+ 211 : :
+ 212 : : /**
+ 213 : : * @notice Batch version of {approveTransferRequest}
+ 214 : : */
+ 215 : : function approveTransferRequestBatch(
+ 216 : : TransferRequestKeyElement[] calldata keyElements,
+ 217 : : uint256[] calldata partialValues,
+ 218 : : bool[] calldata isApproved
+ 219 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 220 [ + + ]: 12 : if (keyElements.length == 0) {
+ 221 : 2 : revert RuleConditionalTransfer_EmptyArray();
+ 222 : : }
+ 223 [ + + ]: : if (
+ 224 : 10 : (keyElements.length != partialValues.length) ||
+ 225 : : (partialValues.length != isApproved.length)
+ 226 : : ) {
+ 227 : 6 : revert RuleConditionalTransfer_InvalidLengthArray();
228 : : }
- 229 : : }
- 230 : :
- 231 : : function _createTransferRequestWithApproval(
- 232 : : TransferRequestKeyElement memory keyElement
- 233 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- 234 : : // WAIT => Will overwrite
- 235 : : // APPROVED => will overwrite previous status with a new delay
- 236 : : // DENIED => will overwrite
- 237 : 45 : bytes32 key = keccak256(abi.encode(keyElement.from, keyElement.to, keyElement.value));
- 238 [ # + ]: 30 : if(_checkRequestStatus(key)){
- 239 : 42 : TransferRequest memory newTransferApproval = TransferRequest({
- 240 : : key: key,
- 241 : : id: requestId,
- 242 : : from: keyElement.from,
- 243 : : to: keyElement.to,
- 244 : : value: keyElement.value,
- 245 : : askTime:0,
- 246 : : maxTime : block.timestamp + options.timeLimit.timeLimitToTransfer,
- 247 : : status:STATUS.APPROVED
- 248 : : });
- 249 : 28 : transferRequests[key] = newTransferApproval;
- 250 : 28 : IdToKey[requestId] = key;
- 251 : 28 : emit transferApproved(key, keyElement.from, keyElement.to, keyElement.value, requestId);
- 252 : 28 : ++requestId;
- 253 : : } else {
- 254 : : // Overwrite previous approval
- 255 : 2 : transferRequests[key].maxTime = block.timestamp + options.timeLimit.timeLimitToTransfer;
- 256 : 2 : transferRequests[key].status = STATUS.APPROVED;
- 257 : 2 : emit transferApproved(key, keyElement.from, keyElement.to, keyElement.value, transferRequests[key].id);
- 258 : : }
- 259 : : }
- 260 : :
- 261 : : function _resetRequestStatus(
- 262 : : bytes32 key
- 263 : : ) internal {
- 264 : 20 : transferRequests[key].status = STATUS.NONE;
- 265 : 20 : emit transferReset(key, transferRequests[key].from, transferRequests[key].to, transferRequests[key].value, transferRequests[key].id );
- 266 : : }
- 267 : :
- 268 : : function _checkRequestStatus(bytes32 key) internal view returns(bool) {
- 269 : : // Status NONE not enough because reset is possible
- 270 : 357 : return (transferRequests[key].status == STATUS.NONE) && (transferRequests[key].key == 0x0);
+ 229 : 24 : for (uint256 i = 0; i < keyElements.length; ++i) {
+ 230 : 18 : _approveTransferRequestKeyElement(
+ 231 : : keyElements[i],
+ 232 : : partialValues[i],
+ 233 : : isApproved[i]
+ 234 : : );
+ 235 : : }
+ 236 : : }
+ 237 : :
+ 238 : : /**
+ 239 : : * @notice Batch version of {createTransferRequestWithApproval}
+ 240 : : */
+ 241 : : function createTransferRequestWithApprovalBatch(
+ 242 : : TransferRequestKeyElement[] calldata keyElements
+ 243 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 244 [ + + ]: 4 : if (keyElements.length == 0) {
+ 245 : 2 : revert RuleConditionalTransfer_EmptyArray();
+ 246 : : }
+ 247 : 11 : for (uint256 i = 0; i < keyElements.length; ++i) {
+ 248 : 8 : _createTransferRequestWithApproval(keyElements[i]);
+ 249 : : }
+ 250 : : }
+ 251 : :
+ 252 : : /**
+ 253 : : * @notice Batch version of {resetRequestStatus}
+ 254 : : */
+ 255 : : function resetRequestStatusBatch(
+ 256 : : uint256[] memory requestIds
+ 257 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 258 [ + + ]: 6 : if (requestIds.length == 0) {
+ 259 : 2 : revert RuleConditionalTransfer_EmptyArray();
+ 260 : : }
+ 261 : : // Check id validity before performing actions
+ 262 : 12 : for (uint256 i = 0; i < requestIds.length; ++i) {
+ 263 [ + + ]: 12 : if (requestIds[i] + 1 > requestId) {
+ 264 : 2 : revert RuleConditionalTransfer_InvalidId();
+ 265 : : }
+ 266 : : }
+ 267 : 9 : for (uint256 i = 0; i < requestIds.length; ++i) {
+ 268 : 6 : bytes32 key = IdToKey[requestIds[i]];
+ 269 : 6 : _resetRequestStatus(key);
+ 270 : : }
271 : : }
272 : :
- 273 : : function _approveRequest(TransferRequest memory transferRequest , bool isApproved) internal{
- 274 : : // status
- 275 [ + + ]: 92 : if(transferRequest.status != STATUS.WAIT){
- 276 : 2 : revert RuleConditionalTransfer_Wrong_Status();
- 277 : : }
- 278 [ + + ]: 45 : if(isApproved){
- 279 : : // Time
- 280 [ + + ]: 54 : if(block.timestamp > (transferRequest.askTime + options.timeLimit.timeLimitToApprove)){
- 281 : 6 : revert RuleConditionalTransfer_timeExceeded();
- 282 : : }
- 283 : : // Set status
- 284 : 48 : transferRequests[transferRequest.key].status = STATUS.APPROVED;
- 285 : : // Set max time
- 286 : 48 : transferRequests[transferRequest.key].maxTime = block.timestamp + options.timeLimit.timeLimitToTransfer;
- 287 : 48 : emit transferApproved(transferRequest.key, transferRequest.from, transferRequest.to, transferRequest.value, transferRequests[transferRequest.key].id );
- 288 [ + + ]: 54 : if(options.automaticTransfer.isActivate && address(options.automaticTransfer.cmtat) != address(0)){
- 289 : : // Transfer with approval
- 290 : : // External call
- 291 [ + + ]: 6 : if(options.automaticTransfer.cmtat.allowance(transferRequest.from, address(this)) >= transferRequest.value){
- 292 : : // Will call the ruleEngine and the rule again...
- 293 : 4 : options.automaticTransfer.cmtat.safeTransferFrom(transferRequest.from, transferRequest.to, transferRequest.value);
- 294 : : }
- 295 : : }
- 296 : : } else {
- 297 : 36 : transferRequests[transferRequest.key].status = STATUS.DENIED;
- 298 : 36 : emit transferDenied(transferRequest.key, transferRequest.from, transferRequest.to, transferRequest.value, transferRequests[transferRequest.key].id );
- 299 : : }
- 300 : : }
- 301 : :
- 302 : : /**
- 303 : : * @notice update the request during a transfer
- 304 : : */
- 305 : : function _updateProcessedTransfer(bytes32 key) internal {
- 306 : : // Reset to zero
- 307 : 20 : transferRequests[key].maxTime = 0;
- 308 : 20 : transferRequests[key].askTime = 0;
- 309 : : // Change status
- 310 : 20 : transferRequests[key].status = STATUS.EXECUTED;
- 311 : : // Emit event
- 312 : 20 : emit transferProcessed(key, transferRequests[key].from, transferRequests[key].to, transferRequests[key].value, transferRequests[key].id);
- 313 : : }
- 314 : : }
+ 273 : : /*** Internal functions ****/
+ 274 : : function _approveTransferRequestKeyElement(
+ 275 : : TransferRequestKeyElement calldata keyElement,
+ 276 : : uint256 partialValue,
+ 277 : : bool isApproved
+ 278 : : ) internal {
+ 279 [ + + ]: 82 : if (partialValue > keyElement.value) {
+ 280 : 2 : revert RuleConditionalTransfer_InvalidValueApproved();
+ 281 : : }
+ 282 : 120 : bytes32 key = keccak256(
+ 283 : : abi.encode(keyElement.from, keyElement.to, keyElement.value)
+ 284 : : );
+ 285 : 80 : TransferRequest memory transferRequest = transferRequests[key];
+ 286 [ + + ]: 80 : if (partialValue > 0) {
+ 287 [ + + ]: 14 : if (!isApproved) {
+ 288 : 2 : revert RuleConditionalTransfer_CannotDeniedPartially();
+ 289 : : }
+ 290 : : // Denied the first request
+ 291 : 12 : _approveRequest(transferRequest, false);
+ 292 : : // Create new request
+ 293 : 12 : _createTransferRequestWithApproval(
+ 294 : : TransferRequestKeyElement({
+ 295 : : from: keyElement.from,
+ 296 : : to: keyElement.to,
+ 297 : : value: partialValue
+ 298 : : })
+ 299 : : );
+ 300 : : } else {
+ 301 : 66 : _approveRequest(transferRequest, isApproved);
+ 302 : : }
+ 303 : : }
+ 304 : :
+ 305 : : function _createTransferRequestWithApproval(
+ 306 : : TransferRequestKeyElement memory keyElement
+ 307 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ 308 : : // WAIT => Will overwrite
+ 309 : : // APPROVED => will overwrite previous status with a new delay
+ 310 : : // DENIED => will overwrite
+ 311 : 45 : bytes32 key = keccak256(
+ 312 : : abi.encode(keyElement.from, keyElement.to, keyElement.value)
+ 313 : : );
+ 314 [ # + ]: 30 : if (_checkRequestStatus(key)) {
+ 315 : 42 : TransferRequest memory newTransferApproval = TransferRequest({
+ 316 : : key: key,
+ 317 : : id: requestId,
+ 318 : : from: keyElement.from,
+ 319 : : to: keyElement.to,
+ 320 : : value: keyElement.value,
+ 321 : : askTime: 0,
+ 322 : : maxTime: block.timestamp +
+ 323 : : options.timeLimit.timeLimitToTransfer,
+ 324 : : status: STATUS.APPROVED
+ 325 : : });
+ 326 : 28 : transferRequests[key] = newTransferApproval;
+ 327 : 28 : IdToKey[requestId] = key;
+ 328 : 28 : emit transferApproved(
+ 329 : : key,
+ 330 : : keyElement.from,
+ 331 : : keyElement.to,
+ 332 : : keyElement.value,
+ 333 : : requestId
+ 334 : : );
+ 335 : 28 : ++requestId;
+ 336 : : } else {
+ 337 : : // Overwrite previous approval
+ 338 : 2 : transferRequests[key].maxTime =
+ 339 : : block.timestamp +
+ 340 : : options.timeLimit.timeLimitToTransfer;
+ 341 : 2 : transferRequests[key].status = STATUS.APPROVED;
+ 342 : 2 : emit transferApproved(
+ 343 : : key,
+ 344 : : keyElement.from,
+ 345 : : keyElement.to,
+ 346 : : keyElement.value,
+ 347 : : transferRequests[key].id
+ 348 : : );
+ 349 : : }
+ 350 : : }
+ 351 : :
+ 352 : : function _resetRequestStatus(bytes32 key) internal {
+ 353 : 20 : transferRequests[key].status = STATUS.NONE;
+ 354 : 20 : emit transferReset(
+ 355 : : key,
+ 356 : : transferRequests[key].from,
+ 357 : : transferRequests[key].to,
+ 358 : : transferRequests[key].value,
+ 359 : : transferRequests[key].id
+ 360 : : );
+ 361 : : }
+ 362 : :
+ 363 : : function _checkRequestStatus(bytes32 key) internal view returns (bool) {
+ 364 : : // Status NONE not enough because reset is possible
+ 365 : 238 : return
+ 366 : 238 : (transferRequests[key].status == STATUS.NONE) &&
+ 367 : : (transferRequests[key].key == 0x0);
+ 368 : : }
+ 369 : :
+ 370 : : function _approveRequest(
+ 371 : : TransferRequest memory transferRequest,
+ 372 : : bool isApproved
+ 373 : : ) internal {
+ 374 : : // status
+ 375 [ + + ]: 92 : if (transferRequest.status != STATUS.WAIT) {
+ 376 : 2 : revert RuleConditionalTransfer_Wrong_Status();
+ 377 : : }
+ 378 [ + + ]: 45 : if (isApproved) {
+ 379 : : // Time
+ 380 [ + + ]: : if (
+ 381 : 54 : block.timestamp >
+ 382 : : (transferRequest.askTime + options.timeLimit.timeLimitToApprove)
+ 383 : : ) {
+ 384 : 6 : revert RuleConditionalTransfer_timeExceeded();
+ 385 : : }
+ 386 : : // Set status
+ 387 : 48 : transferRequests[transferRequest.key].status = STATUS.APPROVED;
+ 388 : : // Set max time
+ 389 : 48 : transferRequests[transferRequest.key].maxTime =
+ 390 : : block.timestamp +
+ 391 : : options.timeLimit.timeLimitToTransfer;
+ 392 : 48 : emit transferApproved(
+ 393 : : transferRequest.key,
+ 394 : : transferRequest.from,
+ 395 : : transferRequest.to,
+ 396 : : transferRequest.value,
+ 397 : : transferRequests[transferRequest.key].id
+ 398 : : );
+ 399 [ + + ]: : if (
+ 400 : 48 : options.automaticTransfer.isActivate &&
+ 401 : 8 : address(options.automaticTransfer.cmtat) != address(0)
+ 402 : : ) {
+ 403 : : // Transfer with approval
+ 404 : : // External call
+ 405 [ + + ]: : if (
+ 406 : 6 : options.automaticTransfer.cmtat.allowance(
+ 407 : : transferRequest.from,
+ 408 : : address(this)
+ 409 : : ) >= transferRequest.value
+ 410 : : ) {
+ 411 : : // Will call the ruleEngine and the rule again...
+ 412 : 4 : options.automaticTransfer.cmtat.safeTransferFrom(
+ 413 : : transferRequest.from,
+ 414 : : transferRequest.to,
+ 415 : : transferRequest.value
+ 416 : : );
+ 417 : : }
+ 418 : : }
+ 419 : : } else {
+ 420 : 36 : transferRequests[transferRequest.key].status = STATUS.DENIED;
+ 421 : 36 : emit transferDenied(
+ 422 : : transferRequest.key,
+ 423 : : transferRequest.from,
+ 424 : : transferRequest.to,
+ 425 : : transferRequest.value,
+ 426 : : transferRequests[transferRequest.key].id
+ 427 : : );
+ 428 : : }
+ 429 : : }
+ 430 : :
+ 431 : : /**
+ 432 : : * @notice update the request during a transfer
+ 433 : : */
+ 434 : : function _updateProcessedTransfer(bytes32 key) internal {
+ 435 : : // Reset to zero
+ 436 : 20 : transferRequests[key].maxTime = 0;
+ 437 : 20 : transferRequests[key].askTime = 0;
+ 438 : : // Change status
+ 439 : 20 : transferRequests[key].status = STATUS.EXECUTED;
+ 440 : : // Emit event
+ 441 : 20 : emit transferProcessed(
+ 442 : : key,
+ 443 : : transferRequests[key].from,
+ 444 : : transferRequests[key].to,
+ 445 : : transferRequests[key].value,
+ 446 : : transferRequests[key].id
+ 447 : : );
+ 448 : : }
+ 449 : : }
diff --git a/doc/test/coverage/src/rules/operation/abstract/index-sort-b.html b/doc/test/coverage/src/rules/operation/abstract/index-sort-b.html
index ceeab30..214958e 100644
--- a/doc/test/coverage/src/rules/operation/abstract/index-sort-b.html
+++ b/doc/test/coverage/src/rules/operation/abstract/index-sort-b.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -87,7 +87,7 @@
100.0 % |
- 96 / 96 |
+ 99 / 99 |
94.7 % |
18 / 19 |
98.1 % |
diff --git a/doc/test/coverage/src/rules/operation/abstract/index-sort-f.html b/doc/test/coverage/src/rules/operation/abstract/index-sort-f.html
index 8096c28..4c2ae50 100644
--- a/doc/test/coverage/src/rules/operation/abstract/index-sort-f.html
+++ b/doc/test/coverage/src/rules/operation/abstract/index-sort-f.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -87,7 +87,7 @@
100.0 % |
- 96 / 96 |
+ 99 / 99 |
94.7 % |
18 / 19 |
98.1 % |
diff --git a/doc/test/coverage/src/rules/operation/abstract/index-sort-l.html b/doc/test/coverage/src/rules/operation/abstract/index-sort-l.html
index e6d471d..59e6a4a 100644
--- a/doc/test/coverage/src/rules/operation/abstract/index-sort-l.html
+++ b/doc/test/coverage/src/rules/operation/abstract/index-sort-l.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -87,7 +87,7 @@
100.0 % |
- 96 / 96 |
+ 99 / 99 |
94.7 % |
18 / 19 |
98.1 % |
diff --git a/doc/test/coverage/src/rules/operation/abstract/index.html b/doc/test/coverage/src/rules/operation/abstract/index.html
index 1e6e812..acb0ad6 100644
--- a/doc/test/coverage/src/rules/operation/abstract/index.html
+++ b/doc/test/coverage/src/rules/operation/abstract/index.html
@@ -31,13 +31,13 @@
|
-
-
+
+
-
+
|
@@ -87,7 +87,7 @@
100.0 % |
- 96 / 96 |
+ 99 / 99 |
94.7 % |
18 / 19 |
98.1 % |
diff --git a/doc/test/coverage/src/rules/operation/index-sort-b.html b/doc/test/coverage/src/rules/operation/index-sort-b.html
index d557abc..1e39e73 100644
--- a/doc/test/coverage/src/rules/operation/index-sort-b.html
+++ b/doc/test/coverage/src/rules/operation/index-sort-b.html
@@ -31,13 +31,13 @@
|
-
+
-
+
|
@@ -87,7 +87,7 @@
98.8 % |
- 84 / 85 |
+ 85 / 86 |
93.8 % |
15 / 16 |
90.5 % |
diff --git a/doc/test/coverage/src/rules/operation/index-sort-f.html b/doc/test/coverage/src/rules/operation/index-sort-f.html
index 412cd56..2f811c5 100644
--- a/doc/test/coverage/src/rules/operation/index-sort-f.html
+++ b/doc/test/coverage/src/rules/operation/index-sort-f.html
@@ -31,13 +31,13 @@
|
-
+
-
+
|
@@ -87,7 +87,7 @@
98.8 % |
- 84 / 85 |
+ 85 / 86 |
93.8 % |
15 / 16 |
90.5 % |
diff --git a/doc/test/coverage/src/rules/operation/index-sort-l.html b/doc/test/coverage/src/rules/operation/index-sort-l.html
index af166d2..e90b7fc 100644
--- a/doc/test/coverage/src/rules/operation/index-sort-l.html
+++ b/doc/test/coverage/src/rules/operation/index-sort-l.html
@@ -31,13 +31,13 @@
|
-
+
-
+
|
@@ -87,7 +87,7 @@
98.8 % |
- 84 / 85 |
+ 85 / 86 |
93.8 % |
15 / 16 |
90.5 % |
diff --git a/doc/test/coverage/src/rules/operation/index.html b/doc/test/coverage/src/rules/operation/index.html
index 2ae074f..37c948b 100644
--- a/doc/test/coverage/src/rules/operation/index.html
+++ b/doc/test/coverage/src/rules/operation/index.html
@@ -31,13 +31,13 @@
|
-
+
-
+
|
@@ -87,7 +87,7 @@
98.8 % |
- 84 / 85 |
+ 85 / 86 |
93.8 % |
15 / 16 |
90.5 % |
diff --git a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html b/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html
index d6b2d99..8ce4954 100644
--- a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html
+++ b/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,15 +69,15 @@
Hit count |
- RuleBlacklist.canReturnTransferRestrictionCode |
+ RuleBlacklist.canReturnTransferRestrictionCode |
4 |
- RuleBlacklist.messageForTransferRestriction |
+ RuleBlacklist.messageForTransferRestriction |
4 |
- RuleBlacklist.detectTransferRestriction |
+ RuleBlacklist.detectTransferRestriction |
10 |
diff --git a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func.html b/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func.html
index b63e470..82264b6 100644
--- a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func.html
+++ b/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,15 +69,15 @@
Hit count |
- RuleBlacklist.canReturnTransferRestrictionCode |
+ RuleBlacklist.canReturnTransferRestrictionCode |
4 |
- RuleBlacklist.detectTransferRestriction |
+ RuleBlacklist.detectTransferRestriction |
10 |
- RuleBlacklist.messageForTransferRestriction |
+ RuleBlacklist.messageForTransferRestriction |
4 |
diff --git a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html b/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html
index 8f51703..f28a3c4 100644
--- a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html
+++ b/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,74 +73,78 @@
2 : :
3 : : pragma solidity ^0.8.20;
4 : :
- 5 : : import "./abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol";
+ 5 : : import "./abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol";
6 : : import "./abstract/RuleAddressList/RuleAddressList.sol";
7 : : import "./abstract/RuleValidateTransfer.sol";
- 8 : : /**
- 9 : : * @title a blacklist manager
- 10 : : */
- 11 : :
- 12 : : contract RuleBlacklist is RuleValidateTransfer, RuleAddressList, RuleBlacklistInvariantStorage {
- 13 : : /**
- 14 : : * @param admin Address of the contract (Access Control)
- 15 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 16 : : */
- 17 : : constructor(
- 18 : : address admin,
- 19 : : address forwarderIrrevocable
- 20 : : ) RuleAddressList(admin, forwarderIrrevocable) {
- 21 : : }
- 22 : :
- 23 : : /**
- 24 : : * @notice Check if an addres is in the whitelist or not
- 25 : : * @param _from the origin address
- 26 : : * @param _to the destination address
- 27 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 28 : : **/
- 29 : : function detectTransferRestriction(
- 30 : : address _from,
- 31 : : address _to,
- 32 : : uint256 /*_amount */
- 33 : : ) public view override returns (uint8) {
- 34 [ + + ]: 20 : if (addressIsListed(_from)) {
- 35 : 10 : return CODE_ADDRESS_FROM_IS_BLACKLISTED;
- 36 [ + + ]: 10 : } else if (addressIsListed(_to)) {
- 37 : 4 : return CODE_ADDRESS_TO_IS_BLACKLISTED;
- 38 : : } else {
- 39 : 9 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 40 : : }
- 41 : : }
- 42 : :
- 43 : : /**
- 44 : : * @notice To know if the restriction code is valid for this rule or not.
- 45 : : * @param _restrictionCode The target restriction code
- 46 : : * @return true if the restriction code is known, false otherwise
- 47 : : **/
- 48 : : function canReturnTransferRestrictionCode(
- 49 : : uint8 _restrictionCode
- 50 : : ) external pure override returns (bool) {
- 51 : 8 : return
- 52 : 12 : _restrictionCode == CODE_ADDRESS_FROM_IS_BLACKLISTED ||
- 53 : 4 : _restrictionCode == CODE_ADDRESS_TO_IS_BLACKLISTED;
- 54 : : }
- 55 : :
- 56 : : /**
- 57 : : * @notice Return the corresponding message
- 58 : : * @param _restrictionCode The target restriction code
- 59 : : * @return true if the transfer is valid, false otherwise
- 60 : : **/
- 61 : : function messageForTransferRestriction(
- 62 : : uint8 _restrictionCode
- 63 : : ) external pure override returns (string memory) {
- 64 [ + + ]: 8 : if (_restrictionCode == CODE_ADDRESS_FROM_IS_BLACKLISTED) {
- 65 : 4 : return TEXT_ADDRESS_FROM_IS_BLACKLISTED;
- 66 [ + + ]: 4 : } else if (_restrictionCode == CODE_ADDRESS_TO_IS_BLACKLISTED) {
- 67 : 2 : return TEXT_ADDRESS_TO_IS_BLACKLISTED;
- 68 : : } else {
- 69 : 2 : return TEXT_CODE_NOT_FOUND;
- 70 : : }
- 71 : : }
- 72 : : }
+ 8 : :
+ 9 : : /**
+ 10 : : * @title a blacklist manager
+ 11 : : */
+ 12 : :
+ 13 : : contract RuleBlacklist is
+ 14 : : RuleValidateTransfer,
+ 15 : : RuleAddressList,
+ 16 : : RuleBlacklistInvariantStorage
+ 17 : : {
+ 18 : : /**
+ 19 : : * @param admin Address of the contract (Access Control)
+ 20 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ 21 : : */
+ 22 : : constructor(
+ 23 : : address admin,
+ 24 : : address forwarderIrrevocable
+ 25 : : ) RuleAddressList(admin, forwarderIrrevocable) {}
+ 26 : :
+ 27 : : /**
+ 28 : : * @notice Check if an addres is in the whitelist or not
+ 29 : : * @param _from the origin address
+ 30 : : * @param _to the destination address
+ 31 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ 32 : : **/
+ 33 : : function detectTransferRestriction(
+ 34 : : address _from,
+ 35 : : address _to,
+ 36 : : uint256 /*_amount */
+ 37 : : ) public view override returns (uint8) {
+ 38 [ + + ]: 20 : if (addressIsListed(_from)) {
+ 39 : 10 : return CODE_ADDRESS_FROM_IS_BLACKLISTED;
+ 40 [ + + ]: 10 : } else if (addressIsListed(_to)) {
+ 41 : 4 : return CODE_ADDRESS_TO_IS_BLACKLISTED;
+ 42 : : } else {
+ 43 : 9 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 44 : : }
+ 45 : : }
+ 46 : :
+ 47 : : /**
+ 48 : : * @notice To know if the restriction code is valid for this rule or not.
+ 49 : : * @param _restrictionCode The target restriction code
+ 50 : : * @return true if the restriction code is known, false otherwise
+ 51 : : **/
+ 52 : : function canReturnTransferRestrictionCode(
+ 53 : : uint8 _restrictionCode
+ 54 : : ) external pure override returns (bool) {
+ 55 : 8 : return
+ 56 : 12 : _restrictionCode == CODE_ADDRESS_FROM_IS_BLACKLISTED ||
+ 57 : 4 : _restrictionCode == CODE_ADDRESS_TO_IS_BLACKLISTED;
+ 58 : : }
+ 59 : :
+ 60 : : /**
+ 61 : : * @notice Return the corresponding message
+ 62 : : * @param _restrictionCode The target restriction code
+ 63 : : * @return true if the transfer is valid, false otherwise
+ 64 : : **/
+ 65 : : function messageForTransferRestriction(
+ 66 : : uint8 _restrictionCode
+ 67 : : ) external pure override returns (string memory) {
+ 68 [ + + ]: 8 : if (_restrictionCode == CODE_ADDRESS_FROM_IS_BLACKLISTED) {
+ 69 : 4 : return TEXT_ADDRESS_FROM_IS_BLACKLISTED;
+ 70 [ + + ]: 4 : } else if (_restrictionCode == CODE_ADDRESS_TO_IS_BLACKLISTED) {
+ 71 : 2 : return TEXT_ADDRESS_TO_IS_BLACKLISTED;
+ 72 : : } else {
+ 73 : 2 : return TEXT_CODE_NOT_FOUND;
+ 74 : : }
+ 75 : : }
+ 76 : : }
diff --git a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html b/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html
index 03e72d5..4b23bb9 100644
--- a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html
+++ b/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,31 +69,31 @@
Hit count |
- RuleSanctionList._msgData |
+ RuleSanctionList._msgData |
0 |
- RuleSanctionList.canReturnTransferRestrictionCode |
+ RuleSanctionList.canReturnTransferRestrictionCode |
3 |
- RuleSanctionList.messageForTransferRestriction |
+ RuleSanctionList.messageForTransferRestriction |
3 |
- RuleSanctionList.detectTransferRestriction |
+ RuleSanctionList.detectTransferRestriction |
7 |
- RuleSanctionList._contextSuffixLength |
+ RuleSanctionList._contextSuffixLength |
10 |
- RuleSanctionList._msgSender |
+ RuleSanctionList._msgSender |
10 |
- RuleSanctionList.setSanctionListOracle |
+ RuleSanctionList.setSanctionListOracle |
10 |
diff --git a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func.html b/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func.html
index 0dfd668..e04194a 100644
--- a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func.html
+++ b/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,31 +69,31 @@
Hit count |
- RuleSanctionList._contextSuffixLength |
+ RuleSanctionList._contextSuffixLength |
10 |
- RuleSanctionList._msgData |
+ RuleSanctionList._msgData |
0 |
- RuleSanctionList._msgSender |
+ RuleSanctionList._msgSender |
10 |
- RuleSanctionList.canReturnTransferRestrictionCode |
+ RuleSanctionList.canReturnTransferRestrictionCode |
3 |
- RuleSanctionList.detectTransferRestriction |
+ RuleSanctionList.detectTransferRestriction |
7 |
- RuleSanctionList.messageForTransferRestriction |
+ RuleSanctionList.messageForTransferRestriction |
3 |
- RuleSanctionList.setSanctionListOracle |
+ RuleSanctionList.setSanctionListOracle |
10 |
diff --git a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html b/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html
index a629c51..668801c 100644
--- a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html
+++ b/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -77,121 +77,132 @@
6 : : import "../../modules/MetaTxModuleStandalone.sol";
7 : : import "./abstract/RuleSanctionListInvariantStorage.sol";
8 : : import "./abstract/RuleValidateTransfer.sol";
- 9 : : interface SanctionsList {
- 10 : : function isSanctioned(address addr) external view returns (bool);
- 11 : : }
- 12 : :
- 13 : : contract RuleSanctionList is AccessControl, MetaTxModuleStandalone, RuleValidateTransfer, RuleSanctionlistInvariantStorage {
- 14 : : SanctionsList public sanctionsList;
- 15 : :
- 16 : : /**
- 17 : : * @param admin Address of the contract (Access Control)
- 18 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 19 : : */
- 20 : : constructor(
- 21 : : address admin,
- 22 : : address forwarderIrrevocable
- 23 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 24 : : if(admin == address(0)){
- 25 : : revert RuleSanctionList_AdminWithAddressZeroNotAllowed();
- 26 : : }
- 27 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 28 : : _grantRole(SANCTIONLIST_ROLE, admin);
- 29 : : }
- 30 : :
- 31 : : /**
- 32 : : * @notice Set the oracle contract
- 33 : : * @param sanctionContractOracle_ address of your oracle contract
- 34 : : * @dev zero address is authorized to authorize all transfers
- 35 : : */
- 36 : : function setSanctionListOracle(
- 37 : : address sanctionContractOracle_
- 38 : : ) public onlyRole(SANCTIONLIST_ROLE) {
- 39 : 18 : sanctionsList = SanctionsList(sanctionContractOracle_);
- 40 : : }
- 41 : :
- 42 : : /**
- 43 : : * @notice Check if an addres is in the whitelist or not
- 44 : : * @param _from the origin address
- 45 : : * @param _to the destination address
- 46 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 47 : : **/
- 48 : : function detectTransferRestriction(
- 49 : : address _from,
- 50 : : address _to,
- 51 : : uint256 /*_amount */
- 52 : : ) public view override returns (uint8) {
- 53 [ + + ]: 28 : if(address(sanctionsList) != address(0)){
- 54 [ + + ]: 14 : if (sanctionsList.isSanctioned(_from)) {
- 55 : 4 : return CODE_ADDRESS_FROM_IS_SANCTIONED;
- 56 [ + + ]: 10 : } else if (sanctionsList.isSanctioned(_to)) {
- 57 : 4 : return CODE_ADDRESS_TO_IS_SANCTIONED;
- 58 : : }
- 59 : : }
- 60 : 9 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 61 : : }
- 62 : :
- 63 : : /**
- 64 : : * @notice To know if the restriction code is valid for this rule or not.
- 65 : : * @param _restrictionCode The target restriction code
- 66 : : * @return true if the restriction code is known, false otherwise
- 67 : : **/
- 68 : : function canReturnTransferRestrictionCode(
- 69 : : uint8 _restrictionCode
- 70 : : ) external pure override returns (bool) {
- 71 : 6 : return
- 72 : 9 : _restrictionCode == CODE_ADDRESS_FROM_IS_SANCTIONED ||
- 73 : 4 : _restrictionCode == CODE_ADDRESS_TO_IS_SANCTIONED;
- 74 : : }
- 75 : :
- 76 : : /**
- 77 : : * @notice Return the corresponding message
- 78 : : * @param _restrictionCode The target restriction code
- 79 : : * @return true if the transfer is valid, false otherwise
- 80 : : **/
- 81 : : function messageForTransferRestriction(
- 82 : : uint8 _restrictionCode
- 83 : : ) external pure override returns (string memory) {
- 84 [ + + ]: 6 : if (_restrictionCode == CODE_ADDRESS_FROM_IS_SANCTIONED) {
- 85 : 2 : return TEXT_ADDRESS_FROM_IS_SANCTIONED;
- 86 [ + + ]: 4 : } else if (_restrictionCode == CODE_ADDRESS_TO_IS_SANCTIONED) {
- 87 : 2 : return TEXT_ADDRESS_TO_IS_SANCTIONED;
- 88 : : } else {
- 89 : 2 : return TEXT_CODE_NOT_FOUND;
- 90 : : }
- 91 : : }
- 92 : :
- 93 : : /**
- 94 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 95 : : */
- 96 : : function _msgSender()
- 97 : : internal
- 98 : : view
- 99 : : override(ERC2771Context, Context)
- 100 : : returns (address sender)
- 101 : : {
- 102 : 30 : return ERC2771Context._msgSender();
- 103 : : }
- 104 : :
- 105 : : /**
- 106 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 107 : : */
- 108 : : function _msgData()
- 109 : : internal
- 110 : : view
- 111 : : override(ERC2771Context, Context)
- 112 : : returns (bytes calldata)
- 113 : : {
- 114 : 0 : return ERC2771Context._msgData();
- 115 : : }
- 116 : :
- 117 : : /**
- 118 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 119 : : */
- 120 : : function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
- 121 : 30 : return ERC2771Context._contextSuffixLength();
- 122 : : }
- 123 : : }
+ 9 : :
+ 10 : : interface SanctionsList {
+ 11 : : function isSanctioned(address addr) external view returns (bool);
+ 12 : : }
+ 13 : :
+ 14 : : contract RuleSanctionList is
+ 15 : : AccessControl,
+ 16 : : MetaTxModuleStandalone,
+ 17 : : RuleValidateTransfer,
+ 18 : : RuleSanctionlistInvariantStorage
+ 19 : : {
+ 20 : : SanctionsList public sanctionsList;
+ 21 : :
+ 22 : : /**
+ 23 : : * @param admin Address of the contract (Access Control)
+ 24 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ 25 : : */
+ 26 : : constructor(
+ 27 : : address admin,
+ 28 : : address forwarderIrrevocable
+ 29 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
+ 30 : : if (admin == address(0)) {
+ 31 : : revert RuleSanctionList_AdminWithAddressZeroNotAllowed();
+ 32 : : }
+ 33 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ 34 : : _grantRole(SANCTIONLIST_ROLE, admin);
+ 35 : : }
+ 36 : :
+ 37 : : /**
+ 38 : : * @notice Set the oracle contract
+ 39 : : * @param sanctionContractOracle_ address of your oracle contract
+ 40 : : * @dev zero address is authorized to authorize all transfers
+ 41 : : */
+ 42 : : function setSanctionListOracle(
+ 43 : : address sanctionContractOracle_
+ 44 : : ) public onlyRole(SANCTIONLIST_ROLE) {
+ 45 : 18 : sanctionsList = SanctionsList(sanctionContractOracle_);
+ 46 : : }
+ 47 : :
+ 48 : : /**
+ 49 : : * @notice Check if an addres is in the whitelist or not
+ 50 : : * @param _from the origin address
+ 51 : : * @param _to the destination address
+ 52 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ 53 : : **/
+ 54 : : function detectTransferRestriction(
+ 55 : : address _from,
+ 56 : : address _to,
+ 57 : : uint256 /*_amount */
+ 58 : : ) public view override returns (uint8) {
+ 59 [ + + ]: 28 : if (address(sanctionsList) != address(0)) {
+ 60 [ + + ]: 14 : if (sanctionsList.isSanctioned(_from)) {
+ 61 : 4 : return CODE_ADDRESS_FROM_IS_SANCTIONED;
+ 62 [ + + ]: 10 : } else if (sanctionsList.isSanctioned(_to)) {
+ 63 : 4 : return CODE_ADDRESS_TO_IS_SANCTIONED;
+ 64 : : }
+ 65 : : }
+ 66 : 9 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 67 : : }
+ 68 : :
+ 69 : : /**
+ 70 : : * @notice To know if the restriction code is valid for this rule or not.
+ 71 : : * @param _restrictionCode The target restriction code
+ 72 : : * @return true if the restriction code is known, false otherwise
+ 73 : : **/
+ 74 : : function canReturnTransferRestrictionCode(
+ 75 : : uint8 _restrictionCode
+ 76 : : ) external pure override returns (bool) {
+ 77 : 6 : return
+ 78 : 9 : _restrictionCode == CODE_ADDRESS_FROM_IS_SANCTIONED ||
+ 79 : 4 : _restrictionCode == CODE_ADDRESS_TO_IS_SANCTIONED;
+ 80 : : }
+ 81 : :
+ 82 : : /**
+ 83 : : * @notice Return the corresponding message
+ 84 : : * @param _restrictionCode The target restriction code
+ 85 : : * @return true if the transfer is valid, false otherwise
+ 86 : : **/
+ 87 : : function messageForTransferRestriction(
+ 88 : : uint8 _restrictionCode
+ 89 : : ) external pure override returns (string memory) {
+ 90 [ + + ]: 6 : if (_restrictionCode == CODE_ADDRESS_FROM_IS_SANCTIONED) {
+ 91 : 2 : return TEXT_ADDRESS_FROM_IS_SANCTIONED;
+ 92 [ + + ]: 4 : } else if (_restrictionCode == CODE_ADDRESS_TO_IS_SANCTIONED) {
+ 93 : 2 : return TEXT_ADDRESS_TO_IS_SANCTIONED;
+ 94 : : } else {
+ 95 : 2 : return TEXT_CODE_NOT_FOUND;
+ 96 : : }
+ 97 : : }
+ 98 : :
+ 99 : : /**
+ 100 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 101 : : */
+ 102 : : function _msgSender()
+ 103 : : internal
+ 104 : : view
+ 105 : : override(ERC2771Context, Context)
+ 106 : : returns (address sender)
+ 107 : : {
+ 108 : 30 : return ERC2771Context._msgSender();
+ 109 : : }
+ 110 : :
+ 111 : : /**
+ 112 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 113 : : */
+ 114 : : function _msgData()
+ 115 : : internal
+ 116 : : view
+ 117 : : override(ERC2771Context, Context)
+ 118 : : returns (bytes calldata)
+ 119 : : {
+ 120 : 0 : return ERC2771Context._msgData();
+ 121 : : }
+ 122 : :
+ 123 : : /**
+ 124 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 125 : : */
+ 126 : : function _contextSuffixLength()
+ 127 : : internal
+ 128 : : view
+ 129 : : override(ERC2771Context, Context)
+ 130 : : returns (uint256)
+ 131 : : {
+ 132 : 30 : return ERC2771Context._contextSuffixLength();
+ 133 : : }
+ 134 : : }
diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html b/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html
index 625c644..1860092 100644
--- a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html
+++ b/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,15 +69,15 @@
Hit count |
- RuleWhitelist.messageForTransferRestriction |
+ RuleWhitelist.messageForTransferRestriction |
7 |
- RuleWhitelist.canReturnTransferRestrictionCode |
+ RuleWhitelist.canReturnTransferRestrictionCode |
8 |
- RuleWhitelist.detectTransferRestriction |
+ RuleWhitelist.detectTransferRestriction |
28 |
diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func.html b/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func.html
index 0b98954..4cd41b0 100644
--- a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func.html
+++ b/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,15 +69,15 @@
Hit count |
- RuleWhitelist.canReturnTransferRestrictionCode |
+ RuleWhitelist.canReturnTransferRestrictionCode |
8 |
- RuleWhitelist.detectTransferRestriction |
+ RuleWhitelist.detectTransferRestriction |
28 |
- RuleWhitelist.messageForTransferRestriction |
+ RuleWhitelist.messageForTransferRestriction |
7 |
diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html b/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html
index 158f5d7..b99bd74 100644
--- a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html
+++ b/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,74 +73,78 @@
2 : :
3 : : pragma solidity ^0.8.20;
4 : :
- 5 : : import "./abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol";
+ 5 : : import "./abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol";
6 : : import "./abstract/RuleAddressList/RuleAddressList.sol";
7 : : import "./abstract/RuleValidateTransfer.sol";
- 8 : : /**
- 9 : : * @title a whitelist manager
- 10 : : */
- 11 : :
- 12 : : contract RuleWhitelist is RuleValidateTransfer, RuleAddressList, RuleWhitelistInvariantStorage {
- 13 : : /**
- 14 : : * @param admin Address of the contract (Access Control)
- 15 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 16 : : */
- 17 : : constructor(
- 18 : : address admin,
- 19 : : address forwarderIrrevocable
- 20 : : ) RuleAddressList(admin, forwarderIrrevocable) {
- 21 : : }
- 22 : :
- 23 : : /**
- 24 : : * @notice Check if an addres is in the whitelist or not
- 25 : : * @param _from the origin address
- 26 : : * @param _to the destination address
- 27 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- 28 : : **/
- 29 : : function detectTransferRestriction(
- 30 : : address _from,
- 31 : : address _to,
- 32 : : uint256 /*_amount */
- 33 : : ) public view override returns (uint8) {
- 34 [ + + ]: 56 : if (!addressIsListed(_from)) {
- 35 : 26 : return CODE_ADDRESS_FROM_NOT_WHITELISTED;
- 36 [ + + ]: 30 : } else if (! addressIsListed(_to)) {
- 37 : 10 : return CODE_ADDRESS_TO_NOT_WHITELISTED;
- 38 : : } else {
- 39 : 30 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- 40 : : }
- 41 : : }
- 42 : :
- 43 : : /**
- 44 : : * @notice To know if the restriction code is valid for this rule or not
- 45 : : * @param _restrictionCode The target restriction code
- 46 : : * @return true if the restriction code is known, false otherwise
- 47 : : **/
- 48 : : function canReturnTransferRestrictionCode(
- 49 : : uint8 _restrictionCode
- 50 : : ) external pure override returns (bool) {
- 51 : 16 : return
- 52 : 24 : _restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED ||
- 53 : 8 : _restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED;
- 54 : : }
- 55 : :
- 56 : : /**
- 57 : : * @notice Return the corresponding message
- 58 : : * @param _restrictionCode The target restriction code
- 59 : : * @return true if the transfer is valid, false otherwise
- 60 : : **/
- 61 : : function messageForTransferRestriction(
- 62 : : uint8 _restrictionCode
- 63 : : ) external pure override returns (string memory) {
- 64 [ + + ]: 14 : if (_restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED) {
- 65 : 8 : return TEXT_ADDRESS_FROM_NOT_WHITELISTED;
- 66 [ + + ]: 6 : } else if (_restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED) {
- 67 : 4 : return TEXT_ADDRESS_TO_NOT_WHITELISTED;
- 68 : : } else {
- 69 : 2 : return TEXT_CODE_NOT_FOUND;
- 70 : : }
- 71 : : }
- 72 : : }
+ 8 : :
+ 9 : : /**
+ 10 : : * @title a whitelist manager
+ 11 : : */
+ 12 : :
+ 13 : : contract RuleWhitelist is
+ 14 : : RuleValidateTransfer,
+ 15 : : RuleAddressList,
+ 16 : : RuleWhitelistInvariantStorage
+ 17 : : {
+ 18 : : /**
+ 19 : : * @param admin Address of the contract (Access Control)
+ 20 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ 21 : : */
+ 22 : : constructor(
+ 23 : : address admin,
+ 24 : : address forwarderIrrevocable
+ 25 : : ) RuleAddressList(admin, forwarderIrrevocable) {}
+ 26 : :
+ 27 : : /**
+ 28 : : * @notice Check if an addres is in the whitelist or not
+ 29 : : * @param _from the origin address
+ 30 : : * @param _to the destination address
+ 31 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ 32 : : **/
+ 33 : : function detectTransferRestriction(
+ 34 : : address _from,
+ 35 : : address _to,
+ 36 : : uint256 /*_amount */
+ 37 : : ) public view override returns (uint8) {
+ 38 [ + + ]: 56 : if (!addressIsListed(_from)) {
+ 39 : 26 : return CODE_ADDRESS_FROM_NOT_WHITELISTED;
+ 40 [ + + ]: 30 : } else if (!addressIsListed(_to)) {
+ 41 : 10 : return CODE_ADDRESS_TO_NOT_WHITELISTED;
+ 42 : : } else {
+ 43 : 30 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 44 : : }
+ 45 : : }
+ 46 : :
+ 47 : : /**
+ 48 : : * @notice To know if the restriction code is valid for this rule or not
+ 49 : : * @param _restrictionCode The target restriction code
+ 50 : : * @return true if the restriction code is known, false otherwise
+ 51 : : **/
+ 52 : : function canReturnTransferRestrictionCode(
+ 53 : : uint8 _restrictionCode
+ 54 : : ) external pure override returns (bool) {
+ 55 : 16 : return
+ 56 : 24 : _restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED ||
+ 57 : 8 : _restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED;
+ 58 : : }
+ 59 : :
+ 60 : : /**
+ 61 : : * @notice Return the corresponding message
+ 62 : : * @param _restrictionCode The target restriction code
+ 63 : : * @return true if the transfer is valid, false otherwise
+ 64 : : **/
+ 65 : : function messageForTransferRestriction(
+ 66 : : uint8 _restrictionCode
+ 67 : : ) external pure override returns (string memory) {
+ 68 [ + + ]: 14 : if (_restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED) {
+ 69 : 8 : return TEXT_ADDRESS_FROM_NOT_WHITELISTED;
+ 70 [ + + ]: 6 : } else if (_restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED) {
+ 71 : 4 : return TEXT_ADDRESS_TO_NOT_WHITELISTED;
+ 72 : : } else {
+ 73 : 2 : return TEXT_CODE_NOT_FOUND;
+ 74 : : }
+ 75 : : }
+ 76 : : }
diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html b/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html
new file mode 100644
index 0000000..b52bb36
--- /dev/null
+++ b/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/rules/validation/RuleWhitelistWrapper.sol - functions
+
+
+
+
+
+
+ LCOV - code coverage report |
+ |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html b/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html
new file mode 100644
index 0000000..72bf006
--- /dev/null
+++ b/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/rules/validation/RuleWhitelistWrapper.sol - functions
+
+
+
+
+
+
+ LCOV - code coverage report |
+ |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html b/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html
new file mode 100644
index 0000000..e33534c
--- /dev/null
+++ b/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+ LCOV - lcov.info - src/rules/validation/RuleWhitelistWrapper.sol
+
+
+
+
+
+
+ LCOV - code coverage report |
+ |
+
+
+
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+
+
+ |
+ |
+ |
+
+
+
+
+
+ |
+
+ |
+
+
+ |
+
+
+
+
+
|
+
+
+
+ Branch data Line data Source code
+
+ 1 : : // SPDX-License-Identifier: MPL-2.0
+ 2 : :
+ 3 : : pragma solidity ^0.8.20;
+ 4 : :
+ 5 : : import "OZ/access/AccessControl.sol";
+ 6 : : import "../../modules/RuleEngineValidationCommon.sol";
+ 7 : : import "../../modules/MetaTxModuleStandalone.sol";
+ 8 : : import "./abstract/RuleValidateTransfer.sol";
+ 9 : : import "./abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol";
+ 10 : : import "./abstract/RuleAddressList/RuleAddressList.sol";
+ 11 : :
+ 12 : : /**
+ 13 : : * @title Wrapper to call several different whitelist rules
+ 14 : : */
+ 15 : : contract RuleWhitelistWrapper is
+ 16 : : RuleEngineValidationCommon,
+ 17 : : MetaTxModuleStandalone,
+ 18 : : RuleValidateTransfer,
+ 19 : : RuleWhitelistInvariantStorage
+ 20 : : {
+ 21 : : /**
+ 22 : : * @param admin Address of the contract (Access Control)
+ 23 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ 24 : : */
+ 25 : : constructor(
+ 26 : : address admin,
+ 27 : : address forwarderIrrevocable
+ 28 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
+ 29 : : if (admin == address(0)) {
+ 30 : : revert RuleEngine_AdminWithAddressZeroNotAllowed();
+ 31 : : }
+ 32 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ 33 : : _grantRole(RULE_ENGINE_OPERATOR_ROLE, admin);
+ 34 : : }
+ 35 : :
+ 36 : : /**
+ 37 : : * @notice Go through all the whitelist rules to know if a restriction exists on the transfer
+ 38 : : * @param _from the origin address
+ 39 : : * @param _to the destination address
+ 40 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ 41 : : **/
+ 42 : : function detectTransferRestriction(
+ 43 : : address _from,
+ 44 : : address _to,
+ 45 : : uint256 /*_amount*/
+ 46 : : ) public view override returns (uint8) {
+ 47 : 33 : address[] memory targetAddress = new address[](2);
+ 48 : 33 : bool[] memory isListed = new bool[](2);
+ 49 : 33 : bool[] memory result = new bool[](2);
+ 50 : 22 : targetAddress[0] = _from;
+ 51 : 22 : targetAddress[1] = _to;
+ 52 : 22 : uint256 rulesLength = _rulesValidation.length;
+ 53 : : // For each whitelist rule, we ask if from or to are in the whitelist
+ 54 : 99 : for (uint256 i = 0; i < rulesLength; ++i) {
+ 55 : : // External call
+ 56 : 66 : isListed = RuleAddressList(_rulesValidation[i])
+ 57 : : .addressIsListedBatch(targetAddress);
+ 58 [ # + ]: 74 : if (isListed[0] && !result[0]) {
+ 59 : : // Update if from is in the list
+ 60 : 14 : result[0] = true;
+ 61 : : }
+ 62 [ # + ]: 74 : if (isListed[1] && !result[1]) {
+ 63 : : // Update if to is in the list
+ 64 : 14 : result[1] = true;
+ 65 : : }
+ 66 : : }
+ 67 [ + + ]: 22 : if (!result[0]) {
+ 68 : 8 : return CODE_ADDRESS_FROM_NOT_WHITELISTED;
+ 69 [ + + ]: 14 : } else if (!result[1]) {
+ 70 : 4 : return CODE_ADDRESS_TO_NOT_WHITELISTED;
+ 71 : : } else {
+ 72 : 15 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ 73 : : }
+ 74 : : }
+ 75 : :
+ 76 : : /**
+ 77 : : * @notice To know if the restriction code is valid for this rule or not
+ 78 : : * @param _restrictionCode The target restriction code
+ 79 : : * @return true if the restriction code is known, false otherwise
+ 80 : : **/
+ 81 : : function canReturnTransferRestrictionCode(
+ 82 : : uint8 _restrictionCode
+ 83 : : ) external pure override returns (bool) {
+ 84 : 8 : return
+ 85 : 12 : _restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED ||
+ 86 : 4 : _restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED;
+ 87 : : }
+ 88 : :
+ 89 : : /**
+ 90 : : * @notice Return the corresponding message
+ 91 : : * @param _restrictionCode The target restriction code
+ 92 : : * @return true if the transfer is valid, false otherwise
+ 93 : : **/
+ 94 : : function messageForTransferRestriction(
+ 95 : : uint8 _restrictionCode
+ 96 : : ) external pure override returns (string memory) {
+ 97 [ + + ]: 6 : if (_restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED) {
+ 98 : 4 : return TEXT_ADDRESS_FROM_NOT_WHITELISTED;
+ 99 [ + # ]: 2 : } else if (_restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED) {
+ 100 : 2 : return TEXT_ADDRESS_TO_NOT_WHITELISTED;
+ 101 : : } else {
+ 102 : 0 : return TEXT_CODE_NOT_FOUND;
+ 103 : : }
+ 104 : : }
+ 105 : :
+ 106 : : /**
+ 107 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 108 : : */
+ 109 : : function _msgSender()
+ 110 : : internal
+ 111 : : view
+ 112 : : override(ERC2771Context, Context)
+ 113 : : returns (address sender)
+ 114 : : {
+ 115 : 108 : return ERC2771Context._msgSender();
+ 116 : : }
+ 117 : :
+ 118 : : /**
+ 119 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 120 : : */
+ 121 : : function _msgData()
+ 122 : : internal
+ 123 : : view
+ 124 : : override(ERC2771Context, Context)
+ 125 : : returns (bytes calldata)
+ 126 : : {
+ 127 : 0 : return ERC2771Context._msgData();
+ 128 : : }
+ 129 : :
+ 130 : : /**
+ 131 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 132 : : */
+ 133 : : function _contextSuffixLength()
+ 134 : : internal
+ 135 : : view
+ 136 : : override(ERC2771Context, Context)
+ 137 : : returns (uint256)
+ 138 : : {
+ 139 : 108 : return ERC2771Context._contextSuffixLength();
+ 140 : : }
+ 141 : : }
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html
index 7380e8e..4d71919 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
|
@@ -69,40 +69,44 @@
Hit count |
- RuleAddressList._msgData |
+ RuleAddressList._msgData |
0 |
- RuleAddressList.removeAddressFromTheList |
+ RuleAddressList.removeAddressFromTheList |
3 |
- RuleAddressList.removeAddressesFromTheList |
+ RuleAddressList.removeAddressesFromTheList |
4 |
- RuleAddressList.addAddressesToTheList |
- 15 |
+ RuleAddressList.addAddressesToTheList |
+ 17 |
- RuleAddressList.numberListedAddress |
+ RuleAddressList.numberListedAddress |
24 |
- RuleAddressList.addAddressToTheList |
- 40 |
+ RuleAddressList.addressIsListedBatch |
+ 36 |
+
+
+ RuleAddressList.addAddressToTheList |
+ 52 |
- RuleAddressList._contextSuffixLength |
- 72 |
+ RuleAddressList._contextSuffixLength |
+ 86 |
- RuleAddressList._msgSender |
- 72 |
+ RuleAddressList._msgSender |
+ 86 |
- RuleAddressList.addressIsListed |
- 83 |
+ RuleAddressList.addressIsListed |
+ 86 |
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html
index 0905f5b..dda2ef2 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
|
@@ -69,39 +69,43 @@
Hit count |
- RuleAddressList._contextSuffixLength |
- 72 |
+ RuleAddressList._contextSuffixLength |
+ 86 |
- RuleAddressList._msgData |
+ RuleAddressList._msgData |
0 |
- RuleAddressList._msgSender |
- 72 |
+ RuleAddressList._msgSender |
+ 86 |
+
+
+ RuleAddressList.addAddressToTheList |
+ 52 |
- RuleAddressList.addAddressToTheList |
- 40 |
+ RuleAddressList.addAddressesToTheList |
+ 17 |
- RuleAddressList.addAddressesToTheList |
- 15 |
+ RuleAddressList.addressIsListed |
+ 86 |
- RuleAddressList.addressIsListed |
- 83 |
+ RuleAddressList.addressIsListedBatch |
+ 36 |
- RuleAddressList.numberListedAddress |
+ RuleAddressList.numberListedAddress |
24 |
- RuleAddressList.removeAddressFromTheList |
+ RuleAddressList.removeAddressFromTheList |
3 |
- RuleAddressList.removeAddressesFromTheList |
+ RuleAddressList.removeAddressesFromTheList |
4 |
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html
index ae31a25..3e44820 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
|
@@ -76,132 +76,153 @@
5 : : import "OZ/access/AccessControl.sol";
6 : : import "./../../../../modules/MetaTxModuleStandalone.sol";
7 : : import "./RuleAddressListInternal.sol";
- 8 : : import "./RuleAddressListInvariantStorage.sol";
- 9 : : /**
- 10 : : @title an addresses list manager
- 11 : : */
- 12 : :
- 13 : : abstract contract RuleAddressList is AccessControl, MetaTxModuleStandalone, RuleAddressListInternal, RuleAddressListInvariantStorage {
- 14 : :
- 15 : :
- 16 : : // Number of addresses in the whitelist at the moment
- 17 : : uint256 private numAddressesWhitelisted;
- 18 : :
- 19 : : /**
- 20 : : * @param admin Address of the contract (Access Control)
- 21 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- 22 : : */
- 23 : : constructor(
- 24 : : address admin,
- 25 : : address forwarderIrrevocable
- 26 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
- 27 : : if(admin == address(0)){
- 28 : : revert RuleAddressList_AdminWithAddressZeroNotAllowed();
- 29 : : }
- 30 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
- 31 : : _grantRole(ADDRESS_LIST_ROLE, admin);
- 32 : : }
- 33 : :
- 34 : : /**
- 35 : : * @notice Add addresses to the whitelist
- 36 : : * If one of addresses already exist, there is no change for this address. The transaction remains valid (no revert).
- 37 : : * @param listWhitelistedAddress an array with the addresses to whitelist
- 38 : : */
- 39 : : function addAddressesToTheList(
- 40 : : address[] calldata listWhitelistedAddress
- 41 : : ) public onlyRole(ADDRESS_LIST_ROLE) {
- 42 : 28 : _addAddressesToThelist(listWhitelistedAddress);
- 43 : : }
- 44 : :
- 45 : : /**
- 46 : : * @notice Remove addresses from the whitelist
- 47 : : * If the address does not exist in the whitelist, there is no change for this address.
- 48 : : * The transaction remains valid (no revert).
- 49 : : * @param listWhitelistedAddress an array with the addresses to remove
- 50 : : */
- 51 : : function removeAddressesFromTheList(
- 52 : : address[] calldata listWhitelistedAddress
- 53 : : ) public onlyRole(ADDRESS_LIST_ROLE) {
- 54 : 6 : _removeAddressesFromThelist(listWhitelistedAddress);
- 55 : : }
- 56 : :
- 57 : : /**
- 58 : : * @notice Add one address to the whitelist
- 59 : : * If the address already exists, the transaction is reverted to save gas.
- 60 : : * @param _newWhitelistAddress The address to whitelist
- 61 : : */
- 62 : : function addAddressToTheList(
- 63 : : address _newWhitelistAddress
- 64 : : ) public onlyRole(ADDRESS_LIST_ROLE) {
- 65 : 78 : _addAddressToThelist(_newWhitelistAddress);
- 66 : : }
- 67 : :
- 68 : : /**
- 69 : : * @notice Remove one address from the whitelist
- 70 : : * If the address does not exist in the whitelist, the transaction is reverted to save gas.
- 71 : : * @param _removeWhitelistAddress The address to remove
- 72 : : *
- 73 : : */
- 74 : : function removeAddressFromTheList(
- 75 : : address _removeWhitelistAddress
- 76 : : ) public onlyRole(ADDRESS_LIST_ROLE) {
- 77 : 4 : _removeAddressFromThelist( _removeWhitelistAddress);
- 78 : : }
- 79 : :
- 80 : : /**
- 81 : : * @notice Get the number of listed addresses
- 82 : : * @return Number of listed addresses
- 83 : : *
- 84 : : */
- 85 : : function numberListedAddress() public view returns (uint256) {
- 86 : 72 : return _numberListedAddress();
- 87 : : }
- 88 : :
- 89 : :
- 90 : : /**
- 91 : : * @notice Know if an address is listed or not
- 92 : : * @param _targetAddress The concerned address
- 93 : : * @return True if the address is listed, false otherwise
- 94 : : *
- 95 : : */
- 96 : : function addressIsListed(
- 97 : : address _targetAddress
- 98 : : ) public view returns (bool) {
- 99 : 423 : return _addressIsListed(_targetAddress);
- 100 : : }
- 101 : :
- 102 : :
- 103 : : /**
- 104 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 105 : : */
- 106 : : function _msgSender()
- 107 : : internal
- 108 : : view
- 109 : : override(ERC2771Context, Context)
- 110 : : returns (address sender)
- 111 : : {
- 112 : 216 : return ERC2771Context._msgSender();
- 113 : : }
- 114 : :
- 115 : : /**
- 116 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 117 : : */
- 118 : : function _msgData()
- 119 : : internal
- 120 : : view
- 121 : : override(ERC2771Context, Context)
- 122 : : returns (bytes calldata)
- 123 : : {
- 124 : 0 : return ERC2771Context._msgData();
- 125 : : }
- 126 : :
- 127 : : /**
- 128 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
- 129 : : */
- 130 : : function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
- 131 : 216 : return ERC2771Context._contextSuffixLength();
- 132 : : }
- 133 : : }
+ 8 : : import "./invariantStorage/RuleAddressListInvariantStorage.sol";
+ 9 : :
+ 10 : : /**
+ 11 : : @title an addresses list manager
+ 12 : : */
+ 13 : :
+ 14 : : abstract contract RuleAddressList is
+ 15 : : AccessControl,
+ 16 : : MetaTxModuleStandalone,
+ 17 : : RuleAddressListInternal,
+ 18 : : RuleAddressListInvariantStorage
+ 19 : : {
+ 20 : : // Number of addresses in the whitelist at the moment
+ 21 : : uint256 private numAddressesWhitelisted;
+ 22 : :
+ 23 : : /**
+ 24 : : * @param admin Address of the contract (Access Control)
+ 25 : : * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ 26 : : */
+ 27 : : constructor(
+ 28 : : address admin,
+ 29 : : address forwarderIrrevocable
+ 30 : : ) MetaTxModuleStandalone(forwarderIrrevocable) {
+ 31 : : if (admin == address(0)) {
+ 32 : : revert RuleAddressList_AdminWithAddressZeroNotAllowed();
+ 33 : : }
+ 34 : : _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ 35 : : _grantRole(ADDRESS_LIST_ROLE, admin);
+ 36 : : }
+ 37 : :
+ 38 : : /**
+ 39 : : * @notice Add addresses to the whitelist
+ 40 : : * If one of addresses already exist, there is no change for this address. The transaction remains valid (no revert).
+ 41 : : * @param listWhitelistedAddress an array with the addresses to whitelist
+ 42 : : */
+ 43 : : function addAddressesToTheList(
+ 44 : : address[] calldata listWhitelistedAddress
+ 45 : : ) public onlyRole(ADDRESS_LIST_ROLE) {
+ 46 : 32 : _addAddressesToThelist(listWhitelistedAddress);
+ 47 : : }
+ 48 : :
+ 49 : : /**
+ 50 : : * @notice Remove addresses from the whitelist
+ 51 : : * If the address does not exist in the whitelist, there is no change for this address.
+ 52 : : * The transaction remains valid (no revert).
+ 53 : : * @param listWhitelistedAddress an array with the addresses to remove
+ 54 : : */
+ 55 : : function removeAddressesFromTheList(
+ 56 : : address[] calldata listWhitelistedAddress
+ 57 : : ) public onlyRole(ADDRESS_LIST_ROLE) {
+ 58 : 6 : _removeAddressesFromThelist(listWhitelistedAddress);
+ 59 : : }
+ 60 : :
+ 61 : : /**
+ 62 : : * @notice Add one address to the whitelist
+ 63 : : * If the address already exists, the transaction is reverted to save gas.
+ 64 : : * @param _newWhitelistAddress The address to whitelist
+ 65 : : */
+ 66 : : function addAddressToTheList(
+ 67 : : address _newWhitelistAddress
+ 68 : : ) public onlyRole(ADDRESS_LIST_ROLE) {
+ 69 : 102 : _addAddressToThelist(_newWhitelistAddress);
+ 70 : : }
+ 71 : :
+ 72 : : /**
+ 73 : : * @notice Remove one address from the whitelist
+ 74 : : * If the address does not exist in the whitelist, the transaction is reverted to save gas.
+ 75 : : * @param _removeWhitelistAddress The address to remove
+ 76 : : *
+ 77 : : */
+ 78 : : function removeAddressFromTheList(
+ 79 : : address _removeWhitelistAddress
+ 80 : : ) public onlyRole(ADDRESS_LIST_ROLE) {
+ 81 : 4 : _removeAddressFromThelist(_removeWhitelistAddress);
+ 82 : : }
+ 83 : :
+ 84 : : /**
+ 85 : : * @notice Get the number of listed addresses
+ 86 : : * @return Number of listed addresses
+ 87 : : *
+ 88 : : */
+ 89 : : function numberListedAddress() public view returns (uint256) {
+ 90 : 72 : return _numberListedAddress();
+ 91 : : }
+ 92 : :
+ 93 : : /**
+ 94 : : * @notice Know if an address is listed or not
+ 95 : : * @param _targetAddress The concerned address
+ 96 : : * @return True if the address is listed, false otherwise
+ 97 : : *
+ 98 : : */
+ 99 : : function addressIsListed(
+ 100 : : address _targetAddress
+ 101 : : ) public view returns (bool) {
+ 102 : 432 : return _addressIsListed(_targetAddress);
+ 103 : : }
+ 104 : :
+ 105 : : /**
+ 106 : : * @notice batch version of {addressIsListed}
+ 107 : : *
+ 108 : : */
+ 109 : : function addressIsListedBatch(
+ 110 : : address[] memory _targetAddresses
+ 111 : : ) public view returns (bool[] memory) {
+ 112 : 108 : bool[] memory isListed = new bool[](_targetAddresses.length);
+ 113 : 250 : for (uint256 i = 0; i < _targetAddresses.length; ++i) {
+ 114 : 142 : isListed[i] = _addressIsListed(_targetAddresses[i]);
+ 115 : : }
+ 116 : 72 : return isListed;
+ 117 : : }
+ 118 : :
+ 119 : : /**
+ 120 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 121 : : */
+ 122 : : function _msgSender()
+ 123 : : internal
+ 124 : : view
+ 125 : : override(ERC2771Context, Context)
+ 126 : : returns (address sender)
+ 127 : : {
+ 128 : 258 : return ERC2771Context._msgSender();
+ 129 : : }
+ 130 : :
+ 131 : : /**
+ 132 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 133 : : */
+ 134 : : function _msgData()
+ 135 : : internal
+ 136 : : view
+ 137 : : override(ERC2771Context, Context)
+ 138 : : returns (bytes calldata)
+ 139 : : {
+ 140 : 0 : return ERC2771Context._msgData();
+ 141 : : }
+ 142 : :
+ 143 : : /**
+ 144 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ 145 : : */
+ 146 : : function _contextSuffixLength()
+ 147 : : internal
+ 148 : : view
+ 149 : : override(ERC2771Context, Context)
+ 150 : : returns (uint256)
+ 151 : : {
+ 152 : 258 : return ERC2771Context._contextSuffixLength();
+ 153 : : }
+ 154 : : }
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html
index 511dbce..034d5b0 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,28 +69,28 @@
Hit count |
- RuleAddressListInternal._removeAddressFromThelist |
+ RuleAddressListInternal._removeAddressFromThelist |
2 |
- RuleAddressListInternal._removeAddressesFromThelist |
+ RuleAddressListInternal._removeAddressesFromThelist |
3 |
- RuleAddressListInternal._addAddressesToThelist |
- 14 |
+ RuleAddressListInternal._addAddressesToThelist |
+ 16 |
- RuleAddressListInternal._numberListedAddress |
+ RuleAddressListInternal._numberListedAddress |
24 |
- RuleAddressListInternal._addAddressToThelist |
- 39 |
+ RuleAddressListInternal._addAddressToThelist |
+ 51 |
- RuleAddressListInternal._addressIsListed |
- 141 |
+ RuleAddressListInternal._addressIsListed |
+ 215 |
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html
index 66d10d6..3a52fd0 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,27 +69,27 @@
Hit count |
- RuleAddressListInternal._addAddressToThelist |
- 39 |
+ RuleAddressListInternal._addAddressToThelist |
+ 51 |
- RuleAddressListInternal._addAddressesToThelist |
- 14 |
+ RuleAddressListInternal._addAddressesToThelist |
+ 16 |
- RuleAddressListInternal._addressIsListed |
- 141 |
+ RuleAddressListInternal._addressIsListed |
+ 215 |
- RuleAddressListInternal._numberListedAddress |
+ RuleAddressListInternal._numberListedAddress |
24 |
- RuleAddressListInternal._removeAddressFromThelist |
+ RuleAddressListInternal._removeAddressFromThelist |
2 |
- RuleAddressListInternal._removeAddressesFromThelist |
+ RuleAddressListInternal._removeAddressesFromThelist |
3 |
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html
index 5e74800..b102a31 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -74,108 +74,100 @@
3 : : pragma solidity ^0.8.20;
4 : :
5 : : /**
- 6 : : * @title a list manager
- 7 : : */
+ 6 : : * @title a list manager
+ 7 : : */
8 : :
9 : : abstract contract RuleAddressListInternal {
10 : : error Rulelist_AddressAlreadylisted();
11 : : error Rulelist_AddressNotPresent();
- 12 : :
+ 12 : :
13 : : mapping(address => bool) private list;
14 : : // Number of addresses in the list at the moment
15 : : uint256 private numAddressesList;
16 : :
- 17 : :
- 18 : : /**
- 19 : : * @notice Add addresses to the list
- 20 : : * If one of addresses already exist, there is no change for this address. The transaction remains valid (no revert).
- 21 : : * @param listAddresses an array with the addresses to list
- 22 : : */
- 23 : : function _addAddressesToThelist(
- 24 : : address[] calldata listAddresses
- 25 : : ) internal {
- 26 : 28 : uint256 numAddressesListLocal = numAddressesList;
- 27 : 102 : for (uint256 i = 0; i < listAddresses.length; ++i ) {
- 28 [ # + ]: 60 : if (!list[listAddresses[i]]) {
- 29 : 56 : list[listAddresses[i]] = true;
- 30 : 56 : ++numAddressesListLocal;
- 31 : : }
- 32 : : }
- 33 : 28 : numAddressesList = numAddressesListLocal;
- 34 : : }
- 35 : :
- 36 : : /**
- 37 : : * @notice Remove addresses from the list
- 38 : : * If the address does not exist in the list, there is no change for this address.
- 39 : : * The transaction remains valid (no revert).
- 40 : : * @param listAddresses an array with the addresses to remove
- 41 : : */
- 42 : : function _removeAddressesFromThelist(
- 43 : : address[] calldata listAddresses
- 44 : : ) internal {
- 45 : 6 : uint256 numAddressesListLocal = numAddressesList;
- 46 : 23 : for (uint256 i = 0; i < listAddresses.length; ++i ) {
- 47 [ # + ]: 7 : if (list[listAddresses[i]]) {
- 48 : 12 : list[listAddresses[i]] = false;
- 49 : 12 : --numAddressesListLocal;
- 50 : : }
- 51 : : }
- 52 : 6 : numAddressesList = numAddressesListLocal;
- 53 : : }
- 54 : :
- 55 : : /**
- 56 : : * @notice Add one address to the list
- 57 : : * If the address already exists, the transaction is reverted to save gas.
- 58 : : * @param _newlistAddress The address to list
- 59 : : */
- 60 : : function _addAddressToThelist(
- 61 : : address _newlistAddress
- 62 : : ) internal {
- 63 [ + + ]: 39 : if(list[_newlistAddress])
- 64 : : {
- 65 : 2 : revert Rulelist_AddressAlreadylisted();
- 66 : : }
- 67 : 76 : list[_newlistAddress] = true;
- 68 : 76 : ++numAddressesList;
- 69 : : }
- 70 : :
- 71 : : /**
- 72 : : * @notice Remove one address from the list
- 73 : : * If the address does not exist in the list, the transaction is reverted to save gas.
- 74 : : * @param _removelistAddress The address to remove
- 75 : : *
- 76 : : */
- 77 : : function _removeAddressFromThelist(
- 78 : : address _removelistAddress
- 79 : : ) internal {
- 80 [ + + ]: 4 : if(!list[_removelistAddress]){
- 81 : 2 : revert Rulelist_AddressNotPresent();
- 82 : : }
- 83 : 2 : list[_removelistAddress] = false;
- 84 : 2 : --numAddressesList;
- 85 : : }
- 86 : :
- 87 : : /**
- 88 : : * @notice Get the number of listed addresses
- 89 : : * @return Number of listed addresses
- 90 : : *
- 91 : : */
- 92 : : function _numberListedAddress() internal view returns (uint256) {
- 93 : 48 : return numAddressesList;
- 94 : : }
- 95 : :
- 96 : : /**
- 97 : : * @notice Know if an address is listed or not
- 98 : : * @param _targetAddress The concerned address
- 99 : : * @return True if the address is listed, false otherwise
- 100 : : *
- 101 : : */
- 102 : : function _addressIsListed(
- 103 : : address _targetAddress
- 104 : : ) internal view returns (bool) {
- 105 : 282 : return list[_targetAddress];
- 106 : : }
- 107 : : }
+ 17 : : /**
+ 18 : : * @notice Add addresses to the list
+ 19 : : * If one of addresses already exist, there is no change for this address. The transaction remains valid (no revert).
+ 20 : : * @param listAddresses an array with the addresses to list
+ 21 : : */
+ 22 : : function _addAddressesToThelist(address[] calldata listAddresses) internal {
+ 23 : 32 : uint256 numAddressesListLocal = numAddressesList;
+ 24 : 116 : for (uint256 i = 0; i < listAddresses.length; ++i) {
+ 25 [ # + ]: 68 : if (!list[listAddresses[i]]) {
+ 26 : 64 : list[listAddresses[i]] = true;
+ 27 : 64 : ++numAddressesListLocal;
+ 28 : : }
+ 29 : : }
+ 30 : 32 : numAddressesList = numAddressesListLocal;
+ 31 : : }
+ 32 : :
+ 33 : : /**
+ 34 : : * @notice Remove addresses from the list
+ 35 : : * If the address does not exist in the list, there is no change for this address.
+ 36 : : * The transaction remains valid (no revert).
+ 37 : : * @param listAddresses an array with the addresses to remove
+ 38 : : */
+ 39 : : function _removeAddressesFromThelist(
+ 40 : : address[] calldata listAddresses
+ 41 : : ) internal {
+ 42 : 6 : uint256 numAddressesListLocal = numAddressesList;
+ 43 : 23 : for (uint256 i = 0; i < listAddresses.length; ++i) {
+ 44 [ # + ]: 7 : if (list[listAddresses[i]]) {
+ 45 : 12 : list[listAddresses[i]] = false;
+ 46 : 12 : --numAddressesListLocal;
+ 47 : : }
+ 48 : : }
+ 49 : 6 : numAddressesList = numAddressesListLocal;
+ 50 : : }
+ 51 : :
+ 52 : : /**
+ 53 : : * @notice Add one address to the list
+ 54 : : * If the address already exists, the transaction is reverted to save gas.
+ 55 : : * @param _newlistAddress The address to list
+ 56 : : */
+ 57 : : function _addAddressToThelist(address _newlistAddress) internal {
+ 58 [ + + ]: 51 : if (list[_newlistAddress]) {
+ 59 : 2 : revert Rulelist_AddressAlreadylisted();
+ 60 : : }
+ 61 : 100 : list[_newlistAddress] = true;
+ 62 : 100 : ++numAddressesList;
+ 63 : : }
+ 64 : :
+ 65 : : /**
+ 66 : : * @notice Remove one address from the list
+ 67 : : * If the address does not exist in the list, the transaction is reverted to save gas.
+ 68 : : * @param _removelistAddress The address to remove
+ 69 : : *
+ 70 : : */
+ 71 : : function _removeAddressFromThelist(address _removelistAddress) internal {
+ 72 [ + + ]: 4 : if (!list[_removelistAddress]) {
+ 73 : 2 : revert Rulelist_AddressNotPresent();
+ 74 : : }
+ 75 : 2 : list[_removelistAddress] = false;
+ 76 : 2 : --numAddressesList;
+ 77 : : }
+ 78 : :
+ 79 : : /**
+ 80 : : * @notice Get the number of listed addresses
+ 81 : : * @return Number of listed addresses
+ 82 : : *
+ 83 : : */
+ 84 : : function _numberListedAddress() internal view returns (uint256) {
+ 85 : 48 : return numAddressesList;
+ 86 : : }
+ 87 : :
+ 88 : : /**
+ 89 : : * @notice Know if an address is listed or not
+ 90 : : * @param _targetAddress The concerned address
+ 91 : : * @return True if the address is listed, false otherwise
+ 92 : : *
+ 93 : : */
+ 94 : : function _addressIsListed(
+ 95 : : address _targetAddress
+ 96 : : ) internal view returns (bool) {
+ 97 : 430 : return list[_targetAddress];
+ 98 : : }
+ 99 : : }
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html
index 2c18e01..71a79b8 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
|
@@ -96,12 +96,12 @@
RuleAddressList.sol |
-
+
|
- 88.9 % |
- 8 / 9 |
- 88.9 % |
- 8 / 9 |
+ 92.3 % |
+ 12 / 13 |
+ 90.0 % |
+ 9 / 10 |
- |
0 / 0 |
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html
index 3b3a30a..c73796f 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
|
@@ -84,12 +84,12 @@
RuleAddressList.sol |
-
+
|
- 88.9 % |
- 8 / 9 |
- 88.9 % |
- 8 / 9 |
+ 92.3 % |
+ 12 / 13 |
+ 90.0 % |
+ 9 / 10 |
- |
0 / 0 |
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html
index ab0cc0e..7344e95 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
|
@@ -84,12 +84,12 @@
RuleAddressList.sol |
-
+
|
- 88.9 % |
- 8 / 9 |
- 88.9 % |
- 8 / 9 |
+ 92.3 % |
+ 12 / 13 |
+ 90.0 % |
+ 9 / 10 |
- |
0 / 0 |
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index.html b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index.html
index 1c40a15..8b576c0 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index.html
@@ -31,18 +31,18 @@
|
-
-
-
+
+
+
-
+
|
-
-
+
+
|
@@ -84,12 +84,12 @@
RuleAddressList.sol |
-
+
|
- 88.9 % |
- 8 / 9 |
- 88.9 % |
- 8 / 9 |
+ 92.3 % |
+ 12 / 13 |
+ 90.0 % |
+ 9 / 10 |
- |
0 / 0 |
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html b/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html
index 4495caa..de6e037 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html b/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html
index 97372fa..df568ad 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html b/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html
index a4ed5c4..89b228f 100644
--- a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html
+++ b/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -75,14 +75,14 @@
4 : :
5 : : import "../../../interfaces/IRuleValidation.sol";
6 : :
- 7 : : abstract contract RuleValidateTransfer is IRuleValidation{
- 8 : : /**
- 9 : : * @notice Validate a transfer
- 10 : : * @param _from the origin address
- 11 : : * @param _to the destination address
- 12 : : * @param _amount to transfer
- 13 : : * @return isValid => true if the transfer is valid, false otherwise
- 14 : : **/
+ 7 : : abstract contract RuleValidateTransfer is IRuleValidation {
+ 8 : : /**
+ 9 : : * @notice Validate a transfer
+ 10 : : * @param _from the origin address
+ 11 : : * @param _to the destination address
+ 12 : : * @param _amount to transfer
+ 13 : : * @return isValid => true if the transfer is valid, false otherwise
+ 14 : : **/
15 : : function validateTransfer(
16 : : address _from,
17 : : address _to,
diff --git a/doc/test/coverage/src/rules/validation/abstract/index-sort-b.html b/doc/test/coverage/src/rules/validation/abstract/index-sort-b.html
index 760e987..85c73c5 100644
--- a/doc/test/coverage/src/rules/validation/abstract/index-sort-b.html
+++ b/doc/test/coverage/src/rules/validation/abstract/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/src/rules/validation/abstract/index-sort-f.html b/doc/test/coverage/src/rules/validation/abstract/index-sort-f.html
index f0ef7d6..11ccdbb 100644
--- a/doc/test/coverage/src/rules/validation/abstract/index-sort-f.html
+++ b/doc/test/coverage/src/rules/validation/abstract/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/src/rules/validation/abstract/index-sort-l.html b/doc/test/coverage/src/rules/validation/abstract/index-sort-l.html
index 464156f..a2371ee 100644
--- a/doc/test/coverage/src/rules/validation/abstract/index-sort-l.html
+++ b/doc/test/coverage/src/rules/validation/abstract/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/src/rules/validation/abstract/index.html b/doc/test/coverage/src/rules/validation/abstract/index.html
index 093d2c0..f79bdac 100644
--- a/doc/test/coverage/src/rules/validation/abstract/index.html
+++ b/doc/test/coverage/src/rules/validation/abstract/index.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/src/rules/validation/index-sort-b.html b/doc/test/coverage/src/rules/validation/index-sort-b.html
index 4fe50bf..0a4a8dd 100644
--- a/doc/test/coverage/src/rules/validation/index-sort-b.html
+++ b/doc/test/coverage/src/rules/validation/index-sort-b.html
@@ -31,27 +31,27 @@
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
|
@@ -81,6 +81,18 @@
Functions |
Branches |
+
+ RuleWhitelistWrapper.sol |
+
+
+ |
+ 92.9 % |
+ 26 / 28 |
+ 83.3 % |
+ 5 / 6 |
+ 75.0 % |
+ 9 / 12 |
+
RuleBlacklist.sol |
diff --git a/doc/test/coverage/src/rules/validation/index-sort-f.html b/doc/test/coverage/src/rules/validation/index-sort-f.html
index 946c249..086d6a1 100644
--- a/doc/test/coverage/src/rules/validation/index-sort-f.html
+++ b/doc/test/coverage/src/rules/validation/index-sort-f.html
@@ -31,27 +31,27 @@
|
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
|
@@ -81,6 +81,18 @@
Functions |
Branches |
+
+ RuleWhitelistWrapper.sol |
+
+
+ |
+ 92.9 % |
+ 26 / 28 |
+ 83.3 % |
+ 5 / 6 |
+ 75.0 % |
+ 9 / 12 |
+
RuleSanctionList.sol |
diff --git a/doc/test/coverage/src/rules/validation/index-sort-l.html b/doc/test/coverage/src/rules/validation/index-sort-l.html
index ca1eb77..d20fb85 100644
--- a/doc/test/coverage/src/rules/validation/index-sort-l.html
+++ b/doc/test/coverage/src/rules/validation/index-sort-l.html
@@ -31,27 +31,27 @@
|
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
|
@@ -81,6 +81,18 @@
Functions |
Branches |
+
+ RuleWhitelistWrapper.sol |
+
+
+ |
+ 92.9 % |
+ 26 / 28 |
+ 83.3 % |
+ 5 / 6 |
+ 75.0 % |
+ 9 / 12 |
+
RuleSanctionList.sol |
diff --git a/doc/test/coverage/src/rules/validation/index.html b/doc/test/coverage/src/rules/validation/index.html
index 7799d57..e0071b7 100644
--- a/doc/test/coverage/src/rules/validation/index.html
+++ b/doc/test/coverage/src/rules/validation/index.html
@@ -31,27 +31,27 @@
|
|
-
-
-
+
+
+
-
+
|
-
-
-
+
+
+
|
|
|
-
-
-
+
+
+
|
@@ -117,6 +117,18 @@
100.0 % |
8 / 8 |
+
+ RuleWhitelistWrapper.sol |
+
+
+ |
+ 92.9 % |
+ 26 / 28 |
+ 83.3 % |
+ 5 / 6 |
+ 75.0 % |
+ 9 / 12 |
+
diff --git a/doc/test/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html b/doc/test/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html
index 70f8339..498ac69 100644
--- a/doc/test/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html
+++ b/doc/test/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,15 +69,15 @@
Hit count |
- SanctionListOracle.removeFromSanctionsList |
+ SanctionListOracle.removeFromSanctionsList |
0 |
- SanctionListOracle.addToSanctionsList |
+ SanctionListOracle.addToSanctionsList |
10 |
- SanctionListOracle.isSanctioned |
+ SanctionListOracle.isSanctioned |
12 |
diff --git a/doc/test/coverage/test/utils/SanctionListOracle.sol.func.html b/doc/test/coverage/test/utils/SanctionListOracle.sol.func.html
index 0928957..b8d16d5 100644
--- a/doc/test/coverage/test/utils/SanctionListOracle.sol.func.html
+++ b/doc/test/coverage/test/utils/SanctionListOracle.sol.func.html
@@ -37,7 +37,7 @@
-
+
|
@@ -69,15 +69,15 @@
Hit count |
- SanctionListOracle.addToSanctionsList |
+ SanctionListOracle.addToSanctionsList |
10 |
- SanctionListOracle.isSanctioned |
+ SanctionListOracle.isSanctioned |
12 |
- SanctionListOracle.removeFromSanctionsList |
+ SanctionListOracle.removeFromSanctionsList |
0 |
diff --git a/doc/test/coverage/test/utils/SanctionListOracle.sol.gcov.html b/doc/test/coverage/test/utils/SanctionListOracle.sol.gcov.html
index fb570e9..2344b67 100644
--- a/doc/test/coverage/test/utils/SanctionListOracle.sol.gcov.html
+++ b/doc/test/coverage/test/utils/SanctionListOracle.sol.gcov.html
@@ -37,7 +37,7 @@
-
+
|
@@ -73,28 +73,26 @@
2 : : pragma solidity ^0.8.20;
3 : :
4 : : /**
- 5 : : * @notice Test contract from
- 6 : : * https://etherscan.io/address/0x40c57923924b5c5c5455c48d93317139addac8fb#code
- 7 : : */
+ 5 : : * @notice Test contract from
+ 6 : : * https://etherscan.io/address/0x40c57923924b5c5c5455c48d93317139addac8fb#code
+ 7 : : */
8 : : contract SanctionListOracle {
- 9 : :
- 10 : : constructor() {}
- 11 : :
- 12 : : mapping(address => bool) private sanctionedAddresses;
- 13 : :
- 14 : :
- 15 : : function addToSanctionsList(address newSanction) public{
- 16 : 20 : sanctionedAddresses[newSanction] = true;
- 17 : : }
- 18 : :
- 19 : : function removeFromSanctionsList(address removeSanction) public{
- 20 : 0 : sanctionedAddresses[removeSanction] = true;
- 21 : : }
- 22 : :
- 23 : : function isSanctioned(address addr) public view returns (bool) {
- 24 : 36 : return sanctionedAddresses[addr] == true ;
- 25 : : }
- 26 : : }
+ 9 : : constructor() {}
+ 10 : :
+ 11 : : mapping(address => bool) private sanctionedAddresses;
+ 12 : :
+ 13 : : function addToSanctionsList(address newSanction) public {
+ 14 : 20 : sanctionedAddresses[newSanction] = true;
+ 15 : : }
+ 16 : :
+ 17 : : function removeFromSanctionsList(address removeSanction) public {
+ 18 : 0 : sanctionedAddresses[removeSanction] = true;
+ 19 : : }
+ 20 : :
+ 21 : : function isSanctioned(address addr) public view returns (bool) {
+ 22 : 36 : return sanctionedAddresses[addr] == true;
+ 23 : : }
+ 24 : : }
diff --git a/doc/test/coverage/test/utils/index-sort-b.html b/doc/test/coverage/test/utils/index-sort-b.html
index 252f067..609b21b 100644
--- a/doc/test/coverage/test/utils/index-sort-b.html
+++ b/doc/test/coverage/test/utils/index-sort-b.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/test/utils/index-sort-f.html b/doc/test/coverage/test/utils/index-sort-f.html
index 25b4893..6a9e697 100644
--- a/doc/test/coverage/test/utils/index-sort-f.html
+++ b/doc/test/coverage/test/utils/index-sort-f.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/test/utils/index-sort-l.html b/doc/test/coverage/test/utils/index-sort-l.html
index 2c71311..788f148 100644
--- a/doc/test/coverage/test/utils/index-sort-l.html
+++ b/doc/test/coverage/test/utils/index-sort-l.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/coverage/test/utils/index.html b/doc/test/coverage/test/utils/index.html
index 487e98c..bccc378 100644
--- a/doc/test/coverage/test/utils/index.html
+++ b/doc/test/coverage/test/utils/index.html
@@ -37,7 +37,7 @@
-
+
|
diff --git a/doc/test/lcov.info b/doc/test/lcov.info
index 0ce6817..ea61b44 100644
--- a/doc/test/lcov.info
+++ b/doc/test/lcov.info
@@ -1,10 +1,7 @@
TN:
SF:script/CMTATWithRuleEngineScript.s.sol
-FN:14,CMTATWithRuleEngineScript.run
+FN:15,CMTATWithRuleEngineScript.run
FNDA:0,CMTATWithRuleEngineScript.run
-DA:16,0
-DA:16,0
-DA:16,0
DA:17,0
DA:17,0
DA:17,0
@@ -13,31 +10,34 @@ DA:18,0
DA:18,0
DA:19,0
DA:19,0
+DA:19,0
DA:20,0
DA:20,0
DA:21,0
DA:21,0
-DA:23,0
-DA:23,0
-DA:23,0
-DA:36,0
-DA:36,0
-DA:38,0
-DA:38,0
-DA:38,0
-DA:42,0
-DA:42,0
-DA:44,0
-DA:44,0
-DA:44,0
+DA:22,0
+DA:22,0
+DA:24,0
+DA:24,0
+DA:24,0
+DA:37,0
+DA:37,0
+DA:39,0
+DA:39,0
+DA:39,0
+DA:43,0
+DA:43,0
DA:45,0
DA:45,0
-DA:46,0
-DA:46,0
-DA:47,0
-DA:47,0
-DA:49,0
-DA:49,0
+DA:45,0
+DA:50,0
+DA:50,0
+DA:51,0
+DA:51,0
+DA:52,0
+DA:52,0
+DA:54,0
+DA:54,0
FNF:1
FNH:0
LF:15
@@ -90,192 +90,194 @@ BRH:0
end_of_record
TN:
SF:src/RuleEngine.sol
-FN:44,RuleEngine.detectTransferRestriction
-FNDA:13,RuleEngine.detectTransferRestriction
-DA:50,22
-DA:50,22
-DA:50,22
-DA:51,22
-DA:51,22
-DA:51,22
-BRDA:51,0,0,12
-BRDA:51,0,1,10
-DA:52,12
-DA:52,12
-DA:56,10
-DA:56,10
-DA:57,10
-DA:57,10
-DA:57,11
-DA:57,1
-DA:58,6
-DA:58,6
-DA:58,6
-DA:63,6
-DA:63,6
-BRDA:63,1,0,5
-BRDA:63,1,1,1
-DA:64,5
-DA:64,5
-DA:68,5
+FN:47,RuleEngine.detectTransferRestriction
+FNDA:17,RuleEngine.detectTransferRestriction
+DA:53,26
+DA:53,26
+DA:53,26
+DA:58,26
+DA:58,26
+DA:58,26
+BRDA:58,0,0,15
+BRDA:58,0,1,11
+DA:59,15
+DA:59,15
+DA:63,11
+DA:63,11
+DA:64,11
+DA:64,11
+DA:64,12
+DA:64,1
+DA:65,6
+DA:65,6
+DA:65,6
+DA:67,6
+DA:67,6
+BRDA:67,1,0,5
+BRDA:67,1,1,1
DA:68,5
DA:68,5
-FN:78,RuleEngine.validateTransfer
+DA:72,6
+DA:72,6
+DA:72,6
+FN:82,RuleEngine.validateTransfer
FNDA:9,RuleEngine.validateTransfer
-DA:83,9
-DA:83,9
-DA:83,9
-DA:83,9
-DA:83,9
-FN:91,RuleEngine.messageForTransferRestriction
-FNDA:14,RuleEngine.messageForTransferRestriction
-DA:95,14
-DA:95,14
-DA:96,14
-DA:96,14
-DA:96,16
-DA:96,2
-DA:97,9
-DA:97,9
-BRDA:97,2,0,-
-BRDA:97,2,1,7
-DA:98,7
-DA:98,7
-DA:99,7
-DA:99,7
-DA:103,7
-DA:103,7
-DA:104,7
-DA:104,7
-DA:104,8
-DA:104,1
-DA:105,2
-DA:105,2
-BRDA:105,3,0,-
-BRDA:105,3,1,1
-DA:106,1
-DA:106,1
-DA:107,1
-DA:107,1
-DA:110,6
-DA:110,6
-FN:116,RuleEngine.operateOnTransfer
-FNDA:45,RuleEngine.operateOnTransfer
-DA:118,44
-DA:118,44
-BRDA:118,4,0,7
-BRDA:118,4,1,37
-DA:119,7
-DA:119,7
-DA:122,37
-DA:122,37
-DA:122,37
-FN:128,RuleEngine._msgSender
-FNDA:244,RuleEngine._msgSender
-DA:134,244
-DA:134,244
-DA:134,244
-FN:140,RuleEngine._msgData
+DA:87,9
+DA:87,9
+DA:88,9
+DA:88,9
+DA:88,9
+DA:89,9
+DA:89,9
+FN:97,RuleEngine.messageForTransferRestriction
+FNDA:18,RuleEngine.messageForTransferRestriction
+DA:101,18
+DA:101,18
+DA:102,18
+DA:102,18
+DA:102,21
+DA:102,3
+DA:104,13
+DA:104,13
+BRDA:103,2,0,-
+BRDA:103,2,1,10
+DA:107,10
+DA:107,10
+DA:108,10
+DA:108,10
+DA:113,8
+DA:113,8
+DA:114,8
+DA:114,8
+DA:114,9
+DA:114,1
+DA:116,2
+DA:116,2
+BRDA:115,3,0,-
+BRDA:115,3,1,1
+DA:119,1
+DA:119,1
+DA:120,1
+DA:120,1
+DA:124,7
+DA:124,7
+FN:130,RuleEngine.operateOnTransfer
+FNDA:52,RuleEngine.operateOnTransfer
+DA:137,51
+DA:137,51
+BRDA:136,4,0,10
+BRDA:136,4,1,41
+DA:139,10
+DA:139,10
+DA:142,41
+DA:142,41
+DA:142,41
+FN:148,RuleEngine._msgSender
+FNDA:263,RuleEngine._msgSender
+DA:154,263
+DA:154,263
+DA:154,263
+FN:160,RuleEngine._msgData
FNDA:0,RuleEngine._msgData
-DA:146,0
-DA:146,0
-DA:146,0
-FN:152,RuleEngine._contextSuffixLength
-FNDA:244,RuleEngine._contextSuffixLength
-DA:153,244
-DA:153,244
-DA:153,244
+DA:166,0
+DA:166,0
+DA:166,0
+FN:172,RuleEngine._contextSuffixLength
+FNDA:263,RuleEngine._contextSuffixLength
+DA:178,263
+DA:178,263
+DA:178,263
FNF:7
FNH:6
-LF:27
-LH:26
+LF:29
+LH:28
BRF:10
BRH:8
end_of_record
TN:
SF:src/modules/RuleEngineOperation.sol
-FN:21,RuleEngineOperation.setRulesOperation
+FN:26,RuleEngineOperation.setRulesOperation
FNDA:11,RuleEngineOperation.setRulesOperation
-DA:24,11
-DA:24,11
-BRDA:24,0,0,10
-BRDA:24,0,1,11
-DA:25,10
-DA:25,10
-DA:27,11
-DA:27,11
-DA:28,8
-DA:28,8
-FN:35,RuleEngineOperation.clearRulesOperation
+DA:29,11
+DA:29,11
+BRDA:29,0,0,10
+BRDA:29,0,1,11
+DA:30,10
+DA:30,10
+DA:32,11
+DA:32,11
+DA:33,8
+DA:33,8
+FN:40,RuleEngineOperation.clearRulesOperation
FNDA:4,RuleEngineOperation.clearRulesOperation
-DA:36,4
-DA:36,4
-FN:43,RuleEngineOperation._clearRulesOperation
+DA:41,4
+DA:41,4
+FN:48,RuleEngineOperation._clearRulesOperation
FNDA:14,RuleEngineOperation._clearRulesOperation
-DA:44,14
-DA:44,14
-DA:46,14
-DA:46,14
-DA:46,31
-DA:46,17
-DA:49,17
-DA:49,17
+DA:49,14
+DA:49,14
+DA:51,14
+DA:51,14
+DA:51,31
DA:51,17
-DA:51,17
-DA:53,14
-DA:53,14
-FN:61,RuleEngineOperation.addRuleOperation
+DA:54,17
+DA:54,17
+DA:56,17
+DA:56,17
+DA:58,14
+DA:58,14
+FN:66,RuleEngineOperation.addRuleOperation
FNDA:68,RuleEngineOperation.addRuleOperation
-DA:62,68
-DA:62,68
-DA:63,66
-DA:63,66
-FN:76,RuleEngineOperation.removeRuleOperation
+DA:69,68
+DA:69,68
+DA:70,66
+DA:70,66
+FN:83,RuleEngineOperation.removeRuleOperation
FNDA:5,RuleEngineOperation.removeRuleOperation
-DA:80,5
-DA:80,5
-FN:93,RuleEngineOperation._removeRuleOperation
+DA:87,5
+DA:87,5
+FN:100,RuleEngineOperation._removeRuleOperation
FNDA:22,RuleEngineOperation._removeRuleOperation
-DA:97,22
-DA:97,22
-DA:98,21
-DA:98,21
-FN:104,RuleEngineOperation.rulesCountOperation
+DA:101,22
+DA:101,22
+DA:102,21
+DA:102,21
+FN:108,RuleEngineOperation.rulesCountOperation
FNDA:41,RuleEngineOperation.rulesCountOperation
-DA:105,41
-DA:105,41
-FN:112,RuleEngineOperation.getRuleIndexOperation
+DA:109,41
+DA:109,41
+FN:116,RuleEngineOperation.getRuleIndexOperation
FNDA:3,RuleEngineOperation.getRuleIndexOperation
-DA:113,3
-DA:113,3
-DA:113,3
-FN:121,RuleEngineOperation.ruleOperation
+DA:119,3
+DA:119,3
+DA:119,3
+FN:127,RuleEngineOperation.ruleOperation
FNDA:1,RuleEngineOperation.ruleOperation
-DA:122,1
-DA:122,1
-FN:129,RuleEngineOperation.rulesOperation
+DA:130,1
+DA:130,1
+FN:137,RuleEngineOperation.rulesOperation
FNDA:5,RuleEngineOperation.rulesOperation
-DA:130,5
-DA:130,5
-FN:140,RuleEngineOperation._operateOnTransfer
-FNDA:37,RuleEngineOperation._operateOnTransfer
-DA:145,37
-DA:145,37
-DA:146,37
-DA:146,37
-DA:146,53
-DA:146,16
-DA:147,33
-DA:147,33
-DA:147,33
-DA:152,33
-DA:152,33
-BRDA:152,1,0,17
-BRDA:152,1,1,16
-DA:153,17
-DA:153,17
-DA:156,20
-DA:156,20
+DA:143,5
+DA:143,5
+FN:152,RuleEngineOperation._operateOnTransfer
+FNDA:41,RuleEngineOperation._operateOnTransfer
+DA:157,41
+DA:157,41
+DA:158,41
+DA:158,41
+DA:158,57
+DA:158,16
+DA:159,33
+DA:159,33
+DA:159,33
+DA:164,33
+DA:164,33
+BRDA:164,1,0,17
+BRDA:164,1,1,16
+DA:165,17
+DA:165,17
+DA:168,24
+DA:168,24
FNF:11
FNH:11
LF:25
@@ -285,192 +287,203 @@ BRH:4
end_of_record
TN:
SF:src/modules/RuleEngineValidation.sol
-FN:24,RuleEngineValidation.setRulesValidation
-FNDA:22,RuleEngineValidation.setRulesValidation
-DA:27,21
-DA:27,21
-BRDA:27,0,0,20
-BRDA:27,0,1,21
-DA:28,20
-DA:28,20
+FN:29,RuleEngineValidation.detectTransferRestrictionValidation
+FNDA:3,RuleEngineValidation.detectTransferRestrictionValidation
+DA:34,82
+DA:34,82
+DA:35,82
+DA:35,82
+DA:35,97
+DA:35,15
+DA:36,43
+DA:36,43
+DA:36,43
+DA:38,43
+DA:38,43
+BRDA:38,0,0,28
+BRDA:38,0,1,15
+DA:39,28
+DA:39,28
+DA:43,54
+DA:43,54
+DA:43,54
+FN:53,RuleEngineValidation.validateTransferValidation
+FNDA:2,RuleEngineValidation.validateTransferValidation
+DA:58,53
+DA:58,53
+DA:59,53
+DA:59,53
+DA:59,53
+DA:60,53
+DA:60,53
+FNF:2
+FNH:2
+LF:9
+LH:9
+BRF:2
+BRH:2
+end_of_record
+TN:
+SF:src/modules/RuleEngineValidationCommon.sol
+FN:27,RuleEngineValidationCommon.setRulesValidation
+FNDA:22,RuleEngineValidationCommon.setRulesValidation
DA:30,21
DA:30,21
-DA:31,18
-DA:31,18
-FN:38,RuleEngineValidation.clearRulesValidation
-FNDA:6,RuleEngineValidation.clearRulesValidation
-DA:39,5
-DA:39,5
-FN:46,RuleEngineValidation._clearRulesValidation
-FNDA:25,RuleEngineValidation._clearRulesValidation
-DA:47,25
-DA:47,25
-DA:49,25
-DA:49,25
-DA:49,53
-DA:49,28
+BRDA:30,0,0,20
+BRDA:30,0,1,21
+DA:31,20
+DA:31,20
+DA:33,21
+DA:33,21
+DA:34,18
+DA:34,18
+FN:41,RuleEngineValidationCommon.clearRulesValidation
+FNDA:6,RuleEngineValidationCommon.clearRulesValidation
+DA:42,5
+DA:42,5
+FN:49,RuleEngineValidationCommon._clearRulesValidation
+FNDA:25,RuleEngineValidationCommon._clearRulesValidation
+DA:50,25
+DA:50,25
+DA:52,25
+DA:52,25
+DA:52,53
DA:52,28
-DA:52,28
-DA:54,28
-DA:54,28
-DA:56,25
-DA:56,25
-FN:64,RuleEngineValidation.addRuleValidation
-FNDA:67,RuleEngineValidation.addRuleValidation
-DA:65,66
-DA:65,66
-DA:66,64
-DA:66,64
-FN:79,RuleEngineValidation.removeRuleValidation
-FNDA:6,RuleEngineValidation.removeRuleValidation
-DA:83,5
-DA:83,5
-FN:96,RuleEngineValidation._removeRuleValidation
-FNDA:33,RuleEngineValidation._removeRuleValidation
-DA:100,33
-DA:100,33
-DA:101,32
-DA:101,32
-FN:107,RuleEngineValidation.rulesCountValidation
-FNDA:69,RuleEngineValidation.rulesCountValidation
-DA:108,69
-DA:108,69
-FN:115,RuleEngineValidation.getRuleIndexValidation
-FNDA:3,RuleEngineValidation.getRuleIndexValidation
-DA:116,3
-DA:116,3
-DA:116,3
-FN:124,RuleEngineValidation.ruleValidation
-FNDA:1,RuleEngineValidation.ruleValidation
-DA:125,1
-DA:125,1
-FN:132,RuleEngineValidation.rulesValidation
-FNDA:5,RuleEngineValidation.rulesValidation
-DA:133,5
-DA:133,5
-FN:143,RuleEngineValidation.detectTransferRestrictionValidation
-FNDA:3,RuleEngineValidation.detectTransferRestrictionValidation
-DA:148,71
-DA:148,71
-DA:149,71
-DA:149,71
-DA:149,81
-DA:149,10
-DA:150,32
-DA:150,32
-DA:150,32
-DA:155,32
-DA:155,32
-BRDA:155,1,0,22
-BRDA:155,1,1,10
-DA:156,22
-DA:156,22
-DA:160,49
-DA:160,49
-DA:160,49
-FN:170,RuleEngineValidation.validateTransferValidation
-FNDA:2,RuleEngineValidation.validateTransferValidation
-DA:175,46
-DA:175,46
-DA:175,46
-DA:175,46
-DA:175,46
-FNF:12
-FNH:12
-LF:26
-LH:26
-BRF:4
-BRH:4
+DA:55,28
+DA:55,28
+DA:57,28
+DA:57,28
+DA:59,25
+DA:59,25
+FN:67,RuleEngineValidationCommon.addRuleValidation
+FNDA:115,RuleEngineValidationCommon.addRuleValidation
+DA:70,114
+DA:70,114
+DA:71,112
+DA:71,112
+FN:84,RuleEngineValidationCommon.removeRuleValidation
+FNDA:6,RuleEngineValidationCommon.removeRuleValidation
+DA:88,5
+DA:88,5
+FN:101,RuleEngineValidationCommon._removeRuleValidation
+FNDA:33,RuleEngineValidationCommon._removeRuleValidation
+DA:102,33
+DA:102,33
+DA:103,32
+DA:103,32
+FN:109,RuleEngineValidationCommon.rulesCountValidation
+FNDA:69,RuleEngineValidationCommon.rulesCountValidation
+DA:110,69
+DA:110,69
+FN:117,RuleEngineValidationCommon.getRuleIndexValidation
+FNDA:3,RuleEngineValidationCommon.getRuleIndexValidation
+DA:120,3
+DA:120,3
+DA:120,3
+FN:128,RuleEngineValidationCommon.ruleValidation
+FNDA:1,RuleEngineValidationCommon.ruleValidation
+DA:131,1
+DA:131,1
+FN:138,RuleEngineValidationCommon.rulesValidation
+FNDA:5,RuleEngineValidationCommon.rulesValidation
+DA:144,5
+DA:144,5
+FNF:10
+FNH:10
+LF:19
+LH:19
+BRF:2
+BRH:2
end_of_record
TN:
SF:src/modules/RuleInternal.sol
-FN:20,RuleInternal._setRules
+FN:19,RuleInternal._setRules
FNDA:32,RuleInternal._setRules
-DA:23,32
-DA:23,32
-BRDA:23,0,0,2
-BRDA:23,0,1,30
-DA:24,2
-DA:24,2
-DA:26,30
-DA:26,30
-DA:26,74
-DA:27,48
-DA:27,48
-DA:27,48
-DA:27,48
-BRDA:27,1,0,2
-BRDA:27,1,1,46
+DA:20,32
+DA:20,32
+BRDA:20,0,0,2
+BRDA:20,0,1,30
+DA:21,2
+DA:21,2
+DA:23,30
+DA:23,30
+DA:23,74
+DA:24,48
+DA:24,48
+DA:24,48
+DA:24,48
+BRDA:24,1,0,2
+BRDA:24,1,1,46
+DA:25,2
+DA:25,2
+DA:27,46
+BRDA:27,2,0,2
+BRDA:27,2,1,44
DA:28,2
DA:28,2
-DA:30,46
-BRDA:30,2,0,2
-BRDA:30,2,1,44
-DA:31,2
-DA:31,2
+DA:30,44
+DA:30,44
+DA:31,44
+DA:31,44
DA:33,44
DA:33,44
-DA:34,44
-DA:34,44
-DA:36,44
-DA:36,44
-FN:46,RuleInternal._addRule
-FNDA:134,RuleInternal._addRule
-DA:47,134
-DA:47,134
-DA:47,134
-DA:47,134
-BRDA:47,3,0,2
-BRDA:47,3,1,132
-DA:49,2
-DA:49,2
-DA:51,132
-BRDA:51,4,0,2
-BRDA:51,4,1,130
-DA:53,2
-DA:53,2
-DA:55,130
-DA:55,130
-DA:56,130
-DA:56,130
-FN:69,RuleInternal._removeRule
+FN:43,RuleInternal._addRule
+FNDA:182,RuleInternal._addRule
+DA:44,182
+DA:44,182
+DA:44,182
+DA:44,182
+BRDA:44,3,0,2
+BRDA:44,3,1,180
+DA:45,2
+DA:45,2
+DA:47,180
+BRDA:47,4,0,2
+BRDA:47,4,1,178
+DA:48,2
+DA:48,2
+DA:50,178
+DA:50,178
+DA:51,178
+DA:51,178
+FN:64,RuleInternal._removeRule
FNDA:55,RuleInternal._removeRule
-DA:74,55
-DA:74,55
-BRDA:74,5,0,2
-BRDA:74,5,1,53
-DA:76,2
-DA:76,2
-DA:78,53
-DA:78,53
-DA:78,53
-BRDA:78,6,0,-
-BRDA:78,6,1,4
-DA:79,4
-DA:79,4
-DA:81,53
-DA:81,53
-DA:82,53
-DA:82,53
-DA:83,53
-DA:83,53
-FN:90,RuleInternal.getRuleIndex
+DA:69,55
+DA:69,55
+BRDA:69,5,0,2
+BRDA:69,5,1,53
+DA:70,2
+DA:70,2
+DA:72,53
+DA:72,53
+DA:72,53
+BRDA:72,6,0,-
+BRDA:72,6,1,4
+DA:73,4
+DA:73,4
+DA:75,53
+DA:75,53
+DA:76,53
+DA:76,53
+DA:77,53
+DA:77,53
+FN:84,RuleInternal.getRuleIndex
FNDA:6,RuleInternal.getRuleIndex
-DA:91,6
-DA:91,6
-DA:92,6
-DA:92,6
-DA:92,12
-DA:93,10
-DA:93,10
-BRDA:93,7,0,4
-BRDA:93,7,1,6
-DA:94,4
-DA:94,4
-DA:97,6
-DA:97,6
-DA:100,2
-DA:100,2
+DA:88,6
+DA:88,6
+DA:89,6
+DA:89,6
+DA:89,12
+DA:90,10
+DA:90,10
+BRDA:90,7,0,4
+BRDA:90,7,1,6
+DA:91,4
+DA:91,4
+DA:94,6
+DA:94,6
+DA:97,2
+DA:97,2
FNF:4
FNH:4
LF:29
@@ -480,147 +493,134 @@ BRH:15
end_of_record
TN:
SF:src/rules/operation/RuleConditionalTransfer.sol
-FN:50,RuleConditionalTransfer.createTransferRequest
+FN:55,RuleConditionalTransfer.createTransferRequest
FNDA:102,RuleConditionalTransfer.createTransferRequest
-DA:56,105
-DA:56,105
-DA:56,105
-DA:57,105
-DA:57,105
-DA:57,105
-DA:58,105
-DA:58,105
-BRDA:58,0,0,1
-BRDA:58,0,1,104
-DA:59,1
-DA:59,1
-DA:61,104
-DA:61,104
-BRDA:61,1,0,-
-BRDA:61,1,1,101
-DA:62,101
-DA:62,101
-DA:63,101
-DA:63,101
-DA:63,101
-DA:74,101
-DA:74,101
-DA:75,101
-DA:75,101
+DA:59,105
+DA:59,105
+DA:59,105
+DA:60,105
+DA:60,105
+DA:60,105
+DA:61,105
+DA:61,105
+BRDA:61,0,0,1
+BRDA:61,0,1,104
+DA:62,1
+DA:62,1
+DA:64,104
+DA:64,104
+BRDA:64,1,0,-
+BRDA:64,1,1,101
+DA:65,101
+DA:65,101
+DA:66,101
+DA:66,101
+DA:66,101
DA:76,101
DA:76,101
DA:77,101
DA:77,101
-DA:80,3
-DA:80,3
-DA:81,3
-DA:81,3
+DA:78,101
+DA:78,101
+DA:79,101
+DA:79,101
DA:82,3
DA:82,3
-FN:89,RuleConditionalTransfer.createTransferRequestBatch
+DA:83,3
+DA:83,3
+DA:84,3
+DA:84,3
+FN:97,RuleConditionalTransfer.createTransferRequestBatch
FNDA:3,RuleConditionalTransfer.createTransferRequestBatch
-DA:90,3
-DA:90,3
-BRDA:90,2,0,1
-BRDA:90,2,1,2
-DA:91,1
-DA:91,1
-DA:93,2
-DA:93,2
-BRDA:93,3,0,1
-BRDA:93,3,1,1
-DA:94,1
-DA:94,1
-DA:96,1
-DA:96,1
-DA:96,4
-DA:96,3
-DA:97,3
-DA:97,3
-FN:104,RuleConditionalTransfer.cancelTransferRequest
+DA:101,3
+DA:101,3
+BRDA:101,2,0,1
+BRDA:101,2,1,2
+DA:102,1
+DA:102,1
+DA:104,2
+DA:104,2
+BRDA:104,3,0,1
+BRDA:104,3,1,1
+DA:105,1
+DA:105,1
+DA:107,1
+DA:107,1
+DA:107,4
+DA:107,3
+DA:108,3
+DA:108,3
+FN:115,RuleConditionalTransfer.cancelTransferRequest
FNDA:6,RuleConditionalTransfer.cancelTransferRequest
-DA:107,6
-DA:107,6
-FN:113,RuleConditionalTransfer.cancelTransferRequestBatch
+DA:116,6
+DA:116,6
+FN:122,RuleConditionalTransfer.cancelTransferRequestBatch
FNDA:3,RuleConditionalTransfer.cancelTransferRequestBatch
-DA:116,3
-DA:116,3
-BRDA:116,4,0,1
-BRDA:116,4,1,2
-DA:117,1
-DA:117,1
-DA:120,2
-DA:120,2
-DA:120,6
-DA:120,4
-DA:121,5
-DA:121,5
-DA:121,5
-BRDA:121,5,0,1
-BRDA:121,5,1,4
-DA:122,1
-DA:122,1
-DA:125,1
-DA:125,1
-DA:125,4
-DA:125,3
-DA:126,3
-DA:126,3
-FN:131,RuleConditionalTransfer._cancelTransferRequest
+DA:123,3
+DA:123,3
+BRDA:123,4,0,1
+BRDA:123,4,1,2
+DA:124,1
+DA:124,1
+DA:127,2
+DA:127,2
+DA:127,6
+DA:127,4
+DA:128,5
+DA:128,5
+DA:128,5
+BRDA:128,5,0,1
+BRDA:128,5,1,4
+DA:129,1
+DA:129,1
+DA:132,1
+DA:132,1
+DA:132,4
+DA:132,3
+DA:133,3
+DA:133,3
+FN:137,RuleConditionalTransfer._cancelTransferRequest
FNDA:9,RuleConditionalTransfer._cancelTransferRequest
-DA:134,9
-DA:134,9
-DA:134,9
-BRDA:134,6,0,1
-BRDA:134,6,1,8
-DA:135,1
-DA:135,1
-DA:137,8
-DA:137,8
-DA:139,8
-DA:139,8
-DA:139,8
-BRDA:139,7,0,1
-BRDA:139,7,1,7
-DA:140,1
-DA:140,1
-DA:143,7
-DA:143,7
-DA:143,7
-DA:144,2
-DA:144,2
-BRDA:143,8,0,1
-BRDA:143,8,1,6
-DA:146,1
-DA:146,1
-DA:148,6
-DA:148,6
-FN:152,RuleConditionalTransfer.getRequestTrade
+DA:138,9
+DA:138,9
+DA:138,9
+BRDA:138,6,0,1
+BRDA:138,6,1,8
+DA:139,1
+DA:139,1
+DA:141,8
+DA:141,8
+DA:143,8
+DA:143,8
+DA:143,8
+BRDA:143,7,0,1
+BRDA:143,7,1,7
+DA:144,1
+DA:144,1
+DA:148,7
+DA:148,7
+DA:148,7
+DA:149,2
+DA:149,2
+BRDA:147,8,0,1
+BRDA:147,8,1,6
+DA:151,1
+DA:151,1
+DA:153,6
+DA:153,6
+FN:156,RuleConditionalTransfer.getRequestTrade
FNDA:57,RuleConditionalTransfer.getRequestTrade
-DA:153,57
-DA:153,57
-DA:153,57
-DA:154,57
-DA:154,57
-FN:162,RuleConditionalTransfer.getRequestByStatus
+DA:161,57
+DA:161,57
+DA:161,57
+DA:162,57
+DA:162,57
+FN:170,RuleConditionalTransfer.getRequestByStatus
FNDA:35,RuleConditionalTransfer.getRequestByStatus
-DA:163,35
-DA:163,35
-DA:164,35
-DA:164,35
-DA:165,35
-DA:165,35
-DA:168,35
-DA:168,35
-DA:168,73
-DA:168,38
-DA:169,38
-DA:169,38
-BRDA:169,9,0,36
-BRDA:169,9,1,38
-DA:170,36
-DA:170,36
-DA:175,35
+DA:173,35
+DA:173,35
+DA:174,35
+DA:174,35
DA:175,35
DA:175,35
DA:178,35
@@ -629,508 +629,525 @@ DA:178,73
DA:178,38
DA:179,38
DA:179,38
-BRDA:179,10,0,-
-BRDA:179,10,1,36
-DA:181,36
-DA:181,36
-DA:182,36
-DA:182,36
-DA:183,36
-DA:183,36
-DA:186,35
-DA:186,35
-FN:193,RuleConditionalTransfer.operateOnTransfer
+BRDA:179,9,0,36
+BRDA:179,9,1,38
+DA:180,36
+DA:180,36
+DA:185,35
+DA:185,35
+DA:185,35
+DA:188,35
+DA:188,35
+DA:188,73
+DA:188,38
+DA:189,38
+DA:189,38
+BRDA:189,10,0,-
+BRDA:189,10,1,36
+DA:191,36
+DA:191,36
+DA:194,36
+DA:194,36
+DA:195,36
+DA:195,36
+DA:198,35
+DA:198,35
+FN:205,RuleConditionalTransfer.operateOnTransfer
FNDA:33,RuleConditionalTransfer.operateOnTransfer
-DA:199,33
-DA:199,33
-DA:199,33
-DA:199,33
-BRDA:199,11,0,2
-BRDA:199,11,1,16
-DA:200,18
-DA:200,18
-DA:200,18
-DA:200,3
-BRDA:200,12,0,2
-BRDA:200,12,1,16
-DA:201,2
-DA:201,2
-DA:206,31
-DA:206,31
-BRDA:206,13,0,4
-BRDA:206,13,1,27
-DA:207,4
-DA:207,4
-DA:209,27
-DA:209,27
-DA:209,27
-DA:210,27
-DA:210,27
-BRDA:210,14,0,10
-BRDA:210,14,1,17
-DA:211,10
-DA:211,10
-DA:212,10
-DA:212,10
-DA:214,17
-DA:214,17
-FN:224,RuleConditionalTransfer.detectTransferRestriction
+DA:216,33
+DA:216,33
+DA:216,33
+DA:216,33
+BRDA:216,11,0,2
+BRDA:216,11,1,16
+DA:218,18
+DA:218,18
+DA:218,18
+DA:219,3
+DA:219,3
+BRDA:217,12,0,2
+BRDA:217,12,1,16
+DA:221,2
+DA:221,2
+DA:226,31
+DA:226,31
+BRDA:226,13,0,4
+BRDA:226,13,1,27
+DA:227,4
+DA:227,4
+DA:229,27
+DA:229,27
+DA:229,27
+DA:230,27
+DA:230,27
+BRDA:230,14,0,10
+BRDA:230,14,1,17
+DA:231,10
+DA:231,10
+DA:232,10
+DA:232,10
+DA:234,17
+DA:234,17
+FN:244,RuleConditionalTransfer.detectTransferRestriction
FNDA:11,RuleConditionalTransfer.detectTransferRestriction
-DA:230,11
-DA:230,11
-DA:230,11
-DA:230,11
-BRDA:230,15,0,-
-BRDA:230,15,1,1
-DA:231,3
-DA:231,3
-DA:231,3
-DA:231,2
-BRDA:231,16,0,-
-BRDA:231,16,1,1
-DA:232,1
-DA:232,1
-DA:232,1
-DA:235,10
-DA:235,10
-DA:235,10
-DA:236,10
-DA:236,10
-DA:236,10
-DA:236,10
-BRDA:236,17,0,8
-BRDA:236,17,1,2
-DA:237,8
-DA:237,8
-DA:240,2
-DA:240,2
-DA:240,2
-FN:249,RuleConditionalTransfer.canReturnTransferRestrictionCode
-FNDA:2,RuleConditionalTransfer.canReturnTransferRestrictionCode
-DA:252,2
-DA:252,2
+DA:250,11
+DA:250,11
+DA:250,11
+DA:250,11
+BRDA:250,15,0,-
+BRDA:250,15,1,1
+DA:252,3
+DA:252,3
+DA:252,3
DA:253,2
DA:253,2
-FN:261,RuleConditionalTransfer.messageForTransferRestriction
+BRDA:251,16,0,-
+BRDA:251,16,1,1
+DA:255,1
+DA:255,1
+DA:255,1
+DA:258,10
+DA:258,10
+DA:258,10
+DA:259,10
+DA:259,10
+DA:259,10
+DA:259,10
+BRDA:259,17,0,8
+BRDA:259,17,1,2
+DA:260,8
+DA:260,8
+DA:262,2
+DA:262,2
+DA:262,2
+FN:271,RuleConditionalTransfer.canReturnTransferRestrictionCode
+FNDA:2,RuleConditionalTransfer.canReturnTransferRestrictionCode
+DA:274,2
+DA:274,2
+DA:274,2
+FN:282,RuleConditionalTransfer.messageForTransferRestriction
FNDA:3,RuleConditionalTransfer.messageForTransferRestriction
-DA:264,3
-DA:264,3
-BRDA:264,18,0,2
-BRDA:264,18,1,1
-DA:265,2
-DA:265,2
-DA:267,1
-DA:267,1
-FN:278,RuleConditionalTransfer._validateBurnMint
+DA:285,3
+DA:285,3
+BRDA:285,18,0,2
+BRDA:285,18,1,1
+DA:286,2
+DA:286,2
+DA:288,1
+DA:288,1
+FN:299,RuleConditionalTransfer._validateBurnMint
FNDA:41,RuleConditionalTransfer._validateBurnMint
-DA:284,41
-DA:284,41
-BRDA:283,19,0,4
-BRDA:283,19,1,37
-DA:287,4
-DA:287,4
-DA:289,37
-DA:289,37
-FN:298,RuleConditionalTransfer._validateApproval
+DA:305,41
+DA:305,41
+BRDA:304,19,0,4
+BRDA:304,19,1,37
+DA:310,4
+DA:310,4
+DA:312,37
+DA:312,37
+FN:321,RuleConditionalTransfer._validateApproval
FNDA:37,RuleConditionalTransfer._validateApproval
-DA:301,37
-DA:301,37
-DA:301,37
-DA:302,37
-DA:302,37
-DA:302,37
-DA:304,37
-DA:304,37
-BRDA:304,20,0,12
-BRDA:304,20,1,25
-DA:306,12
-DA:306,12
-DA:308,25
-DA:308,25
-FN:315,RuleConditionalTransfer._msgSender
+DA:324,37
+DA:324,37
+DA:324,37
+DA:330,37
+DA:330,37
+DA:330,37
+DA:333,37
+DA:333,37
+BRDA:333,20,0,12
+BRDA:333,20,1,25
+DA:334,12
+DA:334,12
+DA:336,25
+DA:336,25
+FN:343,RuleConditionalTransfer._msgSender
FNDA:452,RuleConditionalTransfer._msgSender
-DA:321,452
-DA:321,452
-DA:321,452
-FN:327,RuleConditionalTransfer._msgData
+DA:349,452
+DA:349,452
+DA:349,452
+FN:355,RuleConditionalTransfer._msgData
FNDA:0,RuleConditionalTransfer._msgData
-DA:333,0
-DA:333,0
-DA:333,0
-FN:339,RuleConditionalTransfer._contextSuffixLength
+DA:361,0
+DA:361,0
+DA:361,0
+FN:367,RuleConditionalTransfer._contextSuffixLength
FNDA:452,RuleConditionalTransfer._contextSuffixLength
-DA:340,452
-DA:340,452
-DA:340,452
+DA:373,452
+DA:373,452
+DA:373,452
FNF:16
FNH:15
-LF:85
-LH:84
+LF:86
+LH:85
BRF:42
BRH:38
end_of_record
TN:
SF:src/rules/operation/abstract/RuleConditionalTransferOperator.sol
-FN:25,RuleConditionalTransferOperator.setConditionalWhitelist
+FN:29,RuleConditionalTransferOperator.setConditionalWhitelist
FNDA:25,RuleConditionalTransferOperator.setConditionalWhitelist
-DA:26,25
-DA:26,25
-DA:27,25
-DA:27,25
-FN:33,RuleConditionalTransferOperator.setIssuanceOptions
+DA:32,25
+DA:32,25
+DA:33,25
+DA:33,25
+FN:39,RuleConditionalTransferOperator.setIssuanceOptions
FNDA:5,RuleConditionalTransferOperator.setIssuanceOptions
-DA:34,4
-DA:34,4
-BRDA:34,0,0,2
-BRDA:34,0,1,4
-DA:35,2
-DA:35,2
-DA:37,4
-DA:37,4
-BRDA:37,1,0,2
-BRDA:37,1,1,4
-DA:38,2
-DA:38,2
-FN:47,RuleConditionalTransferOperator.setAutomaticTransfer
-FNDA:3,RuleConditionalTransferOperator.setAutomaticTransfer
-DA:48,2
-DA:48,2
-BRDA:48,2,0,2
-BRDA:48,2,1,2
-DA:49,2
-DA:49,2
-DA:52,2
-DA:52,2
-DA:52,2
-DA:52,2
-BRDA:52,3,0,2
-BRDA:52,3,1,2
+DA:43,4
+DA:43,4
+BRDA:42,0,0,2
+BRDA:42,0,1,4
+DA:46,2
+DA:46,2
+DA:50,4
+DA:50,4
+BRDA:49,1,0,2
+BRDA:49,1,1,4
DA:53,2
DA:53,2
-FN:62,RuleConditionalTransferOperator.setTimeLimit
+FN:63,RuleConditionalTransferOperator.setAutomaticTransfer
+FNDA:3,RuleConditionalTransferOperator.setAutomaticTransfer
+DA:67,2
+DA:67,2
+BRDA:66,2,0,2
+BRDA:66,2,1,2
+DA:70,2
+DA:70,2
+DA:75,2
+DA:75,2
+DA:75,2
+DA:76,2
+DA:76,2
+BRDA:74,3,0,2
+BRDA:74,3,1,2
+DA:78,2
+DA:78,2
+FN:87,RuleConditionalTransferOperator.setTimeLimit
FNDA:4,RuleConditionalTransferOperator.setTimeLimit
-DA:63,3
-DA:63,3
-BRDA:63,4,0,3
-BRDA:63,4,1,3
-DA:64,3
-DA:64,3
-DA:66,3
-DA:66,3
-BRDA:66,5,0,3
-BRDA:66,5,1,3
-DA:67,3
-DA:67,3
-FN:75,RuleConditionalTransferOperator.setAutomaticApproval
+DA:91,3
+DA:91,3
+BRDA:90,4,0,3
+BRDA:90,4,1,3
+DA:94,3
+DA:94,3
+DA:98,3
+DA:98,3
+BRDA:97,5,0,3
+BRDA:97,5,1,3
+DA:101,3
+DA:101,3
+FN:111,RuleConditionalTransferOperator.setAutomaticApproval
FNDA:5,RuleConditionalTransferOperator.setAutomaticApproval
-DA:76,4
-DA:76,4
-BRDA:76,6,0,4
-BRDA:76,6,1,4
-DA:77,4
-DA:77,4
-DA:79,4
-DA:79,4
-BRDA:79,7,0,4
-BRDA:79,7,1,4
-DA:80,4
-DA:80,4
-FN:87,RuleConditionalTransferOperator.createTransferRequestWithApproval
+DA:115,4
+DA:115,4
+BRDA:114,6,0,4
+BRDA:114,6,1,4
+DA:118,4
+DA:118,4
+DA:122,4
+DA:122,4
+BRDA:121,7,0,4
+BRDA:121,7,1,4
+DA:125,4
+DA:125,4
+FN:135,RuleConditionalTransferOperator.createTransferRequestWithApproval
FNDA:6,RuleConditionalTransferOperator.createTransferRequestWithApproval
-DA:90,5
-DA:90,5
-FN:99,RuleConditionalTransferOperator.approveTransferRequest
-FNDA:33,RuleConditionalTransferOperator.approveTransferRequest
-DA:102,32
-DA:102,32
-FN:108,RuleConditionalTransferOperator.approveTransferRequestWithId
-FNDA:5,RuleConditionalTransferOperator.approveTransferRequestWithId
-DA:111,4
-DA:111,4
-DA:111,4
-BRDA:111,8,0,2
-BRDA:111,8,1,2
-DA:112,2
-DA:112,2
-DA:114,2
-DA:114,2
-DA:115,2
-DA:115,2
-FN:121,RuleConditionalTransferOperator.resetRequestStatus
-FNDA:3,RuleConditionalTransferOperator.resetRequestStatus
-DA:124,2
-DA:124,2
-DA:124,2
-BRDA:124,9,0,1
-BRDA:124,9,1,1
-DA:125,1
-DA:125,1
-DA:127,1
-DA:127,1
-DA:128,1
-DA:128,1
-FN:135,RuleConditionalTransferOperator.approveTransferRequestBatchWithId
-FNDA:7,RuleConditionalTransferOperator.approveTransferRequestBatchWithId
DA:138,5
DA:138,5
-BRDA:138,10,0,1
-BRDA:138,10,1,4
-DA:139,1
-DA:139,1
-DA:141,4
-DA:141,4
-BRDA:141,11,0,1
-BRDA:141,11,1,3
-DA:142,1
-DA:142,1
-DA:145,3
-DA:145,3
-DA:145,13
-DA:145,10
-DA:146,11
-DA:146,11
-DA:146,11
-BRDA:146,12,0,1
-BRDA:146,12,1,10
-DA:147,1
-DA:147,1
-DA:150,2
-DA:150,2
-DA:150,6
-DA:150,4
-DA:151,5
-DA:151,5
-DA:152,5
-DA:152,5
-FN:159,RuleConditionalTransferOperator.approveTransferRequestBatch
-FNDA:7,RuleConditionalTransferOperator.approveTransferRequestBatch
-DA:162,6
-DA:162,6
-BRDA:162,13,0,1
-BRDA:162,13,1,5
-DA:163,1
-DA:163,1
-DA:165,5
-DA:165,5
-BRDA:165,14,0,3
-BRDA:165,14,1,2
-DA:166,3
-DA:166,3
+FN:147,RuleConditionalTransferOperator.approveTransferRequest
+FNDA:33,RuleConditionalTransferOperator.approveTransferRequest
+DA:152,32
+DA:152,32
+FN:158,RuleConditionalTransferOperator.approveTransferRequestWithId
+FNDA:5,RuleConditionalTransferOperator.approveTransferRequestWithId
+DA:162,4
+DA:162,4
+DA:162,4
+BRDA:162,8,0,2
+BRDA:162,8,1,2
+DA:163,2
+DA:163,2
+DA:165,2
+DA:165,2
DA:168,2
DA:168,2
-DA:168,11
-DA:168,9
-DA:169,9
-DA:169,9
-FN:176,RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch
-FNDA:3,RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch
-DA:179,2
-DA:179,2
-BRDA:179,15,0,1
-BRDA:179,15,1,1
+FN:174,RuleConditionalTransferOperator.resetRequestStatus
+FNDA:3,RuleConditionalTransferOperator.resetRequestStatus
+DA:177,2
+DA:177,2
+DA:177,2
+BRDA:177,9,0,1
+BRDA:177,9,1,1
+DA:178,1
+DA:178,1
DA:180,1
DA:180,1
-DA:182,1
-DA:182,1
-DA:182,5
-DA:182,4
-DA:183,4
-DA:183,4
-FN:190,RuleConditionalTransferOperator.resetRequestStatusBatch
+DA:181,1
+DA:181,1
+FN:188,RuleConditionalTransferOperator.approveTransferRequestBatchWithId
+FNDA:7,RuleConditionalTransferOperator.approveTransferRequestBatchWithId
+DA:192,5
+DA:192,5
+BRDA:192,10,0,1
+BRDA:192,10,1,4
+DA:193,1
+DA:193,1
+DA:195,4
+DA:195,4
+BRDA:195,11,0,1
+BRDA:195,11,1,3
+DA:196,1
+DA:196,1
+DA:199,3
+DA:199,3
+DA:199,13
+DA:199,10
+DA:200,11
+DA:200,11
+DA:200,11
+BRDA:200,12,0,1
+BRDA:200,12,1,10
+DA:201,1
+DA:201,1
+DA:204,2
+DA:204,2
+DA:204,6
+DA:204,4
+DA:205,5
+DA:205,5
+DA:208,5
+DA:208,5
+FN:215,RuleConditionalTransferOperator.approveTransferRequestBatch
+FNDA:7,RuleConditionalTransferOperator.approveTransferRequestBatch
+DA:220,6
+DA:220,6
+BRDA:220,13,0,1
+BRDA:220,13,1,5
+DA:221,1
+DA:221,1
+DA:224,5
+DA:224,5
+BRDA:223,14,0,3
+BRDA:223,14,1,2
+DA:227,3
+DA:227,3
+DA:229,2
+DA:229,2
+DA:229,11
+DA:229,9
+DA:230,9
+DA:230,9
+FN:241,RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch
+FNDA:3,RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch
+DA:244,2
+DA:244,2
+BRDA:244,15,0,1
+BRDA:244,15,1,1
+DA:245,1
+DA:245,1
+DA:247,1
+DA:247,1
+DA:247,5
+DA:247,4
+DA:248,4
+DA:248,4
+FN:255,RuleConditionalTransferOperator.resetRequestStatusBatch
FNDA:3,RuleConditionalTransferOperator.resetRequestStatusBatch
-DA:193,3
-DA:193,3
-BRDA:193,16,0,1
-BRDA:193,16,1,2
-DA:194,1
-DA:194,1
-DA:197,2
-DA:197,2
-DA:197,5
-DA:197,3
-DA:198,4
-DA:198,4
-DA:198,4
-BRDA:198,17,0,1
-BRDA:198,17,1,3
-DA:199,1
-DA:199,1
-DA:202,1
-DA:202,1
-DA:202,4
-DA:202,3
-DA:203,3
-DA:203,3
-DA:204,3
-DA:204,3
-FN:210,RuleConditionalTransferOperator._approveTransferRequestKeyElement
+DA:258,3
+DA:258,3
+BRDA:258,16,0,1
+BRDA:258,16,1,2
+DA:259,1
+DA:259,1
+DA:262,2
+DA:262,2
+DA:262,5
+DA:262,3
+DA:263,4
+DA:263,4
+DA:263,4
+BRDA:263,17,0,1
+BRDA:263,17,1,3
+DA:264,1
+DA:264,1
+DA:267,1
+DA:267,1
+DA:267,4
+DA:267,3
+DA:268,3
+DA:268,3
+DA:269,3
+DA:269,3
+FN:274,RuleConditionalTransferOperator._approveTransferRequestKeyElement
FNDA:41,RuleConditionalTransferOperator._approveTransferRequestKeyElement
-DA:213,41
-DA:213,41
-BRDA:213,18,0,1
-BRDA:213,18,1,40
-DA:214,1
-DA:214,1
-DA:216,40
-DA:216,40
-DA:216,40
-DA:217,40
-DA:217,40
-DA:218,40
-DA:218,40
-BRDA:218,19,0,1
-BRDA:218,19,1,6
-DA:219,7
-DA:219,7
-BRDA:219,20,0,1
-BRDA:219,20,1,6
-DA:220,1
-DA:220,1
-DA:223,6
-DA:223,6
-DA:225,6
-DA:225,6
-DA:227,33
-DA:227,33
-FN:231,RuleConditionalTransferOperator._createTransferRequestWithApproval
+DA:279,41
+DA:279,41
+BRDA:279,18,0,1
+BRDA:279,18,1,40
+DA:280,1
+DA:280,1
+DA:282,40
+DA:282,40
+DA:282,40
+DA:285,40
+DA:285,40
+DA:286,40
+DA:286,40
+BRDA:286,19,0,1
+BRDA:286,19,1,6
+DA:287,7
+DA:287,7
+BRDA:287,20,0,1
+BRDA:287,20,1,6
+DA:288,1
+DA:288,1
+DA:291,6
+DA:291,6
+DA:293,6
+DA:293,6
+DA:301,33
+DA:301,33
+FN:305,RuleConditionalTransferOperator._createTransferRequestWithApproval
FNDA:0,RuleConditionalTransferOperator._createTransferRequestWithApproval
-DA:237,15
-DA:237,15
-DA:237,15
-DA:238,15
-DA:238,15
-BRDA:238,21,0,-
-BRDA:238,21,1,14
-DA:239,14
-DA:239,14
-DA:239,14
-DA:249,14
-DA:249,14
-DA:250,14
-DA:250,14
-DA:251,14
-DA:251,14
-DA:252,14
-DA:252,14
-DA:255,1
-DA:255,1
-DA:256,1
-DA:256,1
-DA:257,1
-DA:257,1
-FN:261,RuleConditionalTransferOperator._resetRequestStatus
+DA:311,15
+DA:311,15
+DA:311,15
+DA:314,15
+DA:314,15
+BRDA:314,21,0,-
+BRDA:314,21,1,14
+DA:315,14
+DA:315,14
+DA:315,14
+DA:326,14
+DA:326,14
+DA:327,14
+DA:327,14
+DA:328,14
+DA:328,14
+DA:335,14
+DA:335,14
+DA:338,1
+DA:338,1
+DA:341,1
+DA:341,1
+DA:342,1
+DA:342,1
+FN:352,RuleConditionalTransferOperator._resetRequestStatus
FNDA:10,RuleConditionalTransferOperator._resetRequestStatus
-DA:264,10
-DA:264,10
-DA:265,10
-DA:265,10
-FN:268,RuleConditionalTransferOperator._checkRequestStatus
+DA:353,10
+DA:353,10
+DA:354,10
+DA:354,10
+FN:363,RuleConditionalTransferOperator._checkRequestStatus
FNDA:119,RuleConditionalTransferOperator._checkRequestStatus
-DA:270,119
-DA:270,119
-DA:270,119
-FN:273,RuleConditionalTransferOperator._approveRequest
+DA:365,119
+DA:365,119
+DA:366,119
+DA:366,119
+FN:370,RuleConditionalTransferOperator._approveRequest
FNDA:46,RuleConditionalTransferOperator._approveRequest
-DA:275,46
-DA:275,46
-BRDA:275,22,0,1
-BRDA:275,22,1,45
-DA:276,1
-DA:276,1
-DA:278,45
-BRDA:278,23,0,2
-BRDA:278,23,1,2
-DA:280,27
-DA:280,27
-BRDA:280,24,0,3
-BRDA:280,24,1,24
-DA:281,3
-DA:281,3
-DA:284,24
-DA:284,24
-DA:286,24
-DA:286,24
-DA:287,24
-DA:287,24
-DA:288,24
-DA:288,24
-DA:288,2
-DA:288,2
-DA:288,2
-BRDA:288,25,0,2
-BRDA:288,25,1,2
-DA:291,2
-DA:291,2
-DA:291,2
-BRDA:291,26,0,2
-BRDA:291,26,1,2
-DA:293,2
-DA:293,2
-DA:297,18
-DA:297,18
-DA:298,18
-DA:298,18
-FN:305,RuleConditionalTransferOperator._updateProcessedTransfer
+DA:375,46
+DA:375,46
+BRDA:375,22,0,1
+BRDA:375,22,1,45
+DA:376,1
+DA:376,1
+DA:378,45
+BRDA:378,23,0,2
+BRDA:378,23,1,2
+DA:381,27
+DA:381,27
+BRDA:380,24,0,3
+BRDA:380,24,1,24
+DA:384,3
+DA:384,3
+DA:387,24
+DA:387,24
+DA:389,24
+DA:389,24
+DA:392,24
+DA:392,24
+DA:400,24
+DA:400,24
+DA:401,2
+DA:401,2
+DA:401,2
+DA:401,2
+BRDA:399,25,0,2
+BRDA:399,25,1,2
+DA:406,2
+DA:406,2
+DA:406,2
+BRDA:405,26,0,2
+BRDA:405,26,1,2
+DA:412,2
+DA:412,2
+DA:420,18
+DA:420,18
+DA:421,18
+DA:421,18
+FN:434,RuleConditionalTransferOperator._updateProcessedTransfer
FNDA:10,RuleConditionalTransferOperator._updateProcessedTransfer
-DA:307,10
-DA:307,10
-DA:308,10
-DA:308,10
-DA:310,10
-DA:310,10
-DA:312,10
-DA:312,10
+DA:436,10
+DA:436,10
+DA:437,10
+DA:437,10
+DA:439,10
+DA:439,10
+DA:441,10
+DA:441,10
FNF:19
FNH:18
-LF:96
-LH:96
+LF:99
+LH:99
BRF:54
BRH:53
end_of_record
TN:
SF:src/rules/validation/RuleBlacklist.sol
-FN:29,RuleBlacklist.detectTransferRestriction
+FN:33,RuleBlacklist.detectTransferRestriction
FNDA:10,RuleBlacklist.detectTransferRestriction
-DA:34,10
-DA:34,10
-BRDA:34,0,0,5
-BRDA:34,0,1,5
-DA:35,5
-DA:35,5
-DA:36,5
-DA:36,5
-BRDA:36,1,0,2
-BRDA:36,1,1,3
-DA:37,2
-DA:37,2
-DA:39,3
-DA:39,3
-DA:39,3
-FN:48,RuleBlacklist.canReturnTransferRestrictionCode
+DA:38,10
+DA:38,10
+BRDA:38,0,0,5
+BRDA:38,0,1,5
+DA:39,5
+DA:39,5
+DA:40,5
+DA:40,5
+BRDA:40,1,0,2
+BRDA:40,1,1,3
+DA:41,2
+DA:41,2
+DA:43,3
+DA:43,3
+DA:43,3
+FN:52,RuleBlacklist.canReturnTransferRestrictionCode
FNDA:4,RuleBlacklist.canReturnTransferRestrictionCode
-DA:51,4
-DA:51,4
-DA:52,4
-DA:52,4
-DA:52,4
-DA:53,2
-DA:53,2
-FN:61,RuleBlacklist.messageForTransferRestriction
+DA:55,4
+DA:55,4
+DA:56,4
+DA:56,4
+DA:56,4
+DA:57,2
+DA:57,2
+FN:65,RuleBlacklist.messageForTransferRestriction
FNDA:4,RuleBlacklist.messageForTransferRestriction
-DA:64,4
-DA:64,4
-BRDA:64,2,0,2
-BRDA:64,2,1,2
-DA:65,2
-DA:65,2
-DA:66,2
-DA:66,2
-BRDA:66,3,0,1
-BRDA:66,3,1,1
-DA:67,1
-DA:67,1
-DA:69,1
-DA:69,1
+DA:68,4
+DA:68,4
+BRDA:68,2,0,2
+BRDA:68,2,1,2
+DA:69,2
+DA:69,2
+DA:70,2
+DA:70,2
+BRDA:70,3,0,1
+BRDA:70,3,1,1
+DA:71,1
+DA:71,1
+DA:73,1
+DA:73,1
FNF:3
FNH:3
LF:13
@@ -1140,73 +1157,73 @@ BRH:8
end_of_record
TN:
SF:src/rules/validation/RuleSanctionList.sol
-FN:36,RuleSanctionList.setSanctionListOracle
+FN:42,RuleSanctionList.setSanctionListOracle
FNDA:10,RuleSanctionList.setSanctionListOracle
-DA:39,9
-DA:39,9
-FN:48,RuleSanctionList.detectTransferRestriction
+DA:45,9
+DA:45,9
+FN:54,RuleSanctionList.detectTransferRestriction
FNDA:7,RuleSanctionList.detectTransferRestriction
-DA:53,7
-DA:53,7
-DA:53,7
-DA:53,7
-BRDA:53,0,0,2
-BRDA:53,0,1,3
-DA:54,7
-DA:54,7
-BRDA:54,1,0,2
-BRDA:54,1,1,5
-DA:55,2
-DA:55,2
-DA:56,5
-DA:56,5
-BRDA:56,2,0,2
-BRDA:56,2,1,3
-DA:57,2
-DA:57,2
-DA:60,3
-DA:60,3
-DA:60,3
-FN:68,RuleSanctionList.canReturnTransferRestrictionCode
+DA:59,7
+DA:59,7
+DA:59,7
+DA:59,7
+BRDA:59,0,0,2
+BRDA:59,0,1,3
+DA:60,7
+DA:60,7
+BRDA:60,1,0,2
+BRDA:60,1,1,5
+DA:61,2
+DA:61,2
+DA:62,5
+DA:62,5
+BRDA:62,2,0,2
+BRDA:62,2,1,3
+DA:63,2
+DA:63,2
+DA:66,3
+DA:66,3
+DA:66,3
+FN:74,RuleSanctionList.canReturnTransferRestrictionCode
FNDA:3,RuleSanctionList.canReturnTransferRestrictionCode
-DA:71,3
-DA:71,3
-DA:72,3
-DA:72,3
-DA:72,3
-DA:73,2
-DA:73,2
-FN:81,RuleSanctionList.messageForTransferRestriction
+DA:77,3
+DA:77,3
+DA:78,3
+DA:78,3
+DA:78,3
+DA:79,2
+DA:79,2
+FN:87,RuleSanctionList.messageForTransferRestriction
FNDA:3,RuleSanctionList.messageForTransferRestriction
-DA:84,3
-DA:84,3
-BRDA:84,3,0,1
-BRDA:84,3,1,2
-DA:85,1
-DA:85,1
-DA:86,2
-DA:86,2
-BRDA:86,4,0,1
-BRDA:86,4,1,1
-DA:87,1
-DA:87,1
-DA:89,1
-DA:89,1
-FN:96,RuleSanctionList._msgSender
+DA:90,3
+DA:90,3
+BRDA:90,3,0,1
+BRDA:90,3,1,2
+DA:91,1
+DA:91,1
+DA:92,2
+DA:92,2
+BRDA:92,4,0,1
+BRDA:92,4,1,1
+DA:93,1
+DA:93,1
+DA:95,1
+DA:95,1
+FN:102,RuleSanctionList._msgSender
FNDA:10,RuleSanctionList._msgSender
-DA:102,10
-DA:102,10
-DA:102,10
-FN:108,RuleSanctionList._msgData
+DA:108,10
+DA:108,10
+DA:108,10
+FN:114,RuleSanctionList._msgData
FNDA:0,RuleSanctionList._msgData
-DA:114,0
-DA:114,0
-DA:114,0
-FN:120,RuleSanctionList._contextSuffixLength
+DA:120,0
+DA:120,0
+DA:120,0
+FN:126,RuleSanctionList._contextSuffixLength
FNDA:10,RuleSanctionList._contextSuffixLength
-DA:121,10
-DA:121,10
-DA:121,10
+DA:132,10
+DA:132,10
+DA:132,10
FNF:7
FNH:6
LF:18
@@ -1216,48 +1233,48 @@ BRH:10
end_of_record
TN:
SF:src/rules/validation/RuleWhitelist.sol
-FN:29,RuleWhitelist.detectTransferRestriction
+FN:33,RuleWhitelist.detectTransferRestriction
FNDA:28,RuleWhitelist.detectTransferRestriction
-DA:34,28
-DA:34,28
-BRDA:34,0,0,13
-BRDA:34,0,1,15
-DA:35,13
-DA:35,13
-DA:36,15
-DA:36,15
-BRDA:36,1,0,5
-BRDA:36,1,1,10
-DA:37,5
-DA:37,5
-DA:39,10
-DA:39,10
-DA:39,10
-FN:48,RuleWhitelist.canReturnTransferRestrictionCode
+DA:38,28
+DA:38,28
+BRDA:38,0,0,13
+BRDA:38,0,1,15
+DA:39,13
+DA:39,13
+DA:40,15
+DA:40,15
+BRDA:40,1,0,5
+BRDA:40,1,1,10
+DA:41,5
+DA:41,5
+DA:43,10
+DA:43,10
+DA:43,10
+FN:52,RuleWhitelist.canReturnTransferRestrictionCode
FNDA:8,RuleWhitelist.canReturnTransferRestrictionCode
-DA:51,8
-DA:51,8
-DA:52,8
-DA:52,8
-DA:52,8
-DA:53,4
-DA:53,4
-FN:61,RuleWhitelist.messageForTransferRestriction
+DA:55,8
+DA:55,8
+DA:56,8
+DA:56,8
+DA:56,8
+DA:57,4
+DA:57,4
+FN:65,RuleWhitelist.messageForTransferRestriction
FNDA:7,RuleWhitelist.messageForTransferRestriction
-DA:64,7
-DA:64,7
-BRDA:64,2,0,4
-BRDA:64,2,1,3
-DA:65,4
-DA:65,4
-DA:66,3
-DA:66,3
-BRDA:66,3,0,2
-BRDA:66,3,1,1
-DA:67,2
-DA:67,2
-DA:69,1
-DA:69,1
+DA:68,7
+DA:68,7
+BRDA:68,2,0,4
+BRDA:68,2,1,3
+DA:69,4
+DA:69,4
+DA:70,3
+DA:70,3
+BRDA:70,3,0,2
+BRDA:70,3,1,1
+DA:71,2
+DA:71,2
+DA:73,1
+DA:73,1
FNF:3
FNH:3
LF:13
@@ -1266,123 +1283,237 @@ BRF:8
BRH:8
end_of_record
TN:
+SF:src/rules/validation/RuleWhitelistWrapper.sol
+FN:42,RuleWhitelistWrapper.detectTransferRestriction
+FNDA:11,RuleWhitelistWrapper.detectTransferRestriction
+DA:47,11
+DA:47,11
+DA:47,11
+DA:48,11
+DA:48,11
+DA:48,11
+DA:49,11
+DA:49,11
+DA:49,11
+DA:50,11
+DA:50,11
+DA:51,11
+DA:51,11
+DA:52,11
+DA:52,11
+DA:54,11
+DA:54,11
+DA:54,44
+DA:54,33
+DA:56,33
+DA:56,33
+DA:58,33
+DA:58,33
+DA:58,8
+BRDA:58,0,0,-
+BRDA:58,0,1,7
+DA:60,7
+DA:60,7
+DA:62,33
+DA:62,33
+DA:62,8
+BRDA:62,1,0,-
+BRDA:62,1,1,7
+DA:64,7
+DA:64,7
+DA:67,11
+DA:67,11
+BRDA:67,2,0,4
+BRDA:67,2,1,7
+DA:68,4
+DA:68,4
+DA:69,7
+DA:69,7
+BRDA:69,3,0,2
+BRDA:69,3,1,5
+DA:70,2
+DA:70,2
+DA:72,5
+DA:72,5
+DA:72,5
+FN:81,RuleWhitelistWrapper.canReturnTransferRestrictionCode
+FNDA:4,RuleWhitelistWrapper.canReturnTransferRestrictionCode
+DA:84,4
+DA:84,4
+DA:85,4
+DA:85,4
+DA:85,4
+DA:86,2
+DA:86,2
+FN:94,RuleWhitelistWrapper.messageForTransferRestriction
+FNDA:3,RuleWhitelistWrapper.messageForTransferRestriction
+DA:97,3
+DA:97,3
+BRDA:97,4,0,2
+BRDA:97,4,1,1
+DA:98,2
+DA:98,2
+DA:99,1
+DA:99,1
+BRDA:99,5,0,1
+BRDA:99,5,1,-
+DA:100,1
+DA:100,1
+DA:102,0
+DA:102,0
+FN:109,RuleWhitelistWrapper._msgSender
+FNDA:36,RuleWhitelistWrapper._msgSender
+DA:115,36
+DA:115,36
+DA:115,36
+FN:121,RuleWhitelistWrapper._msgData
+FNDA:0,RuleWhitelistWrapper._msgData
+DA:127,0
+DA:127,0
+DA:127,0
+FN:133,RuleWhitelistWrapper._contextSuffixLength
+FNDA:36,RuleWhitelistWrapper._contextSuffixLength
+DA:139,36
+DA:139,36
+DA:139,36
+FNF:6
+FNH:5
+LF:28
+LH:26
+BRF:12
+BRH:9
+end_of_record
+TN:
SF:src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol
-FN:39,RuleAddressList.addAddressesToTheList
-FNDA:15,RuleAddressList.addAddressesToTheList
-DA:42,14
-DA:42,14
-FN:51,RuleAddressList.removeAddressesFromTheList
+FN:43,RuleAddressList.addAddressesToTheList
+FNDA:17,RuleAddressList.addAddressesToTheList
+DA:46,16
+DA:46,16
+FN:55,RuleAddressList.removeAddressesFromTheList
FNDA:4,RuleAddressList.removeAddressesFromTheList
-DA:54,3
-DA:54,3
-FN:62,RuleAddressList.addAddressToTheList
-FNDA:40,RuleAddressList.addAddressToTheList
-DA:65,39
-DA:65,39
-FN:74,RuleAddressList.removeAddressFromTheList
+DA:58,3
+DA:58,3
+FN:66,RuleAddressList.addAddressToTheList
+FNDA:52,RuleAddressList.addAddressToTheList
+DA:69,51
+DA:69,51
+FN:78,RuleAddressList.removeAddressFromTheList
FNDA:3,RuleAddressList.removeAddressFromTheList
-DA:77,2
-DA:77,2
-FN:85,RuleAddressList.numberListedAddress
+DA:81,2
+DA:81,2
+FN:89,RuleAddressList.numberListedAddress
FNDA:24,RuleAddressList.numberListedAddress
-DA:86,24
-DA:86,24
-DA:86,24
-FN:96,RuleAddressList.addressIsListed
-FNDA:83,RuleAddressList.addressIsListed
-DA:99,141
-DA:99,141
-DA:99,141
-FN:106,RuleAddressList._msgSender
-FNDA:72,RuleAddressList._msgSender
-DA:112,72
-DA:112,72
-DA:112,72
-FN:118,RuleAddressList._msgData
+DA:90,24
+DA:90,24
+DA:90,24
+FN:99,RuleAddressList.addressIsListed
+FNDA:86,RuleAddressList.addressIsListed
+DA:102,144
+DA:102,144
+DA:102,144
+FN:109,RuleAddressList.addressIsListedBatch
+FNDA:36,RuleAddressList.addressIsListedBatch
+DA:112,36
+DA:112,36
+DA:112,36
+DA:113,36
+DA:113,36
+DA:113,107
+DA:113,71
+DA:114,71
+DA:114,71
+DA:116,36
+DA:116,36
+FN:122,RuleAddressList._msgSender
+FNDA:86,RuleAddressList._msgSender
+DA:128,86
+DA:128,86
+DA:128,86
+FN:134,RuleAddressList._msgData
FNDA:0,RuleAddressList._msgData
-DA:124,0
-DA:124,0
-DA:124,0
-FN:130,RuleAddressList._contextSuffixLength
-FNDA:72,RuleAddressList._contextSuffixLength
-DA:131,72
-DA:131,72
-DA:131,72
-FNF:9
-FNH:8
-LF:9
-LH:8
+DA:140,0
+DA:140,0
+DA:140,0
+FN:146,RuleAddressList._contextSuffixLength
+FNDA:86,RuleAddressList._contextSuffixLength
+DA:152,86
+DA:152,86
+DA:152,86
+FNF:10
+FNH:9
+LF:13
+LH:12
BRF:0
BRH:0
end_of_record
TN:
SF:src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol
-FN:23,RuleAddressListInternal._addAddressesToThelist
-FNDA:14,RuleAddressListInternal._addAddressesToThelist
-DA:26,14
-DA:26,14
-DA:27,14
-DA:27,14
-DA:27,44
-DA:27,30
-DA:28,30
-DA:28,30
-BRDA:28,0,0,-
-BRDA:28,0,1,28
-DA:29,28
-DA:29,28
-DA:30,28
-DA:30,28
-DA:33,14
-DA:33,14
-FN:42,RuleAddressListInternal._removeAddressesFromThelist
+FN:22,RuleAddressListInternal._addAddressesToThelist
+FNDA:16,RuleAddressListInternal._addAddressesToThelist
+DA:23,16
+DA:23,16
+DA:24,16
+DA:24,16
+DA:24,50
+DA:24,34
+DA:25,34
+DA:25,34
+BRDA:25,0,0,-
+BRDA:25,0,1,32
+DA:26,32
+DA:26,32
+DA:27,32
+DA:27,32
+DA:30,16
+DA:30,16
+FN:39,RuleAddressListInternal._removeAddressesFromThelist
FNDA:3,RuleAddressListInternal._removeAddressesFromThelist
-DA:45,3
-DA:45,3
-DA:46,3
-DA:46,3
-DA:46,10
-DA:46,7
-DA:47,7
-BRDA:47,1,0,-
-BRDA:47,1,1,6
-DA:48,6
-DA:48,6
-DA:49,6
-DA:49,6
-DA:52,3
-DA:52,3
-FN:60,RuleAddressListInternal._addAddressToThelist
-FNDA:39,RuleAddressListInternal._addAddressToThelist
-DA:63,39
-BRDA:63,2,0,1
-BRDA:63,2,1,38
-DA:65,1
-DA:65,1
-DA:67,38
-DA:67,38
-DA:68,38
-DA:68,38
-FN:77,RuleAddressListInternal._removeAddressFromThelist
+DA:42,3
+DA:42,3
+DA:43,3
+DA:43,3
+DA:43,10
+DA:43,7
+DA:44,7
+BRDA:44,1,0,-
+BRDA:44,1,1,6
+DA:45,6
+DA:45,6
+DA:46,6
+DA:46,6
+DA:49,3
+DA:49,3
+FN:57,RuleAddressListInternal._addAddressToThelist
+FNDA:51,RuleAddressListInternal._addAddressToThelist
+DA:58,51
+BRDA:58,2,0,1
+BRDA:58,2,1,50
+DA:59,1
+DA:59,1
+DA:61,50
+DA:61,50
+DA:62,50
+DA:62,50
+FN:71,RuleAddressListInternal._removeAddressFromThelist
FNDA:2,RuleAddressListInternal._removeAddressFromThelist
-DA:80,2
-DA:80,2
-BRDA:80,3,0,1
-BRDA:80,3,1,1
-DA:81,1
-DA:81,1
-DA:83,1
-DA:83,1
-DA:84,1
-DA:84,1
-FN:92,RuleAddressListInternal._numberListedAddress
+DA:72,2
+DA:72,2
+BRDA:72,3,0,1
+BRDA:72,3,1,1
+DA:73,1
+DA:73,1
+DA:75,1
+DA:75,1
+DA:76,1
+DA:76,1
+FN:84,RuleAddressListInternal._numberListedAddress
FNDA:24,RuleAddressListInternal._numberListedAddress
-DA:93,24
-DA:93,24
-FN:102,RuleAddressListInternal._addressIsListed
-FNDA:141,RuleAddressListInternal._addressIsListed
-DA:105,141
-DA:105,141
+DA:85,24
+DA:85,24
+FN:94,RuleAddressListInternal._addressIsListed
+FNDA:215,RuleAddressListInternal._addressIsListed
+DA:97,215
+DA:97,215
FNF:6
FNH:6
LF:22
@@ -1410,19 +1541,19 @@ BRH:0
end_of_record
TN:
SF:test/utils/SanctionListOracle.sol
-FN:15,SanctionListOracle.addToSanctionsList
+FN:13,SanctionListOracle.addToSanctionsList
FNDA:10,SanctionListOracle.addToSanctionsList
-DA:16,10
-DA:16,10
-FN:19,SanctionListOracle.removeFromSanctionsList
+DA:14,10
+DA:14,10
+FN:17,SanctionListOracle.removeFromSanctionsList
FNDA:0,SanctionListOracle.removeFromSanctionsList
-DA:20,0
-DA:20,0
-FN:23,SanctionListOracle.isSanctioned
+DA:18,0
+DA:18,0
+FN:21,SanctionListOracle.isSanctioned
FNDA:12,SanctionListOracle.isSanctioned
-DA:24,12
-DA:24,12
-DA:24,12
+DA:22,12
+DA:22,12
+DA:22,12
FNF:3
FNH:2
LF:3
diff --git a/script/CMTATWithRuleEngineScript.s.sol b/script/CMTATWithRuleEngineScript.s.sol
index 1bf6313..8303f01 100644
--- a/script/CMTATWithRuleEngineScript.s.sol
+++ b/script/CMTATWithRuleEngineScript.s.sol
@@ -7,6 +7,7 @@ import "forge-std/Script.sol";
import "CMTAT/CMTAT_STANDALONE.sol";
import "src/RuleEngine.sol";
import "src/rules/validation/RuleWhitelist.sol";
+
/**
@title Deploy a CMTAT, a RuleWhitelist and a RuleEngine
*/
@@ -41,7 +42,11 @@ contract CMTATWithRuleEngineScript is Script {
);
console.log("whitelist: ", address(ruleWhitelist));
// ruleEngine
- RuleEngine RULE_ENGINE = new RuleEngine(ADMIN, trustedForwarder, address(CMTAT_CONTRACT));
+ RuleEngine RULE_ENGINE = new RuleEngine(
+ ADMIN,
+ trustedForwarder,
+ address(CMTAT_CONTRACT)
+ );
console.log("RuleEngine : ", address(RULE_ENGINE));
RULE_ENGINE.addRuleValidation(ruleWhitelist);
CMTAT_CONTRACT.setRuleEngine(RULE_ENGINE);
diff --git a/src/RuleEngine.sol b/src/RuleEngine.sol
index 7b56c4b..9e8009c 100644
--- a/src/RuleEngine.sol
+++ b/src/RuleEngine.sol
@@ -7,124 +7,144 @@ import "./modules/MetaTxModuleStandalone.sol";
import "./modules/RuleEngineOperation.sol";
import "./modules/RuleEngineValidation.sol";
-
/**
-* @title Implementation of a ruleEngine as defined by the CMTAT
-*/
-contract RuleEngine is IRuleEngine, RuleEngineOperation, RuleEngineValidation, MetaTxModuleStandalone {
+ * @title Implementation of a ruleEngine as defined by the CMTAT
+ */
+contract RuleEngine is
+ IRuleEngine,
+ RuleEngineOperation,
+ RuleEngineValidation,
+ MetaTxModuleStandalone
+{
error RuleEngine_TransferInvalid();
+
/**
- * @param admin Address of the contract (Access Control)
- * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- */
+ * @param admin Address of the contract (Access Control)
+ * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ */
constructor(
address admin,
address forwarderIrrevocable,
address tokenContract
) MetaTxModuleStandalone(forwarderIrrevocable) {
- if(admin == address(0))
- {
+ if (admin == address(0)) {
revert RuleEngine_AdminWithAddressZeroNotAllowed();
}
- if(tokenContract != address(0)){
+ if (tokenContract != address(0)) {
_grantRole(TOKEN_CONTRACT_ROLE, tokenContract);
}
_grantRole(DEFAULT_ADMIN_ROLE, admin);
- _grantRole(RULE_ENGINE_ROLE, admin);
+ _grantRole(RULE_ENGINE_OPERATOR_ROLE, admin);
}
-
- /**
- * @notice Go through all the rule to know if a restriction exists on the transfer
- * @param _from the origin address
- * @param _to the destination address
- * @param _amount to transfer
- * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- **/
+ /**
+ * @notice Go through all the rule to know if a restriction exists on the transfer
+ * @param _from the origin address
+ * @param _to the destination address
+ * @param _amount to transfer
+ * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ **/
function detectTransferRestriction(
address _from,
address _to,
uint256 _amount
) public view override returns (uint8) {
// Validation
- uint8 code = RuleEngineValidation.detectTransferRestrictionValidation(_from, _to, _amount);
- if(code != uint8(REJECTED_CODE_BASE.TRANSFER_OK) ){
+ uint8 code = RuleEngineValidation.detectTransferRestrictionValidation(
+ _from,
+ _to,
+ _amount
+ );
+ if (code != uint8(REJECTED_CODE_BASE.TRANSFER_OK)) {
return code;
}
// Operation
uint256 rulesLength = _rulesOperation.length;
- for (uint256 i = 0; i < rulesLength; ++i ) {
- uint8 restriction = IRuleValidation(_rulesOperation[i]).detectTransferRestriction(
- _from,
- _to,
- _amount
- );
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ uint8 restriction = IRuleValidation(_rulesOperation[i])
+ .detectTransferRestriction(_from, _to, _amount);
if (restriction > 0) {
return restriction;
}
}
-
+
return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
}
- /**
- * @notice Validate a transfer
- * @param _from the origin address
- * @param _to the destination address
- * @param _amount to transfer
- * @return True if the transfer is valid, false otherwise
- **/
+ /**
+ * @notice Validate a transfer
+ * @param _from the origin address
+ * @param _to the destination address
+ * @param _amount to transfer
+ * @return True if the transfer is valid, false otherwise
+ **/
function validateTransfer(
address _from,
address _to,
uint256 _amount
) public view override returns (bool) {
- return detectTransferRestriction(_from, _to, _amount) == uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ return
+ detectTransferRestriction(_from, _to, _amount) ==
+ uint8(REJECTED_CODE_BASE.TRANSFER_OK);
}
- /**
- * @notice Return the message corresponding to the code
- * @param _restrictionCode The target restriction code
- * @return True if the transfer is valid, false otherwise
- **/
+ /**
+ * @notice Return the message corresponding to the code
+ * @param _restrictionCode The target restriction code
+ * @return True if the transfer is valid, false otherwise
+ **/
function messageForTransferRestriction(
uint8 _restrictionCode
) external view override returns (string memory) {
// Validation
uint256 rulesLength = _rulesValidation.length;
for (uint256 i = 0; i < rulesLength; ++i) {
- if (IRuleValidation(_rulesValidation[i]).canReturnTransferRestrictionCode(_restrictionCode)) {
+ if (
+ IRuleValidation(_rulesValidation[i])
+ .canReturnTransferRestrictionCode(_restrictionCode)
+ ) {
return
- IRuleValidation(_rulesValidation[i]).messageForTransferRestriction(_restrictionCode);
+ IRuleValidation(_rulesValidation[i])
+ .messageForTransferRestriction(_restrictionCode);
}
}
// operation
rulesLength = _rulesOperation.length;
for (uint256 i = 0; i < rulesLength; ++i) {
- if (IRuleValidation(_rulesOperation[i]).canReturnTransferRestrictionCode(_restrictionCode)) {
+ if (
+ IRuleValidation(_rulesOperation[i])
+ .canReturnTransferRestrictionCode(_restrictionCode)
+ ) {
return
- IRuleValidation(_rulesOperation[i]).messageForTransferRestriction(_restrictionCode);
+ IRuleValidation(_rulesOperation[i])
+ .messageForTransferRestriction(_restrictionCode);
}
}
return "Unknown restriction code";
}
/*
- * @notice function protected by access control
- */
- function operateOnTransfer(address from, address to, uint256 amount) external override onlyRole(TOKEN_CONTRACT_ROLE) returns (bool isValid) {
+ * @notice function protected by access control
+ */
+ function operateOnTransfer(
+ address from,
+ address to,
+ uint256 amount
+ ) external override onlyRole(TOKEN_CONTRACT_ROLE) returns (bool isValid) {
// Validate the transfer
- if(!RuleEngineValidation.validateTransferValidation(from, to, amount)){
- return false;
+ if (
+ !RuleEngineValidation.validateTransferValidation(from, to, amount)
+ ) {
+ return false;
}
// Apply operation on RuleEngine
return RuleEngineOperation._operateOnTransfer(from, to, amount);
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
function _msgSender()
internal
view
@@ -134,9 +154,9 @@ contract RuleEngine is IRuleEngine, RuleEngineOperation, RuleEngineValidation, M
return ERC2771Context._msgSender();
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
function _msgData()
internal
view
@@ -146,10 +166,15 @@ contract RuleEngine is IRuleEngine, RuleEngineOperation, RuleEngineValidation, M
return ERC2771Context._msgData();
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
- function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _contextSuffixLength()
+ internal
+ view
+ override(ERC2771Context, Context)
+ returns (uint256)
+ {
return ERC2771Context._contextSuffixLength();
}
}
diff --git a/src/interfaces/IRuleEngineOperation.sol b/src/interfaces/IRuleEngineOperation.sol
index d351510..7b17e2d 100644
--- a/src/interfaces/IRuleEngineOperation.sol
+++ b/src/interfaces/IRuleEngineOperation.sol
@@ -2,8 +2,7 @@
pragma solidity ^0.8.20;
-
-interface IRuleEngineOperation{
+interface IRuleEngineOperation {
/**
* @dev define the rules, the precedent rules will be overwritten
*/
@@ -23,5 +22,4 @@ interface IRuleEngineOperation{
* @dev return all the rules
*/
function rulesOperation() external view returns (address[] memory);
-
}
diff --git a/src/interfaces/IRuleEngineValidation.sol b/src/interfaces/IRuleEngineValidation.sol
index d88be2c..13db097 100644
--- a/src/interfaces/IRuleEngineValidation.sol
+++ b/src/interfaces/IRuleEngineValidation.sol
@@ -3,6 +3,27 @@
pragma solidity ^0.8.20;
interface IRuleEngineValidation {
+ /**
+ * @dev See ERC-1404
+ *
+ */
+ function detectTransferRestrictionValidation(
+ address _from,
+ address _to,
+ uint256 _amount
+ ) external view returns (uint8);
+
+ /**
+ * @dev Returns true if the transfer is valid, and false otherwise.
+ */
+ function validateTransferValidation(
+ address _from,
+ address _to,
+ uint256 _amount
+ ) external view returns (bool isValid);
+}
+
+interface IRuleEngineValidationCommon {
/**
* @dev define the rules, the precedent rules will be overwritten
*/
@@ -22,23 +43,4 @@ interface IRuleEngineValidation {
* @dev return all the rules
*/
function rulesValidation() external view returns (address[] memory);
-
- /**
- * @dev See ERC-1404
- *
- */
- function detectTransferRestrictionValidation(
- address _from,
- address _to,
- uint256 _amount
- ) external view returns (uint8);
-
- /**
- * @dev Returns true if the transfer is valid, and false otherwise.
- */
- function validateTransferValidation(
- address _from,
- address _to,
- uint256 _amount
- ) external view returns (bool isValid);
}
diff --git a/src/interfaces/IRuleOperation.sol b/src/interfaces/IRuleOperation.sol
index f4f3622..5874646 100644
--- a/src/interfaces/IRuleOperation.sol
+++ b/src/interfaces/IRuleOperation.sol
@@ -3,7 +3,6 @@
pragma solidity ^0.8.20;
interface IRuleOperation {
-
/**
* @dev Returns true if the transfer is valid, and false otherwise.
*/
diff --git a/src/modules/RuleEngineInvariantStorage.sol b/src/modules/RuleEngineInvariantStorage.sol
index 774567e..2421e64 100644
--- a/src/modules/RuleEngineInvariantStorage.sol
+++ b/src/modules/RuleEngineInvariantStorage.sol
@@ -16,10 +16,11 @@ abstract contract RuleEngineInvariantStorage {
/// @notice Generate when all the rules are cleared
event ClearRules(address[] rulesRemoved);
-
/// @notice Role to manage the ruleEngine
- bytes32 public constant RULE_ENGINE_ROLE = keccak256("RULE_ENGINE_ROLE");
+ bytes32 public constant RULE_ENGINE_OPERATOR_ROLE =
+ keccak256("RULE_ENGINE_OPERATOR_ROLE");
/// @notice token contract
- bytes32 public constant TOKEN_CONTRACT_ROLE = keccak256("TOKEN_CONTRACT_ROLE");
-}
\ No newline at end of file
+ bytes32 public constant TOKEN_CONTRACT_ROLE =
+ keccak256("TOKEN_CONTRACT_ROLE");
+}
diff --git a/src/modules/RuleEngineOperation.sol b/src/modules/RuleEngineOperation.sol
index 6118b2d..b238ff4 100644
--- a/src/modules/RuleEngineOperation.sol
+++ b/src/modules/RuleEngineOperation.sol
@@ -6,10 +6,15 @@ import "./RuleInternal.sol";
import "../interfaces/IRuleEngineOperation.sol";
import "../interfaces/IRuleOperation.sol";
import "OZ/access/AccessControl.sol";
+
/**
-* @title Implementation of a ruleEngine defined by the CMTAT
-*/
-abstract contract RuleEngineOperation is AccessControl, RuleInternal, IRuleEngineOperation {
+ * @title Implementation of a ruleEngine defined by the CMTAT
+ */
+abstract contract RuleEngineOperation is
+ AccessControl,
+ RuleInternal,
+ IRuleEngineOperation
+{
/// @dev Array of rules
address[] internal _rulesOperation;
@@ -20,9 +25,9 @@ abstract contract RuleEngineOperation is AccessControl, RuleInternal, IRuleEngin
*/
function setRulesOperation(
address[] calldata rules_
- ) public onlyRole(RULE_ENGINE_ROLE) {
- if(_rulesOperation.length > 0){
- _clearRulesOperation();
+ ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ if (_rulesOperation.length > 0) {
+ _clearRulesOperation();
}
_setRules(rules_);
_rulesOperation = rules_;
@@ -32,8 +37,8 @@ abstract contract RuleEngineOperation is AccessControl, RuleInternal, IRuleEngin
* @notice Clear all the rules of the array of rules
*
*/
- function clearRulesOperation() public onlyRole(RULE_ENGINE_ROLE) {
- _clearRulesOperation();
+ function clearRulesOperation() public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ _clearRulesOperation();
}
/**
@@ -43,11 +48,11 @@ abstract contract RuleEngineOperation is AccessControl, RuleInternal, IRuleEngin
function _clearRulesOperation() internal {
uint256 index;
// we remove the last element first since it is more optimized.
- for(uint256 i = _rulesOperation.length; i > 0; --i){
- unchecked {
+ for (uint256 i = _rulesOperation.length; i > 0; --i) {
+ unchecked {
// don't underflow since i > 0
index = i - 1;
- }
+ }
_removeRuleOperation(_rulesOperation[index], index);
}
emit ClearRules(_rulesOperation);
@@ -58,9 +63,11 @@ abstract contract RuleEngineOperation is AccessControl, RuleInternal, IRuleEngin
* Revert if one rule is a zero address or if the rule is already present
*
*/
- function addRuleOperation(IRuleOperation rule_) public onlyRole(RULE_ENGINE_ROLE) {
- RuleInternal._addRule( _rulesOperation, address(rule_));
- emit AddRule(address(rule_));
+ function addRuleOperation(
+ IRuleOperation rule_
+ ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ RuleInternal._addRule(_rulesOperation, address(rule_));
+ emit AddRule(address(rule_));
}
/**
@@ -76,7 +83,7 @@ abstract contract RuleEngineOperation is AccessControl, RuleInternal, IRuleEngin
function removeRuleOperation(
IRuleOperation rule_,
uint256 index
- ) public onlyRole(RULE_ENGINE_ROLE) {
+ ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
_removeRuleOperation(address(rule_), index);
}
@@ -90,69 +97,74 @@ abstract contract RuleEngineOperation is AccessControl, RuleInternal, IRuleEngin
*
*
*/
- function _removeRuleOperation(
- address rule_,
- uint256 index
- ) internal {
- RuleInternal._removeRule(_rulesOperation, rule_, index);
+ function _removeRuleOperation(address rule_, uint256 index) internal {
+ RuleInternal._removeRule(_rulesOperation, rule_, index);
emit RemoveRule(address(rule_));
}
/**
- * @return The number of rules inside the array
- */
+ * @return The number of rules inside the array
+ */
function rulesCountOperation() external view override returns (uint256) {
return _rulesOperation.length;
}
/**
- * @notice Get the index of a rule inside the list
- * @return index if the rule is found, _rulesOperation.length otherwise
- */
- function getRuleIndexOperation(IRuleOperation rule_) external view returns (uint256 index) {
+ * @notice Get the index of a rule inside the list
+ * @return index if the rule is found, _rulesOperation.length otherwise
+ */
+ function getRuleIndexOperation(
+ IRuleOperation rule_
+ ) external view returns (uint256 index) {
return RuleInternal.getRuleIndex(_rulesOperation, address(rule_));
}
/**
- * @notice Get the rule at the position specified by ruleId
- * @param ruleId index of the rule
- * @return a rule address
- */
- function ruleOperation(uint256 ruleId) external view override returns (address) {
+ * @notice Get the rule at the position specified by ruleId
+ * @param ruleId index of the rule
+ * @return a rule address
+ */
+ function ruleOperation(
+ uint256 ruleId
+ ) external view override returns (address) {
return _rulesOperation[ruleId];
}
/**
- * @notice Get all the rules
- * @return An array of rules
- */
- function rulesOperation() external view override returns (address[] memory) {
+ * @notice Get all the rules
+ * @return An array of rules
+ */
+ function rulesOperation()
+ external
+ view
+ override
+ returns (address[] memory)
+ {
return _rulesOperation;
}
-
- /**
- * @notice Go through all the rule to know if a restriction exists on the transfer
- * @param _from the origin address
- * @param _to the destination address
- * @param _amount to transfer
- **/
+ /**
+ * @notice Go through all the rule to know if a restriction exists on the transfer
+ * @param _from the origin address
+ * @param _to the destination address
+ * @param _amount to transfer
+ **/
function _operateOnTransfer(
address _from,
address _to,
uint256 _amount
- ) internal returns (bool isValid){
+ ) internal returns (bool isValid) {
uint256 rulesLength = _rulesOperation.length;
- for (uint256 i = 0; i < rulesLength; ++i ) {
+ for (uint256 i = 0; i < rulesLength; ++i) {
bool result = IRuleOperation(_rulesOperation[i]).operateOnTransfer(
_from,
_to,
_amount
);
- if(!result){
+ if (!result) {
return false;
}
}
return true;
}
-}
\ No newline at end of file
+}
diff --git a/src/modules/RuleEngineValidation.sol b/src/modules/RuleEngineValidation.sol
index 6a8fe02..d049dd4 100644
--- a/src/modules/RuleEngineValidation.sol
+++ b/src/modules/RuleEngineValidation.sol
@@ -4,174 +4,59 @@ pragma solidity ^0.8.20;
import "OZ/access/AccessControl.sol";
import "./RuleInternal.sol";
+import "./RuleEngineValidationCommon.sol";
import "../interfaces/IRuleEngineValidation.sol";
import "../interfaces/IRuleValidation.sol";
import "CMTAT/interfaces/draft-IERC1404/draft-IERC1404EnumCode.sol";
-/**
-* @title Implementation of a ruleEngine defined by the CMTAT
-*/
-abstract contract RuleEngineValidation is AccessControl, RuleInternal, IRuleEngineValidation, IERC1404EnumCode {
- /// @dev Array of rules
- address[] internal _rulesValidation;
-
-
- /**
- * @notice Set all the rules, will overwrite all the previous rules. \n
- * Revert if one rule is a zero address or if the rule is already present
- * @dev take address[] instead of IRuleEngineValidation[] since it is not possible to cast IRuleEngineValidation[] -> address[]
- *
- */
- function setRulesValidation(
- address[] calldata rules_
- ) public override onlyRole(RULE_ENGINE_ROLE) {
- if(_rulesValidation.length > 0){
- _clearRulesValidation();
- }
- _setRules(rules_);
- _rulesValidation = rules_;
- }
-
- /**
- * @notice Clear all the rules of the array of rules
- *
- */
- function clearRulesValidation() public onlyRole(RULE_ENGINE_ROLE) {
- _clearRulesValidation();
- }
-
- /**
- * @notice Clear all the rules of the array of rules
- *
- */
- function _clearRulesValidation() internal {
- uint256 index;
- // we remove the last element first since it is more optimized.
- for(uint256 i = _rulesValidation.length; i > 0; --i){
- unchecked {
- // don't underflow since i > 0
- index = i - 1;
- }
- _removeRuleValidation(_rulesValidation[index], index);
- }
- emit ClearRules(_rulesValidation);
- }
-
- /**
- * @notice Add a rule to the array of rules
- * Revert if one rule is a zero address or if the rule is already present
- *
- */
- function addRuleValidation(IRuleValidation rule_) public onlyRole(RULE_ENGINE_ROLE) {
- RuleInternal._addRule( _rulesValidation, address(rule_));
- emit AddRule(address(rule_));
- }
-
- /**
- * @notice Remove a rule from the array of rules
- * Revert if the rule found at the specified index does not match the rule in argument
- * @param rule_ address of the target rule
- * @param index the position inside the array of rule
- * @dev To reduce the array size, the last rule is moved to the location occupied
- * by the rule to remove
- *
- *
- */
- function removeRuleValidation(
- IRuleValidation rule_,
- uint256 index
- ) public onlyRole(RULE_ENGINE_ROLE) {
- _removeRuleValidation(address(rule_), index);
- }
- /**
- * @notice Remove a rule from the array of rules
- * Revert if the rule found at the specified index does not match the rule in argument
- * @param rule_ address of the target rule
- * @param index the position inside the array of rule
- * @dev To reduce the array size, the last rule is moved to the location occupied
- * by the rule to remove
- *
- *
- */
- function _removeRuleValidation(
- address rule_,
- uint256 index
- ) internal {
- RuleInternal._removeRule(_rulesValidation, rule_, index);
- emit RemoveRule(address(rule_));
- }
-
- /**
- * @return The number of rules inside the array
- */
- function rulesCountValidation() external view override returns (uint256) {
- return _rulesValidation.length;
- }
-
- /**
- * @notice Get the index of a rule inside the list
- * @return index if the rule is found, _rulesValidation.length otherwise
- */
- function getRuleIndexValidation(IRuleValidation rule_) external view returns (uint256 index) {
- return RuleInternal.getRuleIndex(_rulesValidation, address(rule_));
- }
-
- /**
- * @notice Get the rule at the position specified by ruleId
- * @param ruleId index of the rule
- * @return a rule address
- */
- function ruleValidation(uint256 ruleId) external view override returns (address) {
- return _rulesValidation[ruleId];
- }
-
- /**
- * @notice Get all the rules
- * @return An array of rules
- */
- function rulesValidation() external view override returns (address[] memory) {
- return _rulesValidation;
- }
-
- /**
- * @notice Go through all the rule to know if a restriction exists on the transfer
- * @param _from the origin address
- * @param _to the destination address
- * @param _amount to transfer
- * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- **/
+/**
+ * @title Implementation of a ruleEngine defined by the CMTAT
+ */
+abstract contract RuleEngineValidation is
+ AccessControl,
+ RuleInternal,
+ RuleEngineValidationCommon,
+ IRuleEngineValidation,
+ IERC1404EnumCode
+{
+ /**
+ * @notice Go through all the rule to know if a restriction exists on the transfer
+ * @param _from the origin address
+ * @param _to the destination address
+ * @param _amount to transfer
+ * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ **/
function detectTransferRestrictionValidation(
address _from,
address _to,
uint256 _amount
) public view override returns (uint8) {
uint256 rulesLength = _rulesValidation.length;
- for (uint256 i = 0; i < rulesLength; ++i ) {
- uint8 restriction = IRuleValidation(_rulesValidation[i]).detectTransferRestriction(
- _from,
- _to,
- _amount
- );
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ uint8 restriction = IRuleValidation(_rulesValidation[i])
+ .detectTransferRestriction(_from, _to, _amount);
if (restriction > 0) {
return restriction;
}
}
-
+
return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
}
- /**
- * @notice Validate a transfer
- * @param _from the origin address
- * @param _to the destination address
- * @param _amount to transfer
- * @return True if the transfer is valid, false otherwise
- **/
+ /**
+ * @notice Validate a transfer
+ * @param _from the origin address
+ * @param _to the destination address
+ * @param _amount to transfer
+ * @return True if the transfer is valid, false otherwise
+ **/
function validateTransferValidation(
address _from,
address _to,
uint256 _amount
) public view override returns (bool) {
- return detectTransferRestrictionValidation(_from, _to, _amount) == uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ return
+ detectTransferRestrictionValidation(_from, _to, _amount) ==
+ uint8(REJECTED_CODE_BASE.TRANSFER_OK);
}
-}
\ No newline at end of file
+}
diff --git a/src/modules/RuleEngineValidationCommon.sol b/src/modules/RuleEngineValidationCommon.sol
new file mode 100644
index 0000000..e821a64
--- /dev/null
+++ b/src/modules/RuleEngineValidationCommon.sol
@@ -0,0 +1,146 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import "OZ/access/AccessControl.sol";
+import "./RuleInternal.sol";
+import "../interfaces/IRuleEngineValidation.sol";
+import "../interfaces/IRuleValidation.sol";
+
+/**
+ * @title Implementation of a ruleEngine defined by the CMTAT
+ */
+abstract contract RuleEngineValidationCommon is
+ AccessControl,
+ RuleInternal,
+ IRuleEngineValidationCommon
+{
+ /// @dev Array of rules
+ address[] internal _rulesValidation;
+
+ /**
+ * @notice Set all the rules, will overwrite all the previous rules. \n
+ * Revert if one rule is a zero address or if the rule is already present
+ * @dev take address[] instead of IRuleEngineValidation[] since it is not possible to cast IRuleEngineValidation[] -> address[]
+ *
+ */
+ function setRulesValidation(
+ address[] calldata rules_
+ ) public override onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ if (_rulesValidation.length > 0) {
+ _clearRulesValidation();
+ }
+ _setRules(rules_);
+ _rulesValidation = rules_;
+ }
+
+ /**
+ * @notice Clear all the rules of the array of rules
+ *
+ */
+ function clearRulesValidation() public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ _clearRulesValidation();
+ }
+
+ /**
+ * @notice Clear all the rules of the array of rules
+ *
+ */
+ function _clearRulesValidation() internal {
+ uint256 index;
+ // we remove the last element first since it is more optimized.
+ for (uint256 i = _rulesValidation.length; i > 0; --i) {
+ unchecked {
+ // don't underflow since i > 0
+ index = i - 1;
+ }
+ _removeRuleValidation(_rulesValidation[index], index);
+ }
+ emit ClearRules(_rulesValidation);
+ }
+
+ /**
+ * @notice Add a rule to the array of rules
+ * Revert if one rule is a zero address or if the rule is already present
+ *
+ */
+ function addRuleValidation(
+ IRuleValidation rule_
+ ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ RuleInternal._addRule(_rulesValidation, address(rule_));
+ emit AddRule(address(rule_));
+ }
+
+ /**
+ * @notice Remove a rule from the array of rules
+ * Revert if the rule found at the specified index does not match the rule in argument
+ * @param rule_ address of the target rule
+ * @param index the position inside the array of rule
+ * @dev To reduce the array size, the last rule is moved to the location occupied
+ * by the rule to remove
+ *
+ *
+ */
+ function removeRuleValidation(
+ IRuleValidation rule_,
+ uint256 index
+ ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) {
+ _removeRuleValidation(address(rule_), index);
+ }
+
+ /**
+ * @notice Remove a rule from the array of rules
+ * Revert if the rule found at the specified index does not match the rule in argument
+ * @param rule_ address of the target rule
+ * @param index the position inside the array of rule
+ * @dev To reduce the array size, the last rule is moved to the location occupied
+ * by the rule to remove
+ *
+ *
+ */
+ function _removeRuleValidation(address rule_, uint256 index) internal {
+ RuleInternal._removeRule(_rulesValidation, rule_, index);
+ emit RemoveRule(address(rule_));
+ }
+
+ /**
+ * @return The number of rules inside the array
+ */
+ function rulesCountValidation() external view override returns (uint256) {
+ return _rulesValidation.length;
+ }
+
+ /**
+ * @notice Get the index of a rule inside the list
+ * @return index if the rule is found, _rulesValidation.length otherwise
+ */
+ function getRuleIndexValidation(
+ IRuleValidation rule_
+ ) external view returns (uint256 index) {
+ return RuleInternal.getRuleIndex(_rulesValidation, address(rule_));
+ }
+
+ /**
+ * @notice Get the rule at the position specified by ruleId
+ * @param ruleId index of the rule
+ * @return a rule address
+ */
+ function ruleValidation(
+ uint256 ruleId
+ ) external view override returns (address) {
+ return _rulesValidation[ruleId];
+ }
+
+ /**
+ * @notice Get all the rules
+ * @return An array of rules
+ */
+ function rulesValidation()
+ external
+ view
+ override
+ returns (address[] memory)
+ {
+ return _rulesValidation;
+ }
+}
diff --git a/src/modules/RuleInternal.sol b/src/modules/RuleInternal.sol
index 5ce3782..b6ce3cd 100644
--- a/src/modules/RuleInternal.sol
+++ b/src/modules/RuleInternal.sol
@@ -4,10 +4,9 @@ pragma solidity ^0.8.20;
import "./RuleEngineInvariantStorage.sol";
/**
-* @title Implementation of a ruleEngine defined by the CMTAT
-*/
+ * @title Implementation of a ruleEngine defined by the CMTAT
+ */
abstract contract RuleInternal is RuleEngineInvariantStorage {
-
/// @dev Indicate if a rule already exists
// Can be shared betwen RuleOperation and RuleValidation since it is a mapping
mapping(address => bool) _ruleIsPresent;
@@ -17,17 +16,15 @@ abstract contract RuleInternal is RuleEngineInvariantStorage {
* Revert if one rule is a zero address or if the rule is already present
*
*/
- function _setRules(
- address[] calldata rules_
- ) internal {
- if(rules_.length == 0){
+ function _setRules(address[] calldata rules_) internal {
+ if (rules_.length == 0) {
revert RuleEngine_ArrayIsEmpty();
}
for (uint256 i = 0; i < rules_.length; ) {
- if( address(rules_[i]) == address(0x0)){
- revert RuleEngine_RuleAddressZeroNotAllowed();
+ if (address(rules_[i]) == address(0x0)) {
+ revert RuleEngine_RuleAddressZeroNotAllowed();
}
- if(_ruleIsPresent[rules_[i]]){
+ if (_ruleIsPresent[rules_[i]]) {
revert RuleEngine_RuleAlreadyExists();
}
_ruleIsPresent[rules_[i]] = true;
@@ -43,13 +40,11 @@ abstract contract RuleInternal is RuleEngineInvariantStorage {
* Revert if one rule is a zero address or if the rule is already present
*
*/
- function _addRule(address[] storage _rules, address rule_) internal {
- if( address(rule_) == address(0x0))
- {
+ function _addRule(address[] storage _rules, address rule_) internal {
+ if (address(rule_) == address(0x0)) {
revert RuleEngine_RuleAddressZeroNotAllowed();
}
- if( _ruleIsPresent[rule_])
- {
+ if (_ruleIsPresent[rule_]) {
revert RuleEngine_RuleAlreadyExists();
}
_rules.push(rule_);
@@ -71,8 +66,7 @@ abstract contract RuleInternal is RuleEngineInvariantStorage {
address rule_,
uint256 index
) internal {
- if(_rules[index] != rule_)
- {
+ if (_rules[index] != rule_) {
revert RuleEngine_RuleDoNotMatch();
}
if (index != _rules.length - 1) {
@@ -84,12 +78,15 @@ abstract contract RuleInternal is RuleEngineInvariantStorage {
}
/**
- * @notice Get the index of a rule inside the list
- * @return index if the rule is found, _rules.length otherwise
- */
- function getRuleIndex(address[] storage _rules, address rule_) internal view returns (uint256 index) {
+ * @notice Get the index of a rule inside the list
+ * @return index if the rule is found, _rules.length otherwise
+ */
+ function getRuleIndex(
+ address[] storage _rules,
+ address rule_
+ ) internal view returns (uint256 index) {
uint256 rulesLength = _rules.length;
- for (index = 0; index < rulesLength;) {
+ for (index = 0; index < rulesLength; ) {
if (_rules[index] == rule_) {
return index;
}
@@ -99,4 +96,4 @@ abstract contract RuleInternal is RuleEngineInvariantStorage {
}
return _rules.length;
}
-}
\ No newline at end of file
+}
diff --git a/src/rules/operation/RuleConditionalTransfer.sol b/src/rules/operation/RuleConditionalTransfer.sol
index 5b6b03b..431bc38 100644
--- a/src/rules/operation/RuleConditionalTransfer.sol
+++ b/src/rules/operation/RuleConditionalTransfer.sol
@@ -4,73 +4,75 @@ pragma solidity ^0.8.20;
import "OZ/access/AccessControl.sol";
import "../../interfaces/IRuleOperation.sol";
-import "./../../modules/MetaTxModuleStandalone.sol";
+import "./../../modules/MetaTxModuleStandalone.sol";
import "./abstract/RuleConditionalTransferInvariantStorage.sol";
import "./abstract/RuleConditionalTransferOperator.sol";
import "../validation/abstract/RuleValidateTransfer.sol";
import "CMTAT/interfaces/engine/IRuleEngine.sol";
/**
-* @title a whitelist manager
-*/
+ * @title a whitelist manager
+ */
-contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleConditionalTransferOperator, MetaTxModuleStandalone {
+contract RuleConditionalTransfer is
+ RuleValidateTransfer,
+ IRuleOperation,
+ RuleConditionalTransferOperator,
+ MetaTxModuleStandalone
+{
/**
- * @param admin Address of the contract (Access Control)
- * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- */
+ * @param admin Address of the contract (Access Control)
+ * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ */
constructor(
address admin,
address forwarderIrrevocable,
IRuleEngine ruleEngineContract,
OPTION memory options_
) MetaTxModuleStandalone(forwarderIrrevocable) {
- if(admin == address(0)){
+ if (admin == address(0)) {
revert RuleConditionalTransfer_AdminWithAddressZeroNotAllowed();
}
_grantRole(DEFAULT_ADMIN_ROLE, admin);
_grantRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE, admin);
- if(address(ruleEngineContract) != address(0x0)){
+ if (address(ruleEngineContract) != address(0x0)) {
_grantRole(RULE_ENGINE_CONTRACT_ROLE, address(ruleEngineContract));
}
- if(options_.timeLimit.timeLimitToApprove == 0){
+ if (options_.timeLimit.timeLimitToApprove == 0) {
options_.timeLimit.timeLimitToApprove = type(uint64).max;
}
- if(options_.timeLimit.timeLimitToTransfer == 0){
+ if (options_.timeLimit.timeLimitToTransfer == 0) {
options_.timeLimit.timeLimitToTransfer = type(uint64).max;
}
options = options_;
}
/**
- * @notice Create a request of transfer for yourselves
- * @param to recipient of tokens
- * @param value amount of tokens to transfer
- */
- function createTransferRequest(
- address to, uint256 value
- ) public {
+ * @notice Create a request of transfer for yourselves
+ * @param to recipient of tokens
+ * @param value amount of tokens to transfer
+ */
+ function createTransferRequest(address to, uint256 value) public {
// WAIT => Will set a new delay to approve
// APPROVED => will overwrite previous status
// DENIED => reject
address from = _msgSender();
bytes32 key = keccak256(abi.encode(from, to, value));
- if(transferRequests[key].status == STATUS.DENIED){
- revert RuleConditionalTransfer_TransferDenied();
+ if (transferRequests[key].status == STATUS.DENIED) {
+ revert RuleConditionalTransfer_TransferDenied();
}
- if(_checkRequestStatus(key)){
- uint256 requestIdLocal = requestId;
- TransferRequest memory newTransferApproval = TransferRequest({
- key:key,
+ if (_checkRequestStatus(key)) {
+ uint256 requestIdLocal = requestId;
+ TransferRequest memory newTransferApproval = TransferRequest({
+ key: key,
id: requestIdLocal,
from: from,
- to:to,
- value:value,
+ to: to,
+ value: value,
askTime: block.timestamp,
- maxTime:0,
+ maxTime: 0,
status: STATUS.WAIT
- }
- );
+ });
transferRequests[key] = newTransferApproval;
IdToKey[requestIdLocal] = key;
emit transferWaiting(key, from, to, value, requestId);
@@ -79,77 +81,83 @@ contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleC
// Overwrite previous approval
transferRequests[key].askTime = block.timestamp;
transferRequests[key].status = STATUS.WAIT;
- emit transferWaiting(key, from, to, value, transferRequests[key].id);
+ emit transferWaiting(
+ key,
+ from,
+ to,
+ value,
+ transferRequests[key].id
+ );
}
}
/**
- * @notice Batch version of {createTransferRequest}
- */
- function createTransferRequestBatch(address[] memory tos, uint256[] memory values) public{
- if(tos.length == 0){
+ * @notice Batch version of {createTransferRequest}
+ */
+ function createTransferRequestBatch(
+ address[] memory tos,
+ uint256[] memory values
+ ) public {
+ if (tos.length == 0) {
revert RuleConditionalTransfer_EmptyArray();
}
- if(tos.length != values.length){
+ if (tos.length != values.length) {
revert RuleConditionalTransfer_InvalidLengthArray();
}
- for(uint256 i = 0; i < tos.length; ++i){
+ for (uint256 i = 0; i < tos.length; ++i) {
createTransferRequest(tos[i], values[i]);
}
}
/**
- * @notice allow a token holder to cancel/reset his own request
- */
- function cancelTransferRequest(
- uint256 requestId_
- ) public {
+ * @notice allow a token holder to cancel/reset his own request
+ */
+ function cancelTransferRequest(uint256 requestId_) public {
_cancelTransferRequest(requestId_);
}
/**
- * @notice allow a token holder to cancel/reset his own request
- */
- function cancelTransferRequestBatch(
- uint256[] memory requestIds
- ) public {
- if(requestIds.length == 0){
+ * @notice allow a token holder to cancel/reset his own request
+ */
+ function cancelTransferRequestBatch(uint256[] memory requestIds) public {
+ if (requestIds.length == 0) {
revert RuleConditionalTransfer_EmptyArray();
}
// Check id validity before performing actions
- for(uint256 i = 0; i < requestIds.length; ++i){
- if(requestIds[i] + 1 > requestId) {
+ for (uint256 i = 0; i < requestIds.length; ++i) {
+ if (requestIds[i] + 1 > requestId) {
revert RuleConditionalTransfer_InvalidId();
}
}
- for(uint256 i = 0; i < requestIds.length; ++i){
+ for (uint256 i = 0; i < requestIds.length; ++i) {
_cancelTransferRequest(requestIds[i]);
}
-
}
- function _cancelTransferRequest(
- uint256 requestId_
- ) internal {
- if(requestId_ + 1 > requestId) {
+ function _cancelTransferRequest(uint256 requestId_) internal {
+ if (requestId_ + 1 > requestId) {
revert RuleConditionalTransfer_InvalidId();
}
bytes32 key = IdToKey[requestId_];
// Check Sender
- if(transferRequests[key].from != _msgSender()){
+ if (transferRequests[key].from != _msgSender()) {
revert RuleConditionalTransfer_InvalidSender();
}
// Check status
- if(transferRequests[key].status != STATUS.WAIT
- && transferRequests[key].status != STATUS.APPROVED
- ){
+ if (
+ transferRequests[key].status != STATUS.WAIT &&
+ transferRequests[key].status != STATUS.APPROVED
+ ) {
revert RuleConditionalTransfer_Wrong_Status();
}
_resetRequestStatus(key);
}
-
- function getRequestTrade(address from, address to, uint256 value) public view returns (TransferRequest memory) {
+ function getRequestTrade(
+ address from,
+ address to,
+ uint256 value
+ ) public view returns (TransferRequest memory) {
bytes32 key = keccak256(abi.encode(from, to, value));
return transferRequests[key];
}
@@ -159,7 +167,9 @@ contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleC
* @param _targetStatus The status of the transactions you want to retrieve
* @return array with corresponding transactions
*/
- function getRequestByStatus(STATUS _targetStatus) public view returns (TransferRequest[] memory) {
+ function getRequestByStatus(
+ STATUS _targetStatus
+ ) public view returns (TransferRequest[] memory) {
uint totalRequestCount = requestId;
uint requestCount = 0;
uint currentIndex = 0;
@@ -178,7 +188,9 @@ contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleC
for (uint i = 0; i < totalRequestCount; ++i) {
if (transferRequests[IdToKey[i]].status == _targetStatus) {
//uint currentId = i + 1;
- TransferRequest memory currentRequest = transferRequests[IdToKey[i]];
+ TransferRequest memory currentRequest = transferRequests[
+ IdToKey[i]
+ ];
requests[currentIndex] = currentRequest;
currentIndex += 1;
}
@@ -194,70 +206,79 @@ contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleC
address _from,
address _to,
uint256 _amount
- ) public override onlyRole(RULE_ENGINE_CONTRACT_ROLE) returns(bool isValid){
+ )
+ public
+ override
+ onlyRole(RULE_ENGINE_CONTRACT_ROLE)
+ returns (bool isValid)
+ {
// No need of approval if from and to are in the whitelist
- if(address(whitelistConditionalTransfer) != address(0)){
- if(whitelistConditionalTransfer.addressIsListed(_from) && whitelistConditionalTransfer.addressIsListed(_to)){
+ if (address(whitelistConditionalTransfer) != address(0)) {
+ if (
+ whitelistConditionalTransfer.addressIsListed(_from) &&
+ whitelistConditionalTransfer.addressIsListed(_to)
+ ) {
return true;
- }
+ }
}
// Mint & Burn
- if(_validateBurnMint(_from, _to)) {
+ if (_validateBurnMint(_from, _to)) {
return true;
}
bytes32 key = keccak256(abi.encode(_from, _to, _amount));
- if(_validateApproval(key)) {
- _updateProcessedTransfer(key);
- return true;
+ if (_validateApproval(key)) {
+ _updateProcessedTransfer(key);
+ return true;
} else {
- return false;
+ return false;
}
}
- /**
- * @notice Check if the transfer is valid
- * @param _from the origin address
- * @param _to the destination address
- * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- **/
+ /**
+ * @notice Check if the transfer is valid
+ * @param _from the origin address
+ * @param _to the destination address
+ * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ **/
function detectTransferRestriction(
address _from,
address _to,
uint256 _amount
) public view override returns (uint8) {
// No need of approval if from and to are in the whitelist
- if(address(whitelistConditionalTransfer) != address(0)){
- if(whitelistConditionalTransfer.addressIsListed(_from) && whitelistConditionalTransfer.addressIsListed(_to)){
+ if (address(whitelistConditionalTransfer) != address(0)) {
+ if (
+ whitelistConditionalTransfer.addressIsListed(_from) &&
+ whitelistConditionalTransfer.addressIsListed(_to)
+ ) {
return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
- }
+ }
}
bytes32 key = keccak256(abi.encode(_from, _to, _amount));
- if (!_validateBurnMint(_from,_to) && !_validateApproval(key)) {
+ if (!_validateBurnMint(_from, _to) && !_validateApproval(key)) {
return CODE_TRANSFER_REQUEST_NOT_APPROVED;
- }
- else {
+ } else {
return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
}
}
- /**
- * @notice To know if the restriction code is valid for this rule or not.
- * @param _restrictionCode The target restriction code
- * @return true if the restriction code is known, false otherwise
- **/
+ /**
+ * @notice To know if the restriction code is valid for this rule or not.
+ * @param _restrictionCode The target restriction code
+ * @return true if the restriction code is known, false otherwise
+ **/
function canReturnTransferRestrictionCode(
uint8 _restrictionCode
) external pure override returns (bool) {
- return
- _restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED;
+ return _restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED;
}
- /**
- * @notice Return the corresponding message
- * @param _restrictionCode The target restriction code
- * @return true if the transfer is valid, false otherwise
- **/
+ /**
+ * @notice Return the corresponding message
+ * @param _restrictionCode The target restriction code
+ * @return true if the transfer is valid, false otherwise
+ **/
function messageForTransferRestriction(
uint8 _restrictionCode
) external pure override returns (string memory) {
@@ -269,8 +290,8 @@ contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleC
}
/**
- *
- * @dev
+ *
+ * @dev
* Test burn and mint condition
* Returns true if the transfer is valid, and false otherwise.
*
@@ -278,40 +299,47 @@ contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleC
function _validateBurnMint(
address _from,
address _to
- ) internal view returns(bool isValid){
+ ) internal view returns (bool isValid) {
// Mint & Burn
- if(
- (_from == address(0) && options.issuance.authorizedMintWithoutApproval)
- || (_to == address(0) && options.issuance.authorizedBurnWithoutApproval)
- ){
+ if (
+ (_from == address(0) &&
+ options.issuance.authorizedMintWithoutApproval) ||
+ (_to == address(0) &&
+ options.issuance.authorizedBurnWithoutApproval)
+ ) {
return true;
}
return false;
}
/**
- *
- * @dev
+ *
+ * @dev
* Test transfer approval condition
* Returns true if the transfer is valid, and false otherwise.
*/
function _validateApproval(
bytes32 key
- ) internal view returns(bool isValid){
- bool automaticApprovalCondition = options.automaticApproval.isActivate && ((transferRequests[key].askTime + options.automaticApproval.timeLimitBeforeAutomaticApproval ) >= block.timestamp);
- bool isTransferApproved = (transferRequests[key].status == STATUS.APPROVED)
- && (transferRequests[key].maxTime >= block.timestamp);
- if(automaticApprovalCondition || isTransferApproved)
- {
+ ) internal view returns (bool isValid) {
+ bool automaticApprovalCondition = options
+ .automaticApproval
+ .isActivate &&
+ ((transferRequests[key].askTime +
+ options.automaticApproval.timeLimitBeforeAutomaticApproval) >=
+ block.timestamp);
+ bool isTransferApproved = (transferRequests[key].status ==
+ STATUS.APPROVED) &&
+ (transferRequests[key].maxTime >= block.timestamp);
+ if (automaticApprovalCondition || isTransferApproved) {
return true;
} else {
return false;
}
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
function _msgSender()
internal
view
@@ -321,9 +349,9 @@ contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleC
return ERC2771Context._msgSender();
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
function _msgData()
internal
view
@@ -333,10 +361,15 @@ contract RuleConditionalTransfer is RuleValidateTransfer, IRuleOperation, RuleC
return ERC2771Context._msgData();
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
- function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _contextSuffixLength()
+ internal
+ view
+ override(ERC2771Context, Context)
+ returns (uint256)
+ {
return ERC2771Context._contextSuffixLength();
}
}
diff --git a/src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol b/src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol
index 04c40e2..1abcff9 100644
--- a/src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol
+++ b/src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol
@@ -5,12 +5,15 @@ import "OZ/token/ERC20/IERC20.sol";
import "../../validation/abstract/RuleCommonInvariantStorage.sol";
import "src/rules/validation/RuleWhitelist.sol";
-abstract contract RuleConditionalTransferInvariantStorage is RuleCommonInvariantStorage {
+
+abstract contract RuleConditionalTransferInvariantStorage is
+ RuleCommonInvariantStorage
+{
/**
- * perform automatically a transfer if the transfer request is approved.
- * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
- * If the allowance is not sufficient, the request will be approved, but without performing the transfer.
- */
+ * perform automatically a transfer if the transfer request is approved.
+ * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
+ * If the allowance is not sufficient, the request will be approved, but without performing the transfer.
+ */
struct AUTOMATIC_TRANSFER {
bool isActivate;
IERC20 cmtat;
@@ -33,9 +36,9 @@ abstract contract RuleConditionalTransferInvariantStorage is RuleCommonInvariant
struct AUTOMATIC_APPROVAL {
bool isActivate;
/**
- * If the transfer is not approved or denied within {timeLimitBeforeAutomaticApproval},
- * the request is considered as approved during a transfer.
- */
+ * If the transfer is not approved or denied within {timeLimitBeforeAutomaticApproval},
+ * the request is considered as approved during a transfer.
+ */
uint256 timeLimitBeforeAutomaticApproval;
}
@@ -45,8 +48,15 @@ abstract contract RuleConditionalTransferInvariantStorage is RuleCommonInvariant
AUTOMATIC_APPROVAL automaticApproval;
AUTOMATIC_TRANSFER automaticTransfer;
}
-
- enum STATUS { NONE, WAIT, APPROVED, DENIED, EXECUTED, CANCELLED }
+
+ enum STATUS {
+ NONE,
+ WAIT,
+ APPROVED,
+ DENIED,
+ EXECUTED,
+ CANCELLED
+ }
struct TransferRequestKeyElement {
address from;
@@ -65,8 +75,10 @@ abstract contract RuleConditionalTransferInvariantStorage is RuleCommonInvariant
}
// Role
- bytes32 public constant RULE_ENGINE_CONTRACT_ROLE = keccak256("RULE_ENGINE_CONTRACT_ROLE");
- bytes32 public constant RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE = keccak256("RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE");
+ bytes32 public constant RULE_ENGINE_CONTRACT_ROLE =
+ keccak256("RULE_ENGINE_CONTRACT_ROLE");
+ bytes32 public constant RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE =
+ keccak256("RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE");
// String
string constant TEXT_TRANSFER_REQUEST_NOT_APPROVED =
@@ -75,7 +87,6 @@ abstract contract RuleConditionalTransferInvariantStorage is RuleCommonInvariant
// It is very important that each rule uses an unique code
uint8 public constant CODE_TRANSFER_REQUEST_NOT_APPROVED = 51;
-
// error
error RuleConditionalTransfer_AdminWithAddressZeroNotAllowed();
error RuleConditionalTransfer_TransferAlreadyApproved();
@@ -90,11 +101,43 @@ abstract contract RuleConditionalTransferInvariantStorage is RuleCommonInvariant
error RuleConditionalTransfer_EmptyArray();
// Event
- event transferProcessed(bytes32 indexed key, address indexed from, address indexed to, uint256 value, uint256 id);
- event transferWaiting(bytes32 indexed key, address indexed from, address indexed to, uint256 value, uint256 id);
- event transferApproved(bytes32 indexed key, address indexed from, address indexed to, uint256 value, uint256 id );
- event transferDenied(bytes32 indexed key, address indexed from, address indexed to, uint256 value, uint256 id);
- event transferReset(bytes32 indexed key, address indexed from, address indexed to, uint256 value, uint256 id);
+ event transferProcessed(
+ bytes32 indexed key,
+ address indexed from,
+ address indexed to,
+ uint256 value,
+ uint256 id
+ );
+ event transferWaiting(
+ bytes32 indexed key,
+ address indexed from,
+ address indexed to,
+ uint256 value,
+ uint256 id
+ );
+ event transferApproved(
+ bytes32 indexed key,
+ address indexed from,
+ address indexed to,
+ uint256 value,
+ uint256 id
+ );
+ event transferDenied(
+ bytes32 indexed key,
+ address indexed from,
+ address indexed to,
+ uint256 value,
+ uint256 id
+ );
+ event transferReset(
+ bytes32 indexed key,
+ address indexed from,
+ address indexed to,
+ uint256 value,
+ uint256 id
+ );
- event WhitelistConditionalTransfer(RuleWhitelist indexed whitelistConditionalTransfer);
-}
\ No newline at end of file
+ event WhitelistConditionalTransfer(
+ RuleWhitelist indexed whitelistConditionalTransfer
+ );
+}
diff --git a/src/rules/operation/abstract/RuleConditionalTransferOperator.sol b/src/rules/operation/abstract/RuleConditionalTransferOperator.sol
index 5a8497f..80bf67d 100644
--- a/src/rules/operation/abstract/RuleConditionalTransferOperator.sol
+++ b/src/rules/operation/abstract/RuleConditionalTransferOperator.sol
@@ -4,90 +4,138 @@ pragma solidity ^0.8.20;
import "OZ/access/AccessControl.sol";
import "./RuleConditionalTransferInvariantStorage.sol";
-import "OZ/token/ERC20/utils/SafeERC20.sol";
+import "OZ/token/ERC20/utils/SafeERC20.sol";
+
/**
-* @title Restricted functions
-*/
-abstract contract RuleConditionalTransferOperator is AccessControl, RuleConditionalTransferInvariantStorage {
+ * @title Restricted functions
+ */
+abstract contract RuleConditionalTransferOperator is
+ AccessControl,
+ RuleConditionalTransferInvariantStorage
+{
// Security
using SafeERC20 for IERC20;
-
+
// public variable with automatic Getter
OPTION public options;
uint256 public requestId;
mapping(uint256 => bytes32) public IdToKey;
mapping(bytes32 => TransferRequest) public transferRequests;
- RuleWhitelist public whitelistConditionalTransfer;
+ RuleWhitelist public whitelistConditionalTransfer;
/**
- * @notice set a whitelist. A transfer does not need of an approved request if from and to are in the whitelist
- */
- function setConditionalWhitelist(RuleWhitelist newWhitelistConditionalTransfer) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
+ * @notice set a whitelist. A transfer does not need of an approved request if from and to are in the whitelist
+ */
+ function setConditionalWhitelist(
+ RuleWhitelist newWhitelistConditionalTransfer
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
whitelistConditionalTransfer = newWhitelistConditionalTransfer;
emit WhitelistConditionalTransfer(newWhitelistConditionalTransfer);
- }
+ }
/**
set/unset the issuance options (mint & burn)
*/
- function setIssuanceOptions(ISSUANCE calldata issuance_) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(options.issuance.authorizedMintWithoutApproval != issuance_.authorizedMintWithoutApproval ){
- options.issuance.authorizedMintWithoutApproval = issuance_.authorizedMintWithoutApproval;
+ function setIssuanceOptions(
+ ISSUANCE calldata issuance_
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (
+ options.issuance.authorizedMintWithoutApproval !=
+ issuance_.authorizedMintWithoutApproval
+ ) {
+ options.issuance.authorizedMintWithoutApproval = issuance_
+ .authorizedMintWithoutApproval;
}
- if(options.issuance.authorizedBurnWithoutApproval != issuance_.authorizedBurnWithoutApproval ){
- options.issuance.authorizedBurnWithoutApproval = issuance_.authorizedBurnWithoutApproval;
+ if (
+ options.issuance.authorizedBurnWithoutApproval !=
+ issuance_.authorizedBurnWithoutApproval
+ ) {
+ options.issuance.authorizedBurnWithoutApproval = issuance_
+ .authorizedBurnWithoutApproval;
}
}
/**
- * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
- * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
- * If the allowance is not sufficient, the request will be approved, but without performing the transfer.
- */
- function setAutomaticTransfer(AUTOMATIC_TRANSFER calldata automaticTransfer_) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(automaticTransfer_.isActivate != options.automaticTransfer.isActivate){
- options.automaticTransfer.isActivate = automaticTransfer_.isActivate;
- }
- // No need to put the cmtat to zero to deactivate automaticTransfer
- if(address(automaticTransfer_.cmtat) != address(options.automaticTransfer.cmtat)){
+ * @notice set/unset the option to perform the transfer if the request is approved by the rule operator.
+ * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval).
+ * If the allowance is not sufficient, the request will be approved, but without performing the transfer.
+ */
+ function setAutomaticTransfer(
+ AUTOMATIC_TRANSFER calldata automaticTransfer_
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (
+ automaticTransfer_.isActivate !=
+ options.automaticTransfer.isActivate
+ ) {
+ options.automaticTransfer.isActivate = automaticTransfer_
+ .isActivate;
+ }
+ // No need to put the cmtat to zero to deactivate automaticTransfer
+ if (
+ address(automaticTransfer_.cmtat) !=
+ address(options.automaticTransfer.cmtat)
+ ) {
options.automaticTransfer.cmtat = automaticTransfer_.cmtat;
- }
+ }
}
/**
- * @notice set time limit for new requests (Approval and transfer)
- * timeLimitToApprove: time limit for an operator to approve a request
- * timeLimitToTransfer: once a request is approved, time limit for the token holder to perform the transfer
- */
- function setTimeLimit(TIME_LIMIT memory timeLimit_) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(options.timeLimit.timeLimitToApprove != timeLimit_.timeLimitToApprove){
- options.timeLimit.timeLimitToApprove = timeLimit_.timeLimitToApprove;
+ * @notice set time limit for new requests (Approval and transfer)
+ * timeLimitToApprove: time limit for an operator to approve a request
+ * timeLimitToTransfer: once a request is approved, time limit for the token holder to perform the transfer
+ */
+ function setTimeLimit(
+ TIME_LIMIT memory timeLimit_
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (
+ options.timeLimit.timeLimitToApprove !=
+ timeLimit_.timeLimitToApprove
+ ) {
+ options.timeLimit.timeLimitToApprove = timeLimit_
+ .timeLimitToApprove;
}
- if(options.timeLimit.timeLimitToTransfer != timeLimit_.timeLimitToTransfer){
- options.timeLimit.timeLimitToTransfer = timeLimit_.timeLimitToTransfer;
+ if (
+ options.timeLimit.timeLimitToTransfer !=
+ timeLimit_.timeLimitToTransfer
+ ) {
+ options.timeLimit.timeLimitToTransfer = timeLimit_
+ .timeLimitToTransfer;
}
}
+
/**
- * @notice If the transfer is not approved or denied within {timeLimitBeforeAutomaticApproval},
- * the request is considered as approved during a transfer.
- *
- */
- function setAutomaticApproval(AUTOMATIC_APPROVAL memory automaticApproval_) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(options.automaticApproval.isActivate != automaticApproval_.isActivate ){
- options.automaticApproval.isActivate = automaticApproval_.isActivate;
+ * @notice If the transfer is not approved or denied within {timeLimitBeforeAutomaticApproval},
+ * the request is considered as approved during a transfer.
+ *
+ */
+ function setAutomaticApproval(
+ AUTOMATIC_APPROVAL memory automaticApproval_
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (
+ options.automaticApproval.isActivate !=
+ automaticApproval_.isActivate
+ ) {
+ options.automaticApproval.isActivate = automaticApproval_
+ .isActivate;
}
- if(options.automaticApproval.timeLimitBeforeAutomaticApproval != automaticApproval_.timeLimitBeforeAutomaticApproval){
- options.automaticApproval.timeLimitBeforeAutomaticApproval = automaticApproval_.timeLimitBeforeAutomaticApproval;
+ if (
+ options.automaticApproval.timeLimitBeforeAutomaticApproval !=
+ automaticApproval_.timeLimitBeforeAutomaticApproval
+ ) {
+ options
+ .automaticApproval
+ .timeLimitBeforeAutomaticApproval = automaticApproval_
+ .timeLimitBeforeAutomaticApproval;
}
}
/**
- * @notice create a transfer request directly approved
- */
+ * @notice create a transfer request directly approved
+ */
function createTransferRequestWithApproval(
TransferRequestKeyElement calldata keyElement
- ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- _createTransferRequestWithApproval(keyElement);
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ _createTransferRequestWithApproval(keyElement);
}
/**
@@ -97,31 +145,36 @@ abstract contract RuleConditionalTransferOperator is AccessControl, RuleConditio
@param isApproved approved (true) or refused (false). Put true if you use partialApproval
*/
function approveTransferRequest(
- TransferRequestKeyElement calldata keyElement, uint256 partialValue, bool isApproved
+ TransferRequestKeyElement calldata keyElement,
+ uint256 partialValue,
+ bool isApproved
) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
_approveTransferRequestKeyElement(keyElement, partialValue, isApproved);
}
/**
- * @notice approve a transferRequestby using its id
- */
+ * @notice approve a transferRequestby using its id
+ */
function approveTransferRequestWithId(
- uint256 requestId_, bool isApproved
- ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(requestId_ + 1 > requestId) {
+ uint256 requestId_,
+ bool isApproved
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (requestId_ + 1 > requestId) {
revert RuleConditionalTransfer_InvalidId();
}
- TransferRequest memory transferRequest = transferRequests[IdToKey[requestId_]];
+ TransferRequest memory transferRequest = transferRequests[
+ IdToKey[requestId_]
+ ];
_approveRequest(transferRequest, isApproved);
- }
+ }
/**
- * @notice reset to None the status of a request
- */
+ * @notice reset to None the status of a request
+ */
function resetRequestStatus(
uint256 requestId_
- ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(requestId_ + 1 > requestId) {
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (requestId_ + 1 > requestId) {
revert RuleConditionalTransfer_InvalidId();
}
bytes32 key = IdToKey[requestId_];
@@ -130,185 +183,267 @@ abstract contract RuleConditionalTransferOperator is AccessControl, RuleConditio
/***** Batch function */
/**
- * @notice Batch version of {approveTransferRequestWithId}
- */
+ * @notice Batch version of {approveTransferRequestWithId}
+ */
function approveTransferRequestBatchWithId(
- uint256[] calldata requestId_, bool[] calldata isApproved
- ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(requestId_.length == 0){
+ uint256[] calldata requestId_,
+ bool[] calldata isApproved
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (requestId_.length == 0) {
revert RuleConditionalTransfer_EmptyArray();
}
- if(requestId_.length != isApproved.length){
+ if (requestId_.length != isApproved.length) {
revert RuleConditionalTransfer_InvalidLengthArray();
}
// Check id validity before performing actions
- for(uint256 i = 0; i < requestId_.length; ++i){
- if(requestId_[i] + 1 > requestId) {
+ for (uint256 i = 0; i < requestId_.length; ++i) {
+ if (requestId_[i] + 1 > requestId) {
revert RuleConditionalTransfer_InvalidId();
}
}
- for(uint256 i = 0; i < requestId_.length; ++i){
- TransferRequest memory transferRequest = transferRequests[IdToKey[requestId_[i]]];
+ for (uint256 i = 0; i < requestId_.length; ++i) {
+ TransferRequest memory transferRequest = transferRequests[
+ IdToKey[requestId_[i]]
+ ];
_approveRequest(transferRequest, isApproved[i]);
}
}
/**
- * @notice Batch version of {approveTransferRequest}
- */
+ * @notice Batch version of {approveTransferRequest}
+ */
function approveTransferRequestBatch(
- TransferRequestKeyElement[] calldata keyElements, uint256[] calldata partialValues, bool[] calldata isApproved
+ TransferRequestKeyElement[] calldata keyElements,
+ uint256[] calldata partialValues,
+ bool[] calldata isApproved
) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
- if(keyElements.length == 0){
+ if (keyElements.length == 0) {
revert RuleConditionalTransfer_EmptyArray();
}
- if((keyElements.length != partialValues.length) || (partialValues.length != isApproved.length)){
+ if (
+ (keyElements.length != partialValues.length) ||
+ (partialValues.length != isApproved.length)
+ ) {
revert RuleConditionalTransfer_InvalidLengthArray();
}
- for(uint256 i = 0; i < keyElements.length; ++i){
- _approveTransferRequestKeyElement(keyElements[i], partialValues[i], isApproved[i]);
+ for (uint256 i = 0; i < keyElements.length; ++i) {
+ _approveTransferRequestKeyElement(
+ keyElements[i],
+ partialValues[i],
+ isApproved[i]
+ );
}
}
/**
- * @notice Batch version of {createTransferRequestWithApproval}
- */
+ * @notice Batch version of {createTransferRequestWithApproval}
+ */
function createTransferRequestWithApprovalBatch(
- TransferRequestKeyElement[] calldata keyElements
- ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(keyElements.length == 0){
+ TransferRequestKeyElement[] calldata keyElements
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (keyElements.length == 0) {
revert RuleConditionalTransfer_EmptyArray();
}
- for(uint256 i = 0; i < keyElements.length; ++i){
+ for (uint256 i = 0; i < keyElements.length; ++i) {
_createTransferRequestWithApproval(keyElements[i]);
}
}
/**
- * @notice Batch version of {resetRequestStatus}
- */
+ * @notice Batch version of {resetRequestStatus}
+ */
function resetRequestStatusBatch(
uint256[] memory requestIds
- ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
- if(requestIds.length == 0){
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
+ if (requestIds.length == 0) {
revert RuleConditionalTransfer_EmptyArray();
}
// Check id validity before performing actions
- for(uint256 i = 0; i < requestIds.length; ++i){
- if(requestIds[i] + 1 > requestId) {
+ for (uint256 i = 0; i < requestIds.length; ++i) {
+ if (requestIds[i] + 1 > requestId) {
revert RuleConditionalTransfer_InvalidId();
}
}
- for(uint256 i = 0; i < requestIds.length; ++i){
+ for (uint256 i = 0; i < requestIds.length; ++i) {
bytes32 key = IdToKey[requestIds[i]];
_resetRequestStatus(key);
}
}
-
/*** Internal functions ****/
function _approveTransferRequestKeyElement(
- TransferRequestKeyElement calldata keyElement, uint256 partialValue, bool isApproved
+ TransferRequestKeyElement calldata keyElement,
+ uint256 partialValue,
+ bool isApproved
) internal {
- if(partialValue > keyElement.value){
+ if (partialValue > keyElement.value) {
revert RuleConditionalTransfer_InvalidValueApproved();
}
- bytes32 key = keccak256(abi.encode(keyElement.from, keyElement.to, keyElement.value));
+ bytes32 key = keccak256(
+ abi.encode(keyElement.from, keyElement.to, keyElement.value)
+ );
TransferRequest memory transferRequest = transferRequests[key];
- if(partialValue > 0 ){
- if(! isApproved){
+ if (partialValue > 0) {
+ if (!isApproved) {
revert RuleConditionalTransfer_CannotDeniedPartially();
}
// Denied the first request
_approveRequest(transferRequest, false);
// Create new request
- _createTransferRequestWithApproval(TransferRequestKeyElement({from: keyElement.from, to: keyElement.to, value: partialValue}));
- }else{
+ _createTransferRequestWithApproval(
+ TransferRequestKeyElement({
+ from: keyElement.from,
+ to: keyElement.to,
+ value: partialValue
+ })
+ );
+ } else {
_approveRequest(transferRequest, isApproved);
}
}
function _createTransferRequestWithApproval(
TransferRequestKeyElement memory keyElement
- ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE){
+ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) {
// WAIT => Will overwrite
// APPROVED => will overwrite previous status with a new delay
// DENIED => will overwrite
- bytes32 key = keccak256(abi.encode(keyElement.from, keyElement.to, keyElement.value));
- if(_checkRequestStatus(key)){
- TransferRequest memory newTransferApproval = TransferRequest({
+ bytes32 key = keccak256(
+ abi.encode(keyElement.from, keyElement.to, keyElement.value)
+ );
+ if (_checkRequestStatus(key)) {
+ TransferRequest memory newTransferApproval = TransferRequest({
key: key,
id: requestId,
from: keyElement.from,
to: keyElement.to,
value: keyElement.value,
- askTime:0,
- maxTime : block.timestamp + options.timeLimit.timeLimitToTransfer,
- status:STATUS.APPROVED
- });
+ askTime: 0,
+ maxTime: block.timestamp +
+ options.timeLimit.timeLimitToTransfer,
+ status: STATUS.APPROVED
+ });
transferRequests[key] = newTransferApproval;
IdToKey[requestId] = key;
- emit transferApproved(key, keyElement.from, keyElement.to, keyElement.value, requestId);
+ emit transferApproved(
+ key,
+ keyElement.from,
+ keyElement.to,
+ keyElement.value,
+ requestId
+ );
++requestId;
} else {
// Overwrite previous approval
- transferRequests[key].maxTime = block.timestamp + options.timeLimit.timeLimitToTransfer;
+ transferRequests[key].maxTime =
+ block.timestamp +
+ options.timeLimit.timeLimitToTransfer;
transferRequests[key].status = STATUS.APPROVED;
- emit transferApproved(key, keyElement.from, keyElement.to, keyElement.value, transferRequests[key].id);
+ emit transferApproved(
+ key,
+ keyElement.from,
+ keyElement.to,
+ keyElement.value,
+ transferRequests[key].id
+ );
}
}
- function _resetRequestStatus(
- bytes32 key
- ) internal {
+ function _resetRequestStatus(bytes32 key) internal {
transferRequests[key].status = STATUS.NONE;
- emit transferReset(key, transferRequests[key].from, transferRequests[key].to, transferRequests[key].value, transferRequests[key].id );
+ emit transferReset(
+ key,
+ transferRequests[key].from,
+ transferRequests[key].to,
+ transferRequests[key].value,
+ transferRequests[key].id
+ );
}
- function _checkRequestStatus(bytes32 key) internal view returns(bool) {
+ function _checkRequestStatus(bytes32 key) internal view returns (bool) {
// Status NONE not enough because reset is possible
- return (transferRequests[key].status == STATUS.NONE) && (transferRequests[key].key == 0x0);
+ return
+ (transferRequests[key].status == STATUS.NONE) &&
+ (transferRequests[key].key == 0x0);
}
- function _approveRequest(TransferRequest memory transferRequest , bool isApproved) internal{
+ function _approveRequest(
+ TransferRequest memory transferRequest,
+ bool isApproved
+ ) internal {
// status
- if(transferRequest.status != STATUS.WAIT){
+ if (transferRequest.status != STATUS.WAIT) {
revert RuleConditionalTransfer_Wrong_Status();
}
- if(isApproved){
+ if (isApproved) {
// Time
- if(block.timestamp > (transferRequest.askTime + options.timeLimit.timeLimitToApprove)){
+ if (
+ block.timestamp >
+ (transferRequest.askTime + options.timeLimit.timeLimitToApprove)
+ ) {
revert RuleConditionalTransfer_timeExceeded();
}
// Set status
transferRequests[transferRequest.key].status = STATUS.APPROVED;
// Set max time
- transferRequests[transferRequest.key].maxTime = block.timestamp + options.timeLimit.timeLimitToTransfer;
- emit transferApproved(transferRequest.key, transferRequest.from, transferRequest.to, transferRequest.value, transferRequests[transferRequest.key].id );
- if(options.automaticTransfer.isActivate && address(options.automaticTransfer.cmtat) != address(0)){
+ transferRequests[transferRequest.key].maxTime =
+ block.timestamp +
+ options.timeLimit.timeLimitToTransfer;
+ emit transferApproved(
+ transferRequest.key,
+ transferRequest.from,
+ transferRequest.to,
+ transferRequest.value,
+ transferRequests[transferRequest.key].id
+ );
+ if (
+ options.automaticTransfer.isActivate &&
+ address(options.automaticTransfer.cmtat) != address(0)
+ ) {
// Transfer with approval
// External call
- if(options.automaticTransfer.cmtat.allowance(transferRequest.from, address(this)) >= transferRequest.value){
- // Will call the ruleEngine and the rule again...
- options.automaticTransfer.cmtat.safeTransferFrom(transferRequest.from, transferRequest.to, transferRequest.value);
- }
+ if (
+ options.automaticTransfer.cmtat.allowance(
+ transferRequest.from,
+ address(this)
+ ) >= transferRequest.value
+ ) {
+ // Will call the ruleEngine and the rule again...
+ options.automaticTransfer.cmtat.safeTransferFrom(
+ transferRequest.from,
+ transferRequest.to,
+ transferRequest.value
+ );
+ }
}
} else {
transferRequests[transferRequest.key].status = STATUS.DENIED;
- emit transferDenied(transferRequest.key, transferRequest.from, transferRequest.to, transferRequest.value, transferRequests[transferRequest.key].id );
+ emit transferDenied(
+ transferRequest.key,
+ transferRequest.from,
+ transferRequest.to,
+ transferRequest.value,
+ transferRequests[transferRequest.key].id
+ );
}
}
/**
- * @notice update the request during a transfer
- */
+ * @notice update the request during a transfer
+ */
function _updateProcessedTransfer(bytes32 key) internal {
- // Reset to zero
- transferRequests[key].maxTime = 0;
- transferRequests[key].askTime = 0;
- // Change status
- transferRequests[key].status = STATUS.EXECUTED;
- // Emit event
- emit transferProcessed(key, transferRequests[key].from, transferRequests[key].to, transferRequests[key].value, transferRequests[key].id);
+ // Reset to zero
+ transferRequests[key].maxTime = 0;
+ transferRequests[key].askTime = 0;
+ // Change status
+ transferRequests[key].status = STATUS.EXECUTED;
+ // Emit event
+ emit transferProcessed(
+ key,
+ transferRequests[key].from,
+ transferRequests[key].to,
+ transferRequests[key].value,
+ transferRequests[key].id
+ );
}
}
diff --git a/src/rules/validation/RuleBlacklist.sol b/src/rules/validation/RuleBlacklist.sol
index 78b5c53..2ac9028 100644
--- a/src/rules/validation/RuleBlacklist.sol
+++ b/src/rules/validation/RuleBlacklist.sol
@@ -2,30 +2,34 @@
pragma solidity ^0.8.20;
-import "./abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol";
+import "./abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol";
import "./abstract/RuleAddressList/RuleAddressList.sol";
import "./abstract/RuleValidateTransfer.sol";
+
/**
-* @title a blacklist manager
-*/
+ * @title a blacklist manager
+ */
-contract RuleBlacklist is RuleValidateTransfer, RuleAddressList, RuleBlacklistInvariantStorage {
+contract RuleBlacklist is
+ RuleValidateTransfer,
+ RuleAddressList,
+ RuleBlacklistInvariantStorage
+{
/**
- * @param admin Address of the contract (Access Control)
- * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- */
+ * @param admin Address of the contract (Access Control)
+ * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ */
constructor(
address admin,
address forwarderIrrevocable
- ) RuleAddressList(admin, forwarderIrrevocable) {
- }
+ ) RuleAddressList(admin, forwarderIrrevocable) {}
- /**
- * @notice Check if an addres is in the whitelist or not
- * @param _from the origin address
- * @param _to the destination address
- * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- **/
+ /**
+ * @notice Check if an addres is in the whitelist or not
+ * @param _from the origin address
+ * @param _to the destination address
+ * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ **/
function detectTransferRestriction(
address _from,
address _to,
@@ -40,11 +44,11 @@ contract RuleBlacklist is RuleValidateTransfer, RuleAddressList, RuleBlacklistIn
}
}
- /**
- * @notice To know if the restriction code is valid for this rule or not.
- * @param _restrictionCode The target restriction code
- * @return true if the restriction code is known, false otherwise
- **/
+ /**
+ * @notice To know if the restriction code is valid for this rule or not.
+ * @param _restrictionCode The target restriction code
+ * @return true if the restriction code is known, false otherwise
+ **/
function canReturnTransferRestrictionCode(
uint8 _restrictionCode
) external pure override returns (bool) {
@@ -53,11 +57,11 @@ contract RuleBlacklist is RuleValidateTransfer, RuleAddressList, RuleBlacklistIn
_restrictionCode == CODE_ADDRESS_TO_IS_BLACKLISTED;
}
- /**
- * @notice Return the corresponding message
- * @param _restrictionCode The target restriction code
- * @return true if the transfer is valid, false otherwise
- **/
+ /**
+ * @notice Return the corresponding message
+ * @param _restrictionCode The target restriction code
+ * @return true if the transfer is valid, false otherwise
+ **/
function messageForTransferRestriction(
uint8 _restrictionCode
) external pure override returns (string memory) {
diff --git a/src/rules/validation/RuleSanctionList.sol b/src/rules/validation/RuleSanctionList.sol
index b66434a..7c45113 100644
--- a/src/rules/validation/RuleSanctionList.sol
+++ b/src/rules/validation/RuleSanctionList.sol
@@ -6,22 +6,28 @@ import "OZ/access/AccessControl.sol";
import "../../modules/MetaTxModuleStandalone.sol";
import "./abstract/RuleSanctionListInvariantStorage.sol";
import "./abstract/RuleValidateTransfer.sol";
+
interface SanctionsList {
function isSanctioned(address addr) external view returns (bool);
}
-contract RuleSanctionList is AccessControl, MetaTxModuleStandalone, RuleValidateTransfer, RuleSanctionlistInvariantStorage {
- SanctionsList public sanctionsList;
+contract RuleSanctionList is
+ AccessControl,
+ MetaTxModuleStandalone,
+ RuleValidateTransfer,
+ RuleSanctionlistInvariantStorage
+{
+ SanctionsList public sanctionsList;
/**
- * @param admin Address of the contract (Access Control)
- * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- */
+ * @param admin Address of the contract (Access Control)
+ * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ */
constructor(
address admin,
address forwarderIrrevocable
) MetaTxModuleStandalone(forwarderIrrevocable) {
- if(admin == address(0)){
+ if (admin == address(0)) {
revert RuleSanctionList_AdminWithAddressZeroNotAllowed();
}
_grantRole(DEFAULT_ADMIN_ROLE, admin);
@@ -34,50 +40,50 @@ contract RuleSanctionList is AccessControl, MetaTxModuleStandalone, RuleValidat
* @dev zero address is authorized to authorize all transfers
*/
function setSanctionListOracle(
- address sanctionContractOracle_
+ address sanctionContractOracle_
) public onlyRole(SANCTIONLIST_ROLE) {
sanctionsList = SanctionsList(sanctionContractOracle_);
}
- /**
- * @notice Check if an addres is in the whitelist or not
- * @param _from the origin address
- * @param _to the destination address
- * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- **/
+ /**
+ * @notice Check if an addres is in the whitelist or not
+ * @param _from the origin address
+ * @param _to the destination address
+ * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ **/
function detectTransferRestriction(
address _from,
address _to,
uint256 /*_amount */
) public view override returns (uint8) {
- if(address(sanctionsList) != address(0)){
+ if (address(sanctionsList) != address(0)) {
if (sanctionsList.isSanctioned(_from)) {
return CODE_ADDRESS_FROM_IS_SANCTIONED;
} else if (sanctionsList.isSanctioned(_to)) {
- return CODE_ADDRESS_TO_IS_SANCTIONED;
+ return CODE_ADDRESS_TO_IS_SANCTIONED;
}
}
return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
}
- /**
- * @notice To know if the restriction code is valid for this rule or not.
- * @param _restrictionCode The target restriction code
- * @return true if the restriction code is known, false otherwise
- **/
+ /**
+ * @notice To know if the restriction code is valid for this rule or not.
+ * @param _restrictionCode The target restriction code
+ * @return true if the restriction code is known, false otherwise
+ **/
function canReturnTransferRestrictionCode(
uint8 _restrictionCode
) external pure override returns (bool) {
return
- _restrictionCode == CODE_ADDRESS_FROM_IS_SANCTIONED ||
+ _restrictionCode == CODE_ADDRESS_FROM_IS_SANCTIONED ||
_restrictionCode == CODE_ADDRESS_TO_IS_SANCTIONED;
}
- /**
- * @notice Return the corresponding message
- * @param _restrictionCode The target restriction code
- * @return true if the transfer is valid, false otherwise
- **/
+ /**
+ * @notice Return the corresponding message
+ * @param _restrictionCode The target restriction code
+ * @return true if the transfer is valid, false otherwise
+ **/
function messageForTransferRestriction(
uint8 _restrictionCode
) external pure override returns (string memory) {
@@ -90,9 +96,9 @@ contract RuleSanctionList is AccessControl, MetaTxModuleStandalone, RuleValidat
}
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
function _msgSender()
internal
view
@@ -102,9 +108,9 @@ contract RuleSanctionList is AccessControl, MetaTxModuleStandalone, RuleValidat
return ERC2771Context._msgSender();
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
function _msgData()
internal
view
@@ -114,10 +120,15 @@ contract RuleSanctionList is AccessControl, MetaTxModuleStandalone, RuleValidat
return ERC2771Context._msgData();
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
- function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _contextSuffixLength()
+ internal
+ view
+ override(ERC2771Context, Context)
+ returns (uint256)
+ {
return ERC2771Context._contextSuffixLength();
}
-}
\ No newline at end of file
+}
diff --git a/src/rules/validation/RuleWhitelist.sol b/src/rules/validation/RuleWhitelist.sol
index db73956..eac668b 100644
--- a/src/rules/validation/RuleWhitelist.sol
+++ b/src/rules/validation/RuleWhitelist.sol
@@ -2,30 +2,34 @@
pragma solidity ^0.8.20;
-import "./abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol";
+import "./abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol";
import "./abstract/RuleAddressList/RuleAddressList.sol";
import "./abstract/RuleValidateTransfer.sol";
+
/**
-* @title a whitelist manager
-*/
+ * @title a whitelist manager
+ */
-contract RuleWhitelist is RuleValidateTransfer, RuleAddressList, RuleWhitelistInvariantStorage {
+contract RuleWhitelist is
+ RuleValidateTransfer,
+ RuleAddressList,
+ RuleWhitelistInvariantStorage
+{
/**
- * @param admin Address of the contract (Access Control)
- * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- */
+ * @param admin Address of the contract (Access Control)
+ * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ */
constructor(
address admin,
address forwarderIrrevocable
- ) RuleAddressList(admin, forwarderIrrevocable) {
- }
+ ) RuleAddressList(admin, forwarderIrrevocable) {}
- /**
- * @notice Check if an addres is in the whitelist or not
- * @param _from the origin address
- * @param _to the destination address
- * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
- **/
+ /**
+ * @notice Check if an addres is in the whitelist or not
+ * @param _from the origin address
+ * @param _to the destination address
+ * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ **/
function detectTransferRestriction(
address _from,
address _to,
@@ -33,18 +37,18 @@ contract RuleWhitelist is RuleValidateTransfer, RuleAddressList, RuleWhitelistIn
) public view override returns (uint8) {
if (!addressIsListed(_from)) {
return CODE_ADDRESS_FROM_NOT_WHITELISTED;
- } else if (! addressIsListed(_to)) {
+ } else if (!addressIsListed(_to)) {
return CODE_ADDRESS_TO_NOT_WHITELISTED;
} else {
return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
}
}
- /**
- * @notice To know if the restriction code is valid for this rule or not
- * @param _restrictionCode The target restriction code
- * @return true if the restriction code is known, false otherwise
- **/
+ /**
+ * @notice To know if the restriction code is valid for this rule or not
+ * @param _restrictionCode The target restriction code
+ * @return true if the restriction code is known, false otherwise
+ **/
function canReturnTransferRestrictionCode(
uint8 _restrictionCode
) external pure override returns (bool) {
@@ -53,11 +57,11 @@ contract RuleWhitelist is RuleValidateTransfer, RuleAddressList, RuleWhitelistIn
_restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED;
}
- /**
- * @notice Return the corresponding message
- * @param _restrictionCode The target restriction code
- * @return true if the transfer is valid, false otherwise
- **/
+ /**
+ * @notice Return the corresponding message
+ * @param _restrictionCode The target restriction code
+ * @return true if the transfer is valid, false otherwise
+ **/
function messageForTransferRestriction(
uint8 _restrictionCode
) external pure override returns (string memory) {
diff --git a/src/rules/validation/RuleWhitelistWrapper.sol b/src/rules/validation/RuleWhitelistWrapper.sol
new file mode 100644
index 0000000..7038bac
--- /dev/null
+++ b/src/rules/validation/RuleWhitelistWrapper.sol
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: MPL-2.0
+
+pragma solidity ^0.8.20;
+
+import "OZ/access/AccessControl.sol";
+import "../../modules/RuleEngineValidationCommon.sol";
+import "../../modules/MetaTxModuleStandalone.sol";
+import "./abstract/RuleValidateTransfer.sol";
+import "./abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol";
+import "./abstract/RuleAddressList/RuleAddressList.sol";
+
+/**
+ * @title Wrapper to call several different whitelist rules
+ */
+contract RuleWhitelistWrapper is
+ RuleEngineValidationCommon,
+ MetaTxModuleStandalone,
+ RuleValidateTransfer,
+ RuleWhitelistInvariantStorage
+{
+ /**
+ * @param admin Address of the contract (Access Control)
+ * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ */
+ constructor(
+ address admin,
+ address forwarderIrrevocable
+ ) MetaTxModuleStandalone(forwarderIrrevocable) {
+ if (admin == address(0)) {
+ revert RuleEngine_AdminWithAddressZeroNotAllowed();
+ }
+ _grantRole(DEFAULT_ADMIN_ROLE, admin);
+ _grantRole(RULE_ENGINE_OPERATOR_ROLE, admin);
+ }
+
+ /**
+ * @notice Go through all the whitelist rules to know if a restriction exists on the transfer
+ * @param _from the origin address
+ * @param _to the destination address
+ * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK
+ **/
+ function detectTransferRestriction(
+ address _from,
+ address _to,
+ uint256 /*_amount*/
+ ) public view override returns (uint8) {
+ address[] memory targetAddress = new address[](2);
+ bool[] memory isListed = new bool[](2);
+ bool[] memory result = new bool[](2);
+ targetAddress[0] = _from;
+ targetAddress[1] = _to;
+ uint256 rulesLength = _rulesValidation.length;
+ // For each whitelist rule, we ask if from or to are in the whitelist
+ for (uint256 i = 0; i < rulesLength; ++i) {
+ // External call
+ isListed = RuleAddressList(_rulesValidation[i])
+ .addressIsListedBatch(targetAddress);
+ if (isListed[0] && !result[0]) {
+ // Update if from is in the list
+ result[0] = true;
+ }
+ if (isListed[1] && !result[1]) {
+ // Update if to is in the list
+ result[1] = true;
+ }
+ }
+ if (!result[0]) {
+ return CODE_ADDRESS_FROM_NOT_WHITELISTED;
+ } else if (!result[1]) {
+ return CODE_ADDRESS_TO_NOT_WHITELISTED;
+ } else {
+ return uint8(REJECTED_CODE_BASE.TRANSFER_OK);
+ }
+ }
+
+ /**
+ * @notice To know if the restriction code is valid for this rule or not
+ * @param _restrictionCode The target restriction code
+ * @return true if the restriction code is known, false otherwise
+ **/
+ function canReturnTransferRestrictionCode(
+ uint8 _restrictionCode
+ ) external pure override returns (bool) {
+ return
+ _restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED ||
+ _restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED;
+ }
+
+ /**
+ * @notice Return the corresponding message
+ * @param _restrictionCode The target restriction code
+ * @return true if the transfer is valid, false otherwise
+ **/
+ function messageForTransferRestriction(
+ uint8 _restrictionCode
+ ) external pure override returns (string memory) {
+ if (_restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED) {
+ return TEXT_ADDRESS_FROM_NOT_WHITELISTED;
+ } else if (_restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED) {
+ return TEXT_ADDRESS_TO_NOT_WHITELISTED;
+ } else {
+ return TEXT_CODE_NOT_FOUND;
+ }
+ }
+
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _msgSender()
+ internal
+ view
+ override(ERC2771Context, Context)
+ returns (address sender)
+ {
+ return ERC2771Context._msgSender();
+ }
+
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _msgData()
+ internal
+ view
+ override(ERC2771Context, Context)
+ returns (bytes calldata)
+ {
+ return ERC2771Context._msgData();
+ }
+
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _contextSuffixLength()
+ internal
+ view
+ override(ERC2771Context, Context)
+ returns (uint256)
+ {
+ return ERC2771Context._contextSuffixLength();
+ }
+}
diff --git a/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol b/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol
index 7827916..0caddc0 100644
--- a/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol
+++ b/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol
@@ -5,26 +5,30 @@ pragma solidity ^0.8.20;
import "OZ/access/AccessControl.sol";
import "./../../../../modules/MetaTxModuleStandalone.sol";
import "./RuleAddressListInternal.sol";
-import "./RuleAddressListInvariantStorage.sol";
+import "./invariantStorage/RuleAddressListInvariantStorage.sol";
+
/**
@title an addresses list manager
*/
-abstract contract RuleAddressList is AccessControl, MetaTxModuleStandalone, RuleAddressListInternal, RuleAddressListInvariantStorage {
-
-
+abstract contract RuleAddressList is
+ AccessControl,
+ MetaTxModuleStandalone,
+ RuleAddressListInternal,
+ RuleAddressListInvariantStorage
+{
// Number of addresses in the whitelist at the moment
uint256 private numAddressesWhitelisted;
-
+
/**
- * @param admin Address of the contract (Access Control)
- * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
- */
+ * @param admin Address of the contract (Access Control)
+ * @param forwarderIrrevocable Address of the forwarder, required for the gasless support
+ */
constructor(
address admin,
address forwarderIrrevocable
) MetaTxModuleStandalone(forwarderIrrevocable) {
- if(admin == address(0)){
+ if (admin == address(0)) {
revert RuleAddressList_AdminWithAddressZeroNotAllowed();
}
_grantRole(DEFAULT_ADMIN_ROLE, admin);
@@ -39,12 +43,12 @@ abstract contract RuleAddressList is AccessControl, MetaTxModuleStandalone, Rule
function addAddressesToTheList(
address[] calldata listWhitelistedAddress
) public onlyRole(ADDRESS_LIST_ROLE) {
- _addAddressesToThelist(listWhitelistedAddress);
+ _addAddressesToThelist(listWhitelistedAddress);
}
/**
* @notice Remove addresses from the whitelist
- * If the address does not exist in the whitelist, there is no change for this address.
+ * If the address does not exist in the whitelist, there is no change for this address.
* The transaction remains valid (no revert).
* @param listWhitelistedAddress an array with the addresses to remove
*/
@@ -74,7 +78,7 @@ abstract contract RuleAddressList is AccessControl, MetaTxModuleStandalone, Rule
function removeAddressFromTheList(
address _removeWhitelistAddress
) public onlyRole(ADDRESS_LIST_ROLE) {
- _removeAddressFromThelist( _removeWhitelistAddress);
+ _removeAddressFromThelist(_removeWhitelistAddress);
}
/**
@@ -86,7 +90,6 @@ abstract contract RuleAddressList is AccessControl, MetaTxModuleStandalone, Rule
return _numberListedAddress();
}
-
/**
* @notice Know if an address is listed or not
* @param _targetAddress The concerned address
@@ -99,10 +102,23 @@ abstract contract RuleAddressList is AccessControl, MetaTxModuleStandalone, Rule
return _addressIsListed(_targetAddress);
}
+ /**
+ * @notice batch version of {addressIsListed}
+ *
+ */
+ function addressIsListedBatch(
+ address[] memory _targetAddresses
+ ) public view returns (bool[] memory) {
+ bool[] memory isListed = new bool[](_targetAddresses.length);
+ for (uint256 i = 0; i < _targetAddresses.length; ++i) {
+ isListed[i] = _addressIsListed(_targetAddresses[i]);
+ }
+ return isListed;
+ }
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
function _msgSender()
internal
view
@@ -112,9 +128,9 @@ abstract contract RuleAddressList is AccessControl, MetaTxModuleStandalone, Rule
return ERC2771Context._msgSender();
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
function _msgData()
internal
view
@@ -124,10 +140,15 @@ abstract contract RuleAddressList is AccessControl, MetaTxModuleStandalone, Rule
return ERC2771Context._msgData();
}
- /**
- * @dev This surcharge is not necessary if you do not use the MetaTxModule
- */
- function _contextSuffixLength() internal view override(ERC2771Context, Context) returns (uint256) {
+ /**
+ * @dev This surcharge is not necessary if you do not use the MetaTxModule
+ */
+ function _contextSuffixLength()
+ internal
+ view
+ override(ERC2771Context, Context)
+ returns (uint256)
+ {
return ERC2771Context._contextSuffixLength();
}
}
diff --git a/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol b/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol
index bbeac04..862618c 100644
--- a/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol
+++ b/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol
@@ -3,28 +3,25 @@
pragma solidity ^0.8.20;
/**
-* @title a list manager
-*/
+ * @title a list manager
+ */
abstract contract RuleAddressListInternal {
error Rulelist_AddressAlreadylisted();
error Rulelist_AddressNotPresent();
-
+
mapping(address => bool) private list;
// Number of addresses in the list at the moment
uint256 private numAddressesList;
-
/**
* @notice Add addresses to the list
* If one of addresses already exist, there is no change for this address. The transaction remains valid (no revert).
* @param listAddresses an array with the addresses to list
*/
- function _addAddressesToThelist(
- address[] calldata listAddresses
- ) internal {
+ function _addAddressesToThelist(address[] calldata listAddresses) internal {
uint256 numAddressesListLocal = numAddressesList;
- for (uint256 i = 0; i < listAddresses.length; ++i ) {
+ for (uint256 i = 0; i < listAddresses.length; ++i) {
if (!list[listAddresses[i]]) {
list[listAddresses[i]] = true;
++numAddressesListLocal;
@@ -35,7 +32,7 @@ abstract contract RuleAddressListInternal {
/**
* @notice Remove addresses from the list
- * If the address does not exist in the list, there is no change for this address.
+ * If the address does not exist in the list, there is no change for this address.
* The transaction remains valid (no revert).
* @param listAddresses an array with the addresses to remove
*/
@@ -43,7 +40,7 @@ abstract contract RuleAddressListInternal {
address[] calldata listAddresses
) internal {
uint256 numAddressesListLocal = numAddressesList;
- for (uint256 i = 0; i < listAddresses.length; ++i ) {
+ for (uint256 i = 0; i < listAddresses.length; ++i) {
if (list[listAddresses[i]]) {
list[listAddresses[i]] = false;
--numAddressesListLocal;
@@ -57,11 +54,8 @@ abstract contract RuleAddressListInternal {
* If the address already exists, the transaction is reverted to save gas.
* @param _newlistAddress The address to list
*/
- function _addAddressToThelist(
- address _newlistAddress
- ) internal {
- if(list[_newlistAddress])
- {
+ function _addAddressToThelist(address _newlistAddress) internal {
+ if (list[_newlistAddress]) {
revert Rulelist_AddressAlreadylisted();
}
list[_newlistAddress] = true;
@@ -74,10 +68,8 @@ abstract contract RuleAddressListInternal {
* @param _removelistAddress The address to remove
*
*/
- function _removeAddressFromThelist(
- address _removelistAddress
- ) internal {
- if(!list[_removelistAddress]){
+ function _removeAddressFromThelist(address _removelistAddress) internal {
+ if (!list[_removelistAddress]) {
revert Rulelist_AddressNotPresent();
}
list[_removelistAddress] = false;
diff --git a/src/rules/validation/abstract/RuleAddressList/RuleAddressListInvariantStorage.sol b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol
similarity index 80%
rename from src/rules/validation/abstract/RuleAddressList/RuleAddressListInvariantStorage.sol
rename to src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol
index 7c39001..6f7ba17 100644
--- a/src/rules/validation/abstract/RuleAddressList/RuleAddressListInvariantStorage.sol
+++ b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol
@@ -2,10 +2,10 @@
pragma solidity ^0.8.20;
-abstract contract RuleAddressListInvariantStorage{
+abstract contract RuleAddressListInvariantStorage {
// custom errors
error RuleAddressList_AdminWithAddressZeroNotAllowed();
-
+
// Role
bytes32 public constant ADDRESS_LIST_ROLE = keccak256("ADDRESS_LIST_ROLE");
-}
\ No newline at end of file
+}
diff --git a/src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol
similarity index 92%
rename from src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol
rename to src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol
index c363cf8..4543254 100644
--- a/src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol
+++ b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol
@@ -2,9 +2,9 @@
pragma solidity ^0.8.20;
-import "../RuleCommonInvariantStorage.sol";
-abstract contract RuleBlacklistInvariantStorage is RuleCommonInvariantStorage {
+import "../../RuleCommonInvariantStorage.sol";
+abstract contract RuleBlacklistInvariantStorage is RuleCommonInvariantStorage {
// String
string constant TEXT_ADDRESS_FROM_IS_BLACKLISTED =
"The sender is not in the whitelist";
@@ -15,4 +15,4 @@ abstract contract RuleBlacklistInvariantStorage is RuleCommonInvariantStorage {
// It is very important that each rule uses an unique code
uint8 public constant CODE_ADDRESS_FROM_IS_BLACKLISTED = 41;
uint8 public constant CODE_ADDRESS_TO_IS_BLACKLISTED = 42;
-}
\ No newline at end of file
+}
diff --git a/src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol
similarity index 92%
rename from src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol
rename to src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol
index 85b90bf..fd5848b 100644
--- a/src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol
+++ b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol
@@ -2,9 +2,9 @@
pragma solidity ^0.8.20;
-import "../RuleCommonInvariantStorage.sol";
-abstract contract RuleWhitelistInvariantStorage is RuleCommonInvariantStorage {
+import "../../RuleCommonInvariantStorage.sol";
+abstract contract RuleWhitelistInvariantStorage is RuleCommonInvariantStorage {
// String
string constant TEXT_ADDRESS_FROM_NOT_WHITELISTED =
"The sender is not in the whitelist";
@@ -15,4 +15,4 @@ abstract contract RuleWhitelistInvariantStorage is RuleCommonInvariantStorage {
// It is very important that each rule uses an unique code
uint8 public constant CODE_ADDRESS_FROM_NOT_WHITELISTED = 21;
uint8 public constant CODE_ADDRESS_TO_NOT_WHITELISTED = 22;
-}
\ No newline at end of file
+}
diff --git a/src/rules/validation/abstract/RuleCommonInvariantStorage.sol b/src/rules/validation/abstract/RuleCommonInvariantStorage.sol
index f34ae39..855e72f 100644
--- a/src/rules/validation/abstract/RuleCommonInvariantStorage.sol
+++ b/src/rules/validation/abstract/RuleCommonInvariantStorage.sol
@@ -4,4 +4,4 @@ pragma solidity ^0.8.20;
abstract contract RuleCommonInvariantStorage {
// Text
string constant TEXT_CODE_NOT_FOUND = "Unknown restriction code";
-}
\ No newline at end of file
+}
diff --git a/src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol b/src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol
index 36a1fc9..f496498 100644
--- a/src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol
+++ b/src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol
@@ -3,23 +3,25 @@
pragma solidity ^0.8.20;
import "./RuleCommonInvariantStorage.sol";
-abstract contract RuleSanctionlistInvariantStorage is RuleCommonInvariantStorage {
+
+abstract contract RuleSanctionlistInvariantStorage is
+ RuleCommonInvariantStorage
+{
// custom errors
error RuleSanctionList_AdminWithAddressZeroNotAllowed();
error RuleSanctionList_AddressAlreadyWhitelisted();
-
+
// Role
bytes32 public constant SANCTIONLIST_ROLE = keccak256("SANCTIONLIST_ROLE");
-
+
// Text
string constant TEXT_ADDRESS_FROM_IS_SANCTIONED =
"The sender is sanctioned";
string constant TEXT_ADDRESS_TO_IS_SANCTIONED =
"The recipient is sanctioned";
-
// Code
// It is very important that each rule uses an unique code
uint8 public constant CODE_ADDRESS_FROM_IS_SANCTIONED = 31;
uint8 public constant CODE_ADDRESS_TO_IS_SANCTIONED = 32;
-}
\ No newline at end of file
+}
diff --git a/src/rules/validation/abstract/RuleValidateTransfer.sol b/src/rules/validation/abstract/RuleValidateTransfer.sol
index b1cf14f..b6844b2 100644
--- a/src/rules/validation/abstract/RuleValidateTransfer.sol
+++ b/src/rules/validation/abstract/RuleValidateTransfer.sol
@@ -4,14 +4,14 @@ pragma solidity ^0.8.20;
import "../../../interfaces/IRuleValidation.sol";
-abstract contract RuleValidateTransfer is IRuleValidation{
- /**
- * @notice Validate a transfer
- * @param _from the origin address
- * @param _to the destination address
- * @param _amount to transfer
- * @return isValid => true if the transfer is valid, false otherwise
- **/
+abstract contract RuleValidateTransfer is IRuleValidation {
+ /**
+ * @notice Validate a transfer
+ * @param _from the origin address
+ * @param _to the destination address
+ * @param _amount to transfer
+ * @return isValid => true if the transfer is valid, false otherwise
+ **/
function validateTransfer(
address _from,
address _to,
diff --git a/test/HelperContract.sol b/test/HelperContract.sol
index f8a351c..6027ad7 100644
--- a/test/HelperContract.sol
+++ b/test/HelperContract.sol
@@ -14,18 +14,27 @@ import "src/rules/validation/RuleSanctionList.sol";
import "src/rules/validation/RuleBlacklist.sol";
// RuleWhitelist
import "src/rules/validation/RuleWhitelist.sol";
-import "src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol";
-import "src/rules/validation/abstract/RuleAddressList/RuleAddressListInvariantStorage.sol";
+import "src/rules/validation/RuleWhitelistWrapper.sol";
+import "src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol";
+import "src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol";
import "src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol";
import "src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol";
// Rule interface
import "src/interfaces/IRuleValidation.sol";
import "src/interfaces/IRuleOperation.sol";
+
/**
-* @title Constants used by the tests
-*/
-abstract contract HelperContract is RuleWhitelistInvariantStorage, RuleBlacklistInvariantStorage, RuleAddressListInvariantStorage, RuleSanctionlistInvariantStorage, RuleEngineInvariantStorage, RuleConditionalTransferInvariantStorage {
+ * @title Constants used by the tests
+ */
+abstract contract HelperContract is
+ RuleWhitelistInvariantStorage,
+ RuleBlacklistInvariantStorage,
+ RuleAddressListInvariantStorage,
+ RuleSanctionlistInvariantStorage,
+ RuleEngineInvariantStorage,
+ RuleConditionalTransferInvariantStorage
+{
// EOA to perform tests
address constant ZERO_ADDRESS = address(0);
address constant DEFAULT_ADMIN_ADDRESS = address(1);
@@ -44,8 +53,8 @@ abstract contract HelperContract is RuleWhitelistInvariantStorage, RuleBlacklist
"0xdc72ed553f2544c34465af23b847953efeb813428162d767f9ba5f4013be6760";
string constant DEFAULT_ADMIN_ROLE_HASH =
"0x0000000000000000000000000000000000000000000000000000000000000000";
-
- uint256 DEFAULT_TIME_LIMIT_TO_APPROVE = 7 days;
+
+ uint256 DEFAULT_TIME_LIMIT_TO_APPROVE = 7 days;
uint256 DEFAULT_TIME_LIMIT_TO_TRANSFER = 7 days;
// contract
RuleBlacklist ruleBlacklist;
@@ -58,9 +67,10 @@ abstract contract HelperContract is RuleWhitelistInvariantStorage, RuleBlacklist
uint8 constant NO_ERROR = 0;
// Forwarder
- string ERC2771ForwarderDomain = 'ERC2771ForwarderDomain';
+ string ERC2771ForwarderDomain = "ERC2771ForwarderDomain";
error Rulelist_AddressAlreadylisted();
error Rulelist_AddressNotPresent();
+
constructor() {}
}
diff --git a/test/RuleBlacklist/CMTATIntegration.t.sol b/test/RuleBlacklist/CMTATIntegration.t.sol
index de366f5..f8c387d 100644
--- a/test/RuleBlacklist/CMTATIntegration.t.sol
+++ b/test/RuleBlacklist/CMTATIntegration.t.sol
@@ -7,8 +7,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Integration test with the CMTAT
-*/
+ * @title Integration test with the CMTAT
+ */
contract CMTATIntegration is Test, HelperContract {
// Defined in CMTAT.sol
uint8 constant TRANSFER_OK = 0;
@@ -47,7 +47,11 @@ contract CMTATIntegration is Test, HelperContract {
// specific arrange
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleEngineMock = new RuleEngine(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS, address(CMTAT_CONTRACT));
+ ruleEngineMock = new RuleEngine(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS,
+ address(CMTAT_CONTRACT)
+ );
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleEngineMock.addRuleValidation(ruleBlacklist);
vm.prank(DEFAULT_ADMIN_ADDRESS);
@@ -80,7 +84,13 @@ contract CMTATIntegration is Test, HelperContract {
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, amount));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ amount
+ )
+ );
// Act
CMTAT_CONTRACT.transfer(ADDRESS2, amount);
}
@@ -93,7 +103,13 @@ contract CMTATIntegration is Test, HelperContract {
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, amount));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ amount
+ )
+ );
// Act
CMTAT_CONTRACT.transfer(ADDRESS2, amount);
}
@@ -112,12 +128,17 @@ contract CMTATIntegration is Test, HelperContract {
)
);
require(success);
-
// Act
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, amount));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ amount
+ )
+ );
CMTAT_CONTRACT.transfer(ADDRESS2, amount);
}
@@ -238,7 +259,13 @@ contract CMTATIntegration is Test, HelperContract {
// Act
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ZERO_ADDRESS, ADDRESS1, amount));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ZERO_ADDRESS,
+ ADDRESS1,
+ amount
+ )
+ );
vm.prank(DEFAULT_ADMIN_ADDRESS);
CMTAT_CONTRACT.mint(ADDRESS1, amount);
}
diff --git a/test/RuleBlacklist/RuleBlacklist.t.sol b/test/RuleBlacklist/RuleBlacklist.t.sol
index f4dbbed..2e73349 100644
--- a/test/RuleBlacklist/RuleBlacklist.t.sol
+++ b/test/RuleBlacklist/RuleBlacklist.t.sol
@@ -7,8 +7,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Integration test with the CMTAT
-*/
+ * @title Integration test with the CMTAT
+ */
contract RuleBlacklistTest is Test, HelperContract {
// Defined in CMTAT.sol
uint8 constant TRANSFER_OK = 0;
@@ -23,7 +23,10 @@ contract RuleBlacklistTest is Test, HelperContract {
ruleBlacklist = new RuleBlacklist(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS);
}
- function testCanRuleBlacklistReturnMessageNotFoundWithUnknownCodeId() public view {
+ function testCanRuleBlacklistReturnMessageNotFoundWithUnknownCodeId()
+ public
+ view
+ {
// Act
string memory message1 = ruleBlacklist.messageForTransferRestriction(
255
diff --git a/test/RuleConditionalTransfer/CMTATIntegration.t.sol b/test/RuleConditionalTransfer/CMTATIntegration.t.sol
index 5b6f002..67221e0 100644
--- a/test/RuleConditionalTransfer/CMTATIntegration.t.sol
+++ b/test/RuleConditionalTransfer/CMTATIntegration.t.sol
@@ -7,8 +7,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Integration test with the CMTAT
-*/
+ * @title Integration test with the CMTAT
+ */
contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Defined in CMTAT.sol
uint8 constant TRANSFER_OK = 0;
@@ -25,15 +25,15 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
uint256 FLAG = 5;
uint256 defaultValue = 10;
- bytes32 defaultKey = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ bytes32 defaultKey =
+ keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
- TransferRequestKeyElement transferRequestInput = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:defaultValue
- });
-
-
+ value: defaultValue
+ });
// Arrange
function setUp() public {
@@ -42,8 +42,8 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
timeLimitToTransfer: 30 days
});
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:true,
- authorizedBurnWithoutApproval:true
+ authorizedMintWithoutApproval: true,
+ authorizedBurnWithoutApproval: true
});
AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
@@ -52,16 +52,16 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
});
AUTOMATIC_TRANSFER memory automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
+ isActivate: false,
cmtat: IERC20(address(0))
});
OPTION memory options = OPTION({
- issuance:issuanceOption_,
+ issuance: issuanceOption_,
timeLimit: timeLimit_,
automaticApproval: automaticApproval_,
- automaticTransfer:automaticTransfer_
+ automaticTransfer: automaticTransfer_
});
-
+
// global arrange
uint8 decimals = 0;
vm.prank(DEFAULT_ADMIN_ADDRESS);
@@ -79,22 +79,28 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
FLAG
);
-
// RuleEngine
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleEngineMock = new RuleEngine(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS, address(CMTAT_CONTRACT));
+ ruleEngineMock = new RuleEngine(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS,
+ address(CMTAT_CONTRACT)
+ );
// RuleConditionalTransfer
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleConditionalTransfer = new RuleConditionalTransfer(
DEFAULT_ADMIN_ADDRESS,
ZERO_ADDRESS,
- ruleEngineMock,
+ ruleEngineMock,
options
);
- // specific arrange
+ // specific arrange
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleConditionalTransfer.grantRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE, CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.grantRole(
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE,
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS
+ );
// RuleEngine
vm.prank(DEFAULT_ADMIN_ADDRESS);
@@ -108,12 +114,12 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
vm.prank(DEFAULT_ADMIN_ADDRESS);
CMTAT_CONTRACT.mint(ADDRESS3, ADDRESS3_BALANCE_INIT);
vm.prank(DEFAULT_ADMIN_ADDRESS);
-
+
// We set the Rule Engine
CMTAT_CONTRACT.setRuleEngine(ruleEngineMock);
}
- function _createTransferRequest() internal{
+ function _createTransferRequest() internal {
vm.prank(ADDRESS1);
// Act
vm.expectEmit(true, true, true, true);
@@ -126,7 +132,13 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Arrange
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, 21));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ 21
+ )
+ );
// Act
CMTAT_CONTRACT.transfer(ADDRESS2, 21);
}
@@ -135,49 +147,56 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Arrange
vm.prank(ADDRESS1);
// Act
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2,defaultValue));
- ruleConditionalTransfer.createTransferRequest(ADDRESS2,defaultValue);
-
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2,defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, true);
+ emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// Act
vm.expectEmit(true, true, true, true);
emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
// Assert
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT -defaultValue);
+ assertEq(resUint256, ADDRESS1_BALANCE_INIT - defaultValue);
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
- assertEq(resUint256, ADDRESS2_BALANCE_INIT +defaultValue);
+ assertEq(resUint256, ADDRESS2_BALANCE_INIT + defaultValue);
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
assertEq(resUint256, 33);
}
function testCanMakeAPartialTransferIfPartiallyApproved() public {
-
// Arrange
_createTransferRequest();
uint256 partialValue = 5;
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2,partialValue));
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, partialValue, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ true
+ );
// Act
vm.expectEmit(true, true, true, true);
emit transferProcessed(key, ADDRESS1, ADDRESS2, partialValue, 1);
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,partialValue);
+ CMTAT_CONTRACT.transfer(ADDRESS2, partialValue);
// Assert
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
@@ -192,58 +211,81 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Arrange
_createTransferRequest();
uint256 partialValue = 5;
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2,partialValue));
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, partialValue, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ true
+ );
// Act
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, defaultValue));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
vm.prank(ADDRESS1);
CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
-
function testCannotMakeATransferIfDelayExceeded() public {
// Arrange
vm.prank(ADDRESS1);
// Act
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2,defaultValue));
- ruleConditionalTransfer.createTransferRequest(ADDRESS2,defaultValue);
-
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2,defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
+ emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// +30 days and one second
vm.warp(block.timestamp + 2592001);
// Act
- vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2,defaultValue));
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
function testCannotMakeATransferIfDelayJustInTime() public {
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferApproved(defaultKey, ADDRESS1, ADDRESS2,defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
+ emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// 30 days
vm.warp(block.timestamp + 2592000);
// Act
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
function testCanSetTimeLimitWithTransferExceeded() public {
@@ -257,8 +299,11 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Arrange
_createTransferRequest();
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
-
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// Assert
// Timeout
@@ -266,10 +311,15 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
vm.warp(block.timestamp + 1 days + 1 seconds);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2,defaultValue));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
-
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
function testCanMintWithoutApproval() public {
@@ -285,7 +335,7 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
function testCanBurnWithoutApproval() public {
// Act
vm.prank(DEFAULT_ADMIN_ADDRESS);
- CMTAT_CONTRACT.burn(ADDRESS1,defaultValue, "test");
+ CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "test");
// Assert
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
@@ -294,54 +344,70 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
function testCannotMintWithoutApproval() public {
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:true
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: true
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
// Act
vm.prank(DEFAULT_ADMIN_ADDRESS);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ZERO_ADDRESS , ADDRESS1, 11));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ZERO_ADDRESS,
+ ADDRESS1,
+ 11
+ )
+ );
CMTAT_CONTRACT.mint(ADDRESS1, 11);
}
function testCannotBurnWithoutApproval() public {
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:true,
- authorizedBurnWithoutApproval:false
+ authorizedMintWithoutApproval: true,
+ authorizedBurnWithoutApproval: false
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
// Act
vm.prank(DEFAULT_ADMIN_ADDRESS);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ZERO_ADDRESS, defaultValue));
- CMTAT_CONTRACT.burn(ADDRESS1,defaultValue, "test");
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ZERO_ADDRESS,
+ defaultValue
+ )
+ );
+ CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "test");
}
function testAutomaticTransferIfOptionsSet() public {
- AUTOMATIC_TRANSFER memory automaticTransferTest = AUTOMATIC_TRANSFER({
- isActivate:true,
+ AUTOMATIC_TRANSFER memory automaticTransferTest = AUTOMATIC_TRANSFER({
+ isActivate: true,
cmtat: CMTAT_CONTRACT
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setAutomaticTransfer(automaticTransferTest);
-
+
// Aproval
vm.prank(ADDRESS1);
CMTAT_CONTRACT.approve(address(ruleConditionalTransfer), defaultValue);
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferApproved(defaultKey, ADDRESS1, ADDRESS2,defaultValue, 0);
+ emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2,defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
+ emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
}
function testCanTransferIfAutomaticApprovalSetAndTimeExceeds() public {
@@ -351,35 +417,42 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
+
// Arrange
_createTransferRequest();
-
+
vm.warp(block.timestamp + 90 days);
// Act
vm.prank(ADDRESS1);
vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2,defaultValue, 0);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
- function testCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds() public {
+ function testCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds()
+ public
+ {
AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
isActivate: true,
timeLimitBeforeAutomaticApproval: 90 days
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
+
// Arrange
_createTransferRequest();
-
vm.warp(block.timestamp + 92 days);
// Act
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, defaultValue));
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
}
diff --git a/test/RuleConditionalTransfer/CMTATIntegrationWhitelist.t .sol b/test/RuleConditionalTransfer/CMTATIntegrationWhitelist.t .sol
index 64f5664..e0ff4e8 100644
--- a/test/RuleConditionalTransfer/CMTATIntegrationWhitelist.t .sol
+++ b/test/RuleConditionalTransfer/CMTATIntegrationWhitelist.t .sol
@@ -7,8 +7,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Integration test with the CMTAT
-*/
+ * @title Integration test with the CMTAT
+ */
contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Defined in CMTAT.sol
uint8 constant TRANSFER_OK = 0;
@@ -25,15 +25,15 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
uint256 FLAG = 5;
uint256 defaultValue = 10;
- bytes32 defaultKey = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ bytes32 defaultKey =
+ keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
- TransferRequestKeyElement transferRequestInput = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:defaultValue
- });
-
-
+ value: defaultValue
+ });
// Arrange
function setUp() public {
@@ -42,8 +42,8 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
timeLimitToTransfer: 30 days
});
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:true,
- authorizedBurnWithoutApproval:true
+ authorizedMintWithoutApproval: true,
+ authorizedBurnWithoutApproval: true
});
AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
@@ -52,16 +52,16 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
});
AUTOMATIC_TRANSFER memory automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
+ isActivate: false,
cmtat: IERC20(address(0))
});
OPTION memory options = OPTION({
- issuance:issuanceOption_,
+ issuance: issuanceOption_,
timeLimit: timeLimit_,
automaticApproval: automaticApproval_,
- automaticTransfer:automaticTransfer_
+ automaticTransfer: automaticTransfer_
});
-
+
// global arrange
uint8 decimals = 0;
vm.prank(DEFAULT_ADMIN_ADDRESS);
@@ -79,28 +79,34 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
FLAG
);
-
// Whitelist
ruleWhitelist = new RuleWhitelist(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS);
-
+
// RuleEngine
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleEngineMock = new RuleEngine(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS, address(CMTAT_CONTRACT));
+ ruleEngineMock = new RuleEngine(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS,
+ address(CMTAT_CONTRACT)
+ );
// RuleConditionalTransfer
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleConditionalTransfer = new RuleConditionalTransfer(
DEFAULT_ADMIN_ADDRESS,
ZERO_ADDRESS,
- ruleEngineMock,
+ ruleEngineMock,
options
);
// Add whitelist
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleConditionalTransfer.setConditionalWhitelist(ruleWhitelist);
- // specific arrange
+ // specific arrange
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleConditionalTransfer.grantRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE, CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.grantRole(
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE,
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS
+ );
// RuleEngine
vm.prank(DEFAULT_ADMIN_ADDRESS);
@@ -114,12 +120,12 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
vm.prank(DEFAULT_ADMIN_ADDRESS);
CMTAT_CONTRACT.mint(ADDRESS3, ADDRESS3_BALANCE_INIT);
vm.prank(DEFAULT_ADMIN_ADDRESS);
-
+
// We set the Rule Engine
CMTAT_CONTRACT.setRuleEngine(ruleEngineMock);
}
- function _createTransferRequest() internal{
+ function _createTransferRequest() internal {
vm.prank(ADDRESS1);
// Act
vm.expectEmit(true, true, true, true);
@@ -128,7 +134,9 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
}
/******* Transfer *******/
- function testCanMakeATransferWithoutApprovalIfFromAndToAreInTheWhitelist() public {
+ function testCanMakeATransferWithoutApprovalIfFromAndToAreInTheWhitelist()
+ public
+ {
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleWhitelist.addAddressToTheList(ADDRESS1);
vm.prank(DEFAULT_ADMIN_ADDRESS);
@@ -139,30 +147,49 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
CMTAT_CONTRACT.transfer(ADDRESS2, 21);
}
- function testCannotMakeATransferWithoutApprovalIfOnlyFromIsInTheWhitelist() public {
+ function testCannotMakeATransferWithoutApprovalIfOnlyFromIsInTheWhitelist()
+ public
+ {
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleWhitelist.addAddressToTheList(ADDRESS1);
// Arrange
// Act
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, 21));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ 21
+ )
+ );
vm.prank(ADDRESS1);
CMTAT_CONTRACT.transfer(ADDRESS2, 21);
}
- function testCannotMakeATransferWithoutApprovalIfOnlyToIsInTheWhitelist() public {
+ function testCannotMakeATransferWithoutApprovalIfOnlyToIsInTheWhitelist()
+ public
+ {
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleWhitelist.addAddressToTheList(ADDRESS2);
// Arrange
// Act
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, 21));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ 21
+ )
+ );
vm.prank(ADDRESS1);
CMTAT_CONTRACT.transfer(ADDRESS2, 21);
}
function testCanSetANewWhitelist() public {
- RuleWhitelist ruleWhitelist2 = new RuleWhitelist(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS);
+ RuleWhitelist ruleWhitelist2 = new RuleWhitelist(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS
+ );
vm.prank(DEFAULT_ADMIN_ADDRESS);
vm.expectEmit(true, false, false, false);
emit WhitelistConditionalTransfer(ruleWhitelist2);
@@ -180,7 +207,10 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
function testCanUnSetWhitelist() public {
// Arrange
- RuleWhitelist ruleWhitelist2 = new RuleWhitelist(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS);
+ RuleWhitelist ruleWhitelist2 = new RuleWhitelist(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS
+ );
vm.prank(DEFAULT_ADMIN_ADDRESS);
vm.expectEmit(true, false, false, false);
emit WhitelistConditionalTransfer(ruleWhitelist2);
@@ -192,12 +222,20 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Act
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleConditionalTransfer.setConditionalWhitelist(RuleWhitelist(ZERO_ADDRESS));
+ ruleConditionalTransfer.setConditionalWhitelist(
+ RuleWhitelist(ZERO_ADDRESS)
+ );
// Assert
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, 21));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ 21
+ )
+ );
CMTAT_CONTRACT.transfer(ADDRESS2, 21);
}
@@ -207,7 +245,7 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
ruleWhitelist.addAddressToTheList(ADDRESS1);
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleWhitelist.addAddressToTheList(ADDRESS2);
-
+
// Act
uint8 resUint8 = ruleConditionalTransfer.detectTransferRestriction(
ADDRESS1,
@@ -219,11 +257,13 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
assertEq(resUint8, 0);
}
- function testCanDetectTransferRestrictionWithOnlyFromInTheWhitelist() public {
+ function testCanDetectTransferRestrictionWithOnlyFromInTheWhitelist()
+ public
+ {
// Arrange
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleWhitelist.addAddressToTheList(ADDRESS1);
-
+
// Act
uint8 resUint8 = ruleConditionalTransfer.detectTransferRestriction(
ADDRESS1,
@@ -239,7 +279,7 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Arrange
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleWhitelist.addAddressToTheList(ADDRESS2);
-
+
// Act
uint8 resUint8 = ruleConditionalTransfer.detectTransferRestriction(
ADDRESS1,
@@ -251,15 +291,19 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
}
-
-
/***** Test from CMTAT integration */
function testCannotTransferWithoutApproval() public {
// Arrange
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, 21));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ 21
+ )
+ );
// Act
CMTAT_CONTRACT.transfer(ADDRESS2, 21);
}
@@ -268,49 +312,56 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Arrange
vm.prank(ADDRESS1);
// Act
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2,defaultValue));
- ruleConditionalTransfer.createTransferRequest(ADDRESS2,defaultValue);
-
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2,defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, true);
+ emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// Act
vm.expectEmit(true, true, true, true);
emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
// Assert
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
- assertEq(resUint256, ADDRESS1_BALANCE_INIT -defaultValue);
+ assertEq(resUint256, ADDRESS1_BALANCE_INIT - defaultValue);
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
- assertEq(resUint256, ADDRESS2_BALANCE_INIT +defaultValue);
+ assertEq(resUint256, ADDRESS2_BALANCE_INIT + defaultValue);
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
assertEq(resUint256, 33);
}
function testCanMakeAPartialTransferIfPartiallyApproved() public {
-
// Arrange
_createTransferRequest();
uint256 partialValue = 5;
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2,partialValue));
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, partialValue, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ true
+ );
// Act
vm.expectEmit(true, true, true, true);
emit transferProcessed(key, ADDRESS1, ADDRESS2, partialValue, 1);
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,partialValue);
+ CMTAT_CONTRACT.transfer(ADDRESS2, partialValue);
// Assert
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
@@ -325,58 +376,81 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Arrange
_createTransferRequest();
uint256 partialValue = 5;
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2,partialValue));
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValue));
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(key, ADDRESS1, ADDRESS2, partialValue, 1);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, partialValue, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ true
+ );
// Act
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, defaultValue));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
vm.prank(ADDRESS1);
CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
-
function testCannotMakeATransferIfDelayExceeded() public {
// Arrange
vm.prank(ADDRESS1);
// Act
- bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2,defaultValue));
- ruleConditionalTransfer.createTransferRequest(ADDRESS2,defaultValue);
-
+ bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferApproved(key, ADDRESS1, ADDRESS2,defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
+ emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// +30 days and one second
vm.warp(block.timestamp + 2592001);
// Act
- vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2,defaultValue));
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
function testCannotMakeATransferIfDelayJustInTime() public {
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferApproved(defaultKey, ADDRESS1, ADDRESS2,defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
+ emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// 30 days
vm.warp(block.timestamp + 2592000);
// Act
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
function testCanSetTimeLimitWithTransferExceeded() public {
@@ -390,8 +464,11 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
// Arrange
_createTransferRequest();
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
-
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// Assert
// Timeout
@@ -399,10 +476,15 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
vm.warp(block.timestamp + 1 days + 1 seconds);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2,defaultValue));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
vm.prank(ADDRESS1);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
-
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
function testCanMintWithoutApproval() public {
@@ -418,7 +500,7 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
function testCanBurnWithoutApproval() public {
// Act
vm.prank(DEFAULT_ADMIN_ADDRESS);
- CMTAT_CONTRACT.burn(ADDRESS1,defaultValue, "test");
+ CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "test");
// Assert
resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
@@ -427,54 +509,70 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
function testCannotMintWithoutApproval() public {
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:true
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: true
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
// Act
vm.prank(DEFAULT_ADMIN_ADDRESS);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ZERO_ADDRESS , ADDRESS1, 11));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ZERO_ADDRESS,
+ ADDRESS1,
+ 11
+ )
+ );
CMTAT_CONTRACT.mint(ADDRESS1, 11);
}
function testCannotBurnWithoutApproval() public {
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:true,
- authorizedBurnWithoutApproval:false
+ authorizedMintWithoutApproval: true,
+ authorizedBurnWithoutApproval: false
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
// Act
vm.prank(DEFAULT_ADMIN_ADDRESS);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ZERO_ADDRESS, defaultValue));
- CMTAT_CONTRACT.burn(ADDRESS1,defaultValue, "test");
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ZERO_ADDRESS,
+ defaultValue
+ )
+ );
+ CMTAT_CONTRACT.burn(ADDRESS1, defaultValue, "test");
}
function testAutomaticTransferIfOptionsSet() public {
- AUTOMATIC_TRANSFER memory automaticTransferTest = AUTOMATIC_TRANSFER({
- isActivate:true,
+ AUTOMATIC_TRANSFER memory automaticTransferTest = AUTOMATIC_TRANSFER({
+ isActivate: true,
cmtat: CMTAT_CONTRACT
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setAutomaticTransfer(automaticTransferTest);
-
+
// Aproval
vm.prank(ADDRESS1);
CMTAT_CONTRACT.approve(address(ruleConditionalTransfer), defaultValue);
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferApproved(defaultKey, ADDRESS1, ADDRESS2,defaultValue, 0);
+ emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2,defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
+ emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
}
function testCanTransferIfAutomaticApprovalSetAndTimeExceeds() public {
@@ -484,35 +582,42 @@ contract CMTATIntegrationConditionalTransfer is Test, HelperContract {
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
+
// Arrange
_createTransferRequest();
-
+
vm.warp(block.timestamp + 90 days);
// Act
vm.prank(ADDRESS1);
vm.expectEmit(true, true, true, true);
- emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2,defaultValue, 0);
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ emit transferProcessed(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
- function testCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds() public {
+ function testCannotTransferIfAutomaticApprovalSetAndTimeNotExceeds()
+ public
+ {
AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
isActivate: true,
timeLimitBeforeAutomaticApproval: 90 days
});
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
-
+
// Arrange
_createTransferRequest();
-
vm.warp(block.timestamp + 92 days);
// Act
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, defaultValue));
- CMTAT_CONTRACT.transfer(ADDRESS2,defaultValue);
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ )
+ );
+ CMTAT_CONTRACT.transfer(ADDRESS2, defaultValue);
}
}
diff --git a/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol
index 789a04f..3dcac3e 100644
--- a/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol
+++ b/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol
@@ -6,8 +6,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title General functions of the RuleWhitelist
-*/
+ * @title General functions of the RuleWhitelist
+ */
contract RuleConditionalTransferTest is Test, HelperContract {
RuleEngine ruleEngineMock;
uint256 resUint256;
@@ -17,8 +17,8 @@ contract RuleConditionalTransferTest is Test, HelperContract {
string resString;
uint8 CODE_NONEXISTENT = 255;
uint256 defaultValue = 10;
- bytes32 defaultKey = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
-
+ bytes32 defaultKey =
+ keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
// Batch test
uint256 value2 = 1;
@@ -30,33 +30,38 @@ contract RuleConditionalTransferTest is Test, HelperContract {
bytes32 key4 = keccak256(abi.encode(ADDRESS1, ADDRESS2, value4));
bytes32 key5 = keccak256(abi.encode(ADDRESS1, ADDRESS2, value5));
- TransferRequestKeyElement transferRequestInput2 = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput2 =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:value2
- });
+ value: value2
+ });
- TransferRequestKeyElement transferRequestInput3 = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput3 =
+ TransferRequestKeyElement({
from: ADDRESS2,
to: ADDRESS1,
- value:value3
- });
+ value: value3
+ });
- TransferRequestKeyElement transferRequestInput4 = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput4 =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:value4
- });
- TransferRequestKeyElement transferRequestInput5 = TransferRequestKeyElement({
+ value: value4
+ });
+ TransferRequestKeyElement transferRequestInput5 =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:value5
- });
- TransferRequestKeyElement transferRequestInput = TransferRequestKeyElement({
+ value: value5
+ });
+ TransferRequestKeyElement transferRequestInput =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:defaultValue
- });
+ value: defaultValue
+ });
// Arrange
function setUp() public {
@@ -64,26 +69,26 @@ contract RuleConditionalTransferTest is Test, HelperContract {
timeLimitToApprove: 7 days,
timeLimitToTransfer: 30 days
});
-
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
+
+ AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
isActivate: false,
timeLimitBeforeAutomaticApproval: 0
});
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:false
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: false
});
AUTOMATIC_TRANSFER memory automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
+ isActivate: false,
cmtat: IERC20(address(0))
});
OPTION memory options = OPTION({
- issuance:issuanceOption_,
+ issuance: issuanceOption_,
timeLimit: timeLimit_,
automaticApproval: automaticApproval_,
- automaticTransfer:automaticTransfer_
+ automaticTransfer: automaticTransfer_
});
ruleEngineMock = new RuleEngine(
RULE_ENGINE_OPERATOR_ADDRESS,
@@ -94,14 +99,17 @@ contract RuleConditionalTransferTest is Test, HelperContract {
ruleConditionalTransfer = new RuleConditionalTransfer(
DEFAULT_ADMIN_ADDRESS,
ZERO_ADDRESS,
- ruleEngineMock,
+ ruleEngineMock,
options
);
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleConditionalTransfer.grantRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE, CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.grantRole(
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE,
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS
+ );
}
- function _createTransferRequest() internal{
+ function _createTransferRequest() internal {
vm.prank(ADDRESS1);
// Act
vm.expectEmit(true, true, true, true);
@@ -109,7 +117,8 @@ contract RuleConditionalTransferTest is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
// Assert
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -117,13 +126,14 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(transferRequest.value, defaultValue);
assertEq(uint256(transferRequest.status), uint256(STATUS.WAIT));
- TransferRequest[] memory transferRequests = ruleConditionalTransfer.getRequestByStatus(STATUS.WAIT);
- assertEq(transferRequests[0].key , defaultKey);
- assertEq(transferRequests.length , 1);
+ TransferRequest[] memory transferRequests = ruleConditionalTransfer
+ .getRequestByStatus(STATUS.WAIT);
+ assertEq(transferRequests[0].key, defaultKey);
+ assertEq(transferRequests.length, 1);
}
- function _createTransferRequestBatch() public{
- // Arrange
+ function _createTransferRequestBatch() public {
+ // Arrange
_createTransferRequest();
// Second and third request
@@ -139,8 +149,9 @@ contract RuleConditionalTransferTest is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS2, value5);
}
- function _checkRequestPartial() internal view{
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ function _checkRequestPartial() internal view {
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -149,7 +160,11 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED));
// 2
- transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, value2);
+ transferRequest = ruleConditionalTransfer.getRequestTrade(
+ ADDRESS1,
+ ADDRESS2,
+ value2
+ );
assertEq(transferRequest.key, key2);
assertEq(transferRequest.id, 1);
assertEq(transferRequest.from, ADDRESS1);
@@ -158,7 +173,11 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED));
// 3
- transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS2, ADDRESS1, value3);
+ transferRequest = ruleConditionalTransfer.getRequestTrade(
+ ADDRESS2,
+ ADDRESS1,
+ value3
+ );
assertEq(transferRequest.key, key3);
assertEq(transferRequest.id, 2);
assertEq(transferRequest.from, ADDRESS2);
@@ -167,7 +186,11 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED));
// 4
- transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, value4);
+ transferRequest = ruleConditionalTransfer.getRequestTrade(
+ ADDRESS1,
+ ADDRESS2,
+ value4
+ );
assertEq(transferRequest.key, key4);
assertEq(transferRequest.id, 3);
assertEq(transferRequest.from, ADDRESS1);
@@ -176,12 +199,12 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(uint256(transferRequest.status), uint256(STATUS.DENIED));
}
-
function _checkRequestBatch() internal view {
_checkRequestPartial();
-
+
// 5
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, value5);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, value5);
assertEq(transferRequest.key, key5);
assertEq(transferRequest.id, 4);
assertEq(transferRequest.from, ADDRESS1);
@@ -195,24 +218,29 @@ contract RuleConditionalTransferTest is Test, HelperContract {
}
/**
- * @dev test first
- */
+ * @dev test first
+ */
function testCanCreateTransferRequestWithApproval() public {
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
// Act
vm.expectEmit(true, true, true, true);
emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.createTransferRequestWithApproval(transferRequestInput);
+ ruleConditionalTransfer.createTransferRequestWithApproval(
+ transferRequestInput
+ );
}
function testCanCreateTransferRequestWithApprovalBatch() public {
// Arrange
- TransferRequestKeyElement[] memory transferRequestKeyElements = new TransferRequestKeyElement[](4);
+ TransferRequestKeyElement[]
+ memory transferRequestKeyElements = new TransferRequestKeyElement[](
+ 4
+ );
transferRequestKeyElements[0] = transferRequestInput;
transferRequestKeyElements[1] = transferRequestInput2;
transferRequestKeyElements[2] = transferRequestInput3;
transferRequestKeyElements[3] = transferRequestInput4;
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
@@ -223,22 +251,30 @@ contract RuleConditionalTransferTest is Test, HelperContract {
emit transferApproved(key3, ADDRESS2, ADDRESS1, value3, 2);
vm.expectEmit(true, true, true, true);
emit transferApproved(key4, ADDRESS1, ADDRESS2, value4, 3);
- ruleConditionalTransfer.createTransferRequestWithApprovalBatch(transferRequestKeyElements);
+ ruleConditionalTransfer.createTransferRequestWithApprovalBatch(
+ transferRequestKeyElements
+ );
}
- function testCanCreateTransferRequestWithApprovalBatchWithEmptyArray() public {
+ function testCanCreateTransferRequestWithApprovalBatchWithEmptyArray()
+ public
+ {
// Arrange
- TransferRequestKeyElement[] memory transferRequestKeyElements = new TransferRequestKeyElement[](0);
-
+ TransferRequestKeyElement[]
+ memory transferRequestKeyElements = new TransferRequestKeyElement[](
+ 0
+ );
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_EmptyArray.selector);
- ruleConditionalTransfer.createTransferRequestWithApprovalBatch(transferRequestKeyElements);
+ ruleConditionalTransfer.createTransferRequestWithApprovalBatch(
+ transferRequestKeyElements
+ );
}
-
/**
- * @dev test overwrite branch, previous approval
+ * @dev test overwrite branch, previous approval
*/
function testCanCreateTransferRequestWithApprovalAgain() public {
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
@@ -246,16 +282,18 @@ contract RuleConditionalTransferTest is Test, HelperContract {
bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
vm.expectEmit(true, true, true, true);
emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.createTransferRequestWithApproval(transferRequestInput);
+ ruleConditionalTransfer.createTransferRequestWithApproval(
+ transferRequestInput
+ );
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.createTransferRequestWithApproval(transferRequestInput);
+ ruleConditionalTransfer.createTransferRequestWithApproval(
+ transferRequestInput
+ );
}
-
-
/**** Request approval ****** */
function testCanHolderCreateRequestBatch() public {
@@ -264,11 +302,11 @@ contract RuleConditionalTransferTest is Test, HelperContract {
values[0] = defaultValue;
values[1] = value2;
values[2] = value4;
- address[] memory addresses = new address[](3);
+ address[] memory addresses = new address[](3);
addresses[0] = ADDRESS2;
addresses[1] = ADDRESS2;
addresses[2] = ADDRESS2;
-
+
// Act
vm.prank(ADDRESS1);
vm.expectEmit(true, true, true, true);
@@ -277,14 +315,14 @@ contract RuleConditionalTransferTest is Test, HelperContract {
emit transferWaiting(key2, ADDRESS1, ADDRESS2, value2, 1);
vm.expectEmit(true, true, true, true);
emit transferWaiting(key4, ADDRESS1, ADDRESS2, value4, 2);
- ruleConditionalTransfer.createTransferRequestBatch(addresses,values );
+ ruleConditionalTransfer.createTransferRequestBatch(addresses, values);
}
function testCannotHolderCreateRequestBatchEmptyArray() public {
// Arrange
uint256[] memory values = new uint256[](0);
- address[] memory addresses = new address[](0);
-
+ address[] memory addresses = new address[](0);
+
// Act
vm.prank(ADDRESS1);
vm.expectRevert(RuleConditionalTransfer_EmptyArray.selector);
@@ -294,8 +332,8 @@ contract RuleConditionalTransferTest is Test, HelperContract {
function testCannotHolderCreateRequestBatchIfLEngthMismatch() public {
// Arrange
uint256[] memory values = new uint256[](3);
- address[] memory addresses = new address[](1);
-
+ address[] memory addresses = new address[](1);
+
// Act
vm.prank(ADDRESS1);
vm.expectRevert(RuleConditionalTransfer_InvalidLengthArray.selector);
@@ -305,15 +343,18 @@ contract RuleConditionalTransferTest is Test, HelperContract {
function testCanApproveRequestCreatedByHolder() public {
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
}
-
function testCanPartiallyApproveRequestCreatedByHolder() public {
// Arrange
_createTransferRequest();
@@ -324,7 +365,11 @@ contract RuleConditionalTransferTest is Test, HelperContract {
vm.expectEmit(true, true, true, true);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
emit transferWaiting(key, ADDRESS1, ADDRESS2, partialValue, 1);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, partialValue,true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ true
+ );
}
function testCannotPartiallyDeniedRequestCreatedByHolder() public {
@@ -334,29 +379,43 @@ contract RuleConditionalTransferTest is Test, HelperContract {
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_CannotDeniedPartially.selector);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, partialValue, false);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ false
+ );
}
- function testCannotPartiallyApprovedRequestCreatedByHolderIfPartialValueIsBiggerThanValue() public {
+ function testCannotPartiallyApprovedRequestCreatedByHolderIfPartialValueIsBiggerThanValue()
+ public
+ {
// Arrange
_createTransferRequest();
uint256 partialValue = 5000;
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_InvalidValueApproved.selector);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, partialValue, false);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ partialValue,
+ false
+ );
}
function testCanCreateAndApproveRequestCreatedByHolderAgain() public {
// Arrange
// First request
_createTransferRequest();
-
+
// First approval
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// Second request
vm.prank(ADDRESS1);
@@ -366,10 +425,15 @@ contract RuleConditionalTransferTest is Test, HelperContract {
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// Assert
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -378,7 +442,6 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED));
}
-
/*** Batch */
function testCanCreateAndApproveRequestCreatedByHolderInBatch() public {
// Arrange
@@ -388,13 +451,16 @@ contract RuleConditionalTransferTest is Test, HelperContract {
partialValues[1] = 0;
partialValues[2] = 0;
partialValues[3] = 0;
- bool[] memory isApproveds = new bool[](4);
+ bool[] memory isApproveds = new bool[](4);
isApproveds[0] = true;
isApproveds[1] = true;
isApproveds[2] = true;
isApproveds[3] = false;
- TransferRequestKeyElement[] memory transferRequestKeyElements = new TransferRequestKeyElement[](4);
+ TransferRequestKeyElement[]
+ memory transferRequestKeyElements = new TransferRequestKeyElement[](
+ 4
+ );
transferRequestKeyElements[0] = transferRequestInput;
transferRequestKeyElements[1] = transferRequestInput2;
transferRequestKeyElements[2] = transferRequestInput3;
@@ -410,60 +476,92 @@ contract RuleConditionalTransferTest is Test, HelperContract {
emit transferApproved(key3, ADDRESS2, ADDRESS1, value3, 2);
vm.expectEmit(true, true, true, true);
emit transferDenied(key4, ADDRESS1, ADDRESS2, value4, 3);
- ruleConditionalTransfer.approveTransferRequestBatch(transferRequestKeyElements, partialValues, isApproveds);
+ ruleConditionalTransfer.approveTransferRequestBatch(
+ transferRequestKeyElements,
+ partialValues,
+ isApproveds
+ );
// Assert
_checkRequestBatch();
}
-
- function testCannotCreateAndApproveRequestCreatedByHolderInBatchWithLenghtMismatch() public {
+ function testCannotCreateAndApproveRequestCreatedByHolderInBatchWithLenghtMismatch()
+ public
+ {
// Arrange
uint256[] memory partialValues = new uint256[](4);
// Lenght mismatch
- bool[] memory isApproveds = new bool[](3);
+ bool[] memory isApproveds = new bool[](3);
- TransferRequestKeyElement[] memory transferRequestKeyElements = new TransferRequestKeyElement[](4);
+ TransferRequestKeyElement[]
+ memory transferRequestKeyElements = new TransferRequestKeyElement[](
+ 4
+ );
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_InvalidLengthArray.selector);
- ruleConditionalTransfer.approveTransferRequestBatch(transferRequestKeyElements, partialValues, isApproveds);
+ ruleConditionalTransfer.approveTransferRequestBatch(
+ transferRequestKeyElements,
+ partialValues,
+ isApproveds
+ );
// Act
uint256[] memory partialValuesV2 = new uint256[](1);
partialValuesV2[0] = 0;
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_InvalidLengthArray.selector);
- ruleConditionalTransfer.approveTransferRequestBatch(transferRequestKeyElements, partialValuesV2, isApproveds);
-
+ ruleConditionalTransfer.approveTransferRequestBatch(
+ transferRequestKeyElements,
+ partialValuesV2,
+ isApproveds
+ );
// Act
uint256[] memory partialValuesV3 = new uint256[](4);
// Lenght mismatch
- bool[] memory isApprovedsV3 = new bool[](4);
- TransferRequestKeyElement[] memory transferRequestKeyElementsV3 = new TransferRequestKeyElement[](2);
+ bool[] memory isApprovedsV3 = new bool[](4);
+ TransferRequestKeyElement[]
+ memory transferRequestKeyElementsV3 = new TransferRequestKeyElement[](
+ 2
+ );
transferRequestKeyElementsV3[0] = transferRequestInput;
transferRequestKeyElementsV3[1] = transferRequestInput2;
vm.expectRevert(RuleConditionalTransfer_InvalidLengthArray.selector);
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.approveTransferRequestBatch(transferRequestKeyElementsV3, partialValuesV3, isApprovedsV3);
+ ruleConditionalTransfer.approveTransferRequestBatch(
+ transferRequestKeyElementsV3,
+ partialValuesV3,
+ isApprovedsV3
+ );
}
- function testCannotCreateAndApproveRequestCreatedByHolderInBatchWithEmptyArry() public {
+ function testCannotCreateAndApproveRequestCreatedByHolderInBatchWithEmptyArry()
+ public
+ {
// Arrange
uint256[] memory partialValues = new uint256[](0);
// Lenght mismatch
- bool[] memory isApproveds = new bool[](0);
+ bool[] memory isApproveds = new bool[](0);
- TransferRequestKeyElement[] memory transferRequestKeyElements = new TransferRequestKeyElement[](0);
+ TransferRequestKeyElement[]
+ memory transferRequestKeyElements = new TransferRequestKeyElement[](
+ 0
+ );
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_EmptyArray.selector);
- ruleConditionalTransfer.approveTransferRequestBatch(transferRequestKeyElements, partialValues, isApproveds);
-
+ ruleConditionalTransfer.approveTransferRequestBatch(
+ transferRequestKeyElements,
+ partialValues,
+ isApproveds
+ );
}
- function testCanCreateAndApproveRequestCreatedByHolderInBatchWithPartialValues() public {
+ function testCanCreateAndApproveRequestCreatedByHolderInBatchWithPartialValues()
+ public
+ {
// Arrange
_createTransferRequestBatch();
uint256[] memory partialValues = new uint256[](5);
@@ -473,15 +571,20 @@ contract RuleConditionalTransferTest is Test, HelperContract {
partialValues[3] = 0;
// partial value
partialValues[4] = 500;
- bytes32 key5PartialValue = keccak256(abi.encode(ADDRESS1, ADDRESS2, partialValues[4]));
- bool[] memory isApproveds = new bool[](5);
+ bytes32 key5PartialValue = keccak256(
+ abi.encode(ADDRESS1, ADDRESS2, partialValues[4])
+ );
+ bool[] memory isApproveds = new bool[](5);
isApproveds[0] = true;
isApproveds[1] = true;
isApproveds[2] = true;
isApproveds[3] = false;
isApproveds[4] = true;
- TransferRequestKeyElement[] memory transferRequestKeyElements = new TransferRequestKeyElement[](5);
+ TransferRequestKeyElement[]
+ memory transferRequestKeyElements = new TransferRequestKeyElement[](
+ 5
+ );
transferRequestKeyElements[0] = transferRequestInput;
transferRequestKeyElements[1] = transferRequestInput2;
transferRequestKeyElements[2] = transferRequestInput3;
@@ -501,14 +604,25 @@ contract RuleConditionalTransferTest is Test, HelperContract {
vm.expectEmit(true, true, true, true);
emit transferDenied(key5, ADDRESS1, ADDRESS2, value5, 4);
vm.expectEmit(true, true, true, true);
- emit transferApproved(key5PartialValue, ADDRESS1, ADDRESS2, partialValues[4], 5);
- ruleConditionalTransfer.approveTransferRequestBatch(transferRequestKeyElements, partialValues, isApproveds);
+ emit transferApproved(
+ key5PartialValue,
+ ADDRESS1,
+ ADDRESS2,
+ partialValues[4],
+ 5
+ );
+ ruleConditionalTransfer.approveTransferRequestBatch(
+ transferRequestKeyElements,
+ partialValues,
+ isApproveds
+ );
// Assert
_checkRequestPartial();
// 5
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, value5);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, value5);
assertEq(transferRequest.key, key5);
assertEq(transferRequest.id, 4);
assertEq(transferRequest.from, ADDRESS1);
@@ -516,12 +630,16 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(transferRequest.value, value5);
assertEq(uint256(transferRequest.status), uint256(STATUS.DENIED));
// new request
- transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, partialValues[4]);
+ transferRequest = ruleConditionalTransfer.getRequestTrade(
+ ADDRESS1,
+ ADDRESS2,
+ partialValues[4]
+ );
assertEq(transferRequest.key, key5PartialValue);
assertEq(transferRequest.id, 5);
assertEq(transferRequest.from, ADDRESS1);
assertEq(transferRequest.to, ADDRESS2);
- assertEq(transferRequest.value,partialValues[4]);
+ assertEq(transferRequest.value, partialValues[4]);
assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED));
}
@@ -529,16 +647,16 @@ contract RuleConditionalTransferTest is Test, HelperContract {
function testCanApproveRequestCreatedByHolderWithId() public {
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferApproved(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequestWithId( 0, true);
-
+ ruleConditionalTransfer.approveTransferRequestWithId(0, true);
// Assert
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -547,18 +665,16 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED));
}
-
-
/***** Batch */
function testCanApproveRequestInBatchCreatedByHolderWithId() public {
- _createTransferRequestBatch();
+ _createTransferRequestBatch();
uint256[] memory ids = new uint256[](4);
ids[0] = 0;
ids[1] = 1;
ids[2] = 2;
ids[3] = 3;
- bool[] memory isApproveds = new bool[](4);
+ bool[] memory isApproveds = new bool[](4);
isApproveds[0] = true;
isApproveds[1] = true;
isApproveds[2] = true;
@@ -573,38 +689,50 @@ contract RuleConditionalTransferTest is Test, HelperContract {
emit transferApproved(key3, ADDRESS2, ADDRESS1, value3, 2);
vm.expectEmit(true, true, true, true);
emit transferDenied(key4, ADDRESS1, ADDRESS2, value4, 3);
- ruleConditionalTransfer.approveTransferRequestBatchWithId( ids, isApproveds);
-
+ ruleConditionalTransfer.approveTransferRequestBatchWithId(
+ ids,
+ isApproveds
+ );
// Assert
_checkRequestBatch();
}
-
- function testCannotApproveRequestInBatchCreatedByHolderWithIdWithinvalidLength() public {
- _createTransferRequestBatch();
+ function testCannotApproveRequestInBatchCreatedByHolderWithIdWithinvalidLength()
+ public
+ {
+ _createTransferRequestBatch();
uint256[] memory ids = new uint256[](4);
// Wrong length here
- bool[] memory isApproveds = new bool[](3);
+ bool[] memory isApproveds = new bool[](3);
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_InvalidLengthArray.selector);
- ruleConditionalTransfer.approveTransferRequestBatchWithId( ids, isApproveds);
+ ruleConditionalTransfer.approveTransferRequestBatchWithId(
+ ids,
+ isApproveds
+ );
}
- function testCannotApproveRequestInBatchCreatedByHolderWithIdWithEmptyArray() public {
- _createTransferRequestBatch();
+ function testCannotApproveRequestInBatchCreatedByHolderWithIdWithEmptyArray()
+ public
+ {
+ _createTransferRequestBatch();
uint256[] memory ids = new uint256[](0);
// Wrong length here
- bool[] memory isApproveds = new bool[](0);
+ bool[] memory isApproveds = new bool[](0);
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_EmptyArray.selector);
- ruleConditionalTransfer.approveTransferRequestBatchWithId( ids, isApproveds);
+ ruleConditionalTransfer.approveTransferRequestBatchWithId(
+ ids,
+ isApproveds
+ );
}
-
- function testCannotApproveRequestInBatchCreatedByHolderWithWrongId() public {
+ function testCannotApproveRequestInBatchCreatedByHolderWithWrongId()
+ public
+ {
_createTransferRequestBatch();
uint256[] memory ids = new uint256[](4);
ids[0] = 0;
@@ -612,7 +740,7 @@ contract RuleConditionalTransferTest is Test, HelperContract {
////// Wrong id here !!!
ids[2] = 6;
ids[3] = 3;
- bool[] memory isApproveds = new bool[](4);
+ bool[] memory isApproveds = new bool[](4);
isApproveds[0] = true;
isApproveds[1] = true;
isApproveds[2] = true;
@@ -620,12 +748,16 @@ contract RuleConditionalTransferTest is Test, HelperContract {
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_InvalidId.selector);
- ruleConditionalTransfer.approveTransferRequestBatchWithId( ids, isApproveds);
+ ruleConditionalTransfer.approveTransferRequestBatchWithId(
+ ids,
+ isApproveds
+ );
}
-
- function testCannotApproveRequestInBatchCreatedByHolderIfTimeExceed() public {
- _createTransferRequestBatch();
+ function testCannotApproveRequestInBatchCreatedByHolderIfTimeExceed()
+ public
+ {
+ _createTransferRequestBatch();
// Jump
vm.warp(block.timestamp + 604801);
uint256[] memory ids = new uint256[](4);
@@ -633,7 +765,7 @@ contract RuleConditionalTransferTest is Test, HelperContract {
ids[1] = 1;
ids[2] = 2;
ids[3] = 3;
- bool[] memory isApproveds = new bool[](4);
+ bool[] memory isApproveds = new bool[](4);
isApproveds[0] = true;
isApproveds[1] = true;
isApproveds[2] = true;
@@ -641,37 +773,42 @@ contract RuleConditionalTransferTest is Test, HelperContract {
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_timeExceeded.selector);
- ruleConditionalTransfer.approveTransferRequestBatchWithId( ids, isApproveds);
+ ruleConditionalTransfer.approveTransferRequestBatchWithId(
+ ids,
+ isApproveds
+ );
}
- function testCannotApproveOrDeniedRequestCreatedByHolderWithWrongId() public {
+ function testCannotApproveOrDeniedRequestCreatedByHolderWithWrongId()
+ public
+ {
// Arrange
_createTransferRequest();
-
+
// Act
// Approve
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_InvalidId.selector);
- ruleConditionalTransfer.approveTransferRequestWithId( 1, true);
+ ruleConditionalTransfer.approveTransferRequestWithId(1, true);
// Denied
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_InvalidId.selector);
- ruleConditionalTransfer.approveTransferRequestWithId( 1, false);
+ ruleConditionalTransfer.approveTransferRequestWithId(1, false);
}
-
function testCanDeniedRequestCreatedByHolderWithId() public {
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequestWithId( 0, false);
+ ruleConditionalTransfer.approveTransferRequestWithId(0, false);
// Assert
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -684,15 +821,20 @@ contract RuleConditionalTransferTest is Test, HelperContract {
function testCanDeniedRequestCreatedByHolder() public {
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,false);
+ emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ false
+ );
// Assert
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -700,9 +842,10 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(transferRequest.value, defaultValue);
assertEq(uint256(transferRequest.status), uint256(STATUS.DENIED));
- TransferRequest[] memory transferRequests = ruleConditionalTransfer.getRequestByStatus(STATUS.DENIED);
- assertEq(transferRequests[0].key , defaultKey);
- assertEq(transferRequests.length , 1);
+ TransferRequest[] memory transferRequests = ruleConditionalTransfer
+ .getRequestByStatus(STATUS.DENIED);
+ assertEq(transferRequests[0].key, defaultKey);
+ assertEq(transferRequests.length, 1);
}
function testCannotHolderCreateRequestIfDenied() public {
@@ -710,9 +853,12 @@ contract RuleConditionalTransferTest is Test, HelperContract {
_createTransferRequest();
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
- emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,false);
-
+ emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ false
+ );
// Act
vm.prank(ADDRESS1);
@@ -722,15 +868,19 @@ contract RuleConditionalTransferTest is Test, HelperContract {
/****** Getter *****/
function testCanReturnTradeByStatus() public {
- // Arrange
- // First request
+ // Arrange
+ // First request
_createTransferRequest();
// Change the status request to APPROVE
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, false);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ false
+ );
// Second request
uint256 value = 100;
@@ -738,7 +888,8 @@ contract RuleConditionalTransferTest is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS2, value);
// Act
- TransferRequest[] memory transferRequest = ruleConditionalTransfer.getRequestByStatus(STATUS.WAIT);
+ TransferRequest[] memory transferRequest = ruleConditionalTransfer
+ .getRequestByStatus(STATUS.WAIT);
// Assert
assertEq(transferRequest.length, 1);
bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, value));
@@ -755,10 +906,14 @@ contract RuleConditionalTransferTest is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS2, valueThird);
// Act
- transferRequest = ruleConditionalTransfer.getRequestByStatus(STATUS.WAIT);
+ transferRequest = ruleConditionalTransfer.getRequestByStatus(
+ STATUS.WAIT
+ );
// Assert
assertEq(transferRequest.length, 2);
- bytes32 keyThird = keccak256(abi.encode(ADDRESS1, ADDRESS2, valueThird));
+ bytes32 keyThird = keccak256(
+ abi.encode(ADDRESS1, ADDRESS2, valueThird)
+ );
assertEq(transferRequest[1].key, keyThird);
assertEq(transferRequest[1].id, 2);
assertEq(transferRequest[1].from, ADDRESS1);
@@ -767,18 +922,21 @@ contract RuleConditionalTransferTest is Test, HelperContract {
assertEq(uint256(transferRequest[1].status), uint256(STATUS.WAIT));
}
-
function testCannotApproveRequestIfTimeExceeded() public {
// Arrange
_createTransferRequest();
-
+
// Timeout
// 7 days *24*60*60 = 604800 seconds
vm.warp(block.timestamp + 604801);
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_timeExceeded.selector);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
}
/*** Edge case ******/
@@ -786,14 +944,18 @@ contract RuleConditionalTransferTest is Test, HelperContract {
function testCannotApproveRequestIfWrongStatus() public {
// Arrange
// No create request
-
+
// Timeout
// 7 days *24*60*60 = 604800 seconds
vm.warp(block.timestamp + 604801);
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_Wrong_Status.selector);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
}
function testCanSetTimeLimitWithTransferApprovalExceeded() public {
@@ -803,7 +965,7 @@ contract RuleConditionalTransferTest is Test, HelperContract {
});
// Arrange
_createTransferRequest();
-
+
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
ruleConditionalTransfer.setTimeLimit(timeLimit_);
@@ -813,9 +975,12 @@ contract RuleConditionalTransferTest is Test, HelperContract {
// >1 days
vm.warp(block.timestamp + 1 days + 1 seconds);
-
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectRevert(RuleConditionalTransfer_timeExceeded.selector);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
}
}
diff --git a/test/RuleConditionalTransfer/RuleConditionalTransferAccessControl.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransferAccessControl.t.sol
index f9a18c7..fc59416 100644
--- a/test/RuleConditionalTransfer/RuleConditionalTransferAccessControl.t.sol
+++ b/test/RuleConditionalTransfer/RuleConditionalTransferAccessControl.t.sol
@@ -6,8 +6,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Tests on the Access Control
-*/
+ * @title Tests on the Access Control
+ */
contract RuleConditionalTransferAccessControl is Test, HelperContract {
RuleEngine ruleEngineMock;
// Custom error openZeppelin
@@ -22,40 +22,42 @@ contract RuleConditionalTransferAccessControl is Test, HelperContract {
string resString;
uint8 CODE_NONEXISTENT = 255;
uint256 defaultValue = 10;
- bytes32 defaultKey = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ bytes32 defaultKey =
+ keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
- TransferRequestKeyElement transferRequestInput = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:defaultValue
- });
+ value: defaultValue
+ });
// Arrange
function setUp() public {
- TIME_LIMIT memory timeLimit_ =TIME_LIMIT({
+ TIME_LIMIT memory timeLimit_ = TIME_LIMIT({
timeLimitToApprove: 7 days,
timeLimitToTransfer: 30 days
});
-
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
+
+ AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
isActivate: false,
timeLimitBeforeAutomaticApproval: 0
});
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:false
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: false
});
AUTOMATIC_TRANSFER memory automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
+ isActivate: false,
cmtat: IERC20(address(0))
});
-
+
OPTION memory options = OPTION({
- issuance:issuanceOption_,
+ issuance: issuanceOption_,
timeLimit: timeLimit_,
automaticApproval: automaticApproval_,
- automaticTransfer:automaticTransfer_
+ automaticTransfer: automaticTransfer_
});
ruleEngineMock = new RuleEngine(
RULE_ENGINE_OPERATOR_ADDRESS,
@@ -66,14 +68,17 @@ contract RuleConditionalTransferAccessControl is Test, HelperContract {
ruleConditionalTransfer = new RuleConditionalTransfer(
DEFAULT_ADMIN_ADDRESS,
ZERO_ADDRESS,
- ruleEngineMock,
+ ruleEngineMock,
options
);
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleConditionalTransfer.grantRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE, CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.grantRole(
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE,
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS
+ );
}
- function _createTransferRequest() internal{
+ function _createTransferRequest() internal {
vm.prank(ADDRESS1);
// Act
vm.expectEmit(true, true, true, true);
@@ -81,80 +86,145 @@ contract RuleConditionalTransferAccessControl is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
}
-
function testCannotAttackerApproveARequestCreatedByTokenHolder() public {
_createTransferRequest();
-
+
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
}
- function testCannotAttackerApproveWithIdARequestCreatedByTokenHolder() public {
+ function testCannotAttackerApproveWithIdARequestCreatedByTokenHolder()
+ public
+ {
_createTransferRequest();
-
+
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
ruleConditionalTransfer.approveTransferRequestWithId(0, true);
}
function testCannotAttackerResetARequest() public {
- _createTransferRequest();
-
+ _createTransferRequest();
+
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
ruleConditionalTransfer.resetRequestStatus(0);
}
function testCannotAttackerCreateTransferRequestWithApproval() public {
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
- ruleConditionalTransfer.createTransferRequestWithApproval(transferRequestInput);
+ ruleConditionalTransfer.createTransferRequestWithApproval(
+ transferRequestInput
+ );
}
/*** Batch */
- function testCannotAttackerApproveBatchWithIdARequestCreatedByTokenHolder() public {
+ function testCannotAttackerApproveBatchWithIdARequestCreatedByTokenHolder()
+ public
+ {
_createTransferRequest();
uint256[] memory ids = new uint256[](1);
ids[0] = 0;
bool[] memory isApproveds = new bool[](1);
isApproveds[0] = true;
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
- ruleConditionalTransfer.approveTransferRequestBatchWithId(ids, isApproveds);
+ ruleConditionalTransfer.approveTransferRequestBatchWithId(
+ ids,
+ isApproveds
+ );
}
- function testCannotAttackerApproveBatchRequestCreatedByTokenHolder() public {
- TransferRequestKeyElement[] memory keyElements = new TransferRequestKeyElement[](0);
+ function testCannotAttackerApproveBatchRequestCreatedByTokenHolder()
+ public
+ {
+ TransferRequestKeyElement[]
+ memory keyElements = new TransferRequestKeyElement[](0);
uint256[] memory partialValues = new uint256[](0);
bool[] memory boolIsApproved = new bool[](0);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
- ruleConditionalTransfer.approveTransferRequestBatch(keyElements, partialValues, boolIsApproved);
+ ruleConditionalTransfer.approveTransferRequestBatch(
+ keyElements,
+ partialValues,
+ boolIsApproved
+ );
}
function testCannotAttackerResetBatch() public {
uint256[] memory ids = new uint256[](0);
bool[] memory boolIsApproved = new bool[](0);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
- ruleConditionalTransfer.approveTransferRequestBatchWithId(ids, boolIsApproved);
+ ruleConditionalTransfer.approveTransferRequestBatchWithId(
+ ids,
+ boolIsApproved
+ );
}
function testCannotAttackerCreateTransferRequestWithApprovalBatch() public {
- TransferRequestKeyElement[] memory keyElements = new TransferRequestKeyElement[](0);
+ TransferRequestKeyElement[]
+ memory keyElements = new TransferRequestKeyElement[](0);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
- ruleConditionalTransfer.createTransferRequestWithApprovalBatch(keyElements);
+ ruleConditionalTransfer.createTransferRequestWithApprovalBatch(
+ keyElements
+ );
}
/******** OPTIONS CONFIGURATION *********/
@@ -164,40 +234,60 @@ contract RuleConditionalTransferAccessControl is Test, HelperContract {
timeLimitToTransfer: 200 days
});
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
ruleConditionalTransfer.setTimeLimit(timeLimit_);
}
function testCannotAttackerSetAutomaticTransfer() public {
AUTOMATIC_TRANSFER memory automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
+ isActivate: false,
cmtat: IERC20(address(0))
});
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
ruleConditionalTransfer.setAutomaticTransfer(automaticTransfer_);
}
function testCannotAttackerSetIssuanceOptions() public {
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:false
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: false
});
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
ruleConditionalTransfer.setIssuanceOptions(issuanceOption_);
}
function testCannotAttackerSetAuomaticApproval() public {
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
+ AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
isActivate: false,
timeLimitBeforeAutomaticApproval: 0
});
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE
+ )
+ );
vm.prank(ATTACKER);
ruleConditionalTransfer.setAutomaticApproval(automaticApproval_);
}
diff --git a/test/RuleConditionalTransfer/RuleConditionalTransferReset.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransferReset.t.sol
index 5083279..e3c7f8d 100644
--- a/test/RuleConditionalTransfer/RuleConditionalTransferReset.t.sol
+++ b/test/RuleConditionalTransfer/RuleConditionalTransferReset.t.sol
@@ -6,8 +6,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title General functions of the RuleWhitelist
-*/
+ * @title General functions of the RuleWhitelist
+ */
contract RuleConditionalTransferResetTest is Test, HelperContract {
RuleEngine ruleEngineMock;
uint256 resUint256;
@@ -17,13 +17,15 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
string resString;
uint8 CODE_NONEXISTENT = 255;
uint256 defaultValue = 10;
- bytes32 defaultKey = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
+ bytes32 defaultKey =
+ keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
- TransferRequestKeyElement transferRequestInput = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:defaultValue
- });
+ value: defaultValue
+ });
uint256 value2 = 1;
uint256 value3 = 2;
@@ -35,17 +37,19 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
bytes32 key4 = keccak256(abi.encode(ADDRESS1, ADDRESS2, value4));
bytes32 key5 = keccak256(abi.encode(ADDRESS1, ADDRESS2, value5));
- TransferRequestKeyElement transferRequestInput2 = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput2 =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:value2
- });
+ value: value2
+ });
- TransferRequestKeyElement transferRequestInput3 = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput3 =
+ TransferRequestKeyElement({
from: ADDRESS2,
to: ADDRESS1,
- value:value3
- });
+ value: value3
+ });
// Arrange
function setUp() public {
@@ -53,26 +57,26 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
timeLimitToApprove: 7 days,
timeLimitToTransfer: 30 days
});
-
- AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
+
+ AUTOMATIC_APPROVAL memory automaticApproval_ = AUTOMATIC_APPROVAL({
isActivate: false,
timeLimitBeforeAutomaticApproval: 0
});
ISSUANCE memory issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:false
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: false
});
AUTOMATIC_TRANSFER memory automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
+ isActivate: false,
cmtat: IERC20(address(0))
});
OPTION memory options = OPTION({
- issuance:issuanceOption_,
+ issuance: issuanceOption_,
timeLimit: timeLimit_,
automaticApproval: automaticApproval_,
- automaticTransfer:automaticTransfer_
+ automaticTransfer: automaticTransfer_
});
ruleEngineMock = new RuleEngine(
RULE_ENGINE_OPERATOR_ADDRESS,
@@ -83,15 +87,18 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ruleConditionalTransfer = new RuleConditionalTransfer(
DEFAULT_ADMIN_ADDRESS,
ZERO_ADDRESS,
- ruleEngineMock,
+ ruleEngineMock,
options
);
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleConditionalTransfer.grantRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE, CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
+ ruleConditionalTransfer.grantRole(
+ RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE,
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS
+ );
}
- function _createTransferRequestBatch() public{
- // Arrange
+ function _createTransferRequestBatch() public {
+ // Arrange
_createTransferRequest();
// Second and third request
@@ -101,8 +108,8 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS1, value3);
}
- function _createTransferRequestBatchByHodler() public{
- // Arrange
+ function _createTransferRequestBatchByHodler() public {
+ // Arrange
_createTransferRequest();
// Second and third request
@@ -112,7 +119,7 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS2, value3);
}
- function _createTransferRequest() internal{
+ function _createTransferRequest() internal {
vm.prank(ADDRESS1);
// Act
vm.expectEmit(true, true, true, true);
@@ -120,7 +127,8 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
// Assert
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -128,9 +136,10 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
assertEq(transferRequest.value, defaultValue);
assertEq(uint256(transferRequest.status), uint256(STATUS.WAIT));
- TransferRequest[] memory transferRequests = ruleConditionalTransfer.getRequestByStatus(STATUS.WAIT);
- assertEq(transferRequests[0].key , defaultKey);
- assertEq(transferRequests.length , 1);
+ TransferRequest[] memory transferRequests = ruleConditionalTransfer
+ .getRequestByStatus(STATUS.WAIT);
+ assertEq(transferRequests[0].key, defaultKey);
+ assertEq(transferRequests.length, 1);
}
/***** Reset ********/
@@ -139,7 +148,7 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
// Arrange
_createTransferRequest();
- // Act
+ // Act
// Reset
vm.prank(ADDRESS1);
vm.expectEmit(true, true, true, true);
@@ -151,7 +160,11 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
vm.prank(ADDRESS1);
ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,true);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ true
+ );
// Reset
vm.prank(ADDRESS1);
@@ -181,7 +194,7 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ids[0] = 0;
ids[1] = 1;
ids[2] = 2;
- // Act
+ // Act
// Reset
vm.prank(ADDRESS1);
vm.expectEmit(true, true, true, true);
@@ -200,7 +213,7 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ids[0] = 0;
ids[1] = 4;
ids[2] = 2;
- // Act
+ // Act
// Reset
vm.prank(ADDRESS1);
vm.expectRevert(RuleConditionalTransfer_InvalidId.selector);
@@ -211,7 +224,7 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
// Arrange
_createTransferRequestBatchByHodler();
uint256[] memory ids = new uint256[](0);
- // Act
+ // Act
// Reset
vm.prank(ADDRESS1);
vm.expectRevert(RuleConditionalTransfer_EmptyArray.selector);
@@ -222,7 +235,7 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
// Arrange
_createTransferRequest();
- // Act
+ // Act
// Reset
vm.prank(ADDRESS2);
vm.expectRevert(RuleConditionalTransfer_InvalidSender.selector);
@@ -233,7 +246,7 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
// Arrange
_createTransferRequest();
- // Act
+ // Act
// Reset
vm.prank(ADDRESS1);
vm.expectRevert(RuleConditionalTransfer_InvalidId.selector);
@@ -246,9 +259,13 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
// Denied
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0, false);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ false
+ );
- // Act
+ // Act
// Reset
vm.prank(ADDRESS1);
vm.expectRevert(RuleConditionalTransfer_Wrong_Status.selector);
@@ -264,7 +281,11 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,false);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ false
+ );
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
@@ -273,7 +294,8 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ruleConditionalTransfer.resetRequestStatus(0);
// Assert
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -289,7 +311,11 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ruleConditionalTransfer.createTransferRequest(ADDRESS2, defaultValue);
// Assert
- transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ transferRequest = ruleConditionalTransfer.getRequestTrade(
+ ADDRESS1,
+ ADDRESS2,
+ defaultValue
+ );
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -297,7 +323,6 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
assertEq(transferRequest.value, defaultValue);
assertEq(uint256(transferRequest.status), uint256(STATUS.WAIT));
-
// Id different from 0
vm.prank(ADDRESS1);
// Act
@@ -317,7 +342,11 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,false);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ false
+ );
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
@@ -330,7 +359,8 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ruleConditionalTransfer.resetRequestStatusBatch(ids);
// Assert
- TransferRequest memory transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
+ TransferRequest memory transferRequest = ruleConditionalTransfer
+ .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue);
assertEq(transferRequest.key, defaultKey);
assertEq(transferRequest.id, 0);
assertEq(transferRequest.from, ADDRESS1);
@@ -338,8 +368,11 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
assertEq(transferRequest.value, defaultValue);
assertEq(uint256(transferRequest.status), uint256(STATUS.NONE));
-
- transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, value2);
+ transferRequest = ruleConditionalTransfer.getRequestTrade(
+ ADDRESS1,
+ ADDRESS2,
+ value2
+ );
assertEq(transferRequest.key, key2);
assertEq(transferRequest.id, 1);
assertEq(transferRequest.from, ADDRESS1);
@@ -347,7 +380,11 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
assertEq(transferRequest.value, value2);
assertEq(uint256(transferRequest.status), uint256(STATUS.NONE));
- transferRequest = ruleConditionalTransfer.getRequestTrade(ADDRESS1, ADDRESS2, value3);
+ transferRequest = ruleConditionalTransfer.getRequestTrade(
+ ADDRESS1,
+ ADDRESS2,
+ value3
+ );
assertEq(transferRequest.key, key3Hodler);
assertEq(transferRequest.id, 2);
assertEq(transferRequest.from, ADDRESS1);
@@ -356,8 +393,9 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
assertEq(uint256(transferRequest.status), uint256(STATUS.NONE));
}
-
- function testCannotBatchResetADeniedRequestCreatedByHolderWithWrongId() public {
+ function testCannotBatchResetADeniedRequestCreatedByHolderWithWrongId()
+ public
+ {
// Arrange
_createTransferRequestBatchByHodler();
uint256[] memory ids = new uint256[](3);
@@ -368,7 +406,11 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,false);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ false
+ );
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
@@ -376,14 +418,20 @@ contract RuleConditionalTransferResetTest is Test, HelperContract {
ruleConditionalTransfer.resetRequestStatusBatch(ids);
}
- function testCannotBatchResetADeniedRequestCreatedByHolderWithEmptyArray() public {
+ function testCannotBatchResetADeniedRequestCreatedByHolderWithEmptyArray()
+ public
+ {
// Arrange
_createTransferRequestBatchByHodler();
uint256[] memory ids = new uint256[](0);
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
vm.expectEmit(true, true, true, true);
emit transferDenied(defaultKey, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.approveTransferRequest(transferRequestInput, 0,false);
+ ruleConditionalTransfer.approveTransferRequest(
+ transferRequestInput,
+ 0,
+ false
+ );
// Act
vm.prank(CONDITIONAL_TRANSFER_OPERATOR_ADDRESS);
diff --git a/test/RuleConditionalTransfer/RuleConditionalTransferRestriction.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransferRestriction.t.sol
index 1b3d9f2..389843d 100644
--- a/test/RuleConditionalTransfer/RuleConditionalTransferRestriction.t.sol
+++ b/test/RuleConditionalTransfer/RuleConditionalTransferRestriction.t.sol
@@ -4,10 +4,11 @@ pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../HelperContract.sol";
import "src/RuleEngine.sol";
+
//ADmin, forwarder irrect /RuleEngine
/**
-* @title General functions of the RuleEngine
-*/
+ * @title General functions of the RuleEngine
+ */
contract RuleEngineOperationTest is Test, HelperContract {
RuleEngine ruleEngineMock;
uint8 resUint8;
@@ -17,42 +18,45 @@ contract RuleEngineOperationTest is Test, HelperContract {
uint8 CODE_NONEXISTENT = 255;
uint256 defaultValue = 20;
- TIME_LIMIT timeLimit_ = TIME_LIMIT({
- timeLimitToApprove: DEFAULT_TIME_LIMIT_TO_APPROVE,
- timeLimitToTransfer: DEFAULT_TIME_LIMIT_TO_TRANSFER
+ TIME_LIMIT timeLimit_ =
+ TIME_LIMIT({
+ timeLimitToApprove: DEFAULT_TIME_LIMIT_TO_APPROVE,
+ timeLimitToTransfer: DEFAULT_TIME_LIMIT_TO_TRANSFER
});
- ISSUANCE issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:false
+ ISSUANCE issuanceOption_ =
+ ISSUANCE({
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: false
});
- AUTOMATIC_APPROVAL automaticApproval_ = AUTOMATIC_APPROVAL({
+ AUTOMATIC_APPROVAL automaticApproval_ =
+ AUTOMATIC_APPROVAL({
isActivate: false,
timeLimitBeforeAutomaticApproval: 0
});
- AUTOMATIC_TRANSFER automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
- cmtat: IERC20(address(0))
- });
- OPTION options = OPTION({
- issuance:issuanceOption_,
+ AUTOMATIC_TRANSFER automaticTransfer_ =
+ AUTOMATIC_TRANSFER({isActivate: false, cmtat: IERC20(address(0))});
+ OPTION options =
+ OPTION({
+ issuance: issuanceOption_,
timeLimit: timeLimit_,
automaticApproval: automaticApproval_,
- automaticTransfer:automaticTransfer_
+ automaticTransfer: automaticTransfer_
});
- TransferRequestKeyElement transferRequestInput = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:defaultValue
- });
+ value: defaultValue
+ });
// Arrange
function setUp() public {
ruleConditionalTransfer = new RuleConditionalTransfer(
CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
ZERO_ADDRESS,
- ruleEngineMock,
+ ruleEngineMock,
options
);
}
@@ -63,7 +67,9 @@ contract RuleEngineOperationTest is Test, HelperContract {
bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
vm.expectEmit(true, true, true, true);
emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.createTransferRequestWithApproval(transferRequestInput);
+ ruleConditionalTransfer.createTransferRequestWithApproval(
+ transferRequestInput
+ );
// Act
resUint8 = ruleConditionalTransfer.detectTransferRestriction(
ADDRESS1,
@@ -87,7 +93,6 @@ contract RuleEngineOperationTest is Test, HelperContract {
assertEq(resUint8, CODE_TRANSFER_REQUEST_NOT_APPROVED);
}
-
function testMessageForTransferRestrictionWithUnknownRestrictionCode()
public
{
diff --git a/test/RuleEngine/AccessControl/RuleEngineAccessControl.sol b/test/RuleEngine/AccessControl/RuleEngineAccessControl.sol
index 89de71f..940e6b5 100644
--- a/test/RuleEngine/AccessControl/RuleEngineAccessControl.sol
+++ b/test/RuleEngine/AccessControl/RuleEngineAccessControl.sol
@@ -6,8 +6,8 @@ import "../../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Tests on the Access Control
-*/
+ * @title Tests on the Access Control
+ */
contract RuleEngineAccessControlTest is Test, HelperContract {
// Custom error openZeppelin
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
@@ -58,7 +58,12 @@ contract RuleEngineAccessControlTest is Test, HelperContract {
// Act
vm.prank(ATTACKER);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_ENGINE_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_ENGINE_OPERATOR_ROLE
+ )
+ );
(bool success, ) = address(ruleEngineMock).call(
abi.encodeCall(ruleEngineMock.setRulesValidation, ruleWhitelistTab)
);
@@ -73,7 +78,12 @@ contract RuleEngineAccessControlTest is Test, HelperContract {
// Act
vm.prank(ATTACKER);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_ENGINE_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_ENGINE_OPERATOR_ROLE
+ )
+ );
ruleEngineMock.clearRulesValidation();
// Assert
@@ -85,7 +95,12 @@ contract RuleEngineAccessControlTest is Test, HelperContract {
// Act
vm.prank(ATTACKER);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_ENGINE_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_ENGINE_OPERATOR_ROLE
+ )
+ );
ruleEngineMock.addRuleValidation(ruleWhitelist);
// Assert
@@ -97,7 +112,12 @@ contract RuleEngineAccessControlTest is Test, HelperContract {
// Act
vm.prank(ATTACKER);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, RULE_ENGINE_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ RULE_ENGINE_OPERATOR_ROLE
+ )
+ );
ruleEngineMock.removeRuleValidation(ruleWhitelist, 0);
// Assert
@@ -109,7 +129,12 @@ contract RuleEngineAccessControlTest is Test, HelperContract {
// Act
vm.prank(ATTACKER);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, TOKEN_CONTRACT_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ TOKEN_CONTRACT_ROLE
+ )
+ );
ruleEngineMock.operateOnTransfer(ADDRESS1, ADDRESS2, 10);
}
}
diff --git a/test/RuleEngine/AccessControl/RuleEngineAccessControlOZ.t.sol b/test/RuleEngine/AccessControl/RuleEngineAccessControlOZ.t.sol
index 4dfbe9e..ef3d354 100644
--- a/test/RuleEngine/AccessControl/RuleEngineAccessControlOZ.t.sol
+++ b/test/RuleEngine/AccessControl/RuleEngineAccessControlOZ.t.sol
@@ -7,8 +7,8 @@ import "../../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Tests on the provided functions by OpenZeppelin
-*/
+ * @title Tests on the provided functions by OpenZeppelin
+ */
contract RuleEngineAccessControlTest is Test, HelperContract, AccessControl {
RuleEngine ruleEngineMock;
uint8 resUint8;
@@ -43,73 +43,83 @@ contract RuleEngineAccessControlTest is Test, HelperContract, AccessControl {
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
vm.expectEmit(true, true, false, true);
emit RoleGranted(
- RULE_ENGINE_ROLE,
+ RULE_ENGINE_OPERATOR_ROLE,
ADDRESS1,
RULE_ENGINE_OPERATOR_ADDRESS
);
- ruleEngineMock.grantRole(RULE_ENGINE_ROLE, ADDRESS1);
+ ruleEngineMock.grantRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
// Assert
- bool res1 = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, ADDRESS1);
+ bool res1 = ruleEngineMock.hasRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
assertEq(res1, true);
}
function testRevokeRoleAsAdmin() public {
// Arrange
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
- ruleEngineMock.grantRole(RULE_ENGINE_ROLE, ADDRESS1);
+ ruleEngineMock.grantRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
// Arrange - Assert
- bool res1 = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, ADDRESS1);
+ bool res1 = ruleEngineMock.hasRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
assertEq(res1, true);
// Act
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
vm.expectEmit(true, true, false, true);
emit RoleRevoked(
- RULE_ENGINE_ROLE,
+ RULE_ENGINE_OPERATOR_ROLE,
ADDRESS1,
RULE_ENGINE_OPERATOR_ADDRESS
);
- ruleEngineMock.revokeRole(RULE_ENGINE_ROLE, ADDRESS1);
+ ruleEngineMock.revokeRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
// Assert
- bool res2 = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, ADDRESS1);
+ bool res2 = ruleEngineMock.hasRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
assertFalse(res2);
}
function testCannotGrantFromNonAdmin() public {
// Arrange - Assert
- bool res1 = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, ADDRESS1);
+ bool res1 = ruleEngineMock.hasRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
assertFalse(res1);
// Act
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ADDRESS2, DEFAULT_ADMIN_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ADDRESS2,
+ DEFAULT_ADMIN_ROLE
+ )
+ );
vm.prank(ADDRESS2);
- ruleEngineMock.grantRole(RULE_ENGINE_ROLE, ADDRESS2);
+ ruleEngineMock.grantRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS2);
// Assert
- bool res2 = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, ADDRESS1);
+ bool res2 = ruleEngineMock.hasRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
assertFalse(res2);
}
function testCannotRevokeFromNonAdmin() public {
// Arrange - Assert
- bool res1 = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, ADDRESS1);
+ bool res1 = ruleEngineMock.hasRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
assertFalse(res1);
// Arrange
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
- ruleEngineMock.grantRole(RULE_ENGINE_ROLE, ADDRESS1);
+ ruleEngineMock.grantRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
// Arrange - Assert
- bool res2 = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, ADDRESS1);
+ bool res2 = ruleEngineMock.hasRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
assertEq(res2, true);
// Act
vm.prank(ADDRESS2);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ADDRESS2, DEFAULT_ADMIN_ROLE));
- ruleEngineMock.revokeRole(RULE_ENGINE_ROLE, ADDRESS1);
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ADDRESS2,
+ DEFAULT_ADMIN_ROLE
+ )
+ );
+ ruleEngineMock.revokeRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
// Assert
- bool res3 = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, ADDRESS1);
+ bool res3 = ruleEngineMock.hasRole(RULE_ENGINE_OPERATOR_ROLE, ADDRESS1);
assertEq(res3, true);
}
}
diff --git a/test/RuleEngine/RuleEngineDeployment.t.sol b/test/RuleEngine/RuleEngineDeployment.t.sol
index 923b709..258d75e 100644
--- a/test/RuleEngine/RuleEngineDeployment.t.sol
+++ b/test/RuleEngine/RuleEngineDeployment.t.sol
@@ -6,9 +6,10 @@ import "../HelperContract.sol";
import "CMTAT/mocks/MinimalForwarderMock.sol";
import "src/RuleEngine.sol";
import "src/RuleEngine.sol";
+
/**
-* @title General functions of the RuleEngine
-*/
+ * @title General functions of the RuleEngine
+ */
contract RuleEngineTest is Test, HelperContract {
RuleEngine ruleEngineMock;
uint8 resUint8;
@@ -18,15 +19,12 @@ contract RuleEngineTest is Test, HelperContract {
uint8 CODE_NONEXISTENT = 255;
// Arrange
- function setUp() public {
-
- }
+ function setUp() public {}
function testRightDeployment() public {
// Arrange
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
- MinimalForwarderMock forwarder = new MinimalForwarderMock(
- );
+ MinimalForwarderMock forwarder = new MinimalForwarderMock();
forwarder.initialize(ERC2771ForwarderDomain);
// Act
@@ -37,7 +35,10 @@ contract RuleEngineTest is Test, HelperContract {
);
// assert
- resBool = ruleEngineMock.hasRole(RULE_ENGINE_ROLE, RULE_ENGINE_OPERATOR_ADDRESS);
+ resBool = ruleEngineMock.hasRole(
+ RULE_ENGINE_OPERATOR_ROLE,
+ RULE_ENGINE_OPERATOR_ADDRESS
+ );
assertEq(resBool, true);
resBool = ruleEngineMock.isTrustedForwarder(address(forwarder));
assertEq(resBool, true);
@@ -46,8 +47,7 @@ contract RuleEngineTest is Test, HelperContract {
function testCannotDeployContractifAdminAddressIsZero() public {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
- MinimalForwarderMock forwarder = new MinimalForwarderMock(
- );
+ MinimalForwarderMock forwarder = new MinimalForwarderMock();
forwarder.initialize(ERC2771ForwarderDomain);
vm.expectRevert(RuleEngine_AdminWithAddressZeroNotAllowed.selector);
// Act
@@ -57,6 +57,4 @@ contract RuleEngineTest is Test, HelperContract {
ZERO_ADDRESS
);
}
-
-
}
diff --git a/test/RuleEngine/ruleEngineOperation/RuleEngineOperation.t.sol b/test/RuleEngine/ruleEngineOperation/RuleEngineOperation.t.sol
index 48e4383..0b535f0 100644
--- a/test/RuleEngine/ruleEngineOperation/RuleEngineOperation.t.sol
+++ b/test/RuleEngine/ruleEngineOperation/RuleEngineOperation.t.sol
@@ -4,10 +4,11 @@ pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../../HelperContract.sol";
import "src/RuleEngine.sol";
+
//ADmin, forwarder irrect /RuleEngine
/**
-* @title General functions of the RuleEngine
-*/
+ * @title General functions of the RuleEngine
+ */
contract RuleEngineOperationTest is Test, HelperContract {
RuleEngine ruleEngineMock;
uint8 resUint8;
@@ -16,31 +17,32 @@ contract RuleEngineOperationTest is Test, HelperContract {
string resString;
uint8 CODE_NONEXISTENT = 255;
- TIME_LIMIT timeLimit_ = TIME_LIMIT({
- timeLimitToApprove: DEFAULT_TIME_LIMIT_TO_APPROVE,
- timeLimitToTransfer: DEFAULT_TIME_LIMIT_TO_TRANSFER
+ TIME_LIMIT timeLimit_ =
+ TIME_LIMIT({
+ timeLimitToApprove: DEFAULT_TIME_LIMIT_TO_APPROVE,
+ timeLimitToTransfer: DEFAULT_TIME_LIMIT_TO_TRANSFER
});
- ISSUANCE issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:false
+ ISSUANCE issuanceOption_ =
+ ISSUANCE({
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: false
});
- AUTOMATIC_APPROVAL automaticApproval_ = AUTOMATIC_APPROVAL({
+ AUTOMATIC_APPROVAL automaticApproval_ =
+ AUTOMATIC_APPROVAL({
isActivate: false,
timeLimitBeforeAutomaticApproval: 0
});
- AUTOMATIC_TRANSFER automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
- cmtat: IERC20(address(0))
- });
- OPTION options = OPTION({
- issuance:issuanceOption_,
+ AUTOMATIC_TRANSFER automaticTransfer_ =
+ AUTOMATIC_TRANSFER({isActivate: false, cmtat: IERC20(address(0))});
+ OPTION options =
+ OPTION({
+ issuance: issuanceOption_,
timeLimit: timeLimit_,
automaticApproval: automaticApproval_,
- automaticTransfer:automaticTransfer_
+ automaticTransfer: automaticTransfer_
});
-
// Arrange
function setUp() public {
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
@@ -52,11 +54,10 @@ contract RuleEngineOperationTest is Test, HelperContract {
ruleConditionalTransfer = new RuleConditionalTransfer(
CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
ZERO_ADDRESS,
- ruleEngineMock,
+ ruleEngineMock,
options
);
-
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
ruleEngineMock.addRuleOperation(ruleConditionalTransfer);
// Arrange - Assert
@@ -68,21 +69,25 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer2 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
address[] memory RuleConditionalTransferTab = new address[](2);
- RuleConditionalTransferTab[0] = address(IRuleOperation(RuleConditionalTransfer1));
- RuleConditionalTransferTab[1] = address(IRuleOperation(RuleConditionalTransfer2));
+ RuleConditionalTransferTab[0] = address(
+ IRuleOperation(RuleConditionalTransfer1)
+ );
+ RuleConditionalTransferTab[1] = address(
+ IRuleOperation(RuleConditionalTransfer2)
+ );
// Act
vm.expectEmit(true, false, false, false);
emit AddRule(address(RuleConditionalTransfer1));
@@ -90,7 +95,10 @@ contract RuleEngineOperationTest is Test, HelperContract {
emit AddRule(address(RuleConditionalTransfer2));
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
// Assert
@@ -103,11 +111,11 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
address[] memory RuleConditionalTransferTab = new address[](2);
RuleConditionalTransferTab[0] = address(RuleConditionalTransfer1);
RuleConditionalTransferTab[1] = address(RuleConditionalTransfer1);
@@ -116,7 +124,10 @@ contract RuleEngineOperationTest is Test, HelperContract {
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
vm.expectRevert(RuleEngine_RuleAlreadyExists.selector);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
// Assert
@@ -137,7 +148,10 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Act
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
// Assert
@@ -160,7 +174,10 @@ contract RuleEngineOperationTest is Test, HelperContract {
vm.expectRevert("The array is empty2");
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
resBool = ruleEngineMock.validateTransfer(ADDRESS1, ADDRESS2, 20);
@@ -180,25 +197,32 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer2 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
address[] memory RuleConditionalTransferTab = new address[](2);
- RuleConditionalTransferTab[0] = address(IRuleOperation(RuleConditionalTransfer1));
- RuleConditionalTransferTab[1] = address(IRuleOperation(RuleConditionalTransfer2));
+ RuleConditionalTransferTab[0] = address(
+ IRuleOperation(RuleConditionalTransfer1)
+ );
+ RuleConditionalTransferTab[1] = address(
+ IRuleOperation(RuleConditionalTransfer2)
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
ruleEngineMock.rulesOperation();
// Assert - Arrange
@@ -219,25 +243,32 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer2 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
address[] memory RuleConditionalTransferTab = new address[](2);
- RuleConditionalTransferTab[0] = address(IRuleOperation(RuleConditionalTransfer1));
- RuleConditionalTransferTab[1] = address(IRuleOperation(RuleConditionalTransfer2));
+ RuleConditionalTransferTab[0] = address(
+ IRuleOperation(RuleConditionalTransfer1)
+ );
+ RuleConditionalTransferTab[1] = address(
+ IRuleOperation(RuleConditionalTransfer2)
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
// Act
@@ -251,7 +282,10 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Can set again the previous rules
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
assertEq(resCallBool, true);
// Arrange before assert
@@ -273,11 +307,11 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
// Act
vm.expectEmit(true, false, false, false);
@@ -337,11 +371,11 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
// Act
vm.expectRevert(RuleEngine_RuleDoNotMatch.selector);
@@ -357,11 +391,11 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
ruleEngineMock.addRuleOperation(RuleConditionalTransfer1);
@@ -380,11 +414,11 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
ruleEngineMock.addRuleOperation(RuleConditionalTransfer1);
@@ -404,21 +438,21 @@ contract RuleEngineOperationTest is Test, HelperContract {
// First rule
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
ruleEngineMock.addRuleOperation(RuleConditionalTransfer1);
// Second rule
vm.prank(WHITELIST_OPERATOR_ADDRESS);
RuleConditionalTransfer RuleConditionalTransfer2 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
ruleEngineMock.addRuleOperation(RuleConditionalTransfer2);
@@ -447,23 +481,30 @@ contract RuleEngineOperationTest is Test, HelperContract {
// Arrange
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
RuleConditionalTransfer RuleConditionalTransfer2 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
address[] memory RuleConditionalTransferTab = new address[](2);
- RuleConditionalTransferTab[0] = address(IRuleOperation(RuleConditionalTransfer1));
- RuleConditionalTransferTab[1] = address(IRuleOperation(RuleConditionalTransfer2));
+ RuleConditionalTransferTab[0] = address(
+ IRuleOperation(RuleConditionalTransfer1)
+ );
+ RuleConditionalTransferTab[1] = address(
+ IRuleOperation(RuleConditionalTransfer2)
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
// Arrange - Assert
@@ -479,23 +520,30 @@ contract RuleEngineOperationTest is Test, HelperContract {
function testGetRule() public {
// Arrange
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
RuleConditionalTransfer RuleConditionalTransfer2 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
address[] memory RuleConditionalTransferTab = new address[](2);
- RuleConditionalTransferTab[0] = address(IRuleOperation(RuleConditionalTransfer1));
- RuleConditionalTransferTab[1] = address(IRuleOperation(RuleConditionalTransfer2));
+ RuleConditionalTransferTab[0] = address(
+ IRuleOperation(RuleConditionalTransfer1)
+ );
+ RuleConditionalTransferTab[1] = address(
+ IRuleOperation(RuleConditionalTransfer2)
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
// Arrange - Assert
assertEq(resCallBool, true);
@@ -510,23 +558,30 @@ contract RuleEngineOperationTest is Test, HelperContract {
function testGetRules() public {
// Arrange
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
RuleConditionalTransfer RuleConditionalTransfer2 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
address[] memory RuleConditionalTransferTab = new address[](2);
- RuleConditionalTransferTab[0] = address(IRuleOperation(RuleConditionalTransfer1));
- RuleConditionalTransferTab[1] = address(IRuleOperation(RuleConditionalTransfer2));
+ RuleConditionalTransferTab[0] = address(
+ IRuleOperation(RuleConditionalTransfer1)
+ );
+ RuleConditionalTransferTab[1] = address(
+ IRuleOperation(RuleConditionalTransfer2)
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
// Arrange - Assert
assertEq(resCallBool, true);
@@ -544,33 +599,45 @@ contract RuleEngineOperationTest is Test, HelperContract {
function testCanGetRuleIndex() public {
// Arrange
RuleConditionalTransfer RuleConditionalTransfer1 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
RuleConditionalTransfer RuleConditionalTransfer2 = new RuleConditionalTransfer(
- CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
- ZERO_ADDRESS,
- ruleEngineMock,
- options
-
- );
+ CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
+ ZERO_ADDRESS,
+ ruleEngineMock,
+ options
+ );
address[] memory RuleConditionalTransferTab = new address[](2);
- RuleConditionalTransferTab[0] = address(IRuleOperation(RuleConditionalTransfer1));
- RuleConditionalTransferTab[1] = address(IRuleOperation(RuleConditionalTransfer2));
+ RuleConditionalTransferTab[0] = address(
+ IRuleOperation(RuleConditionalTransfer1)
+ );
+ RuleConditionalTransferTab[1] = address(
+ IRuleOperation(RuleConditionalTransfer2)
+ );
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
(bool resCallBool, ) = address(ruleEngineMock).call(
- abi.encodeCall(ruleEngineMock.setRulesOperation, RuleConditionalTransferTab)
+ abi.encodeCall(
+ ruleEngineMock.setRulesOperation,
+ RuleConditionalTransferTab
+ )
);
// Arrange - Assert
assertEq(resCallBool, true);
// Act
- uint256 index1 = ruleEngineMock.getRuleIndexOperation(RuleConditionalTransfer1);
- uint256 index2 = ruleEngineMock.getRuleIndexOperation(RuleConditionalTransfer2);
+ uint256 index1 = ruleEngineMock.getRuleIndexOperation(
+ RuleConditionalTransfer1
+ );
+ uint256 index2 = ruleEngineMock.getRuleIndexOperation(
+ RuleConditionalTransfer2
+ );
// Length of the list because RuleConditionalTransfer is not in the list
- uint256 index3 = ruleEngineMock.getRuleIndexOperation(ruleConditionalTransfer);
+ uint256 index3 = ruleEngineMock.getRuleIndexOperation(
+ ruleConditionalTransfer
+ );
// Assert
assertEq(index1, 0);
diff --git a/test/RuleEngine/ruleEngineOperation/RuleEngineRestriction.t.sol b/test/RuleEngine/ruleEngineOperation/RuleEngineRestriction.t.sol
index 36261be..1f052a3 100644
--- a/test/RuleEngine/ruleEngineOperation/RuleEngineRestriction.t.sol
+++ b/test/RuleEngine/ruleEngineOperation/RuleEngineRestriction.t.sol
@@ -4,10 +4,11 @@ pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../../HelperContract.sol";
import "src/RuleEngine.sol";
+
//ADmin, forwarder irrect /RuleEngine
/**
-* @title General functions of the RuleEngine
-*/
+ * @title General functions of the RuleEngine
+ */
contract RuleEngineOperationTest is Test, HelperContract {
RuleEngine ruleEngineMock;
uint8 resUint8;
@@ -17,35 +18,39 @@ contract RuleEngineOperationTest is Test, HelperContract {
uint8 CODE_NONEXISTENT = 255;
uint256 defaultValue = 20;
- TIME_LIMIT timeLimit_ = TIME_LIMIT({
- timeLimitToApprove: DEFAULT_TIME_LIMIT_TO_APPROVE,
- timeLimitToTransfer: DEFAULT_TIME_LIMIT_TO_TRANSFER
+ TIME_LIMIT timeLimit_ =
+ TIME_LIMIT({
+ timeLimitToApprove: DEFAULT_TIME_LIMIT_TO_APPROVE,
+ timeLimitToTransfer: DEFAULT_TIME_LIMIT_TO_TRANSFER
});
- ISSUANCE issuanceOption_ = ISSUANCE({
- authorizedMintWithoutApproval:false,
- authorizedBurnWithoutApproval:false
+ ISSUANCE issuanceOption_ =
+ ISSUANCE({
+ authorizedMintWithoutApproval: false,
+ authorizedBurnWithoutApproval: false
});
- AUTOMATIC_APPROVAL automaticApproval_ = AUTOMATIC_APPROVAL({
+ AUTOMATIC_APPROVAL automaticApproval_ =
+ AUTOMATIC_APPROVAL({
isActivate: false,
timeLimitBeforeAutomaticApproval: 0
});
- AUTOMATIC_TRANSFER automaticTransfer_ = AUTOMATIC_TRANSFER({
- isActivate:false,
- cmtat: IERC20(address(0))
- });
- OPTION options = OPTION({
- issuance:issuanceOption_,
+ AUTOMATIC_TRANSFER automaticTransfer_ =
+ AUTOMATIC_TRANSFER({isActivate: false, cmtat: IERC20(address(0))});
+ OPTION options =
+ OPTION({
+ issuance: issuanceOption_,
timeLimit: timeLimit_,
automaticApproval: automaticApproval_,
- automaticTransfer:automaticTransfer_
+ automaticTransfer: automaticTransfer_
});
- TransferRequestKeyElement transferRequestInput = TransferRequestKeyElement({
+ TransferRequestKeyElement transferRequestInput =
+ TransferRequestKeyElement({
from: ADDRESS1,
to: ADDRESS2,
- value:defaultValue
- });
+ value: defaultValue
+ });
+
// Arrange
function setUp() public {
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
@@ -57,11 +62,10 @@ contract RuleEngineOperationTest is Test, HelperContract {
ruleConditionalTransfer = new RuleConditionalTransfer(
CONDITIONAL_TRANSFER_OPERATOR_ADDRESS,
ZERO_ADDRESS,
- ruleEngineMock,
+ ruleEngineMock,
options
);
-
vm.prank(RULE_ENGINE_OPERATOR_ADDRESS);
ruleEngineMock.addRuleOperation(ruleConditionalTransfer);
// Arrange - Assert
@@ -75,7 +79,9 @@ contract RuleEngineOperationTest is Test, HelperContract {
bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, defaultValue));
vm.expectEmit(true, true, true, true);
emit transferApproved(key, ADDRESS1, ADDRESS2, defaultValue, 0);
- ruleConditionalTransfer.createTransferRequestWithApproval(transferRequestInput);
+ ruleConditionalTransfer.createTransferRequestWithApproval(
+ transferRequestInput
+ );
// Act
resUint8 = ruleEngineMock.detectTransferRestriction(
ADDRESS1,
@@ -111,7 +117,6 @@ contract RuleEngineOperationTest is Test, HelperContract {
assertEq(resString, "Unknown restriction code");
}
-
function testMessageForTransferRestrictionWithUnknownRestrictionCode()
public
{
diff --git a/test/RuleEngine/ruleEngineValidation/RuleEngineRestriction.t.sol b/test/RuleEngine/ruleEngineValidation/RuleEngineRestriction.t.sol
index feabefc..f6d10a7 100644
--- a/test/RuleEngine/ruleEngineValidation/RuleEngineRestriction.t.sol
+++ b/test/RuleEngine/ruleEngineValidation/RuleEngineRestriction.t.sol
@@ -6,8 +6,8 @@ import "../../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title tests concerning the restrictions and validation for the transfers
-*/
+ * @title tests concerning the restrictions and validation for the transfers
+ */
contract RuleEngineRestrictionTest is Test, HelperContract {
RuleEngine ruleEngineMock;
uint8 resUint8;
@@ -123,7 +123,7 @@ contract RuleEngineRestrictionTest is Test, HelperContract {
// ruleEngineValidation
// Act
- resUint8 = ruleEngineMock.detectTransferRestrictionValidation(
+ resUint8 = ruleEngineMock.detectTransferRestrictionValidation(
ADDRESS1,
ADDRESS2,
20
@@ -181,11 +181,14 @@ contract RuleEngineRestrictionTest is Test, HelperContract {
// ruleEngineValidation
// Act
- resBool = ruleEngineMock.validateTransferValidation(ADDRESS1, ADDRESS2, 20);
+ resBool = ruleEngineMock.validateTransferValidation(
+ ADDRESS1,
+ ADDRESS2,
+ 20
+ );
// Assert
assertEq(resBool, true);
-
}
function testValidateTransferRestricted() public {
@@ -198,7 +201,11 @@ contract RuleEngineRestrictionTest is Test, HelperContract {
// ruleEngineValidation
// Act
- resBool = ruleEngineMock.validateTransferValidation(ADDRESS1, ADDRESS2, 20);
+ resBool = ruleEngineMock.validateTransferValidation(
+ ADDRESS1,
+ ADDRESS2,
+ 20
+ );
// Assert
assertFalse(resBool);
diff --git a/test/RuleEngine/ruleEngineValidation/RuleEngineValidation.t.sol b/test/RuleEngine/ruleEngineValidation/RuleEngineValidation.t.sol
index 923b411..896a054 100644
--- a/test/RuleEngine/ruleEngineValidation/RuleEngineValidation.t.sol
+++ b/test/RuleEngine/ruleEngineValidation/RuleEngineValidation.t.sol
@@ -6,8 +6,8 @@ import "../../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title General functions of the RuleEngine
-*/
+ * @title General functions of the RuleEngine
+ */
contract RuleEngineValidationTest is Test, HelperContract {
RuleEngine ruleEngineMock;
uint8 resUint8;
@@ -122,7 +122,6 @@ contract RuleEngineValidationTest is Test, HelperContract {
assertEq(resUint256, 1);
}
-
function testCannotSetEmptyRulesT1() public {
// Arrange
address[] memory ruleWhitelistTab = new address[](0);
diff --git a/test/RuleSanctionList/RuleSanctionListAdd.t.sol b/test/RuleSanctionList/RuleSanctionListAdd.t.sol
index ae5b6d5..a8d9fcf 100644
--- a/test/RuleSanctionList/RuleSanctionListAdd.t.sol
+++ b/test/RuleSanctionList/RuleSanctionListAdd.t.sol
@@ -6,13 +6,14 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
import "../utils/SanctionListOracle.sol";
+
/**
-* @title General functions of the ruleSanctionList
-*/
+ * @title General functions of the ruleSanctionList
+ */
contract RuleSanctionlistTest is Test, HelperContract {
// Custom error openZeppelin
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
-
+
uint256 resUint256;
uint8 resUint8;
bool resBool;
@@ -21,6 +22,7 @@ contract RuleSanctionlistTest is Test, HelperContract {
uint8 CODE_NONEXISTENT = 255;
SanctionListOracle sanctionlistOracle;
RuleSanctionList ruleSanctionList;
+
// Arrange
function setUp() public {
vm.prank(SANCTIONLIST_OPERATOR_ADDRESS);
@@ -30,7 +32,6 @@ contract RuleSanctionlistTest is Test, HelperContract {
SANCTIONLIST_OPERATOR_ADDRESS,
ZERO_ADDRESS
);
-
}
function testCanSetOracle() public {
@@ -41,7 +42,12 @@ contract RuleSanctionlistTest is Test, HelperContract {
function testCannotAttackerSetOracle() public {
vm.prank(ATTACKER);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, SANCTIONLIST_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ SANCTIONLIST_ROLE
+ )
+ );
ruleSanctionList.setSanctionListOracle(address(sanctionlistOracle));
}
}
diff --git a/test/RuleSanctionList/RuleSanctionListDeployment.t.sol b/test/RuleSanctionList/RuleSanctionListDeployment.t.sol
index 4b1b3cf..2745d2d 100644
--- a/test/RuleSanctionList/RuleSanctionListDeployment.t.sol
+++ b/test/RuleSanctionList/RuleSanctionListDeployment.t.sol
@@ -4,9 +4,10 @@ pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../HelperContract.sol";
import "CMTAT/mocks/MinimalForwarderMock.sol";
+
/**
-* @title General functions of the ruleSanctionList
-*/
+ * @title General functions of the ruleSanctionList
+ */
contract RuleSanctionListDeploymentTest is Test, HelperContract {
uint256 resUint256;
uint8 resUint8;
@@ -15,16 +16,14 @@ contract RuleSanctionListDeploymentTest is Test, HelperContract {
string resString;
uint8 CODE_NONEXISTENT = 255;
RuleSanctionList ruleSanctionList;
- // Arrange
- function setUp() public {
- }
+ // Arrange
+ function setUp() public {}
function testRightDeployment() public {
// Arrange
vm.prank(SANCTIONLIST_OPERATOR_ADDRESS);
- MinimalForwarderMock forwarder = new MinimalForwarderMock(
- );
+ MinimalForwarderMock forwarder = new MinimalForwarderMock();
forwarder.initialize(ERC2771ForwarderDomain);
vm.prank(SANCTIONLIST_OPERATOR_ADDRESS);
ruleSanctionList = new RuleSanctionList(
@@ -33,7 +32,10 @@ contract RuleSanctionListDeploymentTest is Test, HelperContract {
);
// assert
- resBool = ruleSanctionList.hasRole(SANCTIONLIST_ROLE, SANCTIONLIST_OPERATOR_ADDRESS);
+ resBool = ruleSanctionList.hasRole(
+ SANCTIONLIST_ROLE,
+ SANCTIONLIST_OPERATOR_ADDRESS
+ );
assertEq(resBool, true);
resBool = ruleSanctionList.isTrustedForwarder(address(forwarder));
assertEq(resBool, true);
@@ -42,14 +44,12 @@ contract RuleSanctionListDeploymentTest is Test, HelperContract {
function testCannotDeployContractIfAdminAddressIsZero() public {
// Arrange
vm.prank(SANCTIONLIST_OPERATOR_ADDRESS);
- MinimalForwarderMock forwarder = new MinimalForwarderMock(
- );
+ MinimalForwarderMock forwarder = new MinimalForwarderMock();
forwarder.initialize(ERC2771ForwarderDomain);
- vm.expectRevert(RuleSanctionList_AdminWithAddressZeroNotAllowed.selector);
- vm.prank(SANCTIONLIST_OPERATOR_ADDRESS);
- ruleSanctionList = new RuleSanctionList(
- address(0),
- address(forwarder)
+ vm.expectRevert(
+ RuleSanctionList_AdminWithAddressZeroNotAllowed.selector
);
+ vm.prank(SANCTIONLIST_OPERATOR_ADDRESS);
+ ruleSanctionList = new RuleSanctionList(address(0), address(forwarder));
}
}
diff --git a/test/RuleSanctionList/RuleSanctionListTest.t.sol b/test/RuleSanctionList/RuleSanctionListTest.t.sol
index 73a1985..8c9815e 100644
--- a/test/RuleSanctionList/RuleSanctionListTest.t.sol
+++ b/test/RuleSanctionList/RuleSanctionListTest.t.sol
@@ -5,9 +5,10 @@ import "forge-std/Test.sol";
import "../HelperContract.sol";
import "src/RuleEngine.sol";
import "../utils/SanctionListOracle.sol";
+
/**
-* @title General functions of the ruleSanctionList
-*/
+ * @title General functions of the ruleSanctionList
+ */
contract RuleSanctionlistTest is Test, HelperContract {
uint256 resUint256;
uint8 resUint8;
@@ -17,6 +18,7 @@ contract RuleSanctionlistTest is Test, HelperContract {
uint8 CODE_NONEXISTENT = 255;
SanctionListOracle sanctionlistOracle;
RuleSanctionList ruleSanctionList;
+
// Arrange
function setUp() public {
vm.prank(SANCTIONLIST_OPERATOR_ADDRESS);
@@ -33,7 +35,7 @@ contract RuleSanctionlistTest is Test, HelperContract {
function testCanReturnTransferRestrictionCode() public {
// Act
resBool = ruleSanctionList.canReturnTransferRestrictionCode(
- CODE_ADDRESS_FROM_IS_SANCTIONED
+ CODE_ADDRESS_FROM_IS_SANCTIONED
);
// Assert
assertEq(resBool, true);
@@ -54,13 +56,13 @@ contract RuleSanctionlistTest is Test, HelperContract {
function testReturnTheRightMessageForAGivenCode() public {
// Assert
resString = ruleSanctionList.messageForTransferRestriction(
- CODE_ADDRESS_FROM_IS_SANCTIONED
+ CODE_ADDRESS_FROM_IS_SANCTIONED
);
// Assert
assertEq(resString, TEXT_ADDRESS_FROM_IS_SANCTIONED);
// Act
resString = ruleSanctionList.messageForTransferRestriction(
- CODE_ADDRESS_TO_IS_SANCTIONED
+ CODE_ADDRESS_TO_IS_SANCTIONED
);
// Assert
assertEq(resString, TEXT_ADDRESS_TO_IS_SANCTIONED);
diff --git a/test/RuleWhitelist/AccessControl/RuleWhitelistAccessControl.t.sol b/test/RuleWhitelist/AccessControl/RuleWhitelistAccessControl.t.sol
index 65bde0c..e16cb74 100644
--- a/test/RuleWhitelist/AccessControl/RuleWhitelistAccessControl.t.sol
+++ b/test/RuleWhitelist/AccessControl/RuleWhitelistAccessControl.t.sol
@@ -6,8 +6,8 @@ import "../../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Tests on the Access Control
-*/
+ * @title Tests on the Access Control
+ */
contract RuleWhitelistAccessControl is Test, HelperContract {
// Custom error openZeppelin
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
@@ -32,7 +32,12 @@ contract RuleWhitelistAccessControl is Test, HelperContract {
function testCannotAttackerAddAddressToTheList() public {
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, ADDRESS_LIST_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ ADDRESS_LIST_ROLE
+ )
+ );
vm.prank(ATTACKER);
ruleWhitelist.addAddressToTheList(ADDRESS1);
@@ -53,7 +58,12 @@ contract RuleWhitelistAccessControl is Test, HelperContract {
// Act
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, ADDRESS_LIST_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ ADDRESS_LIST_ROLE
+ )
+ );
vm.prank(ATTACKER);
(resCallBool, ) = address(ruleWhitelist).call(
abi.encodeWithSignature(
@@ -85,7 +95,12 @@ contract RuleWhitelistAccessControl is Test, HelperContract {
// Act
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, ADDRESS_LIST_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ ADDRESS_LIST_ROLE
+ )
+ );
vm.prank(ATTACKER);
ruleWhitelist.removeAddressFromTheList(ADDRESS1);
@@ -117,7 +132,12 @@ contract RuleWhitelistAccessControl is Test, HelperContract {
// Act
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ATTACKER, ADDRESS_LIST_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ATTACKER,
+ ADDRESS_LIST_ROLE
+ )
+ );
vm.prank(ATTACKER);
(resCallBool, ) = address(ruleWhitelist).call(
abi.encodeWithSignature(
diff --git a/test/RuleWhitelist/AccessControl/RuleWhitelistAccessControlOZ.t.sol b/test/RuleWhitelist/AccessControl/RuleWhitelistAccessControlOZ.t.sol
index 96f85dd..9c9404b 100644
--- a/test/RuleWhitelist/AccessControl/RuleWhitelistAccessControlOZ.t.sol
+++ b/test/RuleWhitelist/AccessControl/RuleWhitelistAccessControlOZ.t.sol
@@ -7,8 +7,8 @@ import "../../../lib/openzeppelin-contracts/contracts/access/AccessControl.sol";
import "src/RuleEngine.sol";
/**
-* @title Tests on the provided functions by OpenZeppelin
-*/
+ * @title Tests on the provided functions by OpenZeppelin
+ */
contract RuleWhitelistAccessControlOZ is Test, HelperContract, AccessControl {
// Defined in CMTAT.sol
uint8 constant TRANSFER_OK = 0;
@@ -33,7 +33,11 @@ contract RuleWhitelistAccessControlOZ is Test, HelperContract, AccessControl {
// Act
vm.prank(WHITELIST_OPERATOR_ADDRESS);
vm.expectEmit(true, true, false, true);
- emit RoleGranted(ADDRESS_LIST_ROLE, ADDRESS1, WHITELIST_OPERATOR_ADDRESS);
+ emit RoleGranted(
+ ADDRESS_LIST_ROLE,
+ ADDRESS1,
+ WHITELIST_OPERATOR_ADDRESS
+ );
ruleWhitelist.grantRole(ADDRESS_LIST_ROLE, ADDRESS1);
// Assert
bool res1 = ruleWhitelist.hasRole(ADDRESS_LIST_ROLE, ADDRESS1);
@@ -51,7 +55,11 @@ contract RuleWhitelistAccessControlOZ is Test, HelperContract, AccessControl {
// Act
vm.prank(WHITELIST_OPERATOR_ADDRESS);
vm.expectEmit(true, true, false, true);
- emit RoleRevoked(ADDRESS_LIST_ROLE, ADDRESS1, WHITELIST_OPERATOR_ADDRESS);
+ emit RoleRevoked(
+ ADDRESS_LIST_ROLE,
+ ADDRESS1,
+ WHITELIST_OPERATOR_ADDRESS
+ );
ruleWhitelist.revokeRole(ADDRESS_LIST_ROLE, ADDRESS1);
// Assert
bool res2 = ruleWhitelist.hasRole(ADDRESS_LIST_ROLE, ADDRESS1);
@@ -62,10 +70,15 @@ contract RuleWhitelistAccessControlOZ is Test, HelperContract, AccessControl {
// Arrange - Assert
bool res1 = ruleWhitelist.hasRole(ADDRESS_LIST_ROLE, ADDRESS1);
assertFalse(res1);
-
+
// Act
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ADDRESS2, DEFAULT_ADMIN_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ADDRESS2,
+ DEFAULT_ADMIN_ROLE
+ )
+ );
vm.prank(ADDRESS2);
ruleWhitelist.grantRole(ADDRESS_LIST_ROLE, ADDRESS1);
// Assert
@@ -88,7 +101,12 @@ contract RuleWhitelistAccessControlOZ is Test, HelperContract, AccessControl {
// Act
vm.prank(ADDRESS2);
vm.expectRevert(
- abi.encodeWithSelector(AccessControlUnauthorizedAccount.selector, ADDRESS2, DEFAULT_ADMIN_ROLE));
+ abi.encodeWithSelector(
+ AccessControlUnauthorizedAccount.selector,
+ ADDRESS2,
+ DEFAULT_ADMIN_ROLE
+ )
+ );
ruleWhitelist.revokeRole(ADDRESS_LIST_ROLE, ADDRESS1);
// Assert
diff --git a/test/RuleWhitelist/CMTATIntegration.t.sol b/test/RuleWhitelist/CMTATIntegration.t.sol
index acd37d8..b91265b 100644
--- a/test/RuleWhitelist/CMTATIntegration.t.sol
+++ b/test/RuleWhitelist/CMTATIntegration.t.sol
@@ -7,8 +7,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Integration test with the CMTAT
-*/
+ * @title Integration test with the CMTAT
+ */
contract CMTATIntegration is Test, HelperContract {
// Defined in CMTAT.sol
uint8 constant TRANSFER_OK = 0;
@@ -47,7 +47,11 @@ contract CMTATIntegration is Test, HelperContract {
// specific arrange
vm.prank(DEFAULT_ADMIN_ADDRESS);
- ruleEngineMock = new RuleEngine(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS, address(CMTAT_CONTRACT));
+ ruleEngineMock = new RuleEngine(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS,
+ address(CMTAT_CONTRACT)
+ );
vm.prank(DEFAULT_ADMIN_ADDRESS);
ruleEngineMock.addRuleValidation(ruleWhitelist);
vm.prank(DEFAULT_ADMIN_ADDRESS);
@@ -66,7 +70,13 @@ contract CMTATIntegration is Test, HelperContract {
// Arrange
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, 21));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ 21
+ )
+ );
// Act
CMTAT_CONTRACT.transfer(ADDRESS2, 21);
}
@@ -79,7 +89,13 @@ contract CMTATIntegration is Test, HelperContract {
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, amount));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ amount
+ )
+ );
// Act
CMTAT_CONTRACT.transfer(ADDRESS2, amount);
}
@@ -92,7 +108,13 @@ contract CMTATIntegration is Test, HelperContract {
vm.prank(ADDRESS1);
vm.expectRevert(
- abi.encodeWithSelector(Errors.CMTAT_InvalidTransfer.selector, ADDRESS1, ADDRESS2, amount));
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ amount
+ )
+ );
// Act
CMTAT_CONTRACT.transfer(ADDRESS2, amount);
}
diff --git a/test/RuleWhitelist/CMTATIntegrationWhitelistWrapper.t.sol b/test/RuleWhitelist/CMTATIntegrationWhitelistWrapper.t.sol
new file mode 100644
index 0000000..e6dc0e9
--- /dev/null
+++ b/test/RuleWhitelist/CMTATIntegrationWhitelistWrapper.t.sol
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: MPL-2.0
+pragma solidity ^0.8.20;
+
+import "forge-std/Test.sol";
+import "CMTAT/CMTAT_STANDALONE.sol";
+import "../HelperContract.sol";
+import "src/RuleEngine.sol";
+
+/**
+ * @title Integration test with the CMTAT
+ */
+contract CMTATIntegrationWhitelistWrapper is Test, HelperContract {
+ // Defined in CMTAT.sol
+ uint8 constant TRANSFER_OK = 0;
+ string constant TEXT_TRANSFER_OK = "No restriction";
+
+ RuleEngine ruleEngineMock;
+ uint256 resUint256;
+ bool resBool;
+
+ uint256 ADDRESS1_BALANCE_INIT = 31;
+ uint256 ADDRESS2_BALANCE_INIT = 32;
+ uint256 ADDRESS3_BALANCE_INIT = 33;
+
+ uint256 FLAG = 5;
+ RuleWhitelist ruleWhitelist2;
+ RuleWhitelist ruleWhitelist3;
+ RuleWhitelistWrapper ruleWhitelistWrapper;
+
+ // Arrange
+ function setUp() public {
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist = new RuleWhitelist(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS);
+ ruleWhitelist2 = new RuleWhitelist(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS);
+ ruleWhitelist3 = new RuleWhitelist(DEFAULT_ADMIN_ADDRESS, ZERO_ADDRESS);
+ ruleWhitelistWrapper = new RuleWhitelistWrapper(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS
+ );
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelistWrapper.addRuleValidation(ruleWhitelist);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelistWrapper.addRuleValidation(ruleWhitelist2);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelistWrapper.addRuleValidation(ruleWhitelist3);
+ // global arrange
+ uint8 decimals = 0;
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT = new CMTAT_STANDALONE(
+ ZERO_ADDRESS,
+ DEFAULT_ADMIN_ADDRESS,
+ IAuthorizationEngine(address(0)),
+ "CMTA Token",
+ "CMTAT",
+ decimals,
+ "CMTAT_ISIN",
+ "https://cmta.ch",
+ IRuleEngine(address(0)),
+ "CMTAT_info",
+ FLAG
+ );
+
+ // specific arrange
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleEngineMock = new RuleEngine(
+ DEFAULT_ADMIN_ADDRESS,
+ ZERO_ADDRESS,
+ address(CMTAT_CONTRACT)
+ );
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleEngineMock.addRuleValidation(ruleWhitelistWrapper);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.mint(ADDRESS1, ADDRESS1_BALANCE_INIT);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.mint(ADDRESS2, ADDRESS2_BALANCE_INIT);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.mint(ADDRESS3, ADDRESS3_BALANCE_INIT);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ // We set the Rule Engine
+ CMTAT_CONTRACT.setRuleEngine(ruleEngineMock);
+ }
+
+ /******* Transfer *******/
+ function testCannotTransferWithoutAddressWhitelisted() public {
+ // Arrange
+ vm.prank(ADDRESS1);
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ 21
+ )
+ );
+ // Act
+ CMTAT_CONTRACT.transfer(ADDRESS2, 21);
+ }
+
+ function testCannotTransferWithoutFromAddressWhitelisted() public {
+ // Arrange
+ uint256 amount = 21;
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist.addAddressToTheList(ADDRESS2);
+
+ vm.prank(ADDRESS1);
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ amount
+ )
+ );
+ // Act
+ CMTAT_CONTRACT.transfer(ADDRESS2, amount);
+ }
+
+ function testCannotTransferWithoutToAddressWhitelisted() public {
+ // Arrange
+ uint256 amount = 21;
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist.addAddressToTheList(ADDRESS1);
+
+ vm.prank(ADDRESS1);
+ vm.expectRevert(
+ abi.encodeWithSelector(
+ Errors.CMTAT_InvalidTransfer.selector,
+ ADDRESS1,
+ ADDRESS2,
+ amount
+ )
+ );
+ // Act
+ CMTAT_CONTRACT.transfer(ADDRESS2, amount);
+ }
+
+ function testCanMakeATransferIfWhitelistedInSeveralDifferentList() public {
+ // Arrange
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist.addAddressToTheList(ADDRESS1);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist3.addAddressToTheList(ADDRESS1);
+
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist2.addAddressToTheList(ADDRESS2);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist3.addAddressToTheList(ADDRESS2);
+
+ // Act
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, 11);
+
+ // Assert
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
+ assertEq(resUint256, 20);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
+ assertEq(resUint256, 43);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
+ assertEq(resUint256, 33);
+ }
+
+ function testCanMakeATransferIfWhitelistedInDifferentList() public {
+ // Arrange
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist.addAddressToTheList(ADDRESS1);
+
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist2.addAddressToTheList(ADDRESS2);
+
+ // Act
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, 11);
+
+ // Assert
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
+ assertEq(resUint256, 20);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
+ assertEq(resUint256, 43);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
+ assertEq(resUint256, 33);
+ }
+
+ function testCanMakeATransfer() public {
+ // Arrange
+ address[] memory whitelist = new address[](2);
+ whitelist[0] = ADDRESS1;
+ whitelist[1] = ADDRESS2;
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ (bool success, ) = address(ruleWhitelist).call(
+ abi.encodeWithSignature(
+ "addAddressesToTheList(address[])",
+ whitelist
+ )
+ );
+ require(success);
+
+ // Act
+ vm.prank(ADDRESS1);
+ CMTAT_CONTRACT.transfer(ADDRESS2, 11);
+
+ // Assert
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
+ assertEq(resUint256, 20);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS2);
+ assertEq(resUint256, 43);
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS3);
+ assertEq(resUint256, 33);
+ }
+
+ /******* detectTransferRestriction & messageForTransferRestriction *******/
+ function testDetectAndMessageWithFromNotWhitelisted() public {
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist.addAddressToTheList(ADDRESS2);
+ resBool = ruleWhitelist.addressIsListed(ADDRESS2);
+ // Assert
+ assertEq(resBool, true);
+ uint8 res1 = CMTAT_CONTRACT.detectTransferRestriction(
+ ADDRESS1,
+ ADDRESS2,
+ 11
+ );
+ // Assert
+ assertEq(res1, CODE_ADDRESS_FROM_NOT_WHITELISTED);
+ string memory message1 = CMTAT_CONTRACT.messageForTransferRestriction(
+ res1
+ );
+ // Assert
+ assertEq(message1, TEXT_ADDRESS_FROM_NOT_WHITELISTED);
+ }
+
+ function testDetectAndMessageWithToNotWhitelisted() public {
+ // Arrange
+ // We add the sender to the whitelist
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist.addAddressToTheList(ADDRESS1);
+ // Arrange - Assert
+ resBool = ruleWhitelist.addressIsListed(ADDRESS1);
+ assertEq(resBool, true);
+ // Act
+ uint8 res1 = CMTAT_CONTRACT.detectTransferRestriction(
+ ADDRESS1,
+ ADDRESS2,
+ 11
+ );
+ // Assert
+ assertEq(res1, CODE_ADDRESS_TO_NOT_WHITELISTED);
+ // Act
+ string memory message1 = CMTAT_CONTRACT.messageForTransferRestriction(
+ res1
+ );
+ // Assert
+ assertEq(message1, TEXT_ADDRESS_TO_NOT_WHITELISTED);
+ }
+
+ function testDetectAndMessageWithFromAndToNotWhitelisted() public view {
+ // Act
+ uint8 res1 = CMTAT_CONTRACT.detectTransferRestriction(
+ ADDRESS1,
+ ADDRESS2,
+ 11
+ );
+
+ // Assert
+ assertEq(res1, CODE_ADDRESS_FROM_NOT_WHITELISTED);
+ // Act
+ string memory message1 = CMTAT_CONTRACT.messageForTransferRestriction(
+ res1
+ );
+
+ // Assert
+ assertEq(message1, TEXT_ADDRESS_FROM_NOT_WHITELISTED);
+ }
+
+ function testCanReturnUnknownTextMessage() public view {
+ // Act
+ string memory message1 = CMTAT_CONTRACT.messageForTransferRestriction(
+ 200
+ );
+
+ // Assert
+ assertEq(message1, TEXT_CODE_NOT_FOUND);
+ }
+
+ function testDetectAndMessageWithAValidTransfer() public {
+ // Arrange
+ // We add the sender and the recipient to the whitelist.
+ address[] memory whitelist = new address[](2);
+ whitelist[0] = ADDRESS1;
+ whitelist[1] = ADDRESS2;
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ (bool success, ) = address(ruleWhitelist).call(
+ abi.encodeWithSignature(
+ "addAddressesToTheList(address[])",
+ whitelist
+ )
+ );
+ require(success);
+ // Act
+ uint8 res1 = CMTAT_CONTRACT.detectTransferRestriction(
+ ADDRESS1,
+ ADDRESS2,
+ 11
+ );
+ // Assert
+ assertEq(res1, TRANSFER_OK);
+ // Act
+ string memory message1 = CMTAT_CONTRACT.messageForTransferRestriction(
+ res1
+ );
+ // Assert
+ assertEq(message1, TEXT_TRANSFER_OK);
+ }
+
+ function testCanMint() public {
+ // Arrange
+ // Add address zero to the whitelist
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist.addAddressToTheList(ZERO_ADDRESS);
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ ruleWhitelist.addAddressToTheList(ADDRESS1);
+ // Arrange - Assert
+ resBool = ruleWhitelist.addressIsListed(ZERO_ADDRESS);
+ assertEq(resBool, true);
+
+ // Act
+ vm.prank(DEFAULT_ADMIN_ADDRESS);
+ CMTAT_CONTRACT.mint(ADDRESS1, 11);
+
+ // Assert
+ resUint256 = CMTAT_CONTRACT.balanceOf(ADDRESS1);
+ assertEq(resUint256, ADDRESS1_BALANCE_INIT + 11);
+ }
+}
diff --git a/test/RuleWhitelist/RuleWhitelist.t.sol b/test/RuleWhitelist/RuleWhitelist.t.sol
index 47adc6d..d4734ef 100644
--- a/test/RuleWhitelist/RuleWhitelist.t.sol
+++ b/test/RuleWhitelist/RuleWhitelist.t.sol
@@ -6,8 +6,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title General functions of the RuleWhitelist
-*/
+ * @title General functions of the RuleWhitelist
+ */
contract RuleWhitelistTest is Test, HelperContract {
uint256 resUint256;
uint8 resUint8;
@@ -25,7 +25,7 @@ contract RuleWhitelistTest is Test, HelperContract {
);
}
- function _addAddressesToTheList() internal {
+ function _addAddressesToTheList() internal {
address[] memory whitelist = new address[](2);
whitelist[0] = ADDRESS1;
whitelist[1] = ADDRESS2;
diff --git a/test/RuleWhitelist/RuleWhitelistAdd.t.sol b/test/RuleWhitelist/RuleWhitelistAdd.t.sol
index 5bca773..9d425b0 100644
--- a/test/RuleWhitelist/RuleWhitelistAdd.t.sol
+++ b/test/RuleWhitelist/RuleWhitelistAdd.t.sol
@@ -6,8 +6,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Tests the functions to add addresses to the whitelist
-*/
+ * @title Tests the functions to add addresses to the whitelist
+ */
contract RuleWhitelistAddTest is Test, HelperContract {
// Defined in CMTAT.sol
uint8 constant TRANSFER_OK = 0;
@@ -28,7 +28,7 @@ contract RuleWhitelistAddTest is Test, HelperContract {
);
}
- function _addAddressesToTheList() internal {
+ function _addAddressesToTheList() internal {
address[] memory whitelist = new address[](2);
whitelist[0] = ADDRESS1;
whitelist[1] = ADDRESS2;
@@ -47,9 +47,18 @@ contract RuleWhitelistAddTest is Test, HelperContract {
assertEq(resBool, true);
resBool = ruleWhitelist.addressIsListed(ADDRESS2);
assertEq(resBool, true);
+ address[] memory addressesListInput = new address[](2);
+ addressesListInput[0] = ADDRESS1;
+ addressesListInput[1] = ADDRESS2;
+ bool[] memory resBools = ruleWhitelist.addressIsListedBatch(
+ addressesListInput
+ );
+ assertEq(resBools[0], true);
+ assertEq(resBools[1], true);
+ assertEq(resBools.length, 2);
}
- function testaddAddressToTheList() public {
+ function testAddAddressToTheList() public {
// Act
vm.prank(WHITELIST_OPERATOR_ADDRESS);
ruleWhitelist.addAddressToTheList(ADDRESS1);
@@ -57,11 +66,18 @@ contract RuleWhitelistAddTest is Test, HelperContract {
// Assert
resBool = ruleWhitelist.addressIsListed(ADDRESS1);
assertEq(resBool, true);
+ address[] memory addressesListInput = new address[](1);
+ addressesListInput[0] = ADDRESS1;
+ bool[] memory resBools = ruleWhitelist.addressIsListedBatch(
+ addressesListInput
+ );
+ assertEq(resBools[0], true);
+ assertEq(resBools.length, 1);
resUint256 = ruleWhitelist.numberListedAddress();
assertEq(resUint256, 1);
}
- function testaddAddressesToTheList() public {
+ function testAddAddressesToTheList() public {
// Arrange
resUint256 = ruleWhitelist.numberListedAddress();
assertEq(resUint256, 0);
diff --git a/test/RuleWhitelist/RuleWhitelistDeployment.t.sol b/test/RuleWhitelist/RuleWhitelistDeployment.t.sol
index 74f6f41..bddb163 100644
--- a/test/RuleWhitelist/RuleWhitelistDeployment.t.sol
+++ b/test/RuleWhitelist/RuleWhitelistDeployment.t.sol
@@ -5,9 +5,10 @@ import "forge-std/Test.sol";
import "../HelperContract.sol";
import "src/RuleEngine.sol";
import "CMTAT/mocks/MinimalForwarderMock.sol";
+
/**
-* @title General functions of the RuleWhitelist
-*/
+ * @title General functions of the RuleWhitelist
+ */
contract RuleWhitelistTest is Test, HelperContract {
uint256 resUint256;
uint8 resUint8;
@@ -17,14 +18,12 @@ contract RuleWhitelistTest is Test, HelperContract {
uint8 CODE_NONEXISTENT = 255;
// Arrange
- function setUp() public {
- }
+ function setUp() public {}
function testRightDeployment() public {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
- MinimalForwarderMock forwarder = new MinimalForwarderMock(
- );
+ MinimalForwarderMock forwarder = new MinimalForwarderMock();
forwarder.initialize(ERC2771ForwarderDomain);
vm.prank(WHITELIST_OPERATOR_ADDRESS);
ruleWhitelist = new RuleWhitelist(
@@ -33,7 +32,10 @@ contract RuleWhitelistTest is Test, HelperContract {
);
// assert
- resBool = ruleWhitelist.hasRole(ADDRESS_LIST_ROLE, WHITELIST_OPERATOR_ADDRESS);
+ resBool = ruleWhitelist.hasRole(
+ ADDRESS_LIST_ROLE,
+ WHITELIST_OPERATOR_ADDRESS
+ );
assertEq(resBool, true);
resBool = ruleWhitelist.isTrustedForwarder(address(forwarder));
assertEq(resBool, true);
@@ -42,14 +44,12 @@ contract RuleWhitelistTest is Test, HelperContract {
function testCannotDeployContractIfAdminAddressIsZero() public {
// Arrange
vm.prank(WHITELIST_OPERATOR_ADDRESS);
- MinimalForwarderMock forwarder = new MinimalForwarderMock(
- );
+ MinimalForwarderMock forwarder = new MinimalForwarderMock();
forwarder.initialize(ERC2771ForwarderDomain);
- vm.expectRevert(RuleAddressList_AdminWithAddressZeroNotAllowed.selector);
- vm.prank(WHITELIST_OPERATOR_ADDRESS);
- ruleWhitelist = new RuleWhitelist(
- address(0),
- address(forwarder)
+ vm.expectRevert(
+ RuleAddressList_AdminWithAddressZeroNotAllowed.selector
);
+ vm.prank(WHITELIST_OPERATOR_ADDRESS);
+ ruleWhitelist = new RuleWhitelist(address(0), address(forwarder));
}
}
diff --git a/test/RuleWhitelist/RuleWhitelistRemove.t.sol b/test/RuleWhitelist/RuleWhitelistRemove.t.sol
index 89b0550..0edd432 100644
--- a/test/RuleWhitelist/RuleWhitelistRemove.t.sol
+++ b/test/RuleWhitelist/RuleWhitelistRemove.t.sol
@@ -6,8 +6,8 @@ import "../HelperContract.sol";
import "src/RuleEngine.sol";
/**
-* @title Tests the functions to remove addresses from the whitelist
-*/
+ * @title Tests the functions to remove addresses from the whitelist
+ */
contract RuleWhitelistRemoveTest is Test, HelperContract {
// Defined in CMTAT.sol
uint8 constant TRANSFER_OK = 0;
@@ -29,7 +29,7 @@ contract RuleWhitelistRemoveTest is Test, HelperContract {
);
}
- function _addAddressesToTheList() internal {
+ function _addAddressesToTheList() internal {
address[] memory whitelist = new address[](2);
whitelist[0] = ADDRESS1;
whitelist[1] = ADDRESS2;
diff --git a/test/utils/SanctionListOracle.sol b/test/utils/SanctionListOracle.sol
index 308785c..2edaee7 100644
--- a/test/utils/SanctionListOracle.sol
+++ b/test/utils/SanctionListOracle.sol
@@ -2,25 +2,23 @@
pragma solidity ^0.8.20;
/**
-* @notice Test contract from
-* https://etherscan.io/address/0x40c57923924b5c5c5455c48d93317139addac8fb#code
-*/
+ * @notice Test contract from
+ * https://etherscan.io/address/0x40c57923924b5c5c5455c48d93317139addac8fb#code
+ */
contract SanctionListOracle {
+ constructor() {}
- constructor() {}
+ mapping(address => bool) private sanctionedAddresses;
- mapping(address => bool) private sanctionedAddresses;
+ function addToSanctionsList(address newSanction) public {
+ sanctionedAddresses[newSanction] = true;
+ }
+ function removeFromSanctionsList(address removeSanction) public {
+ sanctionedAddresses[removeSanction] = true;
+ }
- function addToSanctionsList(address newSanction) public{
- sanctionedAddresses[newSanction] = true;
- }
-
- function removeFromSanctionsList(address removeSanction) public{
- sanctionedAddresses[removeSanction] = true;
- }
-
- function isSanctioned(address addr) public view returns (bool) {
- return sanctionedAddresses[addr] == true ;
- }
-}
\ No newline at end of file
+ function isSanctioned(address addr) public view returns (bool) {
+ return sanctionedAddresses[addr] == true;
+ }
+}