diff --git a/CHANGELOG.md b/CHANGELOG.md index ef58c05..f97df12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ Please follow [https://changelog.md/](https://changelog.md/) conventions. + + +## v2.0.3 + +- Small optimization in WhitelistWrapper; add a break in a loop +- Set Solidity version to 0.8.26 in config file + ## v2.0.2 - 20240617 - Create abstract contract ruleWhitelistCommon to contain code shared between ruleWhitelist & ruleWhitelistWrapper diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..3ba78c6 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,23 @@ +# Contributing Guidelines + +There are many ways to contribute to RuleEngine Contracts. + +## Opening an issue + +You can [open an issue] to suggest a feature, a difficulty you have or report a minor bug. For serious bugs in an audited version please do not open an issue, instead refer to our [security policy] for appropriate steps. See [SECURITY.md](./SECURITY.MD) in CMTAT project. + +Before opening an issue, be sure to search through the existing open and closed issues, and consider posting a comment in one of those instead. + +When requesting a new feature, include as many details as you can, especially around the use cases that motivate it. + +## Submitting a pull request + +If you would like to contribute code or documentation you may do so by forking the repository and submitting a pull request. + +Run linter and tests to make sure your pull request is good before submitting it. + + + +## Reference + +Based on the version made by [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/CONTRIBUTING.md) diff --git a/README.md b/README.md index 6dc2108..c884de6 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,16 @@ # RuleEngine This repository includes the RuleEngine contract for the [CMTAT](https://github.com/CMTA/CMTAT) token. -- The CMTAT version used is the version [v2.4.0](https://github.com/CMTA/CMTAT/releases/tag/v2.4.0) -- The OpenZeppelin version used is the version [v5.0.2](https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v5.0.2) -The CMTAT contracts and the OpenZeppelin library are included as a submodule of the present repository. +The RuleEngine is an external contract used to apply transfer restrictions to another contract, initially the CMTAT. Acting as a controller, it can call different contract rules and apply these rules on each transfer. + +## Dependencies + +The toolchain includes the following components, where the versions are the latest ones that we tested: + +- Foundry +- Solidity 0.8.26 (via solc-js) +- OpenZeppelin Contracts (submodule) [v5.0.2](https://github.com/OpenZeppelin/openzeppelin-contracts/releases/tag/v5.0.2) ## How to include it @@ -22,7 +28,21 @@ Before each transfer, your contract must call the function `operateOnTransfer` w ![Engine-RuleEngine.drawio](./doc/schema/Engine-RuleEngine.drawio.png) +### UML + +#### Global + +> npm run-script uml + +![uml](./doc/schema/classDiagram.svg) + + + +#### RuleEngine + +> npm run-script uml:ruleEngine +![uml](./doc/schema/RuleEngine.svg) ## Available Rules @@ -38,11 +58,41 @@ The following rules are available: + + +## Functionality + +### Upgradeable + +The Rule Engine and the other rules are not upgradeable. The reason is the following: +If we need a new on, we just issue a new one, and set inside the CMTAT token (or the RuleEngine for the rules) to use the new. + +### Urgency mechanism + +- Pause + +There are no functionalities to put in pause the contracts. + +* Kill / Deactivate the contracts + +There are no functionalities to kill/deactivate the contracts. + + +### Gasless support (ERC-2771) + +> The gasless integration was not part of the audit performed by ABDK on the version [1.0.1](https://github.com/CMTA/RuleEngine/releases/tag/1.0.1) + +The RuleEngine contracts and the other rules support client-side gasless transactions using the [Gas Station Network](https://docs.opengsn.org/#the-problem) (GSN) pattern, the main open standard for transfering fee payment to another account than that of the transaction issuer. The contract uses the OpenZeppelin contract `ERC2771Context`, which allows a contract to get the original client with `_msgSender()` instead of the fee payer given by `msg.sender` . + +At deployment, the parameter `forwarder` inside the contract constructor has to be set with the defined address of the forwarder. Please note that the forwarder can not be changed after deployment. + +Please see the OpenGSN [documentation](https://docs.opengsn.org/contracts/#receiving-a-relayed-call) for more details on what is done to support GSN in the contract. + ## Audit The contracts have been audited by [ABDKConsulting](https://www.abdk.consulting/), a globally recognized firm specialized in smart contracts' security. -#### First Audit - March 2022 +### First Audit - March 2022 Fixed version : [v1.0.2](https://github.com/CMTA/RuleEngine/releases/tag/v1.0.2) @@ -72,24 +122,24 @@ Here a summary of the main documentation | Document | Link/Files | | ----------------------- | ---------------------------------------------------- | -| Technical documentation | [doc/technical/general](./doc/technical/general.md) | +| Technical documentation | [doc/technical/](./doc/technical/) | | Toolchain | [doc/TOOLCHAIN.md](./doc/TOOLCHAIN.md) | | Functionalities | [doc/functionalities.pdf](./doc/functionalities.pdf) | | Surya report | [doc/surya](./doc/surya/) | - +See also [Taurus - Token Transfer Management: How to Apply Restrictions with CMTAT and ERC-1404](https://www.taurushq.com/blog/token-transfer-management-how-to-apply-restrictions-with-cmtat-and-erc-1404/) ## Usage *Explain how it works.* -## Toolchain installation +### Toolchain installation The contracts are developed and tested with [Foundry](https://book.getfoundry.sh), a smart contract development toolchain. To install the Foundry suite, please refer to the official instructions in the [Foundry book](https://book.getfoundry.sh/getting-started/installation). -## Initialization +### Initialization You must first initialize the submodules, with @@ -109,7 +159,7 @@ See also the command's [documentation](https://book.getfoundry.sh/reference/forg -## Compilation +### Compilation The official documentation is available in the Foundry [website](https://book.getfoundry.sh/reference/forge/build-commands) ``` @@ -119,19 +169,25 @@ The official documentation is available in the Foundry [website](https://book.ge forge build --contracts src/RuleWhiteList.sol ``` -## Testing +### Testing You can run the tests with -``` +```bash forge test ``` To run a specific test, use -``` +```bash forge test --match-contract --match-test ``` +Generate gas report + +```bash +forge test --gas-report +``` + See also the test framework's [official documentation](https://book.getfoundry.sh/forge/tests), and that of the [test commands](https://book.getfoundry.sh/reference/forge/test-commands). ### Coverage @@ -153,9 +209,9 @@ forge coverage --report lcov && genhtml lcov.info --branch-coverage --output-dir See [Solidity Coverage in VS Code with Foundry](https://mirror.xyz/devanon.eth/RrDvKPnlD-pmpuW7hQeR5wWdVjklrpOgPCOA-PJkWFU) & [Foundry forge coverage](https://www.rareskills.io/post/foundry-forge-coverage) -## Deployment +### Deployment The official documentation is available in the Foundry [website](https://book.getfoundry.sh/reference/forge/deploy-commands) -### Script +#### Script > This documentation has been written for the version v1.0.2 @@ -174,10 +230,14 @@ CMTAT with RuleEngine ```bash forge script script/CMTATWithRuleEngineScript.s.sol:CMTATWithRuleEngineScript --rpc-url=$RPC_URL --broadcast --verify -vvv ``` -Value of YOUR_RPC_URL with a local instance of anvil : [http://127.0.0.1:8545](http://127.0.0.1:8545) +Value of YOUR_RPC_URL with a local instance of anvil : [127.0.0.1:8545](http://127.0.0.1:8545) Only RuleEngine with a Whitelist contract ```bash forge script script/RuleEngineScript.s.sol:RuleEngineScript --rpc-url=$RPC_URL --broadcast --verify -vvv ``` + +## Intellectual property + +The code is copyright (c) Capital Market and Technology Association, 2018-2024, and is released under [Mozilla Public License 2.0](https://github.com/CMTA/CMTAT/blob/master/LICENSE.md). diff --git a/coverage.json b/coverage.json deleted file mode 100644 index 3f68e85..0000000 --- a/coverage.json +++ /dev/null @@ -1 +0,0 @@ -{"src/modules/MetaTxModuleStandalone.sol":{"l":{"22":0,"32":0},"path":"src/modules/MetaTxModuleStandalone.sol","s":{"1":0,"2":0},"b":{},"f":{"1":0,"2":0,"3":0},"fnMap":{"1":{"name":"constructor","line":11,"loc":{"start":{"line":11,"column":4},"end":{"line":13,"column":4}}},"2":{"name":"_msgSender","line":15,"loc":{"start":{"line":15,"column":4},"end":{"line":23,"column":4}}},"3":{"name":"_msgData","line":25,"loc":{"start":{"line":25,"column":4},"end":{"line":33,"column":4}}}},"statementMap":{"1":{"start":{"line":22,"column":8},"end":{"line":22,"column":42}},"2":{"start":{"line":32,"column":8},"end":{"line":32,"column":40}}},"branchMap":{}},"src/RuleEngine.sol":{"l":{"33":0,"34":0,"35":0,"46":0,"47":0,"48":0,"52":0,"53":0,"54":0,"55":0,"56":0,"59":0,"67":0,"68":0,"77":0,"81":0,"82":0,"83":0,"84":0,"101":0,"102":0,"103":0,"105":0,"106":0,"107":0,"114":0,"122":0,"123":0,"124":0,"126":0,"127":0,"130":0,"139":0,"147":0,"162":0,"163":0,"168":0,"169":0,"171":0,"172":0,"175":0,"190":0,"201":0,"202":0,"203":0,"206":0,"207":0,"210":0,"222":0,"234":0},"path":"src/RuleEngine.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0,"28":0,"29":0,"30":0,"31":0,"32":0,"33":0,"34":0,"35":0,"36":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0],"15":[0,0]},"f":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0},"fnMap":{"1":{"name":"constructor","line":32,"loc":{"start":{"line":29,"column":4},"end":{"line":36,"column":4}}},"2":{"name":"setRules","line":45,"loc":{"start":{"line":43,"column":4},"end":{"line":60,"column":4}}},"3":{"name":"clearRules","line":66,"loc":{"start":{"line":66,"column":4},"end":{"line":69,"column":4}}},"4":{"name":"addRule","line":76,"loc":{"start":{"line":76,"column":4},"end":{"line":85,"column":4}}},"5":{"name":"removeRule","line":100,"loc":{"start":{"line":97,"column":4},"end":{"line":108,"column":4}}},"6":{"name":"rulesCount","line":113,"loc":{"start":{"line":113,"column":4},"end":{"line":115,"column":4}}},"7":{"name":"getRuleIndex","line":121,"loc":{"start":{"line":121,"column":4},"end":{"line":131,"column":4}}},"8":{"name":"rule","line":138,"loc":{"start":{"line":138,"column":4},"end":{"line":140,"column":4}}},"9":{"name":"rules","line":146,"loc":{"start":{"line":146,"column":4},"end":{"line":148,"column":4}}},"10":{"name":"detectTransferRestriction","line":157,"loc":{"start":{"line":157,"column":4},"end":{"line":176,"column":4}}},"11":{"name":"validateTransfer","line":185,"loc":{"start":{"line":185,"column":4},"end":{"line":191,"column":4}}},"12":{"name":"messageForTransferRestriction","line":198,"loc":{"start":{"line":198,"column":4},"end":{"line":211,"column":4}}},"13":{"name":"_msgSender","line":216,"loc":{"start":{"line":216,"column":4},"end":{"line":223,"column":4}}},"14":{"name":"_msgData","line":228,"loc":{"start":{"line":228,"column":4},"end":{"line":235,"column":4}}}},"statementMap":{"1":{"start":{"line":33,"column":8},"end":{"line":33,"column":60}},"2":{"start":{"line":34,"column":8},"end":{"line":34,"column":44}},"3":{"start":{"line":35,"column":8},"end":{"line":35,"column":42}},"4":{"start":{"line":46,"column":8},"end":{"line":46,"column":56}},"5":{"start":{"line":47,"column":8},"end":{"line":47,"column":1735}},"6":{"start":{"line":48,"column":12},"end":{"line":48,"column":1794}},"7":{"start":{"line":52,"column":12},"end":{"line":52,"column":76}},"8":{"start":{"line":54,"column":12},"end":{"line":54,"column":35}},"9":{"start":{"line":67,"column":8},"end":{"line":67,"column":31}},"10":{"start":{"line":77,"column":8},"end":{"line":77,"column":2623}},"11":{"start":{"line":81,"column":8},"end":{"line":81,"column":68}},"12":{"start":{"line":82,"column":8},"end":{"line":82,"column":25}},"13":{"start":{"line":84,"column":8},"end":{"line":84,"column":27}},"14":{"start":{"line":101,"column":8},"end":{"line":101,"column":62}},"15":{"start":{"line":102,"column":8},"end":{"line":102,"column":3483}},"16":{"start":{"line":105,"column":8},"end":{"line":105,"column":19}},"17":{"start":{"line":107,"column":8},"end":{"line":107,"column":30}},"18":{"start":{"line":114,"column":8},"end":{"line":114,"column":28}},"19":{"start":{"line":122,"column":8},"end":{"line":122,"column":4075}},"20":{"start":{"line":123,"column":12},"end":{"line":123,"column":4134}},"21":{"start":{"line":124,"column":16},"end":{"line":124,"column":28}},"22":{"start":{"line":130,"column":8},"end":{"line":130,"column":28}},"23":{"start":{"line":139,"column":8},"end":{"line":139,"column":29}},"24":{"start":{"line":147,"column":8},"end":{"line":147,"column":21}},"25":{"start":{"line":162,"column":8},"end":{"line":162,"column":5196}},"26":{"start":{"line":163,"column":12},"end":{"line":163,"column":5256}},"27":{"start":{"line":168,"column":12},"end":{"line":168,"column":5407}},"28":{"start":{"line":169,"column":16},"end":{"line":169,"column":34}},"29":{"start":{"line":175,"column":8},"end":{"line":175,"column":52}},"30":{"start":{"line":190,"column":8},"end":{"line":190,"column":102}},"31":{"start":{"line":201,"column":8},"end":{"line":201,"column":6417}},"32":{"start":{"line":202,"column":12},"end":{"line":202,"column":6476}},"33":{"start":{"line":203,"column":16},"end":{"line":203,"column":6625}},"34":{"start":{"line":210,"column":8},"end":{"line":210,"column":41}},"35":{"start":{"line":222,"column":8},"end":{"line":222,"column":50}},"36":{"start":{"line":234,"column":8},"end":{"line":234,"column":48}}},"branchMap":{"1":{"line":33,"type":"if","locations":[{"start":{"line":33,"column":8},"end":{"line":33,"column":8}},{"start":{"line":33,"column":8},"end":{"line":33,"column":8}}]},"2":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":24},"end":{"line":45,"column":24}},{"start":{"line":45,"column":24},"end":{"line":45,"column":24}}]},"3":{"line":46,"type":"if","locations":[{"start":{"line":46,"column":8},"end":{"line":46,"column":8}},{"start":{"line":46,"column":8},"end":{"line":46,"column":8}}]},"4":{"line":48,"type":"if","locations":[{"start":{"line":48,"column":12},"end":{"line":48,"column":12}},{"start":{"line":48,"column":12},"end":{"line":48,"column":12}}]},"5":{"line":52,"type":"if","locations":[{"start":{"line":52,"column":12},"end":{"line":52,"column":12}},{"start":{"line":52,"column":12},"end":{"line":52,"column":12}}]},"6":{"line":66,"type":"if","locations":[{"start":{"line":66,"column":33},"end":{"line":66,"column":33}},{"start":{"line":66,"column":33},"end":{"line":66,"column":33}}]},"7":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":41},"end":{"line":76,"column":41}},{"start":{"line":76,"column":41},"end":{"line":76,"column":41}}]},"8":{"line":77,"type":"if","locations":[{"start":{"line":77,"column":8},"end":{"line":77,"column":8}},{"start":{"line":77,"column":8},"end":{"line":77,"column":8}}]},"9":{"line":81,"type":"if","locations":[{"start":{"line":81,"column":8},"end":{"line":81,"column":8}},{"start":{"line":81,"column":8},"end":{"line":81,"column":8}}]},"10":{"line":100,"type":"if","locations":[{"start":{"line":100,"column":13},"end":{"line":100,"column":13}},{"start":{"line":100,"column":13},"end":{"line":100,"column":13}}]},"11":{"line":101,"type":"if","locations":[{"start":{"line":101,"column":8},"end":{"line":101,"column":8}},{"start":{"line":101,"column":8},"end":{"line":101,"column":8}}]},"12":{"line":102,"type":"if","locations":[{"start":{"line":102,"column":8},"end":{"line":102,"column":8}},{"start":{"line":102,"column":8},"end":{"line":102,"column":8}}]},"13":{"line":123,"type":"if","locations":[{"start":{"line":123,"column":12},"end":{"line":123,"column":12}},{"start":{"line":123,"column":12},"end":{"line":123,"column":12}}]},"14":{"line":168,"type":"if","locations":[{"start":{"line":168,"column":12},"end":{"line":168,"column":12}},{"start":{"line":168,"column":12},"end":{"line":168,"column":12}}]},"15":{"line":202,"type":"if","locations":[{"start":{"line":202,"column":12},"end":{"line":202,"column":12}},{"start":{"line":202,"column":12},"end":{"line":202,"column":12}}]}}},"src/RuleWhitelist.sol":{"l":{"39":0,"40":0,"41":0,"52":0,"53":0,"54":0,"55":0,"56":0,"58":0,"59":0,"62":0,"74":0,"75":0,"76":0,"77":0,"78":0,"80":0,"81":0,"84":0,"95":0,"99":0,"100":0,"112":0,"116":0,"117":0,"126":0,"138":0,"153":0,"169":0,"170":0,"172":0,"174":0,"186":0,"199":0,"200":0,"202":0,"204":0,"217":0,"229":0},"path":"src/RuleWhitelist.sol","s":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0,"14":0,"15":0,"16":0,"17":0,"18":0,"19":0,"20":0,"21":0,"22":0,"23":0,"24":0,"25":0,"26":0,"27":0},"b":{"1":[0,0],"2":[0,0],"3":[0,0],"4":[0,0],"5":[0,0],"6":[0,0],"7":[0,0],"8":[0,0],"9":[0,0],"10":[0,0],"11":[0,0],"12":[0,0],"13":[0,0],"14":[0,0]},"f":{"1":0,"2":0,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0,"13":0},"fnMap":{"1":{"name":"constructor","line":38,"loc":{"start":{"line":35,"column":4},"end":{"line":42,"column":4}}},"2":{"name":"addAddressesToTheWhitelist","line":51,"loc":{"start":{"line":49,"column":4},"end":{"line":63,"column":4}}},"3":{"name":"removeAddressesFromTheWhitelist","line":73,"loc":{"start":{"line":71,"column":4},"end":{"line":85,"column":4}}},"4":{"name":"addAddressToTheWhitelist","line":94,"loc":{"start":{"line":92,"column":4},"end":{"line":101,"column":4}}},"5":{"name":"removeAddressFromTheWhitelist","line":111,"loc":{"start":{"line":109,"column":4},"end":{"line":118,"column":4}}},"6":{"name":"numberWhitelistedAddress","line":125,"loc":{"start":{"line":125,"column":4},"end":{"line":127,"column":4}}},"7":{"name":"addressIsWhitelisted","line":135,"loc":{"start":{"line":135,"column":4},"end":{"line":139,"column":4}}},"8":{"name":"validateTransfer","line":148,"loc":{"start":{"line":148,"column":4},"end":{"line":156,"column":4}}},"9":{"name":"detectTransferRestriction","line":164,"loc":{"start":{"line":164,"column":4},"end":{"line":176,"column":4}}},"10":{"name":"canReturnTransferRestrictionCode","line":183,"loc":{"start":{"line":183,"column":4},"end":{"line":189,"column":4}}},"11":{"name":"messageForTransferRestriction","line":196,"loc":{"start":{"line":196,"column":4},"end":{"line":206,"column":4}}},"12":{"name":"_msgSender","line":211,"loc":{"start":{"line":211,"column":4},"end":{"line":218,"column":4}}},"13":{"name":"_msgData","line":223,"loc":{"start":{"line":223,"column":4},"end":{"line":230,"column":4}}}},"statementMap":{"1":{"start":{"line":39,"column":8},"end":{"line":39,"column":60}},"2":{"start":{"line":40,"column":8},"end":{"line":40,"column":44}},"3":{"start":{"line":41,"column":8},"end":{"line":41,"column":40}},"4":{"start":{"line":52,"column":8},"end":{"line":52,"column":70}},"5":{"start":{"line":53,"column":8},"end":{"line":53,"column":1996}},"6":{"start":{"line":54,"column":12},"end":{"line":54,"column":2071}},"7":{"start":{"line":74,"column":8},"end":{"line":74,"column":70}},"8":{"start":{"line":75,"column":8},"end":{"line":75,"column":2876}},"9":{"start":{"line":76,"column":12},"end":{"line":76,"column":2951}},"10":{"start":{"line":95,"column":8},"end":{"line":95,"column":3582}},"11":{"start":{"line":112,"column":8},"end":{"line":112,"column":4152}},"12":{"start":{"line":126,"column":8},"end":{"line":126,"column":38}},"13":{"start":{"line":138,"column":8},"end":{"line":138,"column":40}},"14":{"start":{"line":153,"column":8},"end":{"line":153,"column":5390}},"15":{"start":{"line":169,"column":8},"end":{"line":169,"column":5866}},"16":{"start":{"line":170,"column":12},"end":{"line":170,"column":52}},"17":{"start":{"line":171,"column":15},"end":{"line":171,"column":5960}},"18":{"start":{"line":172,"column":12},"end":{"line":172,"column":50}},"19":{"start":{"line":174,"column":12},"end":{"line":174,"column":56}},"20":{"start":{"line":186,"column":8},"end":{"line":186,"column":6535}},"21":{"start":{"line":199,"column":8},"end":{"line":199,"column":6949}},"22":{"start":{"line":200,"column":12},"end":{"line":200,"column":52}},"23":{"start":{"line":201,"column":15},"end":{"line":201,"column":7079}},"24":{"start":{"line":202,"column":12},"end":{"line":202,"column":50}},"25":{"start":{"line":204,"column":12},"end":{"line":204,"column":38}},"26":{"start":{"line":217,"column":8},"end":{"line":217,"column":50}},"27":{"start":{"line":229,"column":8},"end":{"line":229,"column":48}}},"branchMap":{"1":{"line":39,"type":"if","locations":[{"start":{"line":39,"column":8},"end":{"line":39,"column":8}},{"start":{"line":39,"column":8},"end":{"line":39,"column":8}}]},"2":{"line":51,"type":"if","locations":[{"start":{"line":51,"column":13},"end":{"line":51,"column":13}},{"start":{"line":51,"column":13},"end":{"line":51,"column":13}}]},"3":{"line":54,"type":"if","locations":[{"start":{"line":54,"column":12},"end":{"line":54,"column":12}},{"start":{"line":54,"column":12},"end":{"line":54,"column":12}}]},"4":{"line":73,"type":"if","locations":[{"start":{"line":73,"column":13},"end":{"line":73,"column":13}},{"start":{"line":73,"column":13},"end":{"line":73,"column":13}}]},"5":{"line":76,"type":"if","locations":[{"start":{"line":76,"column":12},"end":{"line":76,"column":12}},{"start":{"line":76,"column":12},"end":{"line":76,"column":12}}]},"6":{"line":94,"type":"if","locations":[{"start":{"line":94,"column":13},"end":{"line":94,"column":13}},{"start":{"line":94,"column":13},"end":{"line":94,"column":13}}]},"7":{"line":95,"type":"if","locations":[{"start":{"line":95,"column":8},"end":{"line":95,"column":8}},{"start":{"line":95,"column":8},"end":{"line":95,"column":8}}]},"8":{"line":111,"type":"if","locations":[{"start":{"line":111,"column":13},"end":{"line":111,"column":13}},{"start":{"line":111,"column":13},"end":{"line":111,"column":13}}]},"9":{"line":112,"type":"if","locations":[{"start":{"line":112,"column":8},"end":{"line":112,"column":8}},{"start":{"line":112,"column":8},"end":{"line":112,"column":8}}]},"10":{"line":169,"type":"if","locations":[{"start":{"line":169,"column":8},"end":{"line":169,"column":8}},{"start":{"line":169,"column":8},"end":{"line":169,"column":8}}]},"11":{"line":171,"type":"if","locations":[{"start":{"line":171,"column":15},"end":{"line":171,"column":15}},{"start":{"line":171,"column":15},"end":{"line":171,"column":15}}]},"12":{"line":187,"type":"cond-expr","locations":[{"start":{"line":187,"column":12},"end":{"line":187,"column":64}},{"start":{"line":188,"column":12},"end":{"line":188,"column":62}}]},"13":{"line":199,"type":"if","locations":[{"start":{"line":199,"column":8},"end":{"line":199,"column":8}},{"start":{"line":199,"column":8},"end":{"line":199,"column":8}}]},"14":{"line":201,"type":"if","locations":[{"start":{"line":201,"column":15},"end":{"line":201,"column":15}},{"start":{"line":201,"column":15},"end":{"line":201,"column":15}}]}}}} \ No newline at end of file diff --git a/doc/TOOLCHAIN.md b/doc/TOOLCHAIN.md index 5d3ced7..f5d9cc1 100644 --- a/doc/TOOLCHAIN.md +++ b/doc/TOOLCHAIN.md @@ -124,7 +124,7 @@ npm run-script surya:report >Slither is a Solidity static analysis framework written in Python3 ```bash - slither . --checklist --filter-paths "openzeppelin-contracts|test|CMTAT|forge-std" > slither-report.md +slither . --checklist --filter-paths "openzeppelin-contracts|test|CMTAT|forge-std" > slither-report.md ``` diff --git a/doc/test/coverage/amber.png b/doc/coverage/coverage/amber.png similarity index 100% rename from doc/test/coverage/amber.png rename to doc/coverage/coverage/amber.png diff --git a/doc/test/coverage/emerald.png b/doc/coverage/coverage/emerald.png similarity index 100% rename from doc/test/coverage/emerald.png rename to doc/coverage/coverage/emerald.png diff --git a/doc/test/coverage/gcov.css b/doc/coverage/coverage/gcov.css similarity index 100% rename from doc/test/coverage/gcov.css rename to doc/coverage/coverage/gcov.css diff --git a/doc/test/coverage/glass.png b/doc/coverage/coverage/glass.png similarity index 100% rename from doc/test/coverage/glass.png rename to doc/coverage/coverage/glass.png diff --git a/doc/test/coverage/index-sort-b.html b/doc/coverage/coverage/index-sort-b.html similarity index 88% rename from doc/test/coverage/index-sort-b.html rename to doc/coverage/coverage/index-sort-b.html index 922799d..a3bbeed 100644 --- a/doc/test/coverage/index-sort-b.html +++ b/doc/coverage/coverage/index-sort-b.html @@ -31,27 +31,27 @@ lcov.info Lines: - 402 - 436 - 92.2 % + 397 + 430 + 92.3 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 101 - 110 - 91.8 % + 99 + 108 + 91.7 % Branches: - 163 - 178 - 91.6 % + 162 + 176 + 92.0 % @@ -132,14 +132,14 @@ src/rules/validation -
95.8%95.8%
+
96.6%96.6%
- 95.8 % - 69 / 72 - 89.5 % - 17 / 19 - 92.1 % - 35 / 38 + 96.6 % + 56 / 58 + 86.7 % + 13 / 15 + 93.8 % + 30 / 32 src/modules @@ -165,18 +165,6 @@ 98.1 % 53 / 54 - - src/rules/validation/abstract - -
100.0%
- - 100.0 % - 3 / 3 - 100.0 % - 1 / 1 - - - 0 / 0 - test/utils @@ -189,6 +177,18 @@ - 0 / 0 + + src/rules/validation/abstract + +
100.0%
+ + 100.0 % + 11 / 11 + 100.0 % + 3 / 3 + 100.0 % + 4 / 4 +
diff --git a/doc/test/coverage/index-sort-f.html b/doc/coverage/coverage/index-sort-f.html similarity index 88% rename from doc/test/coverage/index-sort-f.html rename to doc/coverage/coverage/index-sort-f.html index d45e811..d4d585f 100644 --- a/doc/test/coverage/index-sort-f.html +++ b/doc/coverage/coverage/index-sort-f.html @@ -31,27 +31,27 @@ lcov.info Lines: - 402 - 436 - 92.2 % + 397 + 430 + 92.3 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 101 - 110 - 91.8 % + 99 + 108 + 91.7 % Branches: - 163 - 178 - 91.6 % + 162 + 176 + 92.0 % @@ -120,26 +120,14 @@ src/rules/validation -
95.8%95.8%
- - 95.8 % - 69 / 72 - 89.5 % - 17 / 19 - 92.1 % - 35 / 38 - - - src/rules/validation/abstract/RuleAddressList - -
97.1%97.1%
+
96.6%96.6%
- 97.1 % - 34 / 35 + 96.6 % + 56 / 58 + 86.7 % + 13 / 15 93.8 % - 15 / 16 - 75.0 % - 6 / 8 + 30 / 32 src/rules/operation @@ -153,6 +141,18 @@ 90.5 % 38 / 42 + + src/rules/validation/abstract/RuleAddressList + +
97.1%97.1%
+ + 97.1 % + 34 / 35 + 93.8 % + 15 / 16 + 75.0 % + 6 / 8 + src/rules/operation/abstract @@ -171,11 +171,11 @@
100.0%
100.0 % + 11 / 11 + 100.0 % 3 / 3 100.0 % - 1 / 1 - - - 0 / 0 + 4 / 4 src/modules diff --git a/doc/test/coverage/index-sort-l.html b/doc/coverage/coverage/index-sort-l.html similarity index 88% rename from doc/test/coverage/index-sort-l.html rename to doc/coverage/coverage/index-sort-l.html index 608336a..026a8e5 100644 --- a/doc/test/coverage/index-sort-l.html +++ b/doc/coverage/coverage/index-sort-l.html @@ -31,27 +31,27 @@ lcov.info Lines: - 402 - 436 - 92.2 % + 397 + 430 + 92.3 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 101 - 110 - 91.8 % + 99 + 108 + 91.7 % Branches: - 163 - 178 - 91.6 % + 162 + 176 + 92.0 % @@ -105,18 +105,6 @@ - 0 / 0 - - src/rules/validation - -
95.8%95.8%
- - 95.8 % - 69 / 72 - 89.5 % - 17 / 19 - 92.1 % - 35 / 38 - src @@ -129,6 +117,18 @@ 80.0 % 8 / 10 + + src/rules/validation + +
96.6%96.6%
+ + 96.6 % + 56 / 58 + 86.7 % + 13 / 15 + 93.8 % + 30 / 32 + src/rules/validation/abstract/RuleAddressList @@ -159,11 +159,11 @@
100.0%
100.0 % + 11 / 11 + 100.0 % 3 / 3 100.0 % - 1 / 1 - - - 0 / 0 + 4 / 4 src/modules diff --git a/doc/test/coverage/index.html b/doc/coverage/coverage/index.html similarity index 88% rename from doc/test/coverage/index.html rename to doc/coverage/coverage/index.html index db93b03..5be2146 100644 --- a/doc/test/coverage/index.html +++ b/doc/coverage/coverage/index.html @@ -31,27 +31,27 @@ lcov.info Lines: - 402 - 436 - 92.2 % + 397 + 430 + 92.3 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 101 - 110 - 91.8 % + 99 + 108 + 91.7 % Branches: - 163 - 178 - 91.6 % + 162 + 176 + 92.0 % @@ -144,14 +144,14 @@ src/rules/validation -
95.8%95.8%
+
96.6%96.6%
- 95.8 % - 69 / 72 - 89.5 % - 17 / 19 - 92.1 % - 35 / 38 + 96.6 % + 56 / 58 + 86.7 % + 13 / 15 + 93.8 % + 30 / 32 src/rules/validation/abstract @@ -159,11 +159,11 @@
100.0%
100.0 % + 11 / 11 + 100.0 % 3 / 3 100.0 % - 1 / 1 - - - 0 / 0 + 4 / 4 src/rules/validation/abstract/RuleAddressList diff --git a/doc/test/coverage/ruby.png b/doc/coverage/coverage/ruby.png similarity index 100% rename from doc/test/coverage/ruby.png rename to doc/coverage/coverage/ruby.png diff --git a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html similarity index 98% rename from doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html rename to doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html index 78d135d..02dc237 100644 --- a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html +++ b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html similarity index 98% rename from doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html rename to doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html index 7974e50..29633eb 100644 --- a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html +++ b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html similarity index 99% rename from doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html rename to doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html index f3ff3ee..0957194 100644 --- a/doc/test/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html +++ b/doc/coverage/coverage/script/CMTATWithRuleEngineScript.s.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/RuleEngineScript.s.sol.func-sort-c.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html similarity index 98% rename from doc/test/coverage/script/RuleEngineScript.s.sol.func-sort-c.html rename to doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html index 959b08b..b17bfa2 100644 --- a/doc/test/coverage/script/RuleEngineScript.s.sol.func-sort-c.html +++ b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/RuleEngineScript.s.sol.func.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html similarity index 98% rename from doc/test/coverage/script/RuleEngineScript.s.sol.func.html rename to doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html index 0433035..fd4ce5f 100644 --- a/doc/test/coverage/script/RuleEngineScript.s.sol.func.html +++ b/doc/coverage/coverage/script/RuleEngineScript.s.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/RuleEngineScript.s.sol.gcov.html b/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html similarity index 99% rename from doc/test/coverage/script/RuleEngineScript.s.sol.gcov.html rename to doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html index 48afae6..6e9857d 100644 --- a/doc/test/coverage/script/RuleEngineScript.s.sol.gcov.html +++ b/doc/coverage/coverage/script/RuleEngineScript.s.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/index-sort-b.html b/doc/coverage/coverage/script/index-sort-b.html similarity index 98% rename from doc/test/coverage/script/index-sort-b.html rename to doc/coverage/coverage/script/index-sort-b.html index 4495e7c..58d4173 100644 --- a/doc/test/coverage/script/index-sort-b.html +++ b/doc/coverage/coverage/script/index-sort-b.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/index-sort-f.html b/doc/coverage/coverage/script/index-sort-f.html similarity index 98% rename from doc/test/coverage/script/index-sort-f.html rename to doc/coverage/coverage/script/index-sort-f.html index 12cfb5b..2c13af8 100644 --- a/doc/test/coverage/script/index-sort-f.html +++ b/doc/coverage/coverage/script/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/index-sort-l.html b/doc/coverage/coverage/script/index-sort-l.html similarity index 98% rename from doc/test/coverage/script/index-sort-l.html rename to doc/coverage/coverage/script/index-sort-l.html index a1602b6..3dbf5b4 100644 --- a/doc/test/coverage/script/index-sort-l.html +++ b/doc/coverage/coverage/script/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/script/index.html b/doc/coverage/coverage/script/index.html similarity index 98% rename from doc/test/coverage/script/index.html rename to doc/coverage/coverage/script/index.html index 647bf4f..6c9ce43 100644 --- a/doc/test/coverage/script/index.html +++ b/doc/coverage/coverage/script/index.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 0 diff --git a/doc/test/coverage/snow.png b/doc/coverage/coverage/snow.png similarity index 100% rename from doc/test/coverage/snow.png rename to doc/coverage/coverage/snow.png diff --git a/doc/test/coverage/src/RuleEngine.sol.func-sort-c.html b/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html similarity index 95% rename from doc/test/coverage/src/RuleEngine.sol.func-sort-c.html rename to doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html index 405200a..d947f4d 100644 --- a/doc/test/coverage/src/RuleEngine.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/RuleEngine.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 @@ -69,7 +69,7 @@ Hit count Sort by hit count - RuleEngine._msgData + RuleEngine._msgData 0 @@ -89,11 +89,11 @@ 52 - RuleEngine._contextSuffixLength + RuleEngine._contextSuffixLength 263 - RuleEngine._msgSender + RuleEngine._msgSender 263 diff --git a/doc/test/coverage/src/RuleEngine.sol.func.html b/doc/coverage/coverage/src/RuleEngine.sol.func.html similarity index 95% rename from doc/test/coverage/src/RuleEngine.sol.func.html rename to doc/coverage/coverage/src/RuleEngine.sol.func.html index fe0b6bf..62237e1 100644 --- a/doc/test/coverage/src/RuleEngine.sol.func.html +++ b/doc/coverage/coverage/src/RuleEngine.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 @@ -69,15 +69,15 @@ Hit count Sort by hit count - RuleEngine._contextSuffixLength + RuleEngine._contextSuffixLength 263 - RuleEngine._msgData + RuleEngine._msgData 0 - RuleEngine._msgSender + RuleEngine._msgSender 263 diff --git a/doc/test/coverage/src/RuleEngine.sol.gcov.html b/doc/coverage/coverage/src/RuleEngine.sol.gcov.html similarity index 97% rename from doc/test/coverage/src/RuleEngine.sol.gcov.html rename to doc/coverage/coverage/src/RuleEngine.sol.gcov.html index 4d28c47..78e2c78 100644 --- a/doc/test/coverage/src/RuleEngine.sol.gcov.html +++ b/doc/coverage/coverage/src/RuleEngine.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 @@ -213,42 +213,46 @@ 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 : : } + 145 : : /*////////////////////////////////////////////////////////////// + 146 : : ERC-2771 + 147 : : //////////////////////////////////////////////////////////////*/ + 148 : : + 149 : : /** + 150 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 151 : : */ + 152 : : function _msgSender() + 153 : : internal + 154 : : view + 155 : : override(ERC2771Context, Context) + 156 : : returns (address sender) + 157 : : { + 158 : 789 : return ERC2771Context._msgSender(); + 159 : : } + 160 : : + 161 : : /** + 162 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 163 : : */ + 164 : : function _msgData() + 165 : : internal + 166 : : view + 167 : : override(ERC2771Context, Context) + 168 : : returns (bytes calldata) + 169 : : { + 170 : 0 : return ERC2771Context._msgData(); + 171 : : } + 172 : : + 173 : : /** + 174 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 175 : : */ + 176 : : function _contextSuffixLength() + 177 : : internal + 178 : : view + 179 : : override(ERC2771Context, Context) + 180 : : returns (uint256) + 181 : : { + 182 : 789 : return ERC2771Context._contextSuffixLength(); + 183 : : } + 184 : : } diff --git a/doc/test/coverage/src/index-sort-b.html b/doc/coverage/coverage/src/index-sort-b.html similarity index 98% rename from doc/test/coverage/src/index-sort-b.html rename to doc/coverage/coverage/src/index-sort-b.html index 69c094d..9dd0b4e 100644 --- a/doc/test/coverage/src/index-sort-b.html +++ b/doc/coverage/coverage/src/index-sort-b.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 diff --git a/doc/test/coverage/src/index-sort-f.html b/doc/coverage/coverage/src/index-sort-f.html similarity index 98% rename from doc/test/coverage/src/index-sort-f.html rename to doc/coverage/coverage/src/index-sort-f.html index a0c5e56..961141b 100644 --- a/doc/test/coverage/src/index-sort-f.html +++ b/doc/coverage/coverage/src/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 diff --git a/doc/test/coverage/src/index-sort-l.html b/doc/coverage/coverage/src/index-sort-l.html similarity index 98% rename from doc/test/coverage/src/index-sort-l.html rename to doc/coverage/coverage/src/index-sort-l.html index 7392b50..ef0ece2 100644 --- a/doc/test/coverage/src/index-sort-l.html +++ b/doc/coverage/coverage/src/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 diff --git a/doc/test/coverage/src/index.html b/doc/coverage/coverage/src/index.html similarity index 98% rename from doc/test/coverage/src/index.html rename to doc/coverage/coverage/src/index.html index c192026..b017dd1 100644 --- a/doc/test/coverage/src/index.html +++ b/doc/coverage/coverage/src/index.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 diff --git a/doc/test/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html similarity index 98% rename from doc/test/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html rename to doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html index 0fd50ed..b2d8f3a 100644 --- a/doc/test/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 11 diff --git a/doc/test/coverage/src/modules/RuleEngineOperation.sol.func.html b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html similarity index 98% rename from doc/test/coverage/src/modules/RuleEngineOperation.sol.func.html rename to doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html index 4034157..0b88d8b 100644 --- a/doc/test/coverage/src/modules/RuleEngineOperation.sol.func.html +++ b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 11 diff --git a/doc/test/coverage/src/modules/RuleEngineOperation.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html similarity index 99% rename from doc/test/coverage/src/modules/RuleEngineOperation.sol.gcov.html rename to doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html index 4a3b270..cd0ef49 100644 --- a/doc/test/coverage/src/modules/RuleEngineOperation.sol.gcov.html +++ b/doc/coverage/coverage/src/modules/RuleEngineOperation.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 11 @@ -187,7 +187,7 @@ 116 : : function getRuleIndexOperation( 117 : : IRuleOperation rule_ 118 : : ) external view returns (uint256 index) { - 119 : 9 : return RuleInternal.getRuleIndex(_rulesOperation, address(rule_)); + 119 : 9 : return RuleInternal._getRuleIndex(_rulesOperation, address(rule_)); 120 : : } 121 : : 122 : : /** diff --git a/doc/test/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html similarity index 98% rename from doc/test/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html rename to doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html index ab7d535..5369cc5 100644 --- a/doc/test/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/src/modules/RuleEngineValidation.sol.func.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html similarity index 98% rename from doc/test/coverage/src/modules/RuleEngineValidation.sol.func.html rename to doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html index 9008852..338ecf8 100644 --- a/doc/test/coverage/src/modules/RuleEngineValidation.sol.func.html +++ b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/src/modules/RuleEngineValidation.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html similarity index 99% rename from doc/test/coverage/src/modules/RuleEngineValidation.sol.gcov.html rename to doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html index 6a7a5f3..7427b98 100644 --- a/doc/test/coverage/src/modules/RuleEngineValidation.sol.gcov.html +++ b/doc/coverage/coverage/src/modules/RuleEngineValidation.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html similarity index 85% rename from doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html rename to doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html index 2cc84b0..305045b 100644 --- a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 10 @@ -69,43 +69,43 @@ Hit count Sort by hit count - RuleEngineValidationCommon.ruleValidation + RuleEngineValidationCommon.ruleValidation 1 - RuleEngineValidationCommon.getRuleIndexValidation + RuleEngineValidationCommon.getRuleIndexValidation 3 - RuleEngineValidationCommon.rulesValidation + RuleEngineValidationCommon.rulesValidation 5 - RuleEngineValidationCommon.clearRulesValidation + RuleEngineValidationCommon.clearRulesValidation 6 - RuleEngineValidationCommon.removeRuleValidation + RuleEngineValidationCommon.removeRuleValidation 6 - RuleEngineValidationCommon.setRulesValidation + RuleEngineValidationCommon.setRulesValidation 22 - RuleEngineValidationCommon._clearRulesValidation + RuleEngineValidationCommon._clearRulesValidation 25 - RuleEngineValidationCommon._removeRuleValidation + RuleEngineValidationCommon._removeRuleValidation 33 - RuleEngineValidationCommon.rulesCountValidation + RuleEngineValidationCommon.rulesCountValidation 69 - RuleEngineValidationCommon.addRuleValidation + RuleEngineValidationCommon.addRuleValidation 115 diff --git a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html similarity index 86% rename from doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func.html rename to doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html index cc2d19e..5e3b0cb 100644 --- a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.func.html +++ b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 10 @@ -69,43 +69,43 @@ Hit count Sort by hit count - RuleEngineValidationCommon._clearRulesValidation + RuleEngineValidationCommon._clearRulesValidation 25 - RuleEngineValidationCommon._removeRuleValidation + RuleEngineValidationCommon._removeRuleValidation 33 - RuleEngineValidationCommon.addRuleValidation + RuleEngineValidationCommon.addRuleValidation 115 - RuleEngineValidationCommon.clearRulesValidation + RuleEngineValidationCommon.clearRulesValidation 6 - RuleEngineValidationCommon.getRuleIndexValidation + RuleEngineValidationCommon.getRuleIndexValidation 3 - RuleEngineValidationCommon.removeRuleValidation + RuleEngineValidationCommon.removeRuleValidation 6 - RuleEngineValidationCommon.ruleValidation + RuleEngineValidationCommon.ruleValidation 1 - RuleEngineValidationCommon.rulesCountValidation + RuleEngineValidationCommon.rulesCountValidation 69 - RuleEngineValidationCommon.rulesValidation + RuleEngineValidationCommon.rulesValidation 5 - RuleEngineValidationCommon.setRulesValidation + RuleEngineValidationCommon.setRulesValidation 22 diff --git a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html similarity index 82% rename from doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html rename to doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html index c291df0..c3354cb 100644 --- a/doc/test/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html +++ b/doc/coverage/coverage/src/modules/RuleEngineValidationCommon.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 10 @@ -89,132 +89,139 @@ 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_)); + 21 : : + 22 : : /*////////////////////////////////////////////////////////////// + 23 : : PUBLIC/EXTERNAL FUNCTIONS + 24 : : //////////////////////////////////////////////////////////////*/ + 25 : : /** + 26 : : * @notice Set all the rules, will overwrite all the previous rules. \n + 27 : : * Revert if one rule is a zero address or if the rule is already present + 28 : : * @dev take address[] instead of IRuleEngineValidation[] since it is not possible to cast IRuleEngineValidation[] -> address[] + 29 : : * + 30 : : */ + 31 : : function setRulesValidation( + 32 : : address[] calldata rules_ + 33 : : ) public override onlyRole(RULE_ENGINE_OPERATOR_ROLE) { + 34 [ + + ]: 42 : if (_rulesValidation.length > 0) { + 35 : 40 : _clearRulesValidation(); + 36 : : } + 37 : 42 : _setRules(rules_); + 38 : 36 : _rulesValidation = rules_; + 39 : : } + 40 : : + 41 : : /** + 42 : : * @notice Clear all the rules of the array of rules + 43 : : * + 44 : : */ + 45 : : function clearRulesValidation() public onlyRole(RULE_ENGINE_OPERATOR_ROLE) { + 46 : 10 : _clearRulesValidation(); + 47 : : } + 48 : : + 49 : : /** + 50 : : * @notice Add a rule to the array of rules + 51 : : * Revert if one rule is a zero address or if the rule is already present + 52 : : * + 53 : : */ + 54 : : function addRuleValidation( + 55 : : IRuleValidation rule_ + 56 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) { + 57 : 228 : RuleInternal._addRule(_rulesValidation, address(rule_)); + 58 : 224 : emit AddRule(address(rule_)); + 59 : : } + 60 : : + 61 : : /** + 62 : : * @notice Remove a rule from the array of rules + 63 : : * Revert if the rule found at the specified index does not match the rule in argument + 64 : : * @param rule_ address of the target rule + 65 : : * @param index the position inside the array of rule + 66 : : * @dev To reduce the array size, the last rule is moved to the location occupied + 67 : : * by the rule to remove + 68 : : * + 69 : : * + 70 : : */ + 71 : : function removeRuleValidation( + 72 : : IRuleValidation rule_, + 73 : : uint256 index + 74 : : ) public onlyRole(RULE_ENGINE_OPERATOR_ROLE) { + 75 : 10 : _removeRuleValidation(address(rule_), index); + 76 : : } + 77 : : + 78 : : /** + 79 : : * @return The number of rules inside the array + 80 : : */ + 81 : : function rulesCountValidation() external view override returns (uint256) { + 82 : 138 : return _rulesValidation.length; + 83 : : } + 84 : : + 85 : : /** + 86 : : * @notice Get the index of a rule inside the list + 87 : : * @return index if the rule is found, _rulesValidation.length otherwise + 88 : : */ + 89 : : function getRuleIndexValidation( + 90 : : IRuleValidation rule_ + 91 : : ) external view returns (uint256 index) { + 92 : 9 : return RuleInternal._getRuleIndex(_rulesValidation, address(rule_)); + 93 : : } + 94 : : + 95 : : /** + 96 : : * @notice Get the rule at the position specified by ruleId + 97 : : * @param ruleId index of the rule + 98 : : * @return a rule address + 99 : : */ + 100 : : function ruleValidation( + 101 : : uint256 ruleId + 102 : : ) external view override returns (address) { + 103 : 2 : return _rulesValidation[ruleId]; 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 : : } + 107 : : * @notice Get all the rules + 108 : : * @return An array of rules + 109 : : */ + 110 : : function rulesValidation() + 111 : : external + 112 : : view + 113 : : override + 114 : : returns (address[] memory) + 115 : : { + 116 : 10 : return _rulesValidation; + 117 : : } + 118 : : + 119 : : /*////////////////////////////////////////////////////////////// + 120 : : INTERNAL FUNCTIONS + 121 : : //////////////////////////////////////////////////////////////*/ + 122 : : /** + 123 : : * @notice Clear all the rules of the array of rules + 124 : : * + 125 : : */ + 126 : : function _clearRulesValidation() internal { + 127 : 50 : uint256 index; + 128 : : // we remove the last element first since it is more optimized. + 129 : 131 : for (uint256 i = _rulesValidation.length; i > 0; --i) { + 130 : : unchecked { + 131 : : // don't underflow since i > 0 + 132 : 56 : index = i - 1; + 133 : : } + 134 : 56 : _removeRuleValidation(_rulesValidation[index], index); + 135 : : } + 136 : 50 : emit ClearRules(_rulesValidation); + 137 : : } + 138 : : + 139 : : /** + 140 : : * @notice Remove a rule from the array of rules + 141 : : * Revert if the rule found at the specified index does not match the rule in argument + 142 : : * @param rule_ address of the target rule + 143 : : * @param index the position inside the array of rule + 144 : : * @dev To reduce the array size, the last rule is moved to the location occupied + 145 : : * by the rule to remove + 146 : : * + 147 : : * + 148 : : */ + 149 : : function _removeRuleValidation(address rule_, uint256 index) internal { + 150 : 66 : RuleInternal._removeRule(_rulesValidation, rule_, index); + 151 : 64 : emit RemoveRule(address(rule_)); + 152 : : } + 153 : : } diff --git a/doc/test/coverage/src/modules/RuleInternal.sol.func-sort-c.html b/doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html similarity index 97% rename from doc/test/coverage/src/modules/RuleInternal.sol.func-sort-c.html rename to doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html index 388b450..4d4410d 100644 --- a/doc/test/coverage/src/modules/RuleInternal.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/modules/RuleInternal.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 4 @@ -69,7 +69,7 @@ Hit count Sort by hit count - RuleInternal.getRuleIndex + RuleInternal._getRuleIndex 6 diff --git a/doc/test/coverage/src/modules/RuleInternal.sol.func.html b/doc/coverage/coverage/src/modules/RuleInternal.sol.func.html similarity index 97% rename from doc/test/coverage/src/modules/RuleInternal.sol.func.html rename to doc/coverage/coverage/src/modules/RuleInternal.sol.func.html index c96cc29..2c23e22 100644 --- a/doc/test/coverage/src/modules/RuleInternal.sol.func.html +++ b/doc/coverage/coverage/src/modules/RuleInternal.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 4 @@ -72,6 +72,10 @@ RuleInternal._addRule 182 + + RuleInternal._getRuleIndex + 6 + RuleInternal._removeRule 55 @@ -80,10 +84,6 @@ RuleInternal._setRules 32 - - RuleInternal.getRuleIndex - 6 -
diff --git a/doc/test/coverage/src/modules/RuleInternal.sol.gcov.html b/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html similarity index 99% rename from doc/test/coverage/src/modules/RuleInternal.sol.gcov.html rename to doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html index c533201..2189f88 100644 --- a/doc/test/coverage/src/modules/RuleInternal.sol.gcov.html +++ b/doc/coverage/coverage/src/modules/RuleInternal.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 4 @@ -152,7 +152,7 @@ 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( + 84 : : function _getRuleIndex( 85 : : address[] storage _rules, 86 : : address rule_ 87 : : ) internal view returns (uint256 index) { diff --git a/doc/test/coverage/src/modules/index-sort-b.html b/doc/coverage/coverage/src/modules/index-sort-b.html similarity index 99% rename from doc/test/coverage/src/modules/index-sort-b.html rename to doc/coverage/coverage/src/modules/index-sort-b.html index 014db42..d4aaed9 100644 --- a/doc/test/coverage/src/modules/index-sort-b.html +++ b/doc/coverage/coverage/src/modules/index-sort-b.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 27 diff --git a/doc/test/coverage/src/modules/index-sort-f.html b/doc/coverage/coverage/src/modules/index-sort-f.html similarity index 99% rename from doc/test/coverage/src/modules/index-sort-f.html rename to doc/coverage/coverage/src/modules/index-sort-f.html index 4e1c5fa..6d8c9aa 100644 --- a/doc/test/coverage/src/modules/index-sort-f.html +++ b/doc/coverage/coverage/src/modules/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 27 diff --git a/doc/test/coverage/src/modules/index-sort-l.html b/doc/coverage/coverage/src/modules/index-sort-l.html similarity index 99% rename from doc/test/coverage/src/modules/index-sort-l.html rename to doc/coverage/coverage/src/modules/index-sort-l.html index 4306ce9..f02bd59 100644 --- a/doc/test/coverage/src/modules/index-sort-l.html +++ b/doc/coverage/coverage/src/modules/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 27 diff --git a/doc/test/coverage/src/modules/index.html b/doc/coverage/coverage/src/modules/index.html similarity index 99% rename from doc/test/coverage/src/modules/index.html rename to doc/coverage/coverage/src/modules/index.html index 953d36c..76fbf45 100644 --- a/doc/test/coverage/src/modules/index.html +++ b/doc/coverage/coverage/src/modules/index.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 27 diff --git a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html similarity index 83% rename from doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html index 5abe2e2..b22fc0f 100644 --- a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 @@ -69,67 +69,67 @@ Hit count Sort by 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/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html similarity index 83% rename from doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html rename to doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html index 9fa83d8..c8dd088 100644 --- a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html +++ b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 @@ -69,67 +69,67 @@ Hit count Sort by 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/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html similarity index 81% rename from doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html rename to doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html index 9ad4604..802a866 100644 --- a/doc/test/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/operation/RuleConditionalTransfer.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 @@ -118,332 +118,349 @@ 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]); + 50 : : /*////////////////////////////////////////////////////////////// + 51 : : PUBLIC/EXTERNAL FUNCTIONS + 52 : : //////////////////////////////////////////////////////////////*/ + 53 : : /** + 54 : : * @notice function called by the RuleEngine + 55 : : * @dev Returns true if the transfer is valid, and false otherwise. + 56 : : * Add access control with the RuleEngine + 57 : : */ + 58 : : function operateOnTransfer( + 59 : : address _from, + 60 : : address _to, + 61 : : uint256 _amount + 62 : : ) + 63 : : public + 64 : : override + 65 : : onlyRole(RULE_ENGINE_CONTRACT_ROLE) + 66 : : returns (bool isValid) + 67 : : { + 68 : : // No need of approval if from and to are in the whitelist + 69 [ + + ]: 132 : if (address(whitelistConditionalTransfer) != address(0)) { + 70 [ + + ]: : if ( + 71 : 54 : whitelistConditionalTransfer.addressIsListed(_from) && + 72 : 6 : whitelistConditionalTransfer.addressIsListed(_to) + 73 : : ) { + 74 : 4 : return true; + 75 : : } + 76 : : } + 77 : : + 78 : : // Mint & Burn + 79 [ + + ]: 62 : if (_validateBurnMint(_from, _to)) { + 80 : 8 : return true; + 81 : : } + 82 : 81 : bytes32 key = keccak256(abi.encode(_from, _to, _amount)); + 83 [ + + ]: 54 : if (_validateApproval(key)) { + 84 : 20 : _updateProcessedTransfer(key); + 85 : 20 : return true; + 86 : : } else { + 87 : 34 : return false; + 88 : : } + 89 : : } + 90 : : + 91 : : /** + 92 : : * @notice Create a request of transfer for yourselves + 93 : : * @param to recipient of tokens + 94 : : * @param value amount of tokens to transfer + 95 : : */ + 96 : : function createTransferRequest(address to, uint256 value) public { + 97 : : // WAIT => Will set a new delay to approve + 98 : : // APPROVED => will overwrite previous status + 99 : : // DENIED => reject + 100 : 315 : address from = _msgSender(); + 101 : 315 : bytes32 key = keccak256(abi.encode(from, to, value)); + 102 [ + + ]: 210 : if (transferRequests[key].status == STATUS.DENIED) { + 103 : 2 : revert RuleConditionalTransfer_TransferDenied(); + 104 : : } + 105 [ # + ]: 208 : if (_checkRequestStatus(key)) { + 106 : 202 : uint256 requestIdLocal = requestId; + 107 : 303 : TransferRequest memory newTransferApproval = TransferRequest({ + 108 : : key: key, + 109 : : id: requestIdLocal, + 110 : : keyElement: TransferRequestKeyElement({ + 111 : : from: from, + 112 : : to: to, + 113 : : value: value + 114 : : }), + 115 : : askTime: block.timestamp, + 116 : : maxTime: 0, + 117 : : status: STATUS.WAIT + 118 : : }); + 119 : 202 : transferRequests[key] = newTransferApproval; + 120 : 202 : IdToKey[requestIdLocal] = key; + 121 : 202 : emit transferWaiting(key, from, to, value, requestId); + 122 : 202 : ++requestId; + 123 : : } else { + 124 : : // Overwrite previous approval + 125 : 6 : transferRequests[key].askTime = block.timestamp; + 126 : 6 : transferRequests[key].status = STATUS.WAIT; + 127 : 6 : emit transferWaiting( + 128 : : key, + 129 : : from, + 130 : : to, + 131 : : value, + 132 : : transferRequests[key].id + 133 : : ); 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(); + 137 : : /** + 138 : : * @notice Batch version of {createTransferRequest} + 139 : : */ + 140 : : function createTransferRequestBatch( + 141 : : address[] memory tos, + 142 : : uint256[] memory values + 143 : : ) public { + 144 [ + + ]: 6 : if (tos.length == 0) { + 145 : 2 : revert RuleConditionalTransfer_EmptyArray(); + 146 : : } + 147 [ + + ]: 4 : if (tos.length != values.length) { + 148 : 2 : revert RuleConditionalTransfer_InvalidLengthArray(); + 149 : : } + 150 : 9 : for (uint256 i = 0; i < tos.length; ++i) { + 151 : 6 : createTransferRequest(tos[i], values[i]); 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 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 : 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 : : } + 153 : : } + 154 : : + 155 : : /** + 156 : : * @notice allow a token holder to cancel/reset his own request + 157 : : */ + 158 : : function cancelTransferRequest(uint256 requestId_) public { + 159 : 12 : _cancelTransferRequest(requestId_); + 160 : : } + 161 : : + 162 : : /** + 163 : : * @notice allow a token holder to cancel/reset his own request + 164 : : */ + 165 : : function cancelTransferRequestBatch(uint256[] memory requestIds) public { + 166 [ + + ]: 6 : if (requestIds.length == 0) { + 167 : 2 : revert RuleConditionalTransfer_EmptyArray(); + 168 : : } + 169 : : // Check id validity before performing actions + 170 : 14 : for (uint256 i = 0; i < requestIds.length; ++i) { + 171 [ + + ]: 15 : if (requestIds[i] + 1 > requestId) { + 172 : 2 : revert RuleConditionalTransfer_InvalidId(); + 173 : : } + 174 : : } + 175 : 9 : for (uint256 i = 0; i < requestIds.length; ++i) { + 176 : 6 : _cancelTransferRequest(requestIds[i]); + 177 : : } + 178 : : } + 179 : : + 180 : : function getRequestTrade( + 181 : : address from, + 182 : : address to, + 183 : : uint256 value + 184 : : ) public view returns (TransferRequest memory) { + 185 : 171 : bytes32 key = keccak256(abi.encode(from, to, value)); + 186 : 114 : return transferRequests[key]; + 187 : : } + 188 : : + 189 : : /** + 190 : : * @notice get Trade by status + 191 : : * @param _targetStatus The status of the transactions you want to retrieve + 192 : : * @return array with corresponding transactions + 193 : : */ + 194 : : function getRequestByStatus( + 195 : : STATUS _targetStatus + 196 : : ) public view returns (TransferRequest[] memory) { + 197 : 70 : uint totalRequestCount = requestId; + 198 : 70 : uint requestCount = 0; + 199 : 70 : uint currentIndex = 0; 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 : : } + 201 : : // We count the number of requests matching the criteria + 202 : 181 : for (uint i = 0; i < totalRequestCount; ++i) { + 203 [ + + ]: 76 : if (transferRequests[IdToKey[i]].status == _targetStatus) { + 204 : 72 : requestCount += 1; + 205 : : } + 206 : : } + 207 : : + 208 : : // We reserve the memory to store the trade + 209 : 105 : TransferRequest[] memory requests = new TransferRequest[](requestCount); + 210 : : + 211 : : // We create an array with the list of trade + 212 : 181 : for (uint i = 0; i < totalRequestCount; ++i) { + 213 [ # + ]: 76 : if (transferRequests[IdToKey[i]].status == _targetStatus) { + 214 : : //uint currentId = i + 1; + 215 : 72 : TransferRequest memory currentRequest = transferRequests[ + 216 : : IdToKey[i] + 217 : : ]; + 218 : 72 : requests[currentIndex] = currentRequest; + 219 : 72 : currentIndex += 1; + 220 : : } + 221 : : } + 222 : 70 : return requests; + 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 burn and mint condition - 296 : : * Returns true if the transfer is valid, and false otherwise. - 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 : : } + 225 : : /** + 226 : : * @notice Check if the transfer is valid + 227 : : * @param _from the origin address + 228 : : * @param _to the destination address + 229 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK + 230 : : **/ + 231 : : function detectTransferRestriction( + 232 : : address _from, + 233 : : address _to, + 234 : : uint256 _amount + 235 : : ) public view override returns (uint8) { + 236 : : // No need of approval if from and to are in the whitelist + 237 [ # + ]: 44 : if (address(whitelistConditionalTransfer) != address(0)) { + 238 [ # + ]: : if ( + 239 : 9 : whitelistConditionalTransfer.addressIsListed(_from) && + 240 : 4 : whitelistConditionalTransfer.addressIsListed(_to) + 241 : : ) { + 242 : 3 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK); + 243 : : } + 244 : : } + 245 : 30 : bytes32 key = keccak256(abi.encode(_from, _to, _amount)); + 246 [ + + ]: 40 : if (!_validateBurnMint(_from, _to) && !_validateApproval(key)) { + 247 : 16 : return CODE_TRANSFER_REQUEST_NOT_APPROVED; + 248 : : } else { + 249 : 6 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK); + 250 : : } + 251 : : } + 252 : : + 253 : : /** + 254 : : * @notice To know if the restriction code is valid for this rule or not. + 255 : : * @param _restrictionCode The target restriction code + 256 : : * @return true if the restriction code is known, false otherwise + 257 : : **/ + 258 : : function canReturnTransferRestrictionCode( + 259 : : uint8 _restrictionCode + 260 : : ) external pure override returns (bool) { + 261 : 6 : return _restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED; + 262 : : } + 263 : : + 264 : : /** + 265 : : * @notice Return the corresponding message + 266 : : * @param _restrictionCode The target restriction code + 267 : : * @return true if the transfer is valid, false otherwise + 268 : : **/ + 269 : : function messageForTransferRestriction( + 270 : : uint8 _restrictionCode + 271 : : ) external pure override returns (string memory) { + 272 [ + + ]: 6 : if (_restrictionCode == CODE_TRANSFER_REQUEST_NOT_APPROVED) { + 273 : 4 : return TEXT_TRANSFER_REQUEST_NOT_APPROVED; + 274 : : } else { + 275 : 2 : return TEXT_CODE_NOT_FOUND; + 276 : : } + 277 : : } + 278 : : + 279 : : + 280 : : /*////////////////////////////////////////////////////////////// + 281 : : INTERNAL FUNCTIONS + 282 : : //////////////////////////////////////////////////////////////*/ + 283 : : + 284 : : function _cancelTransferRequest(uint256 requestId_) internal { + 285 [ + + ]: 27 : if (requestId_ + 1 > requestId) { + 286 : 2 : revert RuleConditionalTransfer_InvalidId(); + 287 : : } + 288 : 16 : bytes32 key = IdToKey[requestId_]; + 289 : : // Check Sender + 290 [ + + ]: 24 : if (transferRequests[key].keyElement.from != _msgSender()) { + 291 : 2 : revert RuleConditionalTransfer_InvalidSender(); + 292 : : } + 293 : : // Check status + 294 [ + + ]: : if ( + 295 : 21 : transferRequests[key].status != STATUS.WAIT && + 296 : 4 : transferRequests[key].status != STATUS.APPROVED + 297 : : ) { + 298 : 2 : revert RuleConditionalTransfer_Wrong_Status(); + 299 : : } + 300 : 12 : _resetRequestStatus(key); + 301 : : } + 302 : : + 303 : : /** + 304 : : * + 305 : : * @dev + 306 : : * Test burn and mint condition + 307 : : * Returns true if the transfer is valid, and false otherwise. + 308 : : * + 309 : : */ + 310 : : function _validateBurnMint( + 311 : : address _from, + 312 : : address _to + 313 : : ) internal view returns (bool isValid) { + 314 : : // Mint & Burn + 315 [ + + ]: : if ( + 316 : 82 : (_from == address(0) && + 317 : : options.issuance.authorizedMintWithoutApproval) || + 318 : : (_to == address(0) && + 319 : : options.issuance.authorizedBurnWithoutApproval) + 320 : : ) { + 321 : 8 : return true; + 322 : : } + 323 : 74 : return false; + 324 : : } + 325 : : + 326 : : /** + 327 : : * + 328 : : * @dev + 329 : : * Test transfer approval condition + 330 : : * Returns true if the transfer is valid, and false otherwise. + 331 : : */ + 332 : : function _validateApproval( + 333 : : bytes32 key + 334 : : ) internal view returns (bool isValid) { + 335 : : // If automatic approval is activate and time to approve the request has passed + 336 : 111 : bool automaticApprovalCondition = options + 337 : : .automaticApproval + 338 : : .isActivate && + 339 : : ((transferRequests[key].askTime + + 340 : : options.automaticApproval.timeLimitBeforeAutomaticApproval) >= + 341 : : block.timestamp); + 342 : : // If the transfer is approved and delay to perform the transfer is respected + 343 : 111 : bool isTransferApproved = (transferRequests[key].status == + 344 : : STATUS.APPROVED) && + 345 : : (transferRequests[key].maxTime >= block.timestamp); + 346 [ + + ]: 74 : if (automaticApprovalCondition || isTransferApproved) { + 347 : 24 : return true; + 348 : : } else { + 349 : 50 : return false; + 350 : : } + 351 : : } + 352 : : + 353 : : /*////////////////////////////////////////////////////////////// + 354 : : ERC-2771 + 355 : : //////////////////////////////////////////////////////////////*/ + 356 : : + 357 : : /** + 358 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 359 : : */ + 360 : : function _msgSender() + 361 : : internal + 362 : : view + 363 : : override(ERC2771Context, Context) + 364 : : returns (address sender) + 365 : : { + 366 : 1356 : return ERC2771Context._msgSender(); + 367 : : } + 368 : : + 369 : : /** + 370 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 371 : : */ + 372 : : function _msgData() + 373 : : internal + 374 : : view + 375 : : override(ERC2771Context, Context) + 376 : : returns (bytes calldata) + 377 : : { + 378 : 0 : return ERC2771Context._msgData(); + 379 : : } + 380 : : + 381 : : /** + 382 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 383 : : */ + 384 : : function _contextSuffixLength() + 385 : : internal + 386 : : view + 387 : : override(ERC2771Context, Context) + 388 : : returns (uint256) + 389 : : { + 390 : 1356 : return ERC2771Context._contextSuffixLength(); + 391 : : } + 392 : : } diff --git a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html similarity index 83% rename from doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html index 37c914c..280a1ff 100644 --- a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 18 @@ -69,79 +69,79 @@ Hit count Sort by 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/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html similarity index 83% rename from doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html rename to doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html index dc88726..dfbb084 100644 --- a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html +++ b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 18 @@ -69,79 +69,79 @@ Hit count Sort by 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/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html similarity index 90% rename from doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html rename to doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html index f764155..2179f73 100644 --- a/doc/test/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/operation/abstract/RuleConditionalTransferOperator.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 18 @@ -86,438 +86,441 @@ 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 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 (requestId_ + 1 > requestId) { - 163 : 4 : revert RuleConditionalTransfer_InvalidId(); - 164 : : } - 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(); + 18 : : /* ============ State Variables ============ */ + 19 : : OPTION public options; + 20 : : uint256 public requestId; + 21 : : mapping(uint256 => bytes32) public IdToKey; + 22 : : mapping(bytes32 => TransferRequest) public transferRequests; + 23 : : RuleWhitelist public whitelistConditionalTransfer; + 24 : : + 25 : : /*////////////////////////////////////////////////////////////// + 26 : : PUBLIC/EXTERNAL FUNCTIONS + 27 : : //////////////////////////////////////////////////////////////*/ + 28 : : + 29 : : /** + 30 : : * @notice set a whitelist. A transfer does not need of an approved request if from and to are in the whitelist + 31 : : */ + 32 : : function setConditionalWhitelist( + 33 : : RuleWhitelist newWhitelistConditionalTransfer + 34 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 35 : 50 : whitelistConditionalTransfer = newWhitelistConditionalTransfer; + 36 : 50 : emit WhitelistConditionalTransfer(newWhitelistConditionalTransfer); + 37 : : } + 38 : : + 39 : : /** + 40 : : * @notice set/unset the issuance options (mint & burn) + 41 : : */ + 42 : : function setIssuanceOptions( + 43 : : ISSUANCE calldata issuance_ + 44 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 45 [ + + ]: : if ( + 46 : 8 : options.issuance.authorizedMintWithoutApproval != + 47 : : issuance_.authorizedMintWithoutApproval + 48 : : ) { + 49 : 4 : options.issuance.authorizedMintWithoutApproval = issuance_ + 50 : : .authorizedMintWithoutApproval; + 51 : : } + 52 [ + + ]: : if ( + 53 : 8 : options.issuance.authorizedBurnWithoutApproval != + 54 : : issuance_.authorizedBurnWithoutApproval + 55 : : ) { + 56 : 4 : options.issuance.authorizedBurnWithoutApproval = issuance_ + 57 : : .authorizedBurnWithoutApproval; + 58 : : } + 59 : : } + 60 : : + 61 : : /** + 62 : : * @notice set/unset the option to perform the transfer if the request is approved by the rule operator. + 63 : : * To perform the transfer, the token holder has to approve the rule to spend tokens on his behalf (standard ERC-20 approval). + 64 : : * If the allowance is not sufficient, the request will be approved, but without performing the transfer. + 65 : : */ + 66 : : function setAutomaticTransfer( + 67 : : AUTOMATIC_TRANSFER calldata automaticTransfer_ + 68 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 69 [ + + ]: : if ( + 70 : 4 : automaticTransfer_.isActivate != + 71 : : options.automaticTransfer.isActivate + 72 : : ) { + 73 : 4 : options.automaticTransfer.isActivate = automaticTransfer_ + 74 : : .isActivate; + 75 : : } + 76 : : // No need to put the cmtat to zero to deactivate automaticTransfer + 77 [ + + ]: : if ( + 78 : 6 : address(automaticTransfer_.cmtat) != + 79 : 4 : address(options.automaticTransfer.cmtat) + 80 : : ) { + 81 : 4 : options.automaticTransfer.cmtat = automaticTransfer_.cmtat; + 82 : : } + 83 : : } + 84 : : + 85 : : /** + 86 : : * @notice set time limit for new requests (Approval and transfer) + 87 : : * timeLimitToApprove: time limit for an operator to approve a request + 88 : : * timeLimitToTransfer: once a request is approved, time limit for the token holder to perform the transfer + 89 : : */ + 90 : : function setTimeLimit( + 91 : : TIME_LIMIT memory timeLimit_ + 92 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 93 [ + + ]: : if ( + 94 : 6 : options.timeLimit.timeLimitToApprove != + 95 : : timeLimit_.timeLimitToApprove + 96 : : ) { + 97 : 6 : options.timeLimit.timeLimitToApprove = timeLimit_ + 98 : : .timeLimitToApprove; + 99 : : } + 100 [ + + ]: : if ( + 101 : 6 : options.timeLimit.timeLimitToTransfer != + 102 : : timeLimit_.timeLimitToTransfer + 103 : : ) { + 104 : 6 : options.timeLimit.timeLimitToTransfer = timeLimit_ + 105 : : .timeLimitToTransfer; + 106 : : } + 107 : : } + 108 : : + 109 : : /** + 110 : : * @notice If the transfer is not approved or denied within {timeLimitBeforeAutomaticApproval}, + 111 : : * the request is considered as approved during a transfer. + 112 : : * + 113 : : */ + 114 : : function setAutomaticApproval( + 115 : : AUTOMATIC_APPROVAL memory automaticApproval_ + 116 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 117 [ + + ]: : if ( + 118 : 8 : options.automaticApproval.isActivate != + 119 : : automaticApproval_.isActivate + 120 : : ) { + 121 : 8 : options.automaticApproval.isActivate = automaticApproval_ + 122 : : .isActivate; + 123 : : } + 124 [ + + ]: : if ( + 125 : 8 : options.automaticApproval.timeLimitBeforeAutomaticApproval != + 126 : : automaticApproval_.timeLimitBeforeAutomaticApproval + 127 : : ) { + 128 : 8 : options + 129 : : .automaticApproval + 130 : : .timeLimitBeforeAutomaticApproval = automaticApproval_ + 131 : : .timeLimitBeforeAutomaticApproval; + 132 : : } + 133 : : } + 134 : : + 135 : : /** + 136 : : * @notice create a transfer request directly approved + 137 : : */ + 138 : : function createTransferRequestWithApproval( + 139 : : TransferRequestKeyElement calldata keyElement + 140 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 141 : 10 : _createTransferRequestWithApproval(keyElement); + 142 : : } + 143 : : + 144 : : /** + 145 : : @notice approve a transferRequest + 146 : : @param keyElement contains from, to, value + 147 : : @param partialValue amount approved. Put 0 if all the amount specified by value is approved. + 148 : : @param isApproved approved (true) or refused (false). Put true if you use partialApproval + 149 : : */ + 150 : : function approveTransferRequest( + 151 : : TransferRequestKeyElement calldata keyElement, + 152 : : uint256 partialValue, + 153 : : bool isApproved + 154 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 155 : 64 : _approveTransferRequestKeyElement(keyElement, partialValue, isApproved); + 156 : : } + 157 : : + 158 : : /** + 159 : : * @notice approve a transferRequestby using its id + 160 : : */ + 161 : : function approveTransferRequestWithId( + 162 : : uint256 requestId_, + 163 : : bool isApproved + 164 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 165 [ + + ]: 12 : if (requestId_ + 1 > requestId) { + 166 : 4 : revert RuleConditionalTransfer_InvalidId(); + 167 : : } + 168 : 4 : TransferRequest memory transferRequest = transferRequests[ + 169 : : IdToKey[requestId_] + 170 : : ]; + 171 : 4 : _approveRequest(transferRequest, isApproved); + 172 : : } + 173 : : + 174 : : /** + 175 : : * @notice reset to None the status of a request + 176 : : */ + 177 : : function resetRequestStatus( + 178 : : uint256 requestId_ + 179 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 180 [ + + ]: 6 : if (requestId_ + 1 > requestId) { + 181 : 2 : revert RuleConditionalTransfer_InvalidId(); + 182 : : } + 183 : 2 : bytes32 key = IdToKey[requestId_]; + 184 : 2 : _resetRequestStatus(key); + 185 : : } + 186 : : + 187 : : /***** Batch function */ + 188 : : /** + 189 : : * @notice Batch version of {approveTransferRequestWithId} + 190 : : */ + 191 : : function approveTransferRequestBatchWithId( + 192 : : uint256[] calldata requestId_, + 193 : : bool[] calldata isApproved + 194 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 195 [ + + ]: 10 : if (requestId_.length == 0) { + 196 : 2 : revert RuleConditionalTransfer_EmptyArray(); 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 : 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]); + 198 [ + + ]: 8 : if (requestId_.length != isApproved.length) { + 199 : 2 : revert RuleConditionalTransfer_InvalidLengthArray(); + 200 : : } + 201 : : // Check id validity before performing actions + 202 : 29 : for (uint256 i = 0; i < requestId_.length; ++i) { + 203 [ + + ]: 33 : if (requestId_[i] + 1 > requestId) { + 204 : 2 : revert RuleConditionalTransfer_InvalidId(); + 205 : : } + 206 : : } + 207 : 14 : for (uint256 i = 0; i < requestId_.length; ++i) { + 208 : 10 : TransferRequest memory transferRequest = transferRequests[ + 209 : : IdToKey[requestId_[i]] + 210 : : ]; + 211 : 10 : _approveRequest(transferRequest, isApproved[i]); + 212 : : } + 213 : : } + 214 : : + 215 : : /** + 216 : : * @notice Batch version of {approveTransferRequest} + 217 : : */ + 218 : : function approveTransferRequestBatch( + 219 : : TransferRequestKeyElement[] calldata keyElements, + 220 : : uint256[] calldata partialValues, + 221 : : bool[] calldata isApproved + 222 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 223 [ + + ]: 12 : if (keyElements.length == 0) { + 224 : 2 : revert RuleConditionalTransfer_EmptyArray(); + 225 : : } + 226 [ + + ]: : if ( + 227 : 10 : (keyElements.length != partialValues.length) || + 228 : : (partialValues.length != isApproved.length) + 229 : : ) { + 230 : 6 : revert RuleConditionalTransfer_InvalidLengthArray(); + 231 : : } + 232 : 24 : for (uint256 i = 0; i < keyElements.length; ++i) { + 233 : 18 : _approveTransferRequestKeyElement( + 234 : : keyElements[i], + 235 : : partialValues[i], + 236 : : isApproved[i] + 237 : : ); + 238 : : } + 239 : : } + 240 : : + 241 : : /** + 242 : : * @notice Batch version of {createTransferRequestWithApproval} + 243 : : */ + 244 : : function createTransferRequestWithApprovalBatch( + 245 : : TransferRequestKeyElement[] calldata keyElements + 246 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 247 [ + + ]: 4 : if (keyElements.length == 0) { + 248 : 2 : revert RuleConditionalTransfer_EmptyArray(); 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 : : /*** 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 : : } + 250 : 11 : for (uint256 i = 0; i < keyElements.length; ++i) { + 251 : 8 : _createTransferRequestWithApproval(keyElements[i]); + 252 : : } + 253 : : } + 254 : : + 255 : : /** + 256 : : * @notice Batch version of {resetRequestStatus} + 257 : : */ + 258 : : function resetRequestStatusBatch( + 259 : : uint256[] memory requestIds + 260 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 261 [ + + ]: 6 : if (requestIds.length == 0) { + 262 : 2 : revert RuleConditionalTransfer_EmptyArray(); + 263 : : } + 264 : : // Check id validity before performing actions + 265 : 12 : for (uint256 i = 0; i < requestIds.length; ++i) { + 266 [ + + ]: 12 : if (requestIds[i] + 1 > requestId) { + 267 : 2 : revert RuleConditionalTransfer_InvalidId(); + 268 : : } + 269 : : } + 270 : 9 : for (uint256 i = 0; i < requestIds.length; ++i) { + 271 : 6 : bytes32 key = IdToKey[requestIds[i]]; + 272 : 6 : _resetRequestStatus(key); + 273 : : } + 274 : : } + 275 : : + 276 : : /*////////////////////////////////////////////////////////////// + 277 : : INTERNAL FUNCTIONS + 278 : : //////////////////////////////////////////////////////////////*/ + 279 : : function _approveTransferRequestKeyElement( + 280 : : TransferRequestKeyElement calldata keyElement, + 281 : : uint256 partialValue, + 282 : : bool isApproved + 283 : : ) internal { + 284 [ + + ]: 82 : if (partialValue > keyElement.value) { + 285 : 2 : revert RuleConditionalTransfer_InvalidValueApproved(); + 286 : : } + 287 : 120 : bytes32 key = keccak256( + 288 : : abi.encode(keyElement.from, keyElement.to, keyElement.value) + 289 : : ); + 290 : 80 : TransferRequest memory transferRequest = transferRequests[key]; + 291 [ + + ]: 80 : if (partialValue > 0) { + 292 [ + + ]: 14 : if (!isApproved) { + 293 : 2 : revert RuleConditionalTransfer_CannotDeniedPartially(); + 294 : : } + 295 : : // Denied the first request + 296 : 12 : _approveRequest(transferRequest, false); + 297 : : // Create new request + 298 : 12 : _createTransferRequestWithApproval( + 299 : : TransferRequestKeyElement({ + 300 : : from: keyElement.from, + 301 : : to: keyElement.to, + 302 : : value: partialValue + 303 : : }) + 304 : : ); + 305 : : } else { + 306 : 66 : _approveRequest(transferRequest, isApproved); + 307 : : } + 308 : : } + 309 : : + 310 : : function _createTransferRequestWithApproval( + 311 : : TransferRequestKeyElement memory keyElement_ + 312 : : ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { + 313 : : // WAIT => Will overwrite + 314 : : // APPROVED => will overwrite previous status with a new delay + 315 : : // DENIED => will overwrite + 316 : 45 : bytes32 key = keccak256( + 317 : : abi.encode(keyElement_.from, keyElement_.to, keyElement_.value) + 318 : : ); + 319 [ # + ]: 30 : if (_checkRequestStatus(key)) { + 320 : 42 : TransferRequest memory newTransferApproval = TransferRequest({ + 321 : : key: key, + 322 : : id: requestId, + 323 : : keyElement: keyElement_, + 324 : : askTime: 0, + 325 : : maxTime: block.timestamp + + 326 : : options.timeLimit.timeLimitToTransfer, + 327 : : status: STATUS.APPROVED + 328 : : }); + 329 : 28 : transferRequests[key] = newTransferApproval; + 330 : 28 : IdToKey[requestId] = key; + 331 : 28 : emit transferApproved( + 332 : : key, + 333 : : keyElement_.from, + 334 : : keyElement_.to, + 335 : : keyElement_.value, + 336 : : requestId + 337 : : ); + 338 : 28 : ++requestId; + 339 : : } else { + 340 : : // Overwrite previous approval + 341 : 2 : transferRequests[key].maxTime = + 342 : : block.timestamp + + 343 : : options.timeLimit.timeLimitToTransfer; + 344 : 2 : transferRequests[key].status = STATUS.APPROVED; + 345 : 2 : emit transferApproved( + 346 : : key, + 347 : : keyElement_.from, + 348 : : keyElement_.to, + 349 : : keyElement_.value, + 350 : : transferRequests[key].id + 351 : : ); + 352 : : } + 353 : : } + 354 : : + 355 : : function _resetRequestStatus(bytes32 key) internal { + 356 : 20 : transferRequests[key].status = STATUS.NONE; + 357 : 20 : emit transferReset( + 358 : : key, + 359 : : transferRequests[key].keyElement.from, + 360 : : transferRequests[key].keyElement.to, + 361 : : transferRequests[key].keyElement.value, + 362 : : transferRequests[key].id + 363 : : ); + 364 : : } + 365 : : + 366 : : function _checkRequestStatus(bytes32 key) internal view returns (bool) { + 367 : : // Status NONE not enough because reset is possible + 368 : 238 : return + 369 : 238 : (transferRequests[key].status == STATUS.NONE) && + 370 : : (transferRequests[key].key == 0x0); + 371 : : } + 372 : : + 373 : : function _approveRequest( + 374 : : TransferRequest memory transferRequest, + 375 : : bool isApproved + 376 : : ) internal { + 377 : : // status + 378 [ + + ]: 92 : if (transferRequest.status != STATUS.WAIT) { + 379 : 2 : revert RuleConditionalTransfer_Wrong_Status(); + 380 : : } + 381 [ + + ]: 45 : if (isApproved) { + 382 : : // Time + 383 [ + + ]: : if ( + 384 : 54 : block.timestamp > + 385 : : (transferRequest.askTime + options.timeLimit.timeLimitToApprove) + 386 : : ) { + 387 : 6 : revert RuleConditionalTransfer_timeExceeded(); + 388 : : } + 389 : : // Set status + 390 : 48 : transferRequests[transferRequest.key].status = STATUS.APPROVED; + 391 : : // Set max time + 392 : 48 : transferRequests[transferRequest.key].maxTime = + 393 : : block.timestamp + + 394 : : options.timeLimit.timeLimitToTransfer; + 395 : 48 : emit transferApproved( + 396 : : transferRequest.key, + 397 : : transferRequest.keyElement.from, + 398 : : transferRequest.keyElement.to, + 399 : : transferRequest.keyElement.value, + 400 : : transferRequests[transferRequest.key].id + 401 : : ); + 402 [ + + ]: : if ( + 403 : 48 : options.automaticTransfer.isActivate && + 404 : 8 : address(options.automaticTransfer.cmtat) != address(0) + 405 : : ) { + 406 : : // Transfer with approval + 407 : : // External call + 408 [ + + ]: : if ( + 409 : 6 : options.automaticTransfer.cmtat.allowance( + 410 : : transferRequest.keyElement.from, + 411 : : address(this) + 412 : : ) >= transferRequest.keyElement.value + 413 : : ) { + 414 : : // Will call the ruleEngine and the rule again... + 415 : 4 : options.automaticTransfer.cmtat.safeTransferFrom( + 416 : : transferRequest.keyElement.from, + 417 : : transferRequest.keyElement.to, + 418 : : transferRequest.keyElement.value + 419 : : ); + 420 : : } + 421 : : } + 422 : : } else { + 423 : 36 : transferRequests[transferRequest.key].status = STATUS.DENIED; + 424 : 36 : emit transferDenied( + 425 : : transferRequest.key, + 426 : : transferRequest.keyElement.from, + 427 : : transferRequest.keyElement.to, + 428 : : transferRequest.keyElement.value, + 429 : : transferRequests[transferRequest.key].id + 430 : : ); + 431 : : } + 432 : : } + 433 : : + 434 : : /** + 435 : : * @notice update the request during a transfer + 436 : : */ + 437 : : function _updateProcessedTransfer(bytes32 key) internal { + 438 : : // Reset to zero + 439 : 20 : transferRequests[key].maxTime = 0; + 440 : 20 : transferRequests[key].askTime = 0; + 441 : : // Change status + 442 : 20 : transferRequests[key].status = STATUS.EXECUTED; + 443 : : // Emit event + 444 : 20 : emit transferProcessed( + 445 : : key, + 446 : : transferRequests[key].keyElement.from, + 447 : : transferRequests[key].keyElement.to, + 448 : : transferRequests[key].keyElement.value, + 449 : : transferRequests[key].id + 450 : : ); + 451 : : } + 452 : : } diff --git a/doc/test/coverage/src/rules/operation/abstract/index-sort-b.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html similarity index 98% rename from doc/test/coverage/src/rules/operation/abstract/index-sort-b.html rename to doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html index 214958e..206fec0 100644 --- a/doc/test/coverage/src/rules/operation/abstract/index-sort-b.html +++ b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-b.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 18 diff --git a/doc/test/coverage/src/rules/operation/abstract/index-sort-f.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html similarity index 98% rename from doc/test/coverage/src/rules/operation/abstract/index-sort-f.html rename to doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html index 4c2ae50..65b64ca 100644 --- a/doc/test/coverage/src/rules/operation/abstract/index-sort-f.html +++ b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 18 diff --git a/doc/test/coverage/src/rules/operation/abstract/index-sort-l.html b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html similarity index 98% rename from doc/test/coverage/src/rules/operation/abstract/index-sort-l.html rename to doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html index 59e6a4a..94b0016 100644 --- a/doc/test/coverage/src/rules/operation/abstract/index-sort-l.html +++ b/doc/coverage/coverage/src/rules/operation/abstract/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 18 diff --git a/doc/test/coverage/src/rules/operation/abstract/index.html b/doc/coverage/coverage/src/rules/operation/abstract/index.html similarity index 98% rename from doc/test/coverage/src/rules/operation/abstract/index.html rename to doc/coverage/coverage/src/rules/operation/abstract/index.html index acb0ad6..c127d25 100644 --- a/doc/test/coverage/src/rules/operation/abstract/index.html +++ b/doc/coverage/coverage/src/rules/operation/abstract/index.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 18 diff --git a/doc/test/coverage/src/rules/operation/index-sort-b.html b/doc/coverage/coverage/src/rules/operation/index-sort-b.html similarity index 98% rename from doc/test/coverage/src/rules/operation/index-sort-b.html rename to doc/coverage/coverage/src/rules/operation/index-sort-b.html index 1e39e73..a923b48 100644 --- a/doc/test/coverage/src/rules/operation/index-sort-b.html +++ b/doc/coverage/coverage/src/rules/operation/index-sort-b.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 diff --git a/doc/test/coverage/src/rules/operation/index-sort-f.html b/doc/coverage/coverage/src/rules/operation/index-sort-f.html similarity index 98% rename from doc/test/coverage/src/rules/operation/index-sort-f.html rename to doc/coverage/coverage/src/rules/operation/index-sort-f.html index 2f811c5..53a284c 100644 --- a/doc/test/coverage/src/rules/operation/index-sort-f.html +++ b/doc/coverage/coverage/src/rules/operation/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 diff --git a/doc/test/coverage/src/rules/operation/index-sort-l.html b/doc/coverage/coverage/src/rules/operation/index-sort-l.html similarity index 98% rename from doc/test/coverage/src/rules/operation/index-sort-l.html rename to doc/coverage/coverage/src/rules/operation/index-sort-l.html index e90b7fc..0e34ee2 100644 --- a/doc/test/coverage/src/rules/operation/index-sort-l.html +++ b/doc/coverage/coverage/src/rules/operation/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 diff --git a/doc/test/coverage/src/rules/operation/index.html b/doc/coverage/coverage/src/rules/operation/index.html similarity index 98% rename from doc/test/coverage/src/rules/operation/index.html rename to doc/coverage/coverage/src/rules/operation/index.html index 37c948b..1d7e5b3 100644 --- a/doc/test/coverage/src/rules/operation/index.html +++ b/doc/coverage/coverage/src/rules/operation/index.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 diff --git a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html similarity index 98% rename from doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html index 8ce4954..df48d9c 100644 --- a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 3 diff --git a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html similarity index 98% rename from doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func.html rename to doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html index 82264b6..38fefc5 100644 --- a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.func.html +++ b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 3 diff --git a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html similarity index 99% rename from doc/test/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html rename to doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html index f28a3c4..c135db7 100644 --- a/doc/test/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/validation/RuleBlacklist.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 3 diff --git a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html similarity index 98% rename from doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html index 4b23bb9..3c40cbb 100644 --- a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 diff --git a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html similarity index 98% rename from doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func.html rename to doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html index e04194a..a73eca9 100644 --- a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.func.html +++ b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 diff --git a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html similarity index 99% rename from doc/test/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html rename to doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html index 668801c..fbc12ca 100644 --- a/doc/test/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/validation/RuleSanctionList.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html similarity index 79% rename from doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html index 1860092..312454d 100644 --- a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func-sort-c.html @@ -31,17 +31,17 @@ lcov.info Lines: - 13 - 13 + 5 + 5 100.0 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 3 - 3 + 1 + 1 100.0 % @@ -49,8 +49,8 @@ Branches: - 8 - 8 + 4 + 4 100.0 % @@ -69,15 +69,7 @@ Hit count Sort by hit count - RuleWhitelist.messageForTransferRestriction - 7 - - - RuleWhitelist.canReturnTransferRestrictionCode - 8 - - - RuleWhitelist.detectTransferRestriction + RuleWhitelist.detectTransferRestriction 28 diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html similarity index 79% rename from doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func.html rename to doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html index 4cd41b0..5f20449 100644 --- a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.func.html +++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.func.html @@ -31,17 +31,17 @@ lcov.info Lines: - 13 - 13 + 5 + 5 100.0 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 3 - 3 + 1 + 1 100.0 % @@ -49,8 +49,8 @@ Branches: - 8 - 8 + 4 + 4 100.0 % @@ -69,17 +69,9 @@ Hit count Sort by hit count - RuleWhitelist.canReturnTransferRestrictionCode - 8 - - - RuleWhitelist.detectTransferRestriction + RuleWhitelist.detectTransferRestriction 28 - - RuleWhitelist.messageForTransferRestriction - 7 -
diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html similarity index 56% rename from doc/test/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html rename to doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html index b99bd74..0812899 100644 --- a/doc/test/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelist.sol.gcov.html @@ -31,17 +31,17 @@ lcov.info Lines: - 13 - 13 + 5 + 5 100.0 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 3 - 3 + 1 + 1 100.0 % @@ -49,8 +49,8 @@ Branches: - 8 - 8 + 4 + 4 100.0 % @@ -73,78 +73,43 @@ 2 : : 3 : : pragma solidity ^0.8.20; 4 : : - 5 : : import "./abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol"; - 6 : : import "./abstract/RuleAddressList/RuleAddressList.sol"; - 7 : : import "./abstract/RuleValidateTransfer.sol"; - 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 : : } + 5 : : import "./abstract/RuleAddressList/RuleAddressList.sol"; + 6 : : import "./abstract/RuleWhitelistCommon.sol"; + 7 : : /** + 8 : : * @title a whitelist manager + 9 : : */ + 10 : : + 11 : : contract RuleWhitelist is RuleAddressList, RuleWhitelistCommon + 12 : : { + 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 : : * @notice Check if an addres is in the whitelist or not + 24 : : * @param _from the origin address + 25 : : * @param _to the destination address + 26 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK + 27 : : **/ + 28 : : function detectTransferRestriction( + 29 : : address _from, + 30 : : address _to, + 31 : : uint256 /*_amount */ + 32 : : ) public view override returns (uint8) { + 33 [ + + ]: 56 : if (!addressIsListed(_from)) { + 34 : 26 : return CODE_ADDRESS_FROM_NOT_WHITELISTED; + 35 [ + + ]: 30 : } else if (!addressIsListed(_to)) { + 36 : 10 : return CODE_ADDRESS_TO_NOT_WHITELISTED; + 37 : : } else { + 38 : 30 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK); + 39 : : } + 40 : : } + 41 : : } diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html similarity index 75% rename from doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html index b52bb36..31f73cd 100644 --- a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func-sort-c.html @@ -31,27 +31,27 @@ lcov.info Lines: - 26 - 28 - 92.9 % + 21 + 22 + 95.5 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 5 - 6 - 83.3 % + 3 + 4 + 75.0 % Branches: - 9 - 12 - 75.0 % + 8 + 10 + 80.0 % @@ -69,27 +69,19 @@ Hit count Sort by hit count - RuleWhitelistWrapper._msgData + RuleWhitelistWrapper._msgData 0 - RuleWhitelistWrapper.messageForTransferRestriction - 3 - - - RuleWhitelistWrapper.canReturnTransferRestrictionCode - 4 - - - RuleWhitelistWrapper.detectTransferRestriction + RuleWhitelistWrapper.detectTransferRestriction 11 - RuleWhitelistWrapper._contextSuffixLength + RuleWhitelistWrapper._contextSuffixLength 36 - RuleWhitelistWrapper._msgSender + RuleWhitelistWrapper._msgSender 36 diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html similarity index 75% rename from doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html rename to doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html index 72bf006..be2415d 100644 --- a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html +++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.func.html @@ -31,27 +31,27 @@ lcov.info Lines: - 26 - 28 - 92.9 % + 21 + 22 + 95.5 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 5 - 6 - 83.3 % + 3 + 4 + 75.0 % Branches: - 9 - 12 - 75.0 % + 8 + 10 + 80.0 % @@ -69,29 +69,21 @@ Hit count Sort by hit count - RuleWhitelistWrapper._contextSuffixLength + RuleWhitelistWrapper._contextSuffixLength 36 - RuleWhitelistWrapper._msgData + RuleWhitelistWrapper._msgData 0 - RuleWhitelistWrapper._msgSender + RuleWhitelistWrapper._msgSender 36 - RuleWhitelistWrapper.canReturnTransferRestrictionCode - 4 - - - RuleWhitelistWrapper.detectTransferRestriction + RuleWhitelistWrapper.detectTransferRestriction 11 - - RuleWhitelistWrapper.messageForTransferRestriction - 3 -
diff --git a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html similarity index 67% rename from doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html rename to doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html index e33534c..965cfca 100644 --- a/doc/test/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/validation/RuleWhitelistWrapper.sol.gcov.html @@ -31,27 +31,27 @@ lcov.info Lines: - 26 - 28 - 92.9 % + 21 + 22 + 95.5 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 5 - 6 - 83.3 % + 3 + 4 + 75.0 % Branches: - 9 - 12 - 75.0 % + 8 + 10 + 80.0 % @@ -76,140 +76,111 @@ 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; + 8 : : import "./abstract/RuleAddressList/RuleAddressList.sol"; + 9 : : import "./abstract/RuleWhitelistCommon.sol"; + 10 : : + 11 : : /** + 12 : : * @title Wrapper to call several different whitelist rules + 13 : : */ + 14 : : contract RuleWhitelistWrapper is + 15 : : RuleEngineValidationCommon, + 16 : : MetaTxModuleStandalone, + 17 : : RuleWhitelistCommon + 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 RuleEngine_AdminWithAddressZeroNotAllowed(); + 29 : : } + 30 : : _grantRole(DEFAULT_ADMIN_ROLE, admin); + 31 : : _grantRole(RULE_ENGINE_OPERATOR_ROLE, admin); + 32 : : } + 33 : : + 34 : : /** + 35 : : * @notice Go through all the whitelist rules to know if a restriction exists on the transfer + 36 : : * @param _from the origin address + 37 : : * @param _to the destination address + 38 : : * @return The restricion code or REJECTED_CODE_BASE.TRANSFER_OK + 39 : : **/ + 40 : : function detectTransferRestriction( + 41 : : address _from, + 42 : : address _to, + 43 : : uint256 /*_amount*/ + 44 : : ) public view override returns (uint8) { + 45 : 33 : address[] memory targetAddress = new address[](2); + 46 : 33 : bool[] memory isListed = new bool[](2); + 47 : 33 : bool[] memory result = new bool[](2); + 48 : 22 : targetAddress[0] = _from; + 49 : 22 : targetAddress[1] = _to; + 50 : 22 : uint256 rulesLength = _rulesValidation.length; + 51 : : // For each whitelist rule, we ask if from or to are in the whitelist + 52 : 73 : for (uint256 i = 0; i < rulesLength; ++i) { + 53 : : // External call + 54 : 50 : isListed = RuleAddressList(_rulesValidation[i]) + 55 : : .addressIsListedBatch(targetAddress); + 56 [ # + ]: 57 : if (isListed[0] && !result[0]) { + 57 : : // Update if from is in the list + 58 : 14 : result[0] = true; + 59 : : } + 60 [ # + ]: 57 : if (isListed[1] && !result[1]) { + 61 : : // Update if to is in the list + 62 : 14 : result[1] = true; + 63 : : } + 64 [ + + ]: 50 : if(result[0] && result[1]){ + 65 : 50 : break; + 66 : : } + 67 : : } + 68 [ + + ]: 22 : if (!result[0]) { + 69 : 8 : return CODE_ADDRESS_FROM_NOT_WHITELISTED; + 70 [ + + ]: 14 : } else if (!result[1]) { + 71 : 4 : return CODE_ADDRESS_TO_NOT_WHITELISTED; + 72 : : } else { + 73 : 15 : return uint8(REJECTED_CODE_BASE.TRANSFER_OK); + 74 : : } + 75 : : } + 76 : : + 77 : : /** + 78 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 79 : : */ + 80 : : function _msgSender() + 81 : : internal + 82 : : view + 83 : : override(ERC2771Context, Context) + 84 : : returns (address sender) + 85 : : { + 86 : 108 : return ERC2771Context._msgSender(); 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 : : } + 90 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 91 : : */ + 92 : : function _msgData() + 93 : : internal + 94 : : view + 95 : : override(ERC2771Context, Context) + 96 : : returns (bytes calldata) + 97 : : { + 98 : 0 : return ERC2771Context._msgData(); + 99 : : } + 100 : : + 101 : : /** + 102 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 103 : : */ + 104 : : function _contextSuffixLength() + 105 : : internal + 106 : : view + 107 : : override(ERC2771Context, Context) + 108 : : returns (uint256) + 109 : : { + 110 : 108 : return ERC2771Context._contextSuffixLength(); + 111 : : } + 112 : : } diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html similarity index 87% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html index 4d71919..a1cc6c6 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 9 @@ -69,43 +69,43 @@ Hit count Sort by hit count - RuleAddressList._msgData + RuleAddressList._msgData 0 - RuleAddressList.removeAddressFromTheList + RuleAddressList.removeAddressFromTheList 3 - RuleAddressList.removeAddressesFromTheList + RuleAddressList.removeAddressesFromTheList 4 - RuleAddressList.addAddressesToTheList + RuleAddressList.addAddressesToTheList 17 - RuleAddressList.numberListedAddress + RuleAddressList.numberListedAddress 24 - RuleAddressList.addressIsListedBatch - 36 + RuleAddressList.addressIsListedBatch + 28 - RuleAddressList.addAddressToTheList + RuleAddressList.addAddressToTheList 52 - RuleAddressList._contextSuffixLength + RuleAddressList._contextSuffixLength 86 - RuleAddressList._msgSender + RuleAddressList._msgSender 86 - RuleAddressList.addressIsListed + RuleAddressList.addressIsListed 86 diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html similarity index 87% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html index dda2ef2..80f4a95 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 9 @@ -69,43 +69,43 @@ Hit count Sort by hit count - RuleAddressList._contextSuffixLength + RuleAddressList._contextSuffixLength 86 - RuleAddressList._msgData + RuleAddressList._msgData 0 - RuleAddressList._msgSender + RuleAddressList._msgSender 86 - RuleAddressList.addAddressToTheList + RuleAddressList.addAddressToTheList 52 - RuleAddressList.addAddressesToTheList + RuleAddressList.addAddressesToTheList 17 - RuleAddressList.addressIsListed + RuleAddressList.addressIsListed 86 - RuleAddressList.addressIsListedBatch - 36 + RuleAddressList.addressIsListedBatch + 28 - 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/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html similarity index 93% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html index 3e44820..86424d8 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 9 @@ -103,126 +103,131 @@ 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 : : } + 35 : : _grantRole(ADDRESS_LIST_ADD_ROLE, admin); + 36 : : _grantRole(ADDRESS_LIST_REMOVE_ROLE, admin); + 37 : : } + 38 : : + 39 : : /** + 40 : : * @notice Add addresses to the whitelist + 41 : : * If one of addresses already exist, there is no change for this address. The transaction remains valid (no revert). + 42 : : * @param listWhitelistedAddress an array with the addresses to whitelist + 43 : : */ + 44 : : function addAddressesToTheList( + 45 : : address[] calldata listWhitelistedAddress + 46 : : ) public onlyRole(ADDRESS_LIST_ADD_ROLE) { + 47 : 32 : _addAddressesToThelist(listWhitelistedAddress); + 48 : : } + 49 : : + 50 : : /** + 51 : : * @notice Remove addresses from the whitelist + 52 : : * If the address does not exist in the whitelist, there is no change for this address. + 53 : : * The transaction remains valid (no revert). + 54 : : * @param listWhitelistedAddress an array with the addresses to remove + 55 : : */ + 56 : : function removeAddressesFromTheList( + 57 : : address[] calldata listWhitelistedAddress + 58 : : ) public onlyRole(ADDRESS_LIST_REMOVE_ROLE) { + 59 : 6 : _removeAddressesFromThelist(listWhitelistedAddress); + 60 : : } + 61 : : + 62 : : /** + 63 : : * @notice Add one address to the whitelist + 64 : : * If the address already exists, the transaction is reverted to save gas. + 65 : : * @param _newWhitelistAddress The address to whitelist + 66 : : */ + 67 : : function addAddressToTheList( + 68 : : address _newWhitelistAddress + 69 : : ) public onlyRole(ADDRESS_LIST_ADD_ROLE) { + 70 : 102 : _addAddressToThelist(_newWhitelistAddress); + 71 : : } + 72 : : + 73 : : /** + 74 : : * @notice Remove one address from the whitelist + 75 : : * If the address does not exist in the whitelist, the transaction is reverted to save gas. + 76 : : * @param _removeWhitelistAddress The address to remove + 77 : : * + 78 : : */ + 79 : : function removeAddressFromTheList( + 80 : : address _removeWhitelistAddress + 81 : : ) public onlyRole(ADDRESS_LIST_REMOVE_ROLE) { + 82 : 4 : _removeAddressFromThelist(_removeWhitelistAddress); + 83 : : } + 84 : : + 85 : : /** + 86 : : * @notice Get the number of listed addresses + 87 : : * @return Number of listed addresses + 88 : : * + 89 : : */ + 90 : : function numberListedAddress() public view returns (uint256) { + 91 : 72 : return _numberListedAddress(); + 92 : : } + 93 : : + 94 : : /** + 95 : : * @notice Know if an address is listed or not + 96 : : * @param _targetAddress The concerned address + 97 : : * @return True if the address is listed, false otherwise + 98 : : * + 99 : : */ + 100 : : function addressIsListed( + 101 : : address _targetAddress + 102 : : ) public view returns (bool) { + 103 : 432 : return _addressIsListed(_targetAddress); + 104 : : } + 105 : : + 106 : : /** + 107 : : * @notice batch version of {addressIsListed} + 108 : : * + 109 : : */ + 110 : : function addressIsListedBatch( + 111 : : address[] memory _targetAddresses + 112 : : ) public view returns (bool[] memory) { + 113 : 84 : bool[] memory isListed = new bool[](_targetAddresses.length); + 114 : 194 : for (uint256 i = 0; i < _targetAddresses.length; ++i) { + 115 : 110 : isListed[i] = _addressIsListed(_targetAddresses[i]); + 116 : : } + 117 : 56 : return isListed; + 118 : : } + 119 : : + 120 : : /*////////////////////////////////////////////////////////////// + 121 : : ERC-2771 + 122 : : //////////////////////////////////////////////////////////////*/ + 123 : : + 124 : : /** + 125 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 126 : : */ + 127 : : function _msgSender() + 128 : : internal + 129 : : view + 130 : : override(ERC2771Context, Context) + 131 : : returns (address sender) + 132 : : { + 133 : 258 : return ERC2771Context._msgSender(); + 134 : : } + 135 : : + 136 : : /** + 137 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 138 : : */ + 139 : : function _msgData() + 140 : : internal + 141 : : view + 142 : : override(ERC2771Context, Context) + 143 : : returns (bytes calldata) + 144 : : { + 145 : 0 : return ERC2771Context._msgData(); + 146 : : } + 147 : : + 148 : : /** + 149 : : * @dev This surcharge is not necessary if you do not use the MetaTxModule + 150 : : */ + 151 : : function _contextSuffixLength() + 152 : : internal + 153 : : view + 154 : : override(ERC2771Context, Context) + 155 : : returns (uint256) + 156 : : { + 157 : 258 : return ERC2771Context._contextSuffixLength(); + 158 : : } + 159 : : } diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html similarity index 97% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html index 034d5b0..9b51dc1 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 @@ -90,7 +90,7 @@ RuleAddressListInternal._addressIsListed - 215 + 199
diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html similarity index 97% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html index 3a52fd0..dd99735 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 @@ -78,7 +78,7 @@ RuleAddressListInternal._addressIsListed - 215 + 199 RuleAddressListInternal._numberListedAddress diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html similarity index 99% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html index b102a31..e817af0 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 6 @@ -165,7 +165,7 @@ 94 : : function _addressIsListed( 95 : : address _targetAddress 96 : : ) internal view returns (bool) { - 97 : 430 : return list[_targetAddress]; + 97 : 398 : return list[_targetAddress]; 98 : : } 99 : : } diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html similarity index 98% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html index 71a79b8..8e97c35 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-b.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html similarity index 98% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html index c73796f..62210c7 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html similarity index 98% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html index 7344e95..d62aa4c 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html similarity index 98% rename from doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html index 8b576c0..8a35305 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleAddressList/index.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleAddressList/index.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 15 diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html similarity index 98% rename from doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html index de6e037..599c4e6 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 1 diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html similarity index 98% rename from doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html index df568ad..f2ed4bd 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 1 diff --git a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html similarity index 99% rename from doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html rename to doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html index 89b228f..9bdbb69 100644 --- a/doc/test/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleValidateTransfer.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 1 diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html new file mode 100644 index 0000000..a3f1152 --- /dev/null +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + LCOV - lcov.info - src/rules/validation/abstract/RuleWhitelistCommon.sol - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src/rules/validation/abstract - RuleWhitelistCommon.sol (source / functions)HitTotalCoverage
Test:lcov.infoLines:88100.0 %
Date:2024-09-09 16:58:34Functions:22100.0 %
Branches:44100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
RuleWhitelistCommon.messageForTransferRestriction10
RuleWhitelistCommon.canReturnTransferRestrictionCode12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html new file mode 100644 index 0000000..d07b0b2 --- /dev/null +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.func.html @@ -0,0 +1,89 @@ + + + + + + + LCOV - lcov.info - src/rules/validation/abstract/RuleWhitelistCommon.sol - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src/rules/validation/abstract - RuleWhitelistCommon.sol (source / functions)HitTotalCoverage
Test:lcov.infoLines:88100.0 %
Date:2024-09-09 16:58:34Functions:22100.0 %
Branches:44100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
RuleWhitelistCommon.canReturnTransferRestrictionCode12
RuleWhitelistCommon.messageForTransferRestriction10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html new file mode 100644 index 0000000..4bfca76 --- /dev/null +++ b/doc/coverage/coverage/src/rules/validation/abstract/RuleWhitelistCommon.sol.gcov.html @@ -0,0 +1,125 @@ + + + + + + + LCOV - lcov.info - src/rules/validation/abstract/RuleWhitelistCommon.sol + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - src/rules/validation/abstract - RuleWhitelistCommon.sol (source / functions)HitTotalCoverage
Test:lcov.infoLines:88100.0 %
Date:2024-09-09 16:58:34Functions:22100.0 %
Branches:44100.0 %
+
+ + + + + + + + +

+
           Branch data     Line data    Source code
+
+       1                 :            : // SPDX-License-Identifier: MPL-2.0
+       2                 :            : 
+       3                 :            : pragma solidity ^0.8.20;
+       4                 :            : 
+       5                 :            : import "./RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol";
+       6                 :            : import "./RuleValidateTransfer.sol";
+       7                 :            : 
+       8                 :            : abstract contract RuleWhitelistCommon is
+       9                 :            :     RuleValidateTransfer,
+      10                 :            :     RuleWhitelistInvariantStorage {
+      11                 :            :      /**
+      12                 :            :      * @notice To know if the restriction code is valid for this rule or not
+      13                 :            :      * @param _restrictionCode The target restriction code
+      14                 :            :      * @return true if the restriction code is known, false otherwise
+      15                 :            :      **/
+      16                 :            :     function canReturnTransferRestrictionCode(
+      17                 :            :         uint8 _restrictionCode
+      18                 :            :     ) external pure override returns (bool) {
+      19                 :         24 :         return
+      20                 :         36 :             _restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED ||
+      21                 :         12 :             _restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED;
+      22                 :            :     }
+      23                 :            : 
+      24                 :            :     /**
+      25                 :            :      * @notice Return the corresponding message
+      26                 :            :      * @param _restrictionCode The target restriction code
+      27                 :            :      * @return true if the transfer is valid, false otherwise
+      28                 :            :      **/
+      29                 :            :     function messageForTransferRestriction(
+      30                 :            :         uint8 _restrictionCode
+      31                 :            :     ) external pure override returns (string memory) {
+      32         [ +  + ]:         20 :         if (_restrictionCode == CODE_ADDRESS_FROM_NOT_WHITELISTED) {
+      33                 :         12 :             return TEXT_ADDRESS_FROM_NOT_WHITELISTED;
+      34         [ +  + ]:          8 :         } else if (_restrictionCode == CODE_ADDRESS_TO_NOT_WHITELISTED) {
+      35                 :          6 :             return TEXT_ADDRESS_TO_NOT_WHITELISTED;
+      36                 :            :         } else {
+      37                 :          2 :             return TEXT_CODE_NOT_FOUND;
+      38                 :            :         }
+      39                 :            :     }
+      40                 :            : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/doc/test/coverage/src/rules/validation/abstract/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html similarity index 81% rename from doc/test/coverage/src/rules/validation/abstract/index-sort-b.html rename to doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html index 85c73c5..84222f3 100644 --- a/doc/test/coverage/src/rules/validation/abstract/index-sort-b.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-b.html @@ -31,17 +31,17 @@ lcov.info Lines: - 3 - 3 + 11 + 11 100.0 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 1 - 1 + 3 + 3 100.0 % @@ -49,9 +49,9 @@ Branches: - 0 - 0 - - + 4 + 4 + 100.0 % @@ -93,6 +93,18 @@ - 0 / 0 + + RuleWhitelistCommon.sol + +
100.0%
+ + 100.0 % + 8 / 8 + 100.0 % + 2 / 2 + 100.0 % + 4 / 4 +
diff --git a/doc/test/coverage/src/rules/validation/abstract/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html similarity index 81% rename from doc/test/coverage/src/rules/validation/abstract/index-sort-f.html rename to doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html index 11ccdbb..ae3ecc0 100644 --- a/doc/test/coverage/src/rules/validation/abstract/index-sort-f.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-f.html @@ -31,17 +31,17 @@ lcov.info Lines: - 3 - 3 + 11 + 11 100.0 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 1 - 1 + 3 + 3 100.0 % @@ -49,9 +49,9 @@ Branches: - 0 - 0 - - + 4 + 4 + 100.0 % @@ -93,6 +93,18 @@ - 0 / 0 + + RuleWhitelistCommon.sol + +
100.0%
+ + 100.0 % + 8 / 8 + 100.0 % + 2 / 2 + 100.0 % + 4 / 4 +
diff --git a/doc/test/coverage/src/rules/validation/abstract/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html similarity index 81% rename from doc/test/coverage/src/rules/validation/abstract/index-sort-l.html rename to doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html index a2371ee..a3e7add 100644 --- a/doc/test/coverage/src/rules/validation/abstract/index-sort-l.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/index-sort-l.html @@ -31,17 +31,17 @@ lcov.info Lines: - 3 - 3 + 11 + 11 100.0 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 1 - 1 + 3 + 3 100.0 % @@ -49,9 +49,9 @@ Branches: - 0 - 0 - - + 4 + 4 + 100.0 % @@ -93,6 +93,18 @@ - 0 / 0 + + RuleWhitelistCommon.sol + +
100.0%
+ + 100.0 % + 8 / 8 + 100.0 % + 2 / 2 + 100.0 % + 4 / 4 +
diff --git a/doc/test/coverage/src/rules/validation/abstract/index.html b/doc/coverage/coverage/src/rules/validation/abstract/index.html similarity index 81% rename from doc/test/coverage/src/rules/validation/abstract/index.html rename to doc/coverage/coverage/src/rules/validation/abstract/index.html index f79bdac..637735f 100644 --- a/doc/test/coverage/src/rules/validation/abstract/index.html +++ b/doc/coverage/coverage/src/rules/validation/abstract/index.html @@ -31,17 +31,17 @@ lcov.info Lines: - 3 - 3 + 11 + 11 100.0 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 1 - 1 + 3 + 3 100.0 % @@ -49,9 +49,9 @@ Branches: - 0 - 0 - - + 4 + 4 + 100.0 % @@ -93,6 +93,18 @@ - 0 / 0 + + RuleWhitelistCommon.sol + +
100.0%
+ + 100.0 % + 8 / 8 + 100.0 % + 2 / 2 + 100.0 % + 4 / 4 +
diff --git a/doc/test/coverage/src/rules/validation/index-sort-b.html b/doc/coverage/coverage/src/rules/validation/index-sort-b.html similarity index 83% rename from doc/test/coverage/src/rules/validation/index-sort-b.html rename to doc/coverage/coverage/src/rules/validation/index-sort-b.html index 0a4a8dd..33fbefd 100644 --- a/doc/test/coverage/src/rules/validation/index-sort-b.html +++ b/doc/coverage/coverage/src/rules/validation/index-sort-b.html @@ -31,27 +31,27 @@ lcov.info Lines: - 69 - 72 - 95.8 % + 56 + 58 + 96.6 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 17 - 19 - 89.5 % + 13 + 15 + 86.7 % Branches: - 35 - 38 - 92.1 % + 30 + 32 + 93.8 % @@ -84,29 +84,29 @@ RuleWhitelistWrapper.sol -
92.9%92.9%
+
95.5%95.5%
- 92.9 % - 26 / 28 - 83.3 % - 5 / 6 + 95.5 % + 21 / 22 75.0 % - 9 / 12 + 3 / 4 + 80.0 % + 8 / 10 - RuleBlacklist.sol + RuleWhitelist.sol
100.0%
100.0 % - 13 / 13 + 5 / 5 100.0 % - 3 / 3 + 1 / 1 100.0 % - 8 / 8 + 4 / 4 - RuleWhitelist.sol + RuleBlacklist.sol
100.0%
diff --git a/doc/test/coverage/src/rules/validation/index-sort-f.html b/doc/coverage/coverage/src/rules/validation/index-sort-f.html similarity index 83% rename from doc/test/coverage/src/rules/validation/index-sort-f.html rename to doc/coverage/coverage/src/rules/validation/index-sort-f.html index 086d6a1..80ea1dc 100644 --- a/doc/test/coverage/src/rules/validation/index-sort-f.html +++ b/doc/coverage/coverage/src/rules/validation/index-sort-f.html @@ -31,27 +31,27 @@ lcov.info Lines: - 69 - 72 - 95.8 % + 56 + 58 + 96.6 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 17 - 19 - 89.5 % + 13 + 15 + 86.7 % Branches: - 35 - 38 - 92.1 % + 30 + 32 + 93.8 % @@ -84,14 +84,14 @@ RuleWhitelistWrapper.sol -
92.9%92.9%
+
95.5%95.5%
- 92.9 % - 26 / 28 - 83.3 % - 5 / 6 + 95.5 % + 21 / 22 75.0 % - 9 / 12 + 3 / 4 + 80.0 % + 8 / 10 RuleSanctionList.sol @@ -106,19 +106,19 @@ 10 / 10 - RuleBlacklist.sol + RuleWhitelist.sol
100.0%
100.0 % - 13 / 13 + 5 / 5 100.0 % - 3 / 3 + 1 / 1 100.0 % - 8 / 8 + 4 / 4 - RuleWhitelist.sol + RuleBlacklist.sol
100.0%
diff --git a/doc/test/coverage/src/rules/validation/index-sort-l.html b/doc/coverage/coverage/src/rules/validation/index-sort-l.html similarity index 83% rename from doc/test/coverage/src/rules/validation/index-sort-l.html rename to doc/coverage/coverage/src/rules/validation/index-sort-l.html index d20fb85..735b5bc 100644 --- a/doc/test/coverage/src/rules/validation/index-sort-l.html +++ b/doc/coverage/coverage/src/rules/validation/index-sort-l.html @@ -31,27 +31,27 @@ lcov.info Lines: - 69 - 72 - 95.8 % + 56 + 58 + 96.6 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 17 - 19 - 89.5 % + 13 + 15 + 86.7 % Branches: - 35 - 38 - 92.1 % + 30 + 32 + 93.8 % @@ -81,18 +81,6 @@ Functions Sort by function coverage Branches Sort by branch coverage - - RuleWhitelistWrapper.sol - -
92.9%92.9%
- - 92.9 % - 26 / 28 - 83.3 % - 5 / 6 - 75.0 % - 9 / 12 - RuleSanctionList.sol @@ -106,19 +94,31 @@ 10 / 10 - RuleBlacklist.sol + RuleWhitelistWrapper.sol + +
95.5%95.5%
+ + 95.5 % + 21 / 22 + 75.0 % + 3 / 4 + 80.0 % + 8 / 10 + + + RuleWhitelist.sol
100.0%
100.0 % - 13 / 13 + 5 / 5 100.0 % - 3 / 3 + 1 / 1 100.0 % - 8 / 8 + 4 / 4 - RuleWhitelist.sol + RuleBlacklist.sol
100.0%
diff --git a/doc/test/coverage/src/rules/validation/index.html b/doc/coverage/coverage/src/rules/validation/index.html similarity index 83% rename from doc/test/coverage/src/rules/validation/index.html rename to doc/coverage/coverage/src/rules/validation/index.html index e0071b7..4ad8227 100644 --- a/doc/test/coverage/src/rules/validation/index.html +++ b/doc/coverage/coverage/src/rules/validation/index.html @@ -31,27 +31,27 @@ lcov.info Lines: - 69 - 72 - 95.8 % + 56 + 58 + 96.6 % Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: - 17 - 19 - 89.5 % + 13 + 15 + 86.7 % Branches: - 35 - 38 - 92.1 % + 30 + 32 + 93.8 % @@ -111,23 +111,23 @@
100.0%
100.0 % - 13 / 13 + 5 / 5 100.0 % - 3 / 3 + 1 / 1 100.0 % - 8 / 8 + 4 / 4 RuleWhitelistWrapper.sol -
92.9%92.9%
+
95.5%95.5%
- 92.9 % - 26 / 28 - 83.3 % - 5 / 6 + 95.5 % + 21 / 22 75.0 % - 9 / 12 + 3 / 4 + 80.0 % + 8 / 10 diff --git a/doc/test/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html similarity index 98% rename from doc/test/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html rename to doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html index 498ac69..6e16d92 100644 --- a/doc/test/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html +++ b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func-sort-c.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/test/utils/SanctionListOracle.sol.func.html b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html similarity index 98% rename from doc/test/coverage/test/utils/SanctionListOracle.sol.func.html rename to doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html index b8d16d5..746376d 100644 --- a/doc/test/coverage/test/utils/SanctionListOracle.sol.func.html +++ b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.func.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/test/utils/SanctionListOracle.sol.gcov.html b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html similarity index 98% rename from doc/test/coverage/test/utils/SanctionListOracle.sol.gcov.html rename to doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html index 2344b67..ca478f9 100644 --- a/doc/test/coverage/test/utils/SanctionListOracle.sol.gcov.html +++ b/doc/coverage/coverage/test/utils/SanctionListOracle.sol.gcov.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/test/utils/index-sort-b.html b/doc/coverage/coverage/test/utils/index-sort-b.html similarity index 98% rename from doc/test/coverage/test/utils/index-sort-b.html rename to doc/coverage/coverage/test/utils/index-sort-b.html index 609b21b..e6a9881 100644 --- a/doc/test/coverage/test/utils/index-sort-b.html +++ b/doc/coverage/coverage/test/utils/index-sort-b.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/test/utils/index-sort-f.html b/doc/coverage/coverage/test/utils/index-sort-f.html similarity index 98% rename from doc/test/coverage/test/utils/index-sort-f.html rename to doc/coverage/coverage/test/utils/index-sort-f.html index 6a9e697..0a0bdb8 100644 --- a/doc/test/coverage/test/utils/index-sort-f.html +++ b/doc/coverage/coverage/test/utils/index-sort-f.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/test/utils/index-sort-l.html b/doc/coverage/coverage/test/utils/index-sort-l.html similarity index 98% rename from doc/test/coverage/test/utils/index-sort-l.html rename to doc/coverage/coverage/test/utils/index-sort-l.html index 788f148..84ae466 100644 --- a/doc/test/coverage/test/utils/index-sort-l.html +++ b/doc/coverage/coverage/test/utils/index-sort-l.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/test/utils/index.html b/doc/coverage/coverage/test/utils/index.html similarity index 98% rename from doc/test/coverage/test/utils/index.html rename to doc/coverage/coverage/test/utils/index.html index bccc378..4352a4b 100644 --- a/doc/test/coverage/test/utils/index.html +++ b/doc/coverage/coverage/test/utils/index.html @@ -37,7 +37,7 @@ Date: - 2024-06-11 10:19:24 + 2024-09-09 16:58:34 Functions: 2 diff --git a/doc/test/coverage/updown.png b/doc/coverage/coverage/updown.png similarity index 100% rename from doc/test/coverage/updown.png rename to doc/coverage/coverage/updown.png diff --git a/doc/test/lcov.info b/doc/coverage/lcov.info similarity index 55% rename from doc/test/lcov.info rename to doc/coverage/lcov.info index ea61b44..9a41ccd 100644 --- a/doc/test/lcov.info +++ b/doc/coverage/lcov.info @@ -172,21 +172,21 @@ DA:139,10 DA:142,41 DA:142,41 DA:142,41 -FN:148,RuleEngine._msgSender +FN:152,RuleEngine._msgSender FNDA:263,RuleEngine._msgSender -DA:154,263 -DA:154,263 -DA:154,263 -FN:160,RuleEngine._msgData +DA:158,263 +DA:158,263 +DA:158,263 +FN:164,RuleEngine._msgData FNDA:0,RuleEngine._msgData -DA:166,0 -DA:166,0 -DA:166,0 -FN:172,RuleEngine._contextSuffixLength +DA:170,0 +DA:170,0 +DA:170,0 +FN:176,RuleEngine._contextSuffixLength FNDA:263,RuleEngine._contextSuffixLength -DA:178,263 -DA:178,263 -DA:178,263 +DA:182,263 +DA:182,263 +DA:182,263 FNF:7 FNH:6 LF:29 @@ -325,69 +325,69 @@ BRH:2 end_of_record TN: SF:src/modules/RuleEngineValidationCommon.sol -FN:27,RuleEngineValidationCommon.setRulesValidation +FN:31,RuleEngineValidationCommon.setRulesValidation FNDA:22,RuleEngineValidationCommon.setRulesValidation -DA:30,21 -DA:30,21 -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 +DA:34,21 +DA:34,21 +BRDA:34,0,0,20 +BRDA:34,0,1,21 +DA:35,20 +DA:35,20 +DA:37,21 +DA:37,21 +DA:38,18 +DA:38,18 +FN:45,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:55,28 -DA:55,28 -DA:57,28 -DA:57,28 -DA:59,25 -DA:59,25 -FN:67,RuleEngineValidationCommon.addRuleValidation +DA:46,5 +DA:46,5 +FN:54,RuleEngineValidationCommon.addRuleValidation FNDA:115,RuleEngineValidationCommon.addRuleValidation -DA:70,114 -DA:70,114 -DA:71,112 -DA:71,112 -FN:84,RuleEngineValidationCommon.removeRuleValidation +DA:57,114 +DA:57,114 +DA:58,112 +DA:58,112 +FN:71,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 +DA:75,5 +DA:75,5 +FN:81,RuleEngineValidationCommon.rulesCountValidation FNDA:69,RuleEngineValidationCommon.rulesCountValidation -DA:110,69 -DA:110,69 -FN:117,RuleEngineValidationCommon.getRuleIndexValidation +DA:82,69 +DA:82,69 +FN:89,RuleEngineValidationCommon.getRuleIndexValidation FNDA:3,RuleEngineValidationCommon.getRuleIndexValidation -DA:120,3 -DA:120,3 -DA:120,3 -FN:128,RuleEngineValidationCommon.ruleValidation +DA:92,3 +DA:92,3 +DA:92,3 +FN:100,RuleEngineValidationCommon.ruleValidation FNDA:1,RuleEngineValidationCommon.ruleValidation -DA:131,1 -DA:131,1 -FN:138,RuleEngineValidationCommon.rulesValidation +DA:103,1 +DA:103,1 +FN:110,RuleEngineValidationCommon.rulesValidation FNDA:5,RuleEngineValidationCommon.rulesValidation -DA:144,5 -DA:144,5 +DA:116,5 +DA:116,5 +FN:126,RuleEngineValidationCommon._clearRulesValidation +FNDA:25,RuleEngineValidationCommon._clearRulesValidation +DA:127,25 +DA:127,25 +DA:129,25 +DA:129,25 +DA:129,53 +DA:129,28 +DA:132,28 +DA:132,28 +DA:134,28 +DA:134,28 +DA:136,25 +DA:136,25 +FN:149,RuleEngineValidationCommon._removeRuleValidation +FNDA:33,RuleEngineValidationCommon._removeRuleValidation +DA:150,33 +DA:150,33 +DA:151,32 +DA:151,32 FNF:10 FNH:10 LF:19 @@ -467,8 +467,8 @@ DA:76,53 DA:76,53 DA:77,53 DA:77,53 -FN:84,RuleInternal.getRuleIndex -FNDA:6,RuleInternal.getRuleIndex +FN:84,RuleInternal._getRuleIndex +FNDA:6,RuleInternal._getRuleIndex DA:88,6 DA:88,6 DA:89,6 @@ -493,289 +493,289 @@ BRH:15 end_of_record TN: SF:src/rules/operation/RuleConditionalTransfer.sol -FN:55,RuleConditionalTransfer.createTransferRequest +FN:58,RuleConditionalTransfer.operateOnTransfer +FNDA:33,RuleConditionalTransfer.operateOnTransfer +DA:69,33 +DA:69,33 +DA:69,33 +DA:69,33 +BRDA:69,0,0,2 +BRDA:69,0,1,16 +DA:71,18 +DA:71,18 +DA:71,18 +DA:72,3 +DA:72,3 +BRDA:70,1,0,2 +BRDA:70,1,1,16 +DA:74,2 +DA:74,2 +DA:79,31 +DA:79,31 +BRDA:79,2,0,4 +BRDA:79,2,1,27 +DA:80,4 +DA:80,4 +DA:82,27 +DA:82,27 +DA:82,27 +DA:83,27 +DA:83,27 +BRDA:83,3,0,10 +BRDA:83,3,1,17 +DA:84,10 +DA:84,10 +DA:85,10 +DA:85,10 +DA:87,17 +DA:87,17 +FN:96,RuleConditionalTransfer.createTransferRequest FNDA:102,RuleConditionalTransfer.createTransferRequest -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:78,101 -DA:78,101 -DA:79,101 -DA:79,101 -DA:82,3 -DA:82,3 -DA:83,3 -DA:83,3 -DA:84,3 -DA:84,3 -FN:97,RuleConditionalTransfer.createTransferRequestBatch +DA:100,105 +DA:100,105 +DA:100,105 +DA:101,105 +DA:101,105 +DA:101,105 +DA:102,105 +DA:102,105 +BRDA:102,4,0,1 +BRDA:102,4,1,104 +DA:103,1 +DA:103,1 +DA:105,104 +DA:105,104 +BRDA:105,5,0,- +BRDA:105,5,1,101 +DA:106,101 +DA:106,101 +DA:107,101 +DA:107,101 +DA:107,101 +DA:119,101 +DA:119,101 +DA:120,101 +DA:120,101 +DA:121,101 +DA:121,101 +DA:122,101 +DA:122,101 +DA:125,3 +DA:125,3 +DA:126,3 +DA:126,3 +DA:127,3 +DA:127,3 +FN:140,RuleConditionalTransfer.createTransferRequestBatch FNDA:3,RuleConditionalTransfer.createTransferRequestBatch -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 +DA:144,3 +DA:144,3 +BRDA:144,6,0,1 +BRDA:144,6,1,2 +DA:145,1 +DA:145,1 +DA:147,2 +DA:147,2 +BRDA:147,7,0,1 +BRDA:147,7,1,1 +DA:148,1 +DA:148,1 +DA:150,1 +DA:150,1 +DA:150,4 +DA:150,3 +DA:151,3 +DA:151,3 +FN:158,RuleConditionalTransfer.cancelTransferRequest FNDA:6,RuleConditionalTransfer.cancelTransferRequest -DA:116,6 -DA:116,6 -FN:122,RuleConditionalTransfer.cancelTransferRequestBatch +DA:159,6 +DA:159,6 +FN:165,RuleConditionalTransfer.cancelTransferRequestBatch FNDA:3,RuleConditionalTransfer.cancelTransferRequestBatch -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: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 +DA:166,3 +DA:166,3 +BRDA:166,8,0,1 +BRDA:166,8,1,2 +DA:167,1 +DA:167,1 +DA:170,2 +DA:170,2 +DA:170,6 +DA:170,4 +DA:171,5 +DA:171,5 +DA:171,5 +BRDA:171,9,0,1 +BRDA:171,9,1,4 +DA:172,1 +DA:172,1 +DA:175,1 +DA:175,1 +DA:175,4 +DA:175,3 +DA:176,3 +DA:176,3 +FN:180,RuleConditionalTransfer.getRequestTrade FNDA:57,RuleConditionalTransfer.getRequestTrade -DA:161,57 -DA:161,57 -DA:161,57 -DA:162,57 -DA:162,57 -FN:170,RuleConditionalTransfer.getRequestByStatus +DA:185,57 +DA:185,57 +DA:185,57 +DA:186,57 +DA:186,57 +FN:194,RuleConditionalTransfer.getRequestByStatus FNDA:35,RuleConditionalTransfer.getRequestByStatus -DA:173,35 -DA:173,35 -DA:174,35 -DA:174,35 -DA:175,35 -DA:175,35 -DA:178,35 -DA:178,35 -DA:178,73 -DA:178,38 -DA:179,38 -DA:179,38 -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:197,35 +DA:197,35 DA:198,35 DA:198,35 -FN:205,RuleConditionalTransfer.operateOnTransfer -FNDA:33,RuleConditionalTransfer.operateOnTransfer -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 +DA:199,35 +DA:199,35 +DA:202,35 +DA:202,35 +DA:202,73 +DA:202,38 +DA:203,38 +DA:203,38 +BRDA:203,10,0,36 +BRDA:203,10,1,38 +DA:204,36 +DA:204,36 +DA:209,35 +DA:209,35 +DA:209,35 +DA:212,35 +DA:212,35 +DA:212,73 +DA:212,38 +DA:213,38 +DA:213,38 +BRDA:213,11,0,- +BRDA:213,11,1,36 +DA:215,36 +DA:215,36 +DA:218,36 +DA:218,36 +DA:219,36 +DA:219,36 +DA:222,35 +DA:222,35 +FN:231,RuleConditionalTransfer.detectTransferRestriction FNDA:11,RuleConditionalTransfer.detectTransferRestriction -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 -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 +DA:237,11 +DA:237,11 +DA:237,11 +DA:237,11 +BRDA:237,12,0,- +BRDA:237,12,1,1 +DA:239,3 +DA:239,3 +DA:239,3 +DA:240,2 +DA:240,2 +BRDA:238,13,0,- +BRDA:238,13,1,1 +DA:242,1 +DA:242,1 +DA:242,1 +DA:245,10 +DA:245,10 +DA:245,10 +DA:246,10 +DA:246,10 +DA:246,10 +DA:246,10 +BRDA:246,14,0,8 +BRDA:246,14,1,2 +DA:247,8 +DA:247,8 +DA:249,2 +DA:249,2 +DA:249,2 +FN:258,RuleConditionalTransfer.canReturnTransferRestrictionCode FNDA:2,RuleConditionalTransfer.canReturnTransferRestrictionCode -DA:274,2 -DA:274,2 -DA:274,2 -FN:282,RuleConditionalTransfer.messageForTransferRestriction +DA:261,2 +DA:261,2 +DA:261,2 +FN:269,RuleConditionalTransfer.messageForTransferRestriction FNDA:3,RuleConditionalTransfer.messageForTransferRestriction -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 +DA:272,3 +DA:272,3 +BRDA:272,15,0,2 +BRDA:272,15,1,1 +DA:273,2 +DA:273,2 +DA:275,1 +DA:275,1 +FN:284,RuleConditionalTransfer._cancelTransferRequest +FNDA:9,RuleConditionalTransfer._cancelTransferRequest +DA:285,9 +DA:285,9 +DA:285,9 +BRDA:285,16,0,1 +BRDA:285,16,1,8 +DA:286,1 +DA:286,1 +DA:288,8 +DA:288,8 +DA:290,8 +DA:290,8 +DA:290,8 +BRDA:290,17,0,1 +BRDA:290,17,1,7 +DA:291,1 +DA:291,1 +DA:295,7 +DA:295,7 +DA:295,7 +DA:296,2 +DA:296,2 +BRDA:294,18,0,1 +BRDA:294,18,1,6 +DA:298,1 +DA:298,1 +DA:300,6 +DA:300,6 +FN:310,RuleConditionalTransfer._validateBurnMint FNDA:41,RuleConditionalTransfer._validateBurnMint -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 +DA:316,41 +DA:316,41 +BRDA:315,19,0,4 +BRDA:315,19,1,37 +DA:321,4 +DA:321,4 +DA:323,37 +DA:323,37 +FN:332,RuleConditionalTransfer._validateApproval FNDA:37,RuleConditionalTransfer._validateApproval -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 +DA:336,37 +DA:336,37 +DA:336,37 +DA:343,37 +DA:343,37 +DA:343,37 +DA:346,37 +DA:346,37 +BRDA:346,20,0,12 +BRDA:346,20,1,25 +DA:347,12 +DA:347,12 +DA:349,25 +DA:349,25 +FN:360,RuleConditionalTransfer._msgSender FNDA:452,RuleConditionalTransfer._msgSender -DA:349,452 -DA:349,452 -DA:349,452 -FN:355,RuleConditionalTransfer._msgData +DA:366,452 +DA:366,452 +DA:366,452 +FN:372,RuleConditionalTransfer._msgData FNDA:0,RuleConditionalTransfer._msgData -DA:361,0 -DA:361,0 -DA:361,0 -FN:367,RuleConditionalTransfer._contextSuffixLength +DA:378,0 +DA:378,0 +DA:378,0 +FN:384,RuleConditionalTransfer._contextSuffixLength FNDA:452,RuleConditionalTransfer._contextSuffixLength -DA:373,452 -DA:373,452 -DA:373,452 +DA:390,452 +DA:390,452 +DA:390,452 FNF:16 FNH:15 LF:86 @@ -785,318 +785,318 @@ BRH:38 end_of_record TN: SF:src/rules/operation/abstract/RuleConditionalTransferOperator.sol -FN:29,RuleConditionalTransferOperator.setConditionalWhitelist +FN:32,RuleConditionalTransferOperator.setConditionalWhitelist FNDA:25,RuleConditionalTransferOperator.setConditionalWhitelist -DA:32,25 -DA:32,25 -DA:33,25 -DA:33,25 -FN:39,RuleConditionalTransferOperator.setIssuanceOptions +DA:35,25 +DA:35,25 +DA:36,25 +DA:36,25 +FN:42,RuleConditionalTransferOperator.setIssuanceOptions FNDA:5,RuleConditionalTransferOperator.setIssuanceOptions -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:63,RuleConditionalTransferOperator.setAutomaticTransfer +DA:46,4 +DA:46,4 +BRDA:45,0,0,2 +BRDA:45,0,1,4 +DA:49,2 +DA:49,2 +DA:53,4 +DA:53,4 +BRDA:52,1,0,2 +BRDA:52,1,1,4 +DA:56,2 +DA:56,2 +FN:66,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 +BRDA:69,2,0,2 +BRDA:69,2,1,2 +DA:73,2 +DA:73,2 +DA:78,2 DA:78,2 DA:78,2 -FN:87,RuleConditionalTransferOperator.setTimeLimit +DA:79,2 +DA:79,2 +BRDA:77,3,0,2 +BRDA:77,3,1,2 +DA:81,2 +DA:81,2 +FN:90,RuleConditionalTransferOperator.setTimeLimit FNDA:4,RuleConditionalTransferOperator.setTimeLimit -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 +BRDA:93,4,0,3 +BRDA:93,4,1,3 +DA:97,3 +DA:97,3 DA:101,3 DA:101,3 -FN:111,RuleConditionalTransferOperator.setAutomaticApproval +BRDA:100,5,0,3 +BRDA:100,5,1,3 +DA:104,3 +DA:104,3 +FN:114,RuleConditionalTransferOperator.setAutomaticApproval FNDA:5,RuleConditionalTransferOperator.setAutomaticApproval -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 +BRDA:117,6,0,4 +BRDA:117,6,1,4 +DA:121,4 +DA:121,4 DA:125,4 DA:125,4 -FN:135,RuleConditionalTransferOperator.createTransferRequestWithApproval +BRDA:124,7,0,4 +BRDA:124,7,1,4 +DA:128,4 +DA:128,4 +FN:138,RuleConditionalTransferOperator.createTransferRequestWithApproval FNDA:6,RuleConditionalTransferOperator.createTransferRequestWithApproval -DA:138,5 -DA:138,5 -FN:147,RuleConditionalTransferOperator.approveTransferRequest +DA:141,5 +DA:141,5 +FN:150,RuleConditionalTransferOperator.approveTransferRequest FNDA:33,RuleConditionalTransferOperator.approveTransferRequest -DA:152,32 -DA:152,32 -FN:158,RuleConditionalTransferOperator.approveTransferRequestWithId +DA:155,32 +DA:155,32 +FN:161,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:165,4 +DA:165,4 +DA:165,4 +BRDA:165,8,0,2 +BRDA:165,8,1,2 +DA:166,2 +DA:166,2 DA:168,2 DA:168,2 -FN:174,RuleConditionalTransferOperator.resetRequestStatus +DA:171,2 +DA:171,2 +FN:177,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:180,2 +DA:180,2 +DA:180,2 +BRDA:180,9,0,1 +BRDA:180,9,1,1 DA:181,1 DA:181,1 -FN:188,RuleConditionalTransferOperator.approveTransferRequestBatchWithId +DA:183,1 +DA:183,1 +DA:184,1 +DA:184,1 +FN:191,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:195,5 +DA:195,5 +BRDA:195,10,0,1 +BRDA:195,10,1,4 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:198,4 +DA:198,4 +BRDA:198,11,0,1 +BRDA:198,11,1,3 +DA:199,1 +DA:199,1 +DA:202,3 +DA:202,3 +DA:202,13 +DA:202,10 +DA:203,11 +DA:203,11 +DA:203,11 +BRDA:203,12,0,1 +BRDA:203,12,1,10 +DA:204,1 +DA:204,1 +DA:207,2 +DA:207,2 +DA:207,6 +DA:207,4 DA:208,5 DA:208,5 -FN:215,RuleConditionalTransferOperator.approveTransferRequestBatch +DA:211,5 +DA:211,5 +FN:218,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 +DA:223,6 +DA:223,6 +BRDA:223,13,0,1 +BRDA:223,13,1,5 +DA:224,1 +DA:224,1 +DA:227,5 +DA:227,5 +BRDA:226,14,0,3 +BRDA:226,14,1,2 +DA:230,3 +DA:230,3 +DA:232,2 +DA:232,2 +DA:232,11 +DA:232,9 +DA:233,9 +DA:233,9 +FN:244,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 +DA:247,2 +DA:247,2 +BRDA:247,15,0,1 +BRDA:247,15,1,1 +DA:248,1 +DA:248,1 +DA:250,1 +DA:250,1 +DA:250,5 +DA:250,4 +DA:251,4 +DA:251,4 +FN:258,RuleConditionalTransferOperator.resetRequestStatusBatch FNDA:3,RuleConditionalTransferOperator.resetRequestStatusBatch -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:261,3 +DA:261,3 +BRDA:261,16,0,1 +BRDA:261,16,1,2 +DA:262,1 +DA:262,1 +DA:265,2 +DA:265,2 +DA:265,5 +DA:265,3 +DA:266,4 +DA:266,4 +DA:266,4 +BRDA:266,17,0,1 +BRDA:266,17,1,3 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 +DA:270,1 +DA:270,1 +DA:270,4 +DA:270,3 +DA:271,3 +DA:271,3 +DA:272,3 +DA:272,3 +FN:279,RuleConditionalTransferOperator._approveTransferRequestKeyElement FNDA:41,RuleConditionalTransferOperator._approveTransferRequestKeyElement -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 +DA:284,41 +DA:284,41 +BRDA:284,18,0,1 +BRDA:284,18,1,40 +DA:285,1 +DA:285,1 +DA:287,40 +DA:287,40 +DA:287,40 +DA:290,40 +DA:290,40 +DA:291,40 +DA:291,40 +BRDA:291,19,0,1 +BRDA:291,19,1,6 +DA:292,7 +DA:292,7 +BRDA:292,20,0,1 +BRDA:292,20,1,6 +DA:293,1 +DA:293,1 +DA:296,6 +DA:296,6 +DA:298,6 +DA:298,6 +DA:306,33 +DA:306,33 +FN:310,RuleConditionalTransferOperator._createTransferRequestWithApproval FNDA:0,RuleConditionalTransferOperator._createTransferRequestWithApproval -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:316,15 +DA:316,15 +DA:316,15 +DA:319,15 +DA:319,15 +BRDA:319,21,0,- +BRDA:319,21,1,14 +DA:320,14 +DA:320,14 +DA:320,14 +DA:329,14 +DA:329,14 +DA:330,14 +DA:330,14 +DA:331,14 +DA:331,14 +DA:338,14 +DA:338,14 DA:341,1 DA:341,1 -DA:342,1 -DA:342,1 -FN:352,RuleConditionalTransferOperator._resetRequestStatus +DA:344,1 +DA:344,1 +DA:345,1 +DA:345,1 +FN:355,RuleConditionalTransferOperator._resetRequestStatus FNDA:10,RuleConditionalTransferOperator._resetRequestStatus -DA:353,10 -DA:353,10 -DA:354,10 -DA:354,10 -FN:363,RuleConditionalTransferOperator._checkRequestStatus +DA:356,10 +DA:356,10 +DA:357,10 +DA:357,10 +FN:366,RuleConditionalTransferOperator._checkRequestStatus FNDA:119,RuleConditionalTransferOperator._checkRequestStatus -DA:365,119 -DA:365,119 -DA:366,119 -DA:366,119 -FN:370,RuleConditionalTransferOperator._approveRequest +DA:368,119 +DA:368,119 +DA:369,119 +DA:369,119 +FN:373,RuleConditionalTransferOperator._approveRequest FNDA:46,RuleConditionalTransferOperator._approveRequest -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:378,46 +DA:378,46 +BRDA:378,22,0,1 +BRDA:378,22,1,45 +DA:379,1 +DA:379,1 +DA:381,45 +BRDA:381,23,0,2 +BRDA:381,23,1,2 +DA:384,27 +DA:384,27 +BRDA:383,24,0,3 +BRDA:383,24,1,24 +DA:387,3 +DA:387,3 +DA:390,24 +DA:390,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 +DA:395,24 +DA:395,24 +DA:403,24 +DA:403,24 +DA:404,2 +DA:404,2 +DA:404,2 +DA:404,2 +BRDA:402,25,0,2 +BRDA:402,25,1,2 +DA:409,2 +DA:409,2 +DA:409,2 +BRDA:408,26,0,2 +BRDA:408,26,1,2 +DA:415,2 +DA:415,2 +DA:423,18 +DA:423,18 +DA:424,18 +DA:424,18 +FN:437,RuleConditionalTransferOperator._updateProcessedTransfer FNDA:10,RuleConditionalTransferOperator._updateProcessedTransfer -DA:436,10 -DA:436,10 -DA:437,10 -DA:437,10 DA:439,10 DA:439,10 -DA:441,10 -DA:441,10 +DA:440,10 +DA:440,10 +DA:442,10 +DA:442,10 +DA:444,10 +DA:444,10 FNF:19 FNH:18 LF:99 @@ -1233,212 +1233,168 @@ BRH:10 end_of_record TN: SF:src/rules/validation/RuleWhitelist.sol -FN:33,RuleWhitelist.detectTransferRestriction +FN:28,RuleWhitelist.detectTransferRestriction FNDA:28,RuleWhitelist.detectTransferRestriction -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: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: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 -LH:13 -BRF:8 -BRH:8 +DA:33,28 +DA:33,28 +BRDA:33,0,0,13 +BRDA:33,0,1,15 +DA:34,13 +DA:34,13 +DA:35,15 +DA:35,15 +BRDA:35,1,0,5 +BRDA:35,1,1,10 +DA:36,5 +DA:36,5 +DA:38,10 +DA:38,10 +DA:38,10 +FNF:1 +FNH:1 +LF:5 +LH:5 +BRF:4 +BRH:4 end_of_record TN: SF:src/rules/validation/RuleWhitelistWrapper.sol -FN:42,RuleWhitelistWrapper.detectTransferRestriction +FN:40,RuleWhitelistWrapper.detectTransferRestriction FNDA:11,RuleWhitelistWrapper.detectTransferRestriction +DA:45,11 +DA:45,11 +DA:45,11 +DA:46,11 +DA:46,11 +DA:46,11 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:52,31 +DA:52,20 +DA:54,25 +DA:54,25 +DA:56,25 +DA:56,25 +DA:56,7 +BRDA:56,0,0,- +BRDA:56,0,1,7 +DA:58,7 +DA:58,7 +DA:60,25 +DA:60,25 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 +BRDA:60,1,0,- +BRDA:60,1,1,7 +DA:62,7 +DA:62,7 +DA:64,25 +DA:64,25 +BRDA:64,2,0,20 +BRDA:64,2,1,11 +DA:65,25 +DA:65,25 +DA:68,11 +DA:68,11 +BRDA:68,3,0,4 +BRDA:68,3,1,7 +DA:69,4 +DA:69,4 +DA:70,7 +DA:70,7 +BRDA:70,4,0,2 +BRDA:70,4,1,5 +DA:71,2 +DA:71,2 +DA:73,5 +DA:73,5 +DA:73,5 +FN:80,RuleWhitelistWrapper._msgSender FNDA:36,RuleWhitelistWrapper._msgSender -DA:115,36 -DA:115,36 -DA:115,36 -FN:121,RuleWhitelistWrapper._msgData +DA:86,36 +DA:86,36 +DA:86,36 +FN:92,RuleWhitelistWrapper._msgData FNDA:0,RuleWhitelistWrapper._msgData -DA:127,0 -DA:127,0 -DA:127,0 -FN:133,RuleWhitelistWrapper._contextSuffixLength +DA:98,0 +DA:98,0 +DA:98,0 +FN:104,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 +DA:110,36 +DA:110,36 +DA:110,36 +FNF:4 +FNH:3 +LF:22 +LH:21 +BRF:10 +BRH:8 end_of_record TN: SF:src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol -FN:43,RuleAddressList.addAddressesToTheList +FN:44,RuleAddressList.addAddressesToTheList FNDA:17,RuleAddressList.addAddressesToTheList -DA:46,16 -DA:46,16 -FN:55,RuleAddressList.removeAddressesFromTheList +DA:47,16 +DA:47,16 +FN:56,RuleAddressList.removeAddressesFromTheList FNDA:4,RuleAddressList.removeAddressesFromTheList -DA:58,3 -DA:58,3 -FN:66,RuleAddressList.addAddressToTheList +DA:59,3 +DA:59,3 +FN:67,RuleAddressList.addAddressToTheList FNDA:52,RuleAddressList.addAddressToTheList -DA:69,51 -DA:69,51 -FN:78,RuleAddressList.removeAddressFromTheList +DA:70,51 +DA:70,51 +FN:79,RuleAddressList.removeAddressFromTheList FNDA:3,RuleAddressList.removeAddressFromTheList -DA:81,2 -DA:81,2 -FN:89,RuleAddressList.numberListedAddress +DA:82,2 +DA:82,2 +FN:90,RuleAddressList.numberListedAddress FNDA:24,RuleAddressList.numberListedAddress -DA:90,24 -DA:90,24 -DA:90,24 -FN:99,RuleAddressList.addressIsListed +DA:91,24 +DA:91,24 +DA:91,24 +FN:100,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 +DA:103,144 +DA:103,144 +DA:103,144 +FN:110,RuleAddressList.addressIsListedBatch +FNDA:28,RuleAddressList.addressIsListedBatch +DA:113,28 +DA:113,28 +DA:113,28 +DA:114,28 +DA:114,28 +DA:114,83 +DA:114,55 +DA:115,55 +DA:115,55 +DA:117,28 +DA:117,28 +FN:127,RuleAddressList._msgSender FNDA:86,RuleAddressList._msgSender -DA:128,86 -DA:128,86 -DA:128,86 -FN:134,RuleAddressList._msgData +DA:133,86 +DA:133,86 +DA:133,86 +FN:139,RuleAddressList._msgData FNDA:0,RuleAddressList._msgData -DA:140,0 -DA:140,0 -DA:140,0 -FN:146,RuleAddressList._contextSuffixLength +DA:145,0 +DA:145,0 +DA:145,0 +FN:151,RuleAddressList._contextSuffixLength FNDA:86,RuleAddressList._contextSuffixLength -DA:152,86 -DA:152,86 -DA:152,86 +DA:157,86 +DA:157,86 +DA:157,86 FNF:10 FNH:9 LF:13 @@ -1511,9 +1467,9 @@ FNDA:24,RuleAddressListInternal._numberListedAddress DA:85,24 DA:85,24 FN:94,RuleAddressListInternal._addressIsListed -FNDA:215,RuleAddressListInternal._addressIsListed -DA:97,215 -DA:97,215 +FNDA:199,RuleAddressListInternal._addressIsListed +DA:97,199 +DA:97,199 FNF:6 FNH:6 LF:22 @@ -1540,6 +1496,40 @@ BRF:0 BRH:0 end_of_record TN: +SF:src/rules/validation/abstract/RuleWhitelistCommon.sol +FN:16,RuleWhitelistCommon.canReturnTransferRestrictionCode +FNDA:12,RuleWhitelistCommon.canReturnTransferRestrictionCode +DA:19,12 +DA:19,12 +DA:20,12 +DA:20,12 +DA:20,12 +DA:21,6 +DA:21,6 +FN:29,RuleWhitelistCommon.messageForTransferRestriction +FNDA:10,RuleWhitelistCommon.messageForTransferRestriction +DA:32,10 +DA:32,10 +BRDA:32,0,0,6 +BRDA:32,0,1,4 +DA:33,6 +DA:33,6 +DA:34,4 +DA:34,4 +BRDA:34,1,0,3 +BRDA:34,1,1,1 +DA:35,3 +DA:35,3 +DA:37,1 +DA:37,1 +FNF:2 +FNH:2 +LF:8 +LH:8 +BRF:4 +BRH:4 +end_of_record +TN: SF:test/utils/SanctionListOracle.sol FN:13,SanctionListOracle.addToSanctionsList FNDA:10,SanctionListOracle.addToSanctionsList diff --git a/doc/schema/RuleEngine.svg b/doc/schema/RuleEngine.svg new file mode 100644 index 0000000..4750cf4 --- /dev/null +++ b/doc/schema/RuleEngine.svg @@ -0,0 +1,292 @@ + + + + + + +UmlClassDiagram + + + +0 + +RuleEngine +src/RuleEngine.sol + +Internal: +    _msgSender(): (sender: address) +    _msgData(): bytes +    _contextSuffixLength(): uint256 +External: +    messageForTransferRestriction(_restrictionCode: uint8): string +    operateOnTransfer(from: address, to: address, amount: uint256): (isValid: bool) <<onlyRole>> +Public: +    constructor(admin: address, forwarderIrrevocable: address, tokenContract: address) +    detectTransferRestriction(_from: address, _to: address, _amount: uint256): uint8 +    validateTransfer(_from: address, _to: address, _amount: uint256): bool + + + +5 + +<<Interface>> +IRuleValidation +src/interfaces/IRuleValidation.sol + +External: +     canReturnTransferRestrictionCode(_restrictionCode: uint8): bool + + + +0->5 + + + + + +6 + +<<Abstract>> +MetaTxModuleStandalone +src/modules/MetaTxModuleStandalone.sol + +Public: +    constructor(trustedForwarder: address) + + + +0->6 + + + + + +8 + +<<Abstract>> +RuleEngineOperation +src/modules/RuleEngineOperation.sol + +Internal: +   _rulesOperation: address[] + +Internal: +    _clearRulesOperation() +    _removeRuleOperation(rule_: address, index: uint256) +    _operateOnTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) +External: +    rulesCountOperation(): uint256 +    getRuleIndexOperation(rule_: IRuleOperation): (index: uint256) +    ruleOperation(ruleId: uint256): address +    rulesOperation(): address[] +Public: +    setRulesOperation(rules_: address[]) <<onlyRole>> +    clearRulesOperation() <<onlyRole>> +    addRuleOperation(rule_: IRuleOperation) <<onlyRole>> +    removeRuleOperation(rule_: IRuleOperation, index: uint256) <<onlyRole>> + + + +0->8 + + + + + +9 + +<<Abstract>> +RuleEngineValidation +src/modules/RuleEngineValidation.sol + +Public: +    detectTransferRestrictionValidation(_from: address, _to: address, _amount: uint256): uint8 +    validateTransferValidation(_from: address, _to: address, _amount: uint256): bool + + + +0->9 + + + + + +1 + +<<Interface>> +IRuleEngineOperation +src/interfaces/IRuleEngineOperation.sol + +External: +     setRulesOperation(rules_: address[]) +     rulesCountOperation(): uint256 +     ruleOperation(ruleId: uint256): address +     rulesOperation(): address[] + + + +2 + +<<Interface>> +IRuleEngineValidation +src/interfaces/IRuleEngineValidation.sol + +External: +     detectTransferRestrictionValidation(_from: address, _to: address, _amount: uint256): uint8 +     validateTransferValidation(_from: address, _to: address, _amount: uint256): (isValid: bool) + + + +3 + +<<Interface>> +IRuleEngineValidationCommon +src/interfaces/IRuleEngineValidation.sol + +External: +     setRulesValidation(rules_: address[]) +     rulesCountValidation(): uint256 +     ruleValidation(ruleId: uint256): address +     rulesValidation(): address[] + + + +4 + +<<Interface>> +IRuleOperation +src/interfaces/IRuleOperation.sol + +External: +     operateOnTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) + + + +7 + +<<Abstract>> +RuleEngineInvariantStorage +src/modules/RuleEngineInvariantStorage.sol + +Public: +   RULE_ENGINE_OPERATOR_ROLE: bytes32 +   TOKEN_CONTRACT_ROLE: bytes32 + +Public: +    <<event>> AddRule(rule: address) +    <<event>> RemoveRule(rule: address) +    <<event>> ClearRules(rulesRemoved: address[]) + + + +8->1 + + + + + +8->4 + + + + + +11 + +<<Abstract>> +RuleInternal +src/modules/RuleInternal.sol + +Public: +   _ruleIsPresent: mapping(address=>bool) + +Internal: +    _setRules(rules_: address[]) +    _addRule(_rules: address[], rule_: address) +    _removeRule(_rules: address[], rule_: address, index: uint256) +    _getRuleIndex(_rules: address[], rule_: address): (index: uint256) + + + +8->11 + + + + + +9->2 + + + + + +9->5 + + + + + +10 + +<<Abstract>> +RuleEngineValidationCommon +src/modules/RuleEngineValidationCommon.sol + +Internal: +   _rulesValidation: address[] + +Internal: +    _clearRulesValidation() +    _removeRuleValidation(rule_: address, index: uint256) +External: +    rulesCountValidation(): uint256 +    getRuleIndexValidation(rule_: IRuleValidation): (index: uint256) +    ruleValidation(ruleId: uint256): address +    rulesValidation(): address[] +Public: +    setRulesValidation(rules_: address[]) <<onlyRole>> +    clearRulesValidation() <<onlyRole>> +    addRuleValidation(rule_: IRuleValidation) <<onlyRole>> +    removeRuleValidation(rule_: IRuleValidation, index: uint256) <<onlyRole>> + + + +9->10 + + + + + +9->11 + + + + + +10->3 + + + + + +10->5 + + + + + +10->11 + + + + + +11->7 + + + + + diff --git a/doc/schema/classDiagram.svg b/doc/schema/classDiagram.svg index 8be4172..f407eb7 100644 --- a/doc/schema/classDiagram.svg +++ b/doc/schema/classDiagram.svg @@ -4,861 +4,1005 @@ - - + + UmlClassDiagram - + 0 - -RuleEngine -src/RuleEngine.sol - -Internal: -    _msgSender(): (sender: address) -    _msgData(): bytes -    _contextSuffixLength(): uint256 -External: -    messageForTransferRestriction(_restrictionCode: uint8): string -    operateOnTransfer(from: address, to: address, amount: uint256): (isValid: bool) <<onlyRole>> -Public: -    constructor(admin: address, forwarderIrrevocable: address, tokenContract: address) -    detectTransferRestriction(_from: address, _to: address, _amount: uint256): uint8 -    validateTransfer(_from: address, _to: address, _amount: uint256): bool - - - -4 - -<<Interface>> -IRuleValidation -src/interfaces/IRuleValidation.sol - -External: -     canReturnTransferRestrictionCode(_restrictionCode: uint8): bool - - - -0->4 - - + +RuleEngine +src/RuleEngine.sol + +Internal: +    _msgSender(): (sender: address) +    _msgData(): bytes +    _contextSuffixLength(): uint256 +External: +    messageForTransferRestriction(_restrictionCode: uint8): string +    operateOnTransfer(from: address, to: address, amount: uint256): (isValid: bool) <<onlyRole>> +Public: +    constructor(admin: address, forwarderIrrevocable: address, tokenContract: address) +    detectTransferRestriction(_from: address, _to: address, _amount: uint256): uint8 +    validateTransfer(_from: address, _to: address, _amount: uint256): bool 5 - -<<Abstract>> -MetaTxModuleStandalone -src/modules/MetaTxModuleStandalone.sol - -Public: -    constructor(trustedForwarder: address) + +<<Interface>> +IRuleValidation +src/interfaces/IRuleValidation.sol + +External: +     canReturnTransferRestrictionCode(_restrictionCode: uint8): bool - + 0->5 - - + + - - -7 - -<<Abstract>> -RuleEngineOperation -src/modules/RuleEngineOperation.sol - -Internal: -   _rulesOperation: address[] - -Internal: -    _clearRulesOperation() -    _removeRuleOperation(rule_: address, index: uint256) -    _operateOnTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) -External: -    rulesCountOperation(): uint256 -    getRuleIndexOperation(rule_: IRuleOperation): (index: uint256) -    ruleOperation(ruleId: uint256): address -    rulesOperation(): address[] -Public: -    setRulesOperation(rules_: address[]) <<onlyRole>> -    clearRulesOperation() <<onlyRole>> -    addRuleOperation(rule_: IRuleOperation) <<onlyRole>> -    removeRuleOperation(rule_: IRuleOperation, index: uint256) <<onlyRole>> - - - -0->7 - - + + +6 + +<<Abstract>> +MetaTxModuleStandalone +src/modules/MetaTxModuleStandalone.sol + +Public: +    constructor(trustedForwarder: address) + + + +0->6 + + 8 - -<<Abstract>> -RuleEngineValidation -src/modules/RuleEngineValidation.sol - -Internal: -   _rulesValidation: address[] - -Internal: -    _clearRulesValidation() -    _removeRuleValidation(rule_: address, index: uint256) -External: -    rulesCountValidation(): uint256 -    getRuleIndexValidation(rule_: IRuleValidation): (index: uint256) -    ruleValidation(ruleId: uint256): address -    rulesValidation(): address[] -Public: -    setRulesValidation(rules_: address[]) <<onlyRole>> -    clearRulesValidation() <<onlyRole>> -    addRuleValidation(rule_: IRuleValidation) <<onlyRole>> -    removeRuleValidation(rule_: IRuleValidation, index: uint256) <<onlyRole>> -    detectTransferRestrictionValidation(_from: address, _to: address, _amount: uint256): uint8 -    validateTransferValidation(_from: address, _to: address, _amount: uint256): bool + +<<Abstract>> +RuleEngineOperation +src/modules/RuleEngineOperation.sol + +Internal: +   _rulesOperation: address[] + +Internal: +    _clearRulesOperation() +    _removeRuleOperation(rule_: address, index: uint256) +    _operateOnTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) +External: +    rulesCountOperation(): uint256 +    getRuleIndexOperation(rule_: IRuleOperation): (index: uint256) +    ruleOperation(ruleId: uint256): address +    rulesOperation(): address[] +Public: +    setRulesOperation(rules_: address[]) <<onlyRole>> +    clearRulesOperation() <<onlyRole>> +    addRuleOperation(rule_: IRuleOperation) <<onlyRole>> +    removeRuleOperation(rule_: IRuleOperation, index: uint256) <<onlyRole>> - + 0->8 - - + + + + + +9 + +<<Abstract>> +RuleEngineValidation +src/modules/RuleEngineValidation.sol + +Public: +    detectTransferRestrictionValidation(_from: address, _to: address, _amount: uint256): uint8 +    validateTransferValidation(_from: address, _to: address, _amount: uint256): bool + + + +0->9 + + 1 - -<<Interface>> -IRuleEngineOperation -src/interfaces/IRuleEngineOperation.sol - -External: -     setRulesOperation(rules_: address[]) -     rulesCountOperation(): uint256 -     ruleOperation(ruleId: uint256): address -     rulesOperation(): address[] + +<<Interface>> +IRuleEngineOperation +src/interfaces/IRuleEngineOperation.sol + +External: +     setRulesOperation(rules_: address[]) +     rulesCountOperation(): uint256 +     ruleOperation(ruleId: uint256): address +     rulesOperation(): address[] 2 - -<<Interface>> -IRuleEngineValidation -src/interfaces/IRuleEngineValidation.sol - -External: -     setRulesValidation(rules_: address[]) -     rulesCountValidation(): uint256 -     ruleValidation(ruleId: uint256): address -     rulesValidation(): address[] -     detectTransferRestrictionValidation(_from: address, _to: address, _amount: uint256): uint8 -     validateTransferValidation(_from: address, _to: address, _amount: uint256): (isValid: bool) + +<<Interface>> +IRuleEngineValidation +src/interfaces/IRuleEngineValidation.sol + +External: +     detectTransferRestrictionValidation(_from: address, _to: address, _amount: uint256): uint8 +     validateTransferValidation(_from: address, _to: address, _amount: uint256): (isValid: bool) 3 - -<<Interface>> -IRuleOperation -src/interfaces/IRuleOperation.sol - -External: -     operateOnTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) + +<<Interface>> +IRuleEngineValidationCommon +src/interfaces/IRuleEngineValidation.sol + +External: +     setRulesValidation(rules_: address[]) +     rulesCountValidation(): uint256 +     ruleValidation(ruleId: uint256): address +     rulesValidation(): address[] - - -6 - -<<Abstract>> -RuleEngineInvariantStorage -src/modules/RuleEngineInvariantStorage.sol - -Public: -   RULE_ENGINE_ROLE: bytes32 -   TOKEN_CONTRACT_ROLE: bytes32 - -Public: -    <<event>> AddRule(rule: address) -    <<event>> RemoveRule(rule: address) -    <<event>> ClearRules(rulesRemoved: address[]) - - + + +4 + +<<Interface>> +IRuleOperation +src/interfaces/IRuleOperation.sol + +External: +     operateOnTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) + + + +7 + +<<Abstract>> +RuleEngineInvariantStorage +src/modules/RuleEngineInvariantStorage.sol + +Public: +   RULE_ENGINE_OPERATOR_ROLE: bytes32 +   TOKEN_CONTRACT_ROLE: bytes32 + +Public: +    <<event>> AddRule(rule: address) +    <<event>> RemoveRule(rule: address) +    <<event>> ClearRules(rulesRemoved: address[]) + + -7->1 - - +8->1 + + - + -7->3 - - +8->4 + + - - -9 - -<<Abstract>> -RuleInternal -src/modules/RuleInternal.sol - -Public: -   _ruleIsPresent: mapping(address=>bool) - -Internal: -    _setRules(rules_: address[]) -    _addRule(_rules: address[], rule_: address) -    _removeRule(_rules: address[], rule_: address, index: uint256) -    getRuleIndex(_rules: address[], rule_: address): (index: uint256) - - + + +11 + +<<Abstract>> +RuleInternal +src/modules/RuleInternal.sol + +Public: +   _ruleIsPresent: mapping(address=>bool) + +Internal: +    _setRules(rules_: address[]) +    _addRule(_rules: address[], rule_: address) +    _removeRule(_rules: address[], rule_: address, index: uint256) +    _getRuleIndex(_rules: address[], rule_: address): (index: uint256) + + -7->9 - - +8->11 + + - - -8->2 - - - - + -8->4 - - +9->2 + + - - -8->9 - - - - + -9->6 - - +9->5 + + 10 - -RuleConditionalTransfer -src/rules/operation/RuleConditionalTransfer.sol - -Internal: -    _validateBurnMint(_from: address, _to: address): (isValid: bool) -    _validateApproval(key: bytes32): (isValid: bool) -    _msgSender(): (sender: address) -    _msgData(): bytes -    _contextSuffixLength(): uint256 -External: -    canReturnTransferRestrictionCode(_restrictionCode: uint8): bool -    messageForTransferRestriction(_restrictionCode: uint8): string -Public: -    constructor(admin: address, forwarderIrrevocable: address, ruleEngineContract: IRuleEngine, options_: OPTION) -    createTransferRequest(to: address, value: uint256) -    cancelTransferRequest(requestId_: uint256) -    getRequestTrade(from: address, to: address, value: uint256): TransferRequest -    getRequestByStatus(_targetStatus: STATUS): TransferRequest[] -    operateOnTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) <<onlyRole>> -    detectTransferRestriction(_from: address, _to: address, _amount: uint256): uint8 + +<<Abstract>> +RuleEngineValidationCommon +src/modules/RuleEngineValidationCommon.sol + +Internal: +   _rulesValidation: address[] + +Internal: +    _clearRulesValidation() +    _removeRuleValidation(rule_: address, index: uint256) +External: +    rulesCountValidation(): uint256 +    getRuleIndexValidation(rule_: IRuleValidation): (index: uint256) +    ruleValidation(ruleId: uint256): address +    rulesValidation(): address[] +Public: +    setRulesValidation(rules_: address[]) <<onlyRole>> +    clearRulesValidation() <<onlyRole>> +    addRuleValidation(rule_: IRuleValidation) <<onlyRole>> +    removeRuleValidation(rule_: IRuleValidation, index: uint256) <<onlyRole>> + + + +9->10 + + + + + +9->11 + + 10->3 - - + + - + 10->5 - - + + - - -20 - -<<Struct>> -OPTION -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol - -issuance: ISSUANCE -timeLimit: TIME_LIMIT -automaticApproval: AUTOMATIC_APPROVAL -automaticTransfer: AUTOMATIC_TRANSFER - - - -10->20 - - + + +10->11 + + - - -21 - -<<Enum>> -STATUS -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol - -NONE: 0 -WAIT: 1 -APPROVED: 2 -DENIED: 3 -EXECUTED: 4 -CANCELLED: 5 - - + + +11->7 + + + + + +12 + +RuleConditionalTransfer +src/rules/operation/RuleConditionalTransfer.sol + +Internal: +    _cancelTransferRequest(requestId_: uint256) +    _validateBurnMint(_from: address, _to: address): (isValid: bool) +    _validateApproval(key: bytes32): (isValid: bool) +    _msgSender(): (sender: address) +    _msgData(): bytes +    _contextSuffixLength(): uint256 +External: +    canReturnTransferRestrictionCode(_restrictionCode: uint8): bool +    messageForTransferRestriction(_restrictionCode: uint8): string +Public: +    constructor(admin: address, forwarderIrrevocable: address, ruleEngineContract: IRuleEngine, options_: OPTION) +    operateOnTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) <<onlyRole>> +    createTransferRequest(to: address, value: uint256) +    createTransferRequestBatch(tos: address[], values: uint256[]) +    cancelTransferRequest(requestId_: uint256) +    cancelTransferRequestBatch(requestIds: uint256[]) +    getRequestTrade(from: address, to: address, value: uint256): TransferRequest +    getRequestByStatus(_targetStatus: STATUS): TransferRequest[] +    detectTransferRestriction(_from: address, _to: address, _amount: uint256): uint8 + + -10->21 - - +12->4 + + - - -22 - -<<Struct>> -TransferRequest -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol - -key: bytes32 -id: uint256 -from: address -to: address -value: uint256 -askTime: uint256 -maxTime: uint256 -status: STATUS - - - -10->22 - - + + +12->6 + + - + 23 - -<<Abstract>> -RuleConditionalTransferOperator -src/rules/operation/abstract/RuleConditionalTransferOperator.sol - -Internal: -   options: OPTION -Public: -   transferRequests: mapping(bytes32=>TransferRequest) -   requestId: uint256 -   IdToKey: mapping(uint256=>bytes32) - -Internal: -    _resetRequestStatus(key: bytes32) -    _checkRequestStatus(key: bytes32): bool -    _approveRequest(transferRequest: TransferRequest, isApproved_: bool) -    _updateProcessedTransfer(key: bytes32) -Public: -    setIssuanceOptions(issuance_: ISSUANCE) <<onlyRole>> -    setAutomaticTransfer(automaticTransfer_: AUTOMATIC_TRANSFER) <<onlyRole>> -    setTimeLimit(timeLimit_: TIME_LIMIT) <<onlyRole>> -    setAutomaticApproval(automaticApproval_: AUTOMATIC_APPROVAL) <<onlyRole>> -    createTransferRequestWithApproval(from: address, to: address, value: uint256) <<onlyRole>> -    approveTransferRequest(from: address, to: address, value: uint256, isApproved_: bool) <<onlyRole>> -    approveTransferRequestWithId(requestId_: uint256, isApproved_: bool) <<onlyRole>> -    resetRequestStatus(requestId_: uint256) <<onlyRole>> - - - -10->23 - - + +<<Struct>> +OPTION +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +issuance: ISSUANCE +timeLimit: TIME_LIMIT +automaticApproval: AUTOMATIC_APPROVAL +automaticTransfer: AUTOMATIC_TRANSFER + + + +12->23 + + + + + +24 + +<<Struct>> +TransferRequestKeyElement +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +from: address +to: address +value: uint256 + + + +12->24 + + + + + +25 + +<<Struct>> +TransferRequest +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +key: bytes32 +id: uint256 +keyElement: TransferRequestKeyElement +askTime: uint256 +maxTime: uint256 +status: STATUS + + + +12->25 + + - + 26 - -<<Abstract>> -RuleValidateTransfer -src/rules/validation/abstract/RuleValidateTransfer.sol - -Public: -    validateTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) - - - -10->26 - - + +<<Enum>> +STATUS +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +NONE: 0 +WAIT: 1 +APPROVED: 2 +DENIED: 3 +EXECUTED: 4 + + + +12->26 + + - - -16 - -<<Struct>> -AUTOMATIC_TRANSFER -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol - -isActivate: bool -cmtat: IERC20 + + +27 + +<<Abstract>> +RuleConditionalTransferOperator +src/rules/operation/abstract/RuleConditionalTransferOperator.sol + +Public: +   options: OPTION +   requestId: uint256 +   IdToKey: mapping(uint256=>bytes32) +   transferRequests: mapping(bytes32=>TransferRequest) +   whitelistConditionalTransfer: RuleWhitelist + +Internal: +    _approveTransferRequestKeyElement(keyElement: TransferRequestKeyElement, partialValue: uint256, isApproved: bool) +    _resetRequestStatus(key: bytes32) +    _checkRequestStatus(key: bytes32): bool +    _approveRequest(transferRequest: TransferRequest, isApproved: bool) +    _updateProcessedTransfer(key: bytes32) +Public: +    setConditionalWhitelist(newWhitelistConditionalTransfer: RuleWhitelist) <<onlyRole>> +    setIssuanceOptions(issuance_: ISSUANCE) <<onlyRole>> +    setAutomaticTransfer(automaticTransfer_: AUTOMATIC_TRANSFER) <<onlyRole>> +    setTimeLimit(timeLimit_: TIME_LIMIT) <<onlyRole>> +    setAutomaticApproval(automaticApproval_: AUTOMATIC_APPROVAL) <<onlyRole>> +    createTransferRequestWithApproval(keyElement: TransferRequestKeyElement) <<onlyRole>> +    approveTransferRequest(keyElement: TransferRequestKeyElement, partialValue: uint256, isApproved: bool) <<onlyRole>> +    approveTransferRequestWithId(requestId_: uint256, isApproved: bool) <<onlyRole>> +    resetRequestStatus(requestId_: uint256) <<onlyRole>> +    approveTransferRequestBatchWithId(requestId_: uint256[], isApproved: bool[]) <<onlyRole>> +    approveTransferRequestBatch(keyElements: TransferRequestKeyElement[], partialValues: uint256[], isApproved: bool[]) <<onlyRole>> +    createTransferRequestWithApprovalBatch(keyElements: TransferRequestKeyElement[]) <<onlyRole>> +    resetRequestStatusBatch(requestIds: uint256[]) <<onlyRole>> +    _createTransferRequestWithApproval(keyElement_: TransferRequestKeyElement) <<onlyRole>> + + + +12->27 + + - - -15 - -<<Abstract>> -RuleConditionalTransferInvariantStorage -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol - -Public: -   RULE_ENGINE_CONTRACT_ROLE: bytes32 -   RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE: bytes32 -   TEXT_TRANSFER_REQUEST_NOT_APPROVED: string -   CODE_TRANSFER_REQUEST_NOT_APPROVED: uint8 - -Public: -    <<event>> transferProcessed(key: bytes32, from: address, to: address, value: uint256, id: uint256) -    <<event>> transferWaiting(key: bytes32, from: address, to: address, value: uint256, id: uint256) -    <<event>> transferApproved(key: bytes32, from: address, to: address, value: uint256, id: uint256) -    <<event>> transferDenied(key: bytes32, from: address, to: address, value: uint256, id: uint256) -    <<event>> transferReset(key: bytes32, from: address, to: address, value: uint256, id: uint256) - - - -16->15 - - + + +30 + +<<Abstract>> +RuleValidateTransfer +src/rules/validation/abstract/RuleValidateTransfer.sol + +Public: +    validateTransfer(_from: address, _to: address, _amount: uint256): (isValid: bool) + + + +12->30 + + - - -17 - -<<Struct>> -ISSUANCE -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol - -authorizedMintWithoutApproval: bool -authorizedBurnWithoutApproval: bool - - - -17->15 - - + + +19 + +<<Struct>> +AUTOMATIC_TRANSFER +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +isActivate: bool +cmtat: IERC20 - + 18 - -<<Struct>> -TIME_LIMIT -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol - -timeLimitToApprove: uint256 -timeLimitToTransfer: uint256 - - - -18->15 - - + +<<Abstract>> +RuleConditionalTransferInvariantStorage +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +Public: +   RULE_ENGINE_CONTRACT_ROLE: bytes32 +   RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE: bytes32 +   TEXT_TRANSFER_REQUEST_NOT_APPROVED: string +   CODE_TRANSFER_REQUEST_NOT_APPROVED: uint8 + +Public: +    <<event>> transferProcessed(key: bytes32, from: address, to: address, value: uint256, id: uint256) +    <<event>> transferWaiting(key: bytes32, from: address, to: address, value: uint256, id: uint256) +    <<event>> transferApproved(key: bytes32, from: address, to: address, value: uint256, id: uint256) +    <<event>> transferDenied(key: bytes32, from: address, to: address, value: uint256, id: uint256) +    <<event>> transferReset(key: bytes32, from: address, to: address, value: uint256, id: uint256) +    <<event>> WhitelistConditionalTransfer(whitelistConditionalTransfer: RuleWhitelist) + + + +19->18 + + - + -19 - -<<Struct>> -AUTOMATIC_APPROVAL -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol - -isActivate: bool -timeLimitBeforeAutomaticApproval: uint256 - - - -19->15 - - - - - -20->16 - - - - - -20->17 - - +20 + +<<Struct>> +ISSUANCE +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +authorizedMintWithoutApproval: bool +authorizedBurnWithoutApproval: bool - + 20->18 - - + + - - -20->19 - - - - - -20->15 - - - - - -21->15 - - - - - -22->21 - - - - - -22->15 - - - - - -24 - -<<Abstract>> -RuleCommonInvariantStorage -src/rules/validation/abstract/RuleCommonInvariantStorage.sol - -Public: -   TEXT_CODE_NOT_FOUND: string - - - -15->24 - - - - - -23->16 - - - - - -23->17 - - + + +21 + +<<Struct>> +TIME_LIMIT +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +timeLimitToApprove: uint256 +timeLimitToTransfer: uint256 + + + +21->18 + + - - -23->18 - - + + +22 + +<<Struct>> +AUTOMATIC_APPROVAL +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol + +isActivate: bool +timeLimitBeforeAutomaticApproval: uint256 + + + +22->18 + + - + 23->19 - - + + - + 23->20 - - + + - + 23->21 - - + + - + 23->22 - - + + - - -23->15 - - + + +23->18 + + - - -11 - -RuleBlacklist -src/rules/validation/RuleBlacklist.sol - -External: -    canReturnTransferRestrictionCode(_restrictionCode: uint8): bool -    messageForTransferRestriction(_restrictionCode: uint8): string -Public: -    constructor(admin: address, forwarderIrrevocable: address) -    detectTransferRestriction(_from: address, _to: address, uint256): uint8 + + +24->18 + + - - -27 - -<<Abstract>> -RuleAddressList -src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol - -Private: -   numAddressesWhitelisted: uint256 - -Internal: -    _msgSender(): (sender: address) -    _msgData(): bytes -    _contextSuffixLength(): uint256 -Public: -    constructor(admin: address, forwarderIrrevocable: address) -    addAddressesToTheList(listWhitelistedAddress: address[]) <<onlyRole>> -    removeAddressesFromTheList(listWhitelistedAddress: address[]) <<onlyRole>> -    addAddressToTheList(_newWhitelistAddress: address) <<onlyRole>> -    removeAddressFromTheList(_removeWhitelistAddress: address) <<onlyRole>> -    numberListedAddress(): uint256 -    addressIsListed(_targetAddress: address): bool - - - -11->27 - - + + +25->24 + + - - -30 - -<<Abstract>> -RuleBlacklistInvariantStorage -src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol - -Public: -   TEXT_ADDRESS_FROM_IS_BLACKLISTED: string -   TEXT_ADDRESS_TO_IS_BLACKLISTED: string -   CODE_ADDRESS_FROM_IS_BLACKLISTED: uint8 -   CODE_ADDRESS_TO_IS_BLACKLISTED: uint8 - - - -11->30 - - + + +25->26 + + - - -11->26 - - + + +25->18 + + - - -12 - -<<Interface>> -SanctionsList -src/rules/validation/RuleSanctionList.sol - -External: -     isSanctioned(addr: address): bool + + +26->18 + + - - -13 - -RuleSanctionList -src/rules/validation/RuleSanctionList.sol - -Public: -   sanctionsList: SanctionsList - -Internal: -    _msgSender(): (sender: address) -    _msgData(): bytes -    _contextSuffixLength(): uint256 -External: -    canReturnTransferRestrictionCode(_restrictionCode: uint8): bool -    messageForTransferRestriction(_restrictionCode: uint8): string -Public: -    constructor(admin: address, forwarderIrrevocable: address) -    setSanctionListOracle(sanctionContractOracle_: address) <<onlyRole>> -    detectTransferRestriction(_from: address, _to: address, uint256): uint8 - - + + +28 + +<<Abstract>> +RuleCommonInvariantStorage +src/rules/validation/abstract/RuleCommonInvariantStorage.sol + +Public: +   TEXT_CODE_NOT_FOUND: string + + + +18->28 + + + + -13->5 - - +27->19 + + - - -13->12 - - + + +27->20 + + - - -25 - -<<Abstract>> -RuleSanctionlistInvariantStorage -src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol - -Public: -   SANCTIONLIST_ROLE: bytes32 -   TEXT_ADDRESS_FROM_IS_SANCTIONED: string -   TEXT_ADDRESS_TO_IS_SANCTIONED: string -   CODE_ADDRESS_FROM_IS_SANCTIONED: uint8 -   CODE_ADDRESS_TO_IS_SANCTIONED: uint8 - - + + +27->21 + + + + -13->25 - - +27->22 + + - - -13->26 - - + + +27->23 + + - - -14 - -RuleWhitelist -src/rules/validation/RuleWhitelist.sol - -External: -    canReturnTransferRestrictionCode(_restrictionCode: uint8): bool -    messageForTransferRestriction(_restrictionCode: uint8): string -Public: -    constructor(admin: address, forwarderIrrevocable: address) -    detectTransferRestriction(_from: address, _to: address, uint256): uint8 - - - -14->27 - - + + +27->24 + + - - -31 - -<<Abstract>> -RuleWhitelistInvariantStorage -src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol - -Public: -   TEXT_ADDRESS_FROM_NOT_WHITELISTED: string -   TEXT_ADDRESS_TO_NOT_WHITELISTED: string -   CODE_ADDRESS_FROM_NOT_WHITELISTED: uint8 -   CODE_ADDRESS_TO_NOT_WHITELISTED: uint8 - - - -14->31 - - + + +27->25 + + - + -14->26 - - +27->26 + + + + + +27->18 + + + + + +13 + +RuleBlacklist +src/rules/validation/RuleBlacklist.sol + +External: +    canReturnTransferRestrictionCode(_restrictionCode: uint8): bool +    messageForTransferRestriction(_restrictionCode: uint8): string +Public: +    constructor(admin: address, forwarderIrrevocable: address) +    detectTransferRestriction(_from: address, _to: address, uint256): uint8 + + + +32 + +<<Abstract>> +RuleAddressList +src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol + +Private: +   numAddressesWhitelisted: uint256 + +Internal: +    _msgSender(): (sender: address) +    _msgData(): bytes +    _contextSuffixLength(): uint256 +Public: +    constructor(admin: address, forwarderIrrevocable: address) +    addAddressesToTheList(listWhitelistedAddress: address[]) <<onlyRole>> +    removeAddressesFromTheList(listWhitelistedAddress: address[]) <<onlyRole>> +    addAddressToTheList(_newWhitelistAddress: address) <<onlyRole>> +    removeAddressFromTheList(_removeWhitelistAddress: address) <<onlyRole>> +    numberListedAddress(): uint256 +    addressIsListed(_targetAddress: address): bool +    addressIsListedBatch(_targetAddresses: address[]): bool[] + + + +13->32 + + - + + +35 + +<<Abstract>> +RuleBlacklistInvariantStorage +src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol + +Public: +   TEXT_ADDRESS_FROM_IS_BLACKLISTED: string +   TEXT_ADDRESS_TO_IS_BLACKLISTED: string +   CODE_ADDRESS_FROM_IS_BLACKLISTED: uint8 +   CODE_ADDRESS_TO_IS_BLACKLISTED: uint8 + + -27->5 - - +13->35 + + - + + +13->30 + + + + + +14 + +<<Interface>> +SanctionsList +src/rules/validation/RuleSanctionList.sol + +External: +     isSanctioned(addr: address): bool + + -28 - -<<Abstract>> -RuleAddressListInternal -src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol - -Private: -   list: mapping(address=>bool) -   numAddressesList: uint256 - -Internal: -    _addAddressesToThelist(listAddresses: address[]) -    _removeAddressesFromThelist(listAddresses: address[]) -    _addAddressToThelist(_newlistAddress: address) -    _removeAddressFromThelist(_removelistAddress: address) -    _numberListedAddress(): uint256 -    _addressIsListed(_targetAddress: address): bool - - +15 + +RuleSanctionList +src/rules/validation/RuleSanctionList.sol + +Public: +   sanctionsList: SanctionsList + +Internal: +    _msgSender(): (sender: address) +    _msgData(): bytes +    _contextSuffixLength(): uint256 +External: +    canReturnTransferRestrictionCode(_restrictionCode: uint8): bool +    messageForTransferRestriction(_restrictionCode: uint8): string +Public: +    constructor(admin: address, forwarderIrrevocable: address) +    setSanctionListOracle(sanctionContractOracle_: address) <<onlyRole>> +    detectTransferRestriction(_from: address, _to: address, uint256): uint8 + + -27->28 - - +15->6 + + + + + +15->14 + + - + 29 - -<<Abstract>> -RuleAddressListInvariantStorage -src/rules/validation/abstract/RuleAddressList/RuleAddressListInvariantStorage.sol - -Public: -   ADDRESS_LIST_ROLE: bytes32 - - - -27->29 - - - - + +<<Abstract>> +RuleSanctionlistInvariantStorage +src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol + +Public: +   SANCTIONLIST_ROLE: bytes32 +   TEXT_ADDRESS_FROM_IS_SANCTIONED: string +   TEXT_ADDRESS_TO_IS_SANCTIONED: string +   CODE_ADDRESS_FROM_IS_SANCTIONED: uint8 +   CODE_ADDRESS_TO_IS_SANCTIONED: uint8 + + -30->24 - - +15->29 + + - - -31->24 - - + + +15->30 + + - + + +16 + +RuleWhitelist +src/rules/validation/RuleWhitelist.sol + +Public: +    constructor(admin: address, forwarderIrrevocable: address) +    detectTransferRestriction(_from: address, _to: address, uint256): uint8 + + -25->24 - - +16->32 + + - + + +31 + +<<Abstract>> +RuleWhitelistCommon +src/rules/validation/abstract/RuleWhitelistCommon.sol + +External: +    canReturnTransferRestrictionCode(_restrictionCode: uint8): bool +    messageForTransferRestriction(_restrictionCode: uint8): string + + -26->4 - - +16->31 + + + + + +17 + +RuleWhitelistWrapper +src/rules/validation/RuleWhitelistWrapper.sol + +Internal: +    _msgSender(): (sender: address) +    _msgData(): bytes +    _contextSuffixLength(): uint256 +Public: +    constructor(admin: address, forwarderIrrevocable: address) +    detectTransferRestriction(_from: address, _to: address, uint256): uint8 + + + +17->6 + + + + + +17->10 + + + + + +17->32 + + + + + +17->31 + + + + + +32->6 + + + + + +33 + +<<Abstract>> +RuleAddressListInternal +src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol + +Private: +   list: mapping(address=>bool) +   numAddressesList: uint256 + +Internal: +    _addAddressesToThelist(listAddresses: address[]) +    _removeAddressesFromThelist(listAddresses: address[]) +    _addAddressToThelist(_newlistAddress: address) +    _removeAddressFromThelist(_removelistAddress: address) +    _numberListedAddress(): uint256 +    _addressIsListed(_targetAddress: address): bool + + + +32->33 + + + + + +34 + +<<Abstract>> +RuleAddressListInvariantStorage +src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol + +Public: +   ADDRESS_LIST_REMOVE_ROLE: bytes32 +   ADDRESS_LIST_ADD_ROLE: bytes32 + + + +32->34 + + + + + +35->28 + + + + + +36 + +<<Abstract>> +RuleWhitelistInvariantStorage +src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol + +Public: +   TEXT_ADDRESS_FROM_NOT_WHITELISTED: string +   TEXT_ADDRESS_TO_NOT_WHITELISTED: string +   CODE_ADDRESS_FROM_NOT_WHITELISTED: uint8 +   CODE_ADDRESS_TO_NOT_WHITELISTED: uint8 + + + +36->28 + + + + + +29->28 + + + + + +30->5 + + + + + +31->36 + + + + + +31->30 + + diff --git a/doc/security/audits/tools/slither-report.md b/doc/security/audits/tools/slither-report.md index 3c501f3..abfc923 100644 --- a/doc/security/audits/tools/slither-report.md +++ b/doc/security/audits/tools/slither-report.md @@ -1,105 +1,101 @@ **THIS CHECKLIST IS NOT COMPLETE**. Use `--show-ignored-findings` to show all the results. Summary - - [arbitrary-send-erc20](#arbitrary-send-erc20) (1 results) (High) - [incorrect-equality](#incorrect-equality) (4 results) (Medium) - - [calls-loop](#calls-loop) (6 results) (Low) + - [calls-loop](#calls-loop) (8 results) (Low) - [timestamp](#timestamp) (5 results) (Low) - - [pragma](#pragma) (1 results) (Informational) - - [dead-code](#dead-code) (4 results) (Informational) - - [solc-version](#solc-version) (2 results) (Informational) - - [naming-convention](#naming-convention) (50 results) (Informational) - - [similar-names](#similar-names) (5 results) (Informational) + - [costly-loop](#costly-loop) (2 results) (Informational) + - [dead-code](#dead-code) (5 results) (Informational) + - [solc-version](#solc-version) (1 results) (Informational) + - [naming-convention](#naming-convention) (54 results) (Informational) + - [similar-names](#similar-names) (7 results) (Informational) - [unused-import](#unused-import) (1 results) (Informational) - [var-read-using-this](#var-read-using-this) (1 results) (Optimization) -## arbitrary-send-erc20 - -> from is set inside the smart contract when a request is created - -Impact: High -Confidence: High - - [ ] ID-0 -[RuleConditionalTransferOperator._approveRequest(RuleConditionalTransferInvariantStorage.TransferRequest,bool)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L124-L152) uses arbitrary from in transferFrom: [options.automaticTransfer.cmtat.safeTransferFrom(transferRequest.from,transferRequest.to,transferRequest.value)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L145) - -src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L124-L152 - ## incorrect-equality > Strict equality is required to check the request status Impact: Medium Confidence: High + - [ ] ID-0 + [RuleConditionalTransfer.getRequestByStatus(RuleConditionalTransferInvariantStorage.STATUS)](src/rules/operation/RuleConditionalTransfer.sol#L194-L223) uses a dangerous strict equality: + - [transferRequests[IdToKey[i]].status == _targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L203) + +src/rules/operation/RuleConditionalTransfer.sol#L194-L223 + - [ ] ID-1 - [RuleConditionalTransfer.getRequestByStatus(RuleConditionalTransferInvariantStorage.STATUS)](src/rules/operation/RuleConditionalTransfer.sol#L116-L141) uses a dangerous strict equality: - - [transferRequests[IdToKey[i_scope_0]].status == _targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L133) + [RuleConditionalTransferOperator._checkRequestStatus(bytes32)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L367-L372) uses a dangerous strict equality: + - [(transferRequests[key].status == STATUS.NONE) && (transferRequests[key].key == 0x0)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L369-L371) -src/rules/operation/RuleConditionalTransfer.sol#L116-L141 +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L367-L372 - [ ] ID-2 - [RuleConditionalTransfer.getRequestByStatus(RuleConditionalTransferInvariantStorage.STATUS)](src/rules/operation/RuleConditionalTransfer.sol#L116-L141) uses a dangerous strict equality: - - [transferRequests[IdToKey[i]].status == _targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L123) + [RuleConditionalTransfer.getRequestByStatus(RuleConditionalTransferInvariantStorage.STATUS)](src/rules/operation/RuleConditionalTransfer.sol#L194-L223) uses a dangerous strict equality: + - [transferRequests[IdToKey[i_scope_0]].status == _targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L213) -src/rules/operation/RuleConditionalTransfer.sol#L116-L141 +src/rules/operation/RuleConditionalTransfer.sol#L194-L223 - [ ] ID-3 - [RuleConditionalTransfer._validateApproval(bytes32)](src/rules/operation/RuleConditionalTransfer.sol#L239-L251) uses a dangerous strict equality: - - [isTransferApproved = (transferRequests[key].status == STATUS.APPROVED) && (transferRequests[key].maxTime >= block.timestamp)](src/rules/operation/RuleConditionalTransfer.sol#L243-L244) + [RuleConditionalTransfer._validateApproval(bytes32)](src/rules/operation/RuleConditionalTransfer.sol#L332-L351) uses a dangerous strict equality: + - [isTransferApproved = (transferRequests[key].status == STATUS.APPROVED) && (transferRequests[key].maxTime >= block.timestamp)](src/rules/operation/RuleConditionalTransfer.sol#L343-L345) -src/rules/operation/RuleConditionalTransfer.sol#L239-L251 - - - - [ ] ID-4 - [RuleConditionalTransferOperator._checkRequestStatus(bytes32)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L120-L122) uses a dangerous strict equality: - - [(transferRequests[key].status == STATUS.NONE) && (transferRequests[key].key == 0x0)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L121) - -src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L120-L122 +src/rules/operation/RuleConditionalTransfer.sol#L332-L351 ## calls-loop -> - Rules are trusted contracts deployed by the issuer. -> -> It is not a problem to perform external call to these contracts -> -> - When a ruleEngine is created, the issuer has indeed to keep in mind to limit the number of rules used. +> Acknowledge Impact: Low Confidence: Medium + + - [ ] ID-4 +[RuleEngineValidation.detectTransferRestrictionValidation(address,address,uint256)](src/modules/RuleEngineValidation.sol#L29-L44) has external calls inside a loop: [restriction = IRuleValidation(_rulesValidation[i]).detectTransferRestriction(_from,_to,_amount)](src/modules/RuleEngineValidation.sol#L36-L37) + +src/modules/RuleEngineValidation.sol#L29-L44 + + - [ ] ID-5 -[RuleEngine.messageForTransferRestriction(uint8)](src/RuleEngine.sol#L91-L111) has external calls inside a loop: [IRuleValidation(_rulesOperation[i_scope_0]).messageForTransferRestriction(_restrictionCode)](src/RuleEngine.sol#L106-L107) +[RuleWhitelistWrapper.detectTransferRestriction(address,address,uint256)](src/rules/validation/RuleWhitelistWrapper.sol#L40-L75) has external calls inside a loop: [isListed = RuleAddressList(_rulesValidation[i]).addressIsListedBatch(targetAddress)](src/rules/validation/RuleWhitelistWrapper.sol#L54-L55) -src/RuleEngine.sol#L91-L111 +src/rules/validation/RuleWhitelistWrapper.sol#L40-L75 - [ ] ID-6 -[RuleEngine.messageForTransferRestriction(uint8)](src/RuleEngine.sol#L91-L111) has external calls inside a loop: [IRuleValidation(_rulesValidation[i]).canReturnTransferRestrictionCode(_restrictionCode)](src/RuleEngine.sol#L97) +[RuleEngine.messageForTransferRestriction(uint8)](src/RuleEngine.sol#L97-L125) has external calls inside a loop: [IRuleValidation(_rulesValidation[i]).canReturnTransferRestrictionCode(_restrictionCode)](src/RuleEngine.sol#L104-L105) -src/RuleEngine.sol#L91-L111 +src/RuleEngine.sol#L97-L125 - [ ] ID-7 -[RuleEngine.messageForTransferRestriction(uint8)](src/RuleEngine.sol#L91-L111) has external calls inside a loop: [IRuleValidation(_rulesOperation[i_scope_0]).canReturnTransferRestrictionCode(_restrictionCode)](src/RuleEngine.sol#L105) +[RuleEngine.messageForTransferRestriction(uint8)](src/RuleEngine.sol#L97-L125) has external calls inside a loop: [IRuleValidation(_rulesOperation[i_scope_0]).canReturnTransferRestrictionCode(_restrictionCode)](src/RuleEngine.sol#L116-L117) -src/RuleEngine.sol#L91-L111 +src/RuleEngine.sol#L97-L125 - [ ] ID-8 -[RuleEngine.messageForTransferRestriction(uint8)](src/RuleEngine.sol#L91-L111) has external calls inside a loop: [IRuleValidation(_rulesValidation[i]).messageForTransferRestriction(_restrictionCode)](src/RuleEngine.sol#L98-L99) +[RuleEngine.messageForTransferRestriction(uint8)](src/RuleEngine.sol#L97-L125) has external calls inside a loop: [IRuleValidation(_rulesValidation[i]).messageForTransferRestriction(_restrictionCode)](src/RuleEngine.sol#L107-L109) -src/RuleEngine.sol#L91-L111 +src/RuleEngine.sol#L97-L125 - [ ] ID-9 -[RuleEngineValidation.detectTransferRestrictionValidation(address,address,uint256)](src/modules/RuleEngineValidation.sol#L143-L161) has external calls inside a loop: [restriction = IRuleValidation(_rulesValidation[i]).detectTransferRestriction(_from,_to,_amount)](src/modules/RuleEngineValidation.sol#L150-L154) +[RuleEngine.detectTransferRestriction(address,address,uint256)](src/RuleEngine.sol#L47-L73) has external calls inside a loop: [restriction = IRuleValidation(_rulesOperation[i]).detectTransferRestriction(_from,_to,_amount)](src/RuleEngine.sol#L65-L66) -src/modules/RuleEngineValidation.sol#L143-L161 +src/RuleEngine.sol#L47-L73 - [ ] ID-10 -[RuleEngine.detectTransferRestriction(address,address,uint256)](src/RuleEngine.sol#L44-L69) has external calls inside a loop: [restriction = IRuleValidation(_rulesOperation[i]).detectTransferRestriction(_from,_to,_amount)](src/RuleEngine.sol#L58-L62) +[RuleConditionalTransferOperator._approveRequest(RuleConditionalTransferInvariantStorage.TransferRequest,bool)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L374-L433) has external calls inside a loop: [options.automaticTransfer.cmtat.allowance(transferRequest.keyElement.from,address(this)) >= transferRequest.keyElement.value](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L410-L413) + +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L374-L433 -src/RuleEngine.sol#L44-L69 + + - [ ] ID-11 +[RuleEngine.messageForTransferRestriction(uint8)](src/RuleEngine.sol#L97-L125) has external calls inside a loop: [IRuleValidation(_rulesOperation[i_scope_0]).messageForTransferRestriction(_restrictionCode)](src/RuleEngine.sol#L119-L121) + +src/RuleEngine.sol#L97-L125 ## timestamp @@ -111,97 +107,68 @@ src/RuleEngine.sol#L44-L69 Impact: Low Confidence: Medium - - - [ ] ID-11 - [RuleConditionalTransfer._validateApproval(bytes32)](src/rules/operation/RuleConditionalTransfer.sol#L239-L251) uses timestamp for comparisons - Dangerous comparisons: - - [automaticApprovalCondition = options.automaticApproval.isActivate && ((transferRequests[key].askTime + options.automaticApproval.timeLimitBeforeAutomaticApproval) >= block.timestamp)](src/rules/operation/RuleConditionalTransfer.sol#L242) - - [isTransferApproved = (transferRequests[key].status == STATUS.APPROVED) && (transferRequests[key].maxTime >= block.timestamp)](src/rules/operation/RuleConditionalTransfer.sol#L243-L244) - - [automaticApprovalCondition || isTransferApproved](src/rules/operation/RuleConditionalTransfer.sol#L245) - -src/rules/operation/RuleConditionalTransfer.sol#L239-L251 - - - [ ] ID-12 - [RuleConditionalTransfer.cancelTransferRequest(uint256)](src/rules/operation/RuleConditionalTransfer.sol#L85-L103) uses timestamp for comparisons + [RuleConditionalTransferOperator._checkRequestStatus(bytes32)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L367-L372) uses timestamp for comparisons Dangerous comparisons: - - [transferRequests[key].from != _msgSender()](src/rules/operation/RuleConditionalTransfer.sol#L93) + - [(transferRequests[key].status == STATUS.NONE) && (transferRequests[key].key == 0x0)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L369-L371) -src/rules/operation/RuleConditionalTransfer.sol#L85-L103 +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L367-L372 - [ ] ID-13 - [RuleConditionalTransferOperator._approveRequest(RuleConditionalTransferInvariantStorage.TransferRequest,bool)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L124-L152) uses timestamp for comparisons + [RuleConditionalTransfer._validateApproval(bytes32)](src/rules/operation/RuleConditionalTransfer.sol#L332-L351) uses timestamp for comparisons Dangerous comparisons: - - [block.timestamp > (transferRequest.askTime + options.timeLimit.timeLimitToApprove)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L131) + - [automaticApprovalCondition = options.automaticApproval.isActivate && ((transferRequests[key].askTime + options.automaticApproval.timeLimitBeforeAutomaticApproval) >= block.timestamp)](src/rules/operation/RuleConditionalTransfer.sol#L336-L341) + - [isTransferApproved = (transferRequests[key].status == STATUS.APPROVED) && (transferRequests[key].maxTime >= block.timestamp)](src/rules/operation/RuleConditionalTransfer.sol#L343-L345) + - [automaticApprovalCondition || isTransferApproved](src/rules/operation/RuleConditionalTransfer.sol#L346) -src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L124-L152 +src/rules/operation/RuleConditionalTransfer.sol#L332-L351 - [ ] ID-14 - [RuleConditionalTransfer.getRequestByStatus(RuleConditionalTransferInvariantStorage.STATUS)](src/rules/operation/RuleConditionalTransfer.sol#L116-L141) uses timestamp for comparisons + [RuleConditionalTransfer.getRequestByStatus(RuleConditionalTransferInvariantStorage.STATUS)](src/rules/operation/RuleConditionalTransfer.sol#L194-L223) uses timestamp for comparisons Dangerous comparisons: - - [transferRequests[IdToKey[i]].status == _targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L123) - - [transferRequests[IdToKey[i_scope_0]].status == _targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L133) + - [transferRequests[IdToKey[i]].status == _targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L203) + - [transferRequests[IdToKey[i_scope_0]].status == _targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L213) -src/rules/operation/RuleConditionalTransfer.sol#L116-L141 +src/rules/operation/RuleConditionalTransfer.sol#L194-L223 - [ ] ID-15 - [RuleConditionalTransferOperator._checkRequestStatus(bytes32)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L120-L122) uses timestamp for comparisons + [RuleConditionalTransferOperator._approveRequest(RuleConditionalTransferInvariantStorage.TransferRequest,bool)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L374-L433) uses timestamp for comparisons + Dangerous comparisons: + - [transferRequest.status != STATUS.WAIT](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L379) + - [block.timestamp > (transferRequest.askTime + options.timeLimit.timeLimitToApprove)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L385-L386) + - [options.automaticTransfer.cmtat.allowance(transferRequest.keyElement.from,address(this)) >= transferRequest.keyElement.value](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L410-L413) + +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L374-L433 + + + - [ ] ID-16 + [RuleConditionalTransfer._cancelTransferRequest(uint256)](src/rules/operation/RuleConditionalTransfer.sol#L284-L301) uses timestamp for comparisons Dangerous comparisons: - - [(transferRequests[key].status == STATUS.NONE) && (transferRequests[key].key == 0x0)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L121) + - [transferRequests[key].keyElement.from != _msgSender()](src/rules/operation/RuleConditionalTransfer.sol#L290) -src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L120-L122 +src/rules/operation/RuleConditionalTransfer.sol#L284-L301 -## pragma +## costly-loop -> Concerns the CMTAT lib, will be fixed in the CMTAT lib. +> Acknowledge Impact: Informational -Confidence: High - - [ ] ID-16 - 2 different versions of Solidity are used: - - Version constraint ^0.8.0 is used by: - - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404.sol#3 - - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404EnumCode.sol#3 - - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404Wrapper.sol#3 - - lib/CMTAT/contracts/interfaces/engine/IRuleEngine.sol#3 - - Version constraint ^0.8.20 is used by: - - lib/openzeppelin-contracts/contracts/access/AccessControl.sol#4 - - lib/openzeppelin-contracts/contracts/access/IAccessControl.sol#4 - - lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol#4 - - lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol#4 - - lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Permit.sol#4 - - lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol#4 - - lib/openzeppelin-contracts/contracts/utils/Address.sol#4 - - lib/openzeppelin-contracts/contracts/utils/Context.sol#4 - - lib/openzeppelin-contracts/contracts/utils/introspection/ERC165.sol#4 - - lib/openzeppelin-contracts/contracts/utils/introspection/IERC165.sol#4 - - src/RuleEngine.sol#3 - - src/interfaces/IRuleEngineOperation.sol#3 - - src/interfaces/IRuleEngineValidation.sol#3 - - src/interfaces/IRuleOperation.sol#3 - - src/interfaces/IRuleValidation.sol#3 - - src/modules/MetaTxModuleStandalone.sol#3 - - src/modules/RuleEngineInvariantStorage.sol#3 - - src/modules/RuleEngineOperation.sol#3 - - src/modules/RuleEngineValidation.sol#3 - - src/modules/RuleInternal.sol#3 - - src/rules/operation/RuleConditionalTransfer.sol#3 - - src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#3 - - src/rules/operation/abstract/RuleConditionalTransferOperator.sol#3 - - src/rules/validation/RuleBlacklist.sol#3 - - src/rules/validation/RuleSanctionList.sol#3 - - src/rules/validation/RuleWhitelist.sol#3 - - src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#3 - - src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol#3 - - src/rules/validation/abstract/RuleAddressList/RuleAddressListInvariantStorage.sol#3 - - src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol#3 - - src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol#3 - - src/rules/validation/abstract/RuleCommonInvariantStorage.sol#2 - - src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol#3 - - src/rules/validation/abstract/RuleValidateTransfer.sol#3 +Confidence: Medium + - [ ] ID-17 + [RuleConditionalTransferOperator._createTransferRequestWithApproval(RuleConditionalTransferInvariantStorage.TransferRequestKeyElement)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L311-L354) has costly operations inside a loop: + - [++ requestId](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L339) + +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L311-L354 + + + - [ ] ID-18 + [RuleConditionalTransfer.createTransferRequest(address,uint256)](src/rules/operation/RuleConditionalTransfer.sol#L96-L135) has costly operations inside a loop: + - [++ requestId](src/rules/operation/RuleConditionalTransfer.sol#L122) + +src/rules/operation/RuleConditionalTransfer.sol#L96-L135 ## dead-code @@ -213,59 +180,51 @@ Confidence: High Impact: Informational Confidence: Medium - - [ ] ID-17 -[RuleSanctionList._msgData()](src/rules/validation/RuleSanctionList.sol#L108-L115) is never used and should be removed + - [ ] ID-19 +[RuleSanctionList._msgData()](src/rules/validation/RuleSanctionList.sol#L114-L121) is never used and should be removed -src/rules/validation/RuleSanctionList.sol#L108-L115 +src/rules/validation/RuleSanctionList.sol#L114-L121 - - [ ] ID-18 -[RuleAddressList._msgData()](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L118-L125) is never used and should be removed + - [ ] ID-20 +[RuleAddressList._msgData()](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L135-L142) is never used and should be removed -src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L118-L125 +src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L135-L142 - - [ ] ID-19 -[RuleConditionalTransfer._msgData()](src/rules/operation/RuleConditionalTransfer.sol#L268-L275) is never used and should be removed + - [ ] ID-21 +[RuleWhitelistWrapper._msgData()](src/rules/validation/RuleWhitelistWrapper.sol#L92-L99) is never used and should be removed -src/rules/operation/RuleConditionalTransfer.sol#L268-L275 +src/rules/validation/RuleWhitelistWrapper.sol#L92-L99 - - [ ] ID-20 -[RuleEngine._msgData()](src/RuleEngine.sol#L140-L147) is never used and should be removed + - [ ] ID-22 +[RuleConditionalTransfer._msgData()](src/rules/operation/RuleConditionalTransfer.sol#L368-L375) is never used and should be removed -src/RuleEngine.sol#L140-L147 +src/rules/operation/RuleConditionalTransfer.sol#L368-L375 + + + - [ ] ID-23 +[RuleEngine._msgData()](src/RuleEngine.sol#L160-L167) is never used and should be removed + +src/RuleEngine.sol#L160-L167 ## solc-version -> The version set in the config file is 0.8.22 +> The version set in the config file is 0.8.26 Impact: Informational Confidence: High - - - [ ] ID-21 -Version constraint ^0.8.0 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html) - - FullInlinerNonExpressionSplitArgumentEvaluationOrder - - MissingSideEffectsOnSelectorAccess - - AbiReencodingHeadOverflowWithStaticArrayCleanup - - DirtyBytesArrayToStorage - - DataLocationChangeInInternalOverride - - NestedCalldataArrayAbiReencodingSizeValidation - - SignedImmutables - - ABIDecodeTwoDimensionalArrayMemory - - KeccakCaching. - It is used by: - - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404.sol#3 - - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404EnumCode.sol#3 - - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404Wrapper.sol#3 - - lib/CMTAT/contracts/interfaces/engine/IRuleEngine.sol#3 - - - [ ] ID-22 + - [ ] ID-24 Version constraint ^0.8.20 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html) - VerbatimInvalidDeduplication - FullInlinerNonExpressionSplitArgumentEvaluationOrder - MissingSideEffectsOnSelectorAccess. It is used by: + - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404.sol#3 + - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404EnumCode.sol#3 + - lib/CMTAT/contracts/interfaces/draft-IERC1404/draft-IERC1404Wrapper.sol#3 + - lib/CMTAT/contracts/interfaces/engine/IRuleEngine.sol#3 - lib/openzeppelin-contracts/contracts/access/AccessControl.sol#4 - lib/openzeppelin-contracts/contracts/access/IAccessControl.sol#4 - lib/openzeppelin-contracts/contracts/metatx/ERC2771Context.sol#4 @@ -285,6 +244,7 @@ Version constraint ^0.8.0 contains known severe issues (https://solidity.readthe - src/modules/RuleEngineInvariantStorage.sol#3 - src/modules/RuleEngineOperation.sol#3 - src/modules/RuleEngineValidation.sol#3 + - src/modules/RuleEngineValidationCommon.sol#3 - src/modules/RuleInternal.sol#3 - src/rules/operation/RuleConditionalTransfer.sol#3 - src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#3 @@ -292,370 +252,400 @@ Version constraint ^0.8.0 contains known severe issues (https://solidity.readthe - src/rules/validation/RuleBlacklist.sol#3 - src/rules/validation/RuleSanctionList.sol#3 - src/rules/validation/RuleWhitelist.sol#3 + - src/rules/validation/RuleWhitelistWrapper.sol#3 - src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#3 - src/rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol#3 - - src/rules/validation/abstract/RuleAddressList/RuleAddressListInvariantStorage.sol#3 - - src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol#3 - - src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol#3 + - src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol#3 + - src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol#3 + - src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol#3 - src/rules/validation/abstract/RuleCommonInvariantStorage.sol#2 - src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol#3 - src/rules/validation/abstract/RuleValidateTransfer.sol#3 + - src/rules/validation/abstract/RuleWhitelistCommon.sol#3 ## naming-convention - -> It is not really necessary to rename all the variables. It will generate a lot of work for a minor improvement. - Impact: Informational Confidence: High - - [ ] ID-23 -Event [RuleConditionalTransferInvariantStorage.transferDenied(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L73) is not in CapWords - -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L73 - - - - [ ] ID-24 -Parameter [RuleConditionalTransfer.operateOnTransfer(address,address,uint256)._amount](src/rules/operation/RuleConditionalTransfer.sol#L150) is not in mixedCase - -src/rules/operation/RuleConditionalTransfer.sol#L150 - - - [ ] ID-25 -Parameter [RuleValidateTransfer.validateTransfer(address,address,uint256)._from](src/rules/validation/abstract/RuleValidateTransfer.sol#L16) is not in mixedCase +Event [RuleConditionalTransferInvariantStorage.transferDenied(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L125-L131) is not in CapWords -src/rules/validation/abstract/RuleValidateTransfer.sol#L16 +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L125-L131 - [ ] ID-26 -Parameter [RuleEngine.detectTransferRestriction(address,address,uint256)._amount](src/RuleEngine.sol#L47) is not in mixedCase +Parameter [RuleConditionalTransfer.operateOnTransfer(address,address,uint256)._amount](src/rules/operation/RuleConditionalTransfer.sol#L61) is not in mixedCase -src/RuleEngine.sol#L47 +src/rules/operation/RuleConditionalTransfer.sol#L61 - [ ] ID-27 -Event [RuleConditionalTransferInvariantStorage.transferReset(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L74) is not in CapWords +Parameter [RuleWhitelistCommon.canReturnTransferRestrictionCode(uint8)._restrictionCode](src/rules/validation/abstract/RuleWhitelistCommon.sol#L17) is not in mixedCase -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L74 +src/rules/validation/abstract/RuleWhitelistCommon.sol#L17 - [ ] ID-28 -Parameter [RuleEngineValidation.detectTransferRestrictionValidation(address,address,uint256)._amount](src/modules/RuleEngineValidation.sol#L146) is not in mixedCase +Parameter [RuleValidateTransfer.validateTransfer(address,address,uint256)._from](src/rules/validation/abstract/RuleValidateTransfer.sol#L16) is not in mixedCase -src/modules/RuleEngineValidation.sol#L146 +src/rules/validation/abstract/RuleValidateTransfer.sol#L16 - [ ] ID-29 -Parameter [RuleBlacklist.canReturnTransferRestrictionCode(uint8)._restrictionCode](src/rules/validation/RuleBlacklist.sol#L49) is not in mixedCase +Parameter [RuleEngine.detectTransferRestriction(address,address,uint256)._amount](src/RuleEngine.sol#L50) is not in mixedCase -src/rules/validation/RuleBlacklist.sol#L49 +src/RuleEngine.sol#L50 - [ ] ID-30 -Variable [RuleConditionalTransferOperator.IdToKey](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L22) is not in mixedCase +Event [RuleConditionalTransferInvariantStorage.transferReset(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L132-L138) is not in CapWords -src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L22 +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L132-L138 - [ ] ID-31 -Parameter [RuleSanctionList.detectTransferRestriction(address,address,uint256)._to](src/rules/validation/RuleSanctionList.sol#L50) is not in mixedCase +Parameter [RuleEngineValidation.detectTransferRestrictionValidation(address,address,uint256)._amount](src/modules/RuleEngineValidation.sol#L32) is not in mixedCase -src/rules/validation/RuleSanctionList.sol#L50 +src/modules/RuleEngineValidation.sol#L32 - [ ] ID-32 -Parameter [RuleBlacklist.detectTransferRestriction(address,address,uint256)._to](src/rules/validation/RuleBlacklist.sol#L31) is not in mixedCase +Parameter [RuleBlacklist.canReturnTransferRestrictionCode(uint8)._restrictionCode](src/rules/validation/RuleBlacklist.sol#L53) is not in mixedCase -src/rules/validation/RuleBlacklist.sol#L31 +src/rules/validation/RuleBlacklist.sol#L53 - [ ] ID-33 -Parameter [RuleEngine.detectTransferRestriction(address,address,uint256)._to](src/RuleEngine.sol#L46) is not in mixedCase +Parameter [RuleWhitelistCommon.messageForTransferRestriction(uint8)._restrictionCode](src/rules/validation/abstract/RuleWhitelistCommon.sol#L30) is not in mixedCase -src/RuleEngine.sol#L46 +src/rules/validation/abstract/RuleWhitelistCommon.sol#L30 - [ ] ID-34 -Parameter [RuleConditionalTransfer.detectTransferRestriction(address,address,uint256)._amount](src/rules/operation/RuleConditionalTransfer.sol#L174) is not in mixedCase +Variable [RuleConditionalTransferOperator.IdToKey](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L22) is not in mixedCase -src/rules/operation/RuleConditionalTransfer.sol#L174 +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L22 - [ ] ID-35 -Parameter [RuleConditionalTransfer.getRequestByStatus(RuleConditionalTransferInvariantStorage.STATUS)._targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L116) is not in mixedCase +Parameter [RuleSanctionList.detectTransferRestriction(address,address,uint256)._to](src/rules/validation/RuleSanctionList.sol#L56) is not in mixedCase -src/rules/operation/RuleConditionalTransfer.sol#L116 +src/rules/validation/RuleSanctionList.sol#L56 - [ ] ID-36 -Parameter [RuleEngine.detectTransferRestriction(address,address,uint256)._from](src/RuleEngine.sol#L45) is not in mixedCase +Parameter [RuleBlacklist.detectTransferRestriction(address,address,uint256)._to](src/rules/validation/RuleBlacklist.sol#L35) is not in mixedCase -src/RuleEngine.sol#L45 +src/rules/validation/RuleBlacklist.sol#L35 - [ ] ID-37 -Parameter [RuleConditionalTransfer.operateOnTransfer(address,address,uint256)._from](src/rules/operation/RuleConditionalTransfer.sol#L148) is not in mixedCase +Parameter [RuleEngine.detectTransferRestriction(address,address,uint256)._to](src/RuleEngine.sol#L49) is not in mixedCase -src/rules/operation/RuleConditionalTransfer.sol#L148 +src/RuleEngine.sol#L49 - [ ] ID-38 -Parameter [RuleBlacklist.messageForTransferRestriction(uint8)._restrictionCode](src/rules/validation/RuleBlacklist.sol#L62) is not in mixedCase +Parameter [RuleConditionalTransfer.detectTransferRestriction(address,address,uint256)._amount](src/rules/operation/RuleConditionalTransfer.sol#L234) is not in mixedCase -src/rules/validation/RuleBlacklist.sol#L62 +src/rules/operation/RuleConditionalTransfer.sol#L234 - [ ] ID-39 -Parameter [RuleEngine.messageForTransferRestriction(uint8)._restrictionCode](src/RuleEngine.sol#L92) is not in mixedCase +Parameter [RuleConditionalTransfer.getRequestByStatus(RuleConditionalTransferInvariantStorage.STATUS)._targetStatus](src/rules/operation/RuleConditionalTransfer.sol#L195) is not in mixedCase -src/RuleEngine.sol#L92 +src/rules/operation/RuleConditionalTransfer.sol#L195 - [ ] ID-40 -Parameter [RuleAddressList.removeAddressFromTheList(address)._removeWhitelistAddress](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L75) is not in mixedCase +Parameter [RuleEngine.detectTransferRestriction(address,address,uint256)._from](src/RuleEngine.sol#L48) is not in mixedCase -src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L75 +src/RuleEngine.sol#L48 - [ ] ID-41 -Parameter [RuleSanctionList.canReturnTransferRestrictionCode(uint8)._restrictionCode](src/rules/validation/RuleSanctionList.sol#L69) is not in mixedCase +Parameter [RuleWhitelistWrapper.detectTransferRestriction(address,address,uint256)._to](src/rules/validation/RuleWhitelistWrapper.sol#L42) is not in mixedCase -src/rules/validation/RuleSanctionList.sol#L69 +src/rules/validation/RuleWhitelistWrapper.sol#L42 - [ ] ID-42 -Parameter [RuleAddressList.addressIsListed(address)._targetAddress](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L97) is not in mixedCase +Parameter [RuleConditionalTransfer.operateOnTransfer(address,address,uint256)._from](src/rules/operation/RuleConditionalTransfer.sol#L59) is not in mixedCase -src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L97 +src/rules/operation/RuleConditionalTransfer.sol#L59 - [ ] ID-43 -Parameter [RuleWhitelist.canReturnTransferRestrictionCode(uint8)._restrictionCode](src/rules/validation/RuleWhitelist.sol#L49) is not in mixedCase +Parameter [RuleBlacklist.messageForTransferRestriction(uint8)._restrictionCode](src/rules/validation/RuleBlacklist.sol#L66) is not in mixedCase -src/rules/validation/RuleWhitelist.sol#L49 +src/rules/validation/RuleBlacklist.sol#L66 - [ ] ID-44 -Parameter [RuleEngineValidation.validateTransferValidation(address,address,uint256)._to](src/modules/RuleEngineValidation.sol#L172) is not in mixedCase +Parameter [RuleEngine.messageForTransferRestriction(uint8)._restrictionCode](src/RuleEngine.sol#L98) is not in mixedCase -src/modules/RuleEngineValidation.sol#L172 +src/RuleEngine.sol#L98 - [ ] ID-45 -Event [RuleConditionalTransferInvariantStorage.transferWaiting(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L71) is not in CapWords +Parameter [RuleAddressList.removeAddressFromTheList(address)._removeWhitelistAddress](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L80) is not in mixedCase -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L71 +src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L80 - [ ] ID-46 -Struct [RuleConditionalTransferInvariantStorage.TIME_LIMIT](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L18-L21) is not in CapWords +Parameter [RuleSanctionList.canReturnTransferRestrictionCode(uint8)._restrictionCode](src/rules/validation/RuleSanctionList.sol#L75) is not in mixedCase -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L18-L21 +src/rules/validation/RuleSanctionList.sol#L75 - [ ] ID-47 -Parameter [RuleConditionalTransfer.canReturnTransferRestrictionCode(uint8)._restrictionCode](src/rules/operation/RuleConditionalTransfer.sol#L191) is not in mixedCase +Parameter [RuleAddressList.addressIsListed(address)._targetAddress](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L101) is not in mixedCase -src/rules/operation/RuleConditionalTransfer.sol#L191 +src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L101 - [ ] ID-48 -Parameter [RuleEngine.validateTransfer(address,address,uint256)._amount](src/RuleEngine.sol#L81) is not in mixedCase +Parameter [RuleEngineValidation.validateTransferValidation(address,address,uint256)._to](src/modules/RuleEngineValidation.sol#L55) is not in mixedCase -src/RuleEngine.sol#L81 +src/modules/RuleEngineValidation.sol#L55 - [ ] ID-49 -Struct [RuleConditionalTransferInvariantStorage.AUTOMATIC_APPROVAL](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L23-L26) is not in CapWords +Event [RuleConditionalTransferInvariantStorage.transferWaiting(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L111-L117) is not in CapWords -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L23-L26 +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L111-L117 - [ ] ID-50 -Parameter [RuleEngineValidation.validateTransferValidation(address,address,uint256)._from](src/modules/RuleEngineValidation.sol#L171) is not in mixedCase +Struct [RuleConditionalTransferInvariantStorage.TIME_LIMIT](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L30-L35) is not in CapWords -src/modules/RuleEngineValidation.sol#L171 +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L30-L35 - [ ] ID-51 -Parameter [RuleSanctionList.detectTransferRestriction(address,address,uint256)._from](src/rules/validation/RuleSanctionList.sol#L49) is not in mixedCase +Parameter [RuleConditionalTransfer.canReturnTransferRestrictionCode(uint8)._restrictionCode](src/rules/operation/RuleConditionalTransfer.sol#L259) is not in mixedCase -src/rules/validation/RuleSanctionList.sol#L49 +src/rules/operation/RuleConditionalTransfer.sol#L259 - [ ] ID-52 -Parameter [RuleConditionalTransfer.detectTransferRestriction(address,address,uint256)._to](src/rules/operation/RuleConditionalTransfer.sol#L173) is not in mixedCase +Parameter [RuleEngine.validateTransfer(address,address,uint256)._amount](src/RuleEngine.sol#L85) is not in mixedCase -src/rules/operation/RuleConditionalTransfer.sol#L173 +src/RuleEngine.sol#L85 - [ ] ID-53 -Parameter [RuleEngineValidation.detectTransferRestrictionValidation(address,address,uint256)._from](src/modules/RuleEngineValidation.sol#L144) is not in mixedCase +Struct [RuleConditionalTransferInvariantStorage.AUTOMATIC_APPROVAL](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L37-L44) is not in CapWords -src/modules/RuleEngineValidation.sol#L144 +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L37-L44 - [ ] ID-54 -Parameter [RuleEngineValidation.validateTransferValidation(address,address,uint256)._amount](src/modules/RuleEngineValidation.sol#L173) is not in mixedCase +Parameter [RuleEngineValidation.validateTransferValidation(address,address,uint256)._from](src/modules/RuleEngineValidation.sol#L54) is not in mixedCase -src/modules/RuleEngineValidation.sol#L173 +src/modules/RuleEngineValidation.sol#L54 - [ ] ID-55 -Parameter [RuleWhitelist.detectTransferRestriction(address,address,uint256)._to](src/rules/validation/RuleWhitelist.sol#L31) is not in mixedCase +Parameter [RuleSanctionList.detectTransferRestriction(address,address,uint256)._from](src/rules/validation/RuleSanctionList.sol#L55) is not in mixedCase -src/rules/validation/RuleWhitelist.sol#L31 +src/rules/validation/RuleSanctionList.sol#L55 - [ ] ID-56 -Parameter [RuleWhitelist.messageForTransferRestriction(uint8)._restrictionCode](src/rules/validation/RuleWhitelist.sol#L62) is not in mixedCase +Parameter [RuleConditionalTransfer.detectTransferRestriction(address,address,uint256)._to](src/rules/operation/RuleConditionalTransfer.sol#L233) is not in mixedCase -src/rules/validation/RuleWhitelist.sol#L62 +src/rules/operation/RuleConditionalTransfer.sol#L233 - [ ] ID-57 -Struct [RuleConditionalTransferInvariantStorage.AUTOMATIC_TRANSFER](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L9-L12) is not in CapWords +Parameter [RuleEngineValidation.detectTransferRestrictionValidation(address,address,uint256)._from](src/modules/RuleEngineValidation.sol#L30) is not in mixedCase -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L9-L12 +src/modules/RuleEngineValidation.sol#L30 - [ ] ID-58 -Parameter [RuleValidateTransfer.validateTransfer(address,address,uint256)._to](src/rules/validation/abstract/RuleValidateTransfer.sol#L17) is not in mixedCase +Parameter [RuleEngineValidation.validateTransferValidation(address,address,uint256)._amount](src/modules/RuleEngineValidation.sol#L56) is not in mixedCase -src/rules/validation/abstract/RuleValidateTransfer.sol#L17 +src/modules/RuleEngineValidation.sol#L56 - [ ] ID-59 -Parameter [RuleInternal.getRuleIndex(address[],address)._rules](src/modules/RuleInternal.sol#L90) is not in mixedCase +Parameter [RuleWhitelistWrapper.detectTransferRestriction(address,address,uint256)._from](src/rules/validation/RuleWhitelistWrapper.sol#L41) is not in mixedCase -src/modules/RuleInternal.sol#L90 +src/rules/validation/RuleWhitelistWrapper.sol#L41 - [ ] ID-60 -Parameter [RuleAddressList.addAddressToTheList(address)._newWhitelistAddress](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L63) is not in mixedCase +Parameter [RuleWhitelist.detectTransferRestriction(address,address,uint256)._to](src/rules/validation/RuleWhitelist.sol#L30) is not in mixedCase -src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L63 +src/rules/validation/RuleWhitelist.sol#L30 - [ ] ID-61 -Event [RuleConditionalTransferInvariantStorage.transferProcessed(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L70) is not in CapWords +Struct [RuleConditionalTransferInvariantStorage.AUTOMATIC_TRANSFER](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L18-L21) is not in CapWords -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L70 +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L18-L21 - [ ] ID-62 -Parameter [RuleWhitelist.detectTransferRestriction(address,address,uint256)._from](src/rules/validation/RuleWhitelist.sol#L30) is not in mixedCase +Parameter [RuleValidateTransfer.validateTransfer(address,address,uint256)._to](src/rules/validation/abstract/RuleValidateTransfer.sol#L17) is not in mixedCase -src/rules/validation/RuleWhitelist.sol#L30 +src/rules/validation/abstract/RuleValidateTransfer.sol#L17 - [ ] ID-63 -Parameter [RuleValidateTransfer.validateTransfer(address,address,uint256)._amount](src/rules/validation/abstract/RuleValidateTransfer.sol#L18) is not in mixedCase +Parameter [RuleInternal.getRuleIndex(address[],address)._rules](src/modules/RuleInternal.sol#L85) is not in mixedCase -src/rules/validation/abstract/RuleValidateTransfer.sol#L18 +src/modules/RuleInternal.sol#L85 - [ ] ID-64 -Parameter [RuleEngine.validateTransfer(address,address,uint256)._from](src/RuleEngine.sol#L79) is not in mixedCase +Function [RuleConditionalTransferOperator._createTransferRequestWithApproval(RuleConditionalTransferInvariantStorage.TransferRequestKeyElement)](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L311-L354) is not in mixedCase -src/RuleEngine.sol#L79 +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L311-L354 - [ ] ID-65 -Parameter [RuleConditionalTransfer.operateOnTransfer(address,address,uint256)._to](src/rules/operation/RuleConditionalTransfer.sol#L149) is not in mixedCase +Parameter [RuleAddressList.addAddressToTheList(address)._newWhitelistAddress](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L68) is not in mixedCase -src/rules/operation/RuleConditionalTransfer.sol#L149 +src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L68 - [ ] ID-66 -Parameter [RuleConditionalTransfer.detectTransferRestriction(address,address,uint256)._from](src/rules/operation/RuleConditionalTransfer.sol#L172) is not in mixedCase +Event [RuleConditionalTransferInvariantStorage.transferProcessed(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L104-L110) is not in CapWords -src/rules/operation/RuleConditionalTransfer.sol#L172 +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L104-L110 - [ ] ID-67 -Parameter [RuleEngineValidation.detectTransferRestrictionValidation(address,address,uint256)._to](src/modules/RuleEngineValidation.sol#L145) is not in mixedCase +Parameter [RuleWhitelist.detectTransferRestriction(address,address,uint256)._from](src/rules/validation/RuleWhitelist.sol#L29) is not in mixedCase -src/modules/RuleEngineValidation.sol#L145 +src/rules/validation/RuleWhitelist.sol#L29 - [ ] ID-68 -Parameter [RuleBlacklist.detectTransferRestriction(address,address,uint256)._from](src/rules/validation/RuleBlacklist.sol#L30) is not in mixedCase +Parameter [RuleValidateTransfer.validateTransfer(address,address,uint256)._amount](src/rules/validation/abstract/RuleValidateTransfer.sol#L18) is not in mixedCase -src/rules/validation/RuleBlacklist.sol#L30 +src/rules/validation/abstract/RuleValidateTransfer.sol#L18 - [ ] ID-69 -Parameter [RuleConditionalTransfer.messageForTransferRestriction(uint8)._restrictionCode](src/rules/operation/RuleConditionalTransfer.sol#L203) is not in mixedCase +Parameter [RuleEngine.validateTransfer(address,address,uint256)._from](src/RuleEngine.sol#L83) is not in mixedCase -src/rules/operation/RuleConditionalTransfer.sol#L203 +src/RuleEngine.sol#L83 - [ ] ID-70 -Parameter [RuleSanctionList.messageForTransferRestriction(uint8)._restrictionCode](src/rules/validation/RuleSanctionList.sol#L82) is not in mixedCase +Parameter [RuleConditionalTransfer.operateOnTransfer(address,address,uint256)._to](src/rules/operation/RuleConditionalTransfer.sol#L60) is not in mixedCase -src/rules/validation/RuleSanctionList.sol#L82 +src/rules/operation/RuleConditionalTransfer.sol#L60 - [ ] ID-71 -Parameter [RuleEngine.validateTransfer(address,address,uint256)._to](src/RuleEngine.sol#L80) is not in mixedCase +Parameter [RuleConditionalTransfer.detectTransferRestriction(address,address,uint256)._from](src/rules/operation/RuleConditionalTransfer.sol#L232) is not in mixedCase -src/RuleEngine.sol#L80 +src/rules/operation/RuleConditionalTransfer.sol#L232 - [ ] ID-72 -Event [RuleConditionalTransferInvariantStorage.transferApproved(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L72) is not in CapWords +Parameter [RuleEngineValidation.detectTransferRestrictionValidation(address,address,uint256)._to](src/modules/RuleEngineValidation.sol#L31) is not in mixedCase -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L72 +src/modules/RuleEngineValidation.sol#L31 -## similar-names -Impact: Informational -Confidence: Medium - [ ] ID-73 -Variable [RuleSanctionlistInvariantStorage.CODE_ADDRESS_FROM_IS_SANCTIONED](src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol#L23) is too similar to [RuleSanctionlistInvariantStorage.TEXT_ADDRESS_FROM_IS_SANCTIONED](src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol#L15-L16) +Parameter [RuleBlacklist.detectTransferRestriction(address,address,uint256)._from](src/rules/validation/RuleBlacklist.sol#L34) is not in mixedCase -src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol#L23 +src/rules/validation/RuleBlacklist.sol#L34 - [ ] ID-74 -Variable [RuleConditionalTransferInvariantStorage.CODE_TRANSFER_REQUEST_NOT_APPROVED](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L56) is too similar to [RuleConditionalTransferInvariantStorage.TEXT_TRANSFER_REQUEST_NOT_APPROVED](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L52-L53) +Parameter [RuleConditionalTransfer.messageForTransferRestriction(uint8)._restrictionCode](src/rules/operation/RuleConditionalTransfer.sol#L270) is not in mixedCase -src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L56 +src/rules/operation/RuleConditionalTransfer.sol#L270 - [ ] ID-75 -Variable [RuleBlacklistInvariantStorage.CODE_ADDRESS_FROM_IS_BLACKLISTED](src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol#L16) is too similar to [RuleBlacklistInvariantStorage.TEXT_ADDRESS_FROM_IS_BLACKLISTED](src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol#L9-L10) +Parameter [RuleSanctionList.messageForTransferRestriction(uint8)._restrictionCode](src/rules/validation/RuleSanctionList.sol#L88) is not in mixedCase -src/rules/validation/abstract/RuleAddressList/RuleBlacklistInvariantStorage.sol#L16 +src/rules/validation/RuleSanctionList.sol#L88 - [ ] ID-76 -Variable [RuleWhitelistInvariantStorage.CODE_ADDRESS_TO_NOT_WHITELISTED](src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol#L17) is too similar to [RuleWhitelistInvariantStorage.TEXT_ADDRESS_TO_NOT_WHITELISTED](src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol#L11-L12) +Parameter [RuleAddressList.addressIsListedBatch(address[])._targetAddresses](src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L111) is not in mixedCase -src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol#L17 +src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol#L111 - [ ] ID-77 -Variable [RuleWhitelistInvariantStorage.CODE_ADDRESS_FROM_NOT_WHITELISTED](src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol#L16) is too similar to [RuleWhitelistInvariantStorage.TEXT_ADDRESS_FROM_NOT_WHITELISTED](src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol#L9-L10) +Parameter [RuleEngine.validateTransfer(address,address,uint256)._to](src/RuleEngine.sol#L84) is not in mixedCase -src/rules/validation/abstract/RuleAddressList/RuleWhitelistInvariantStorage.sol#L16 +src/RuleEngine.sol#L84 -## unused-import -> Concerns an external library + - [ ] ID-78 +Event [RuleConditionalTransferInvariantStorage.transferApproved(bytes32,address,address,uint256,uint256)](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L118-L124) is not in CapWords + +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L118-L124 + + +## similar-names +Impact: Informational +Confidence: Medium + - [ ] ID-79 +Variable [RuleSanctionlistInvariantStorage.CODE_ADDRESS_FROM_IS_SANCTIONED](src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol#L25) is too similar to [RuleSanctionlistInvariantStorage.TEXT_ADDRESS_FROM_IS_SANCTIONED](src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol#L18-L19) + +src/rules/validation/abstract/RuleSanctionListInvariantStorage.sol#L25 + + + - [ ] ID-80 +Variable [RuleConditionalTransferOperator._createTransferRequestWithApproval(RuleConditionalTransferInvariantStorage.TransferRequestKeyElement).keyElement_](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L312) is too similar to [RuleConditionalTransferOperator.createTransferRequestWithApprovalBatch(RuleConditionalTransferInvariantStorage.TransferRequestKeyElement[]).keyElements](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L246) + +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L312 + + + - [ ] ID-81 +Variable [RuleConditionalTransferOperator._createTransferRequestWithApproval(RuleConditionalTransferInvariantStorage.TransferRequestKeyElement).keyElement_](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L312) is too similar to [RuleConditionalTransferOperator.approveTransferRequestBatch(RuleConditionalTransferInvariantStorage.TransferRequestKeyElement[],uint256[],bool[]).keyElements](src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L220) + +src/rules/operation/abstract/RuleConditionalTransferOperator.sol#L312 + + - [ ] ID-82 +Variable [RuleConditionalTransferInvariantStorage.CODE_TRANSFER_REQUEST_NOT_APPROVED](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L88) is too similar to [RuleConditionalTransferInvariantStorage.TEXT_TRANSFER_REQUEST_NOT_APPROVED](src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L84-L85) + +src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol#L88 + + + - [ ] ID-83 +Variable [RuleBlacklistInvariantStorage.CODE_ADDRESS_FROM_IS_BLACKLISTED](src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol#L16) is too similar to [RuleBlacklistInvariantStorage.TEXT_ADDRESS_FROM_IS_BLACKLISTED](src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol#L9-L10) + +src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol#L16 + + + - [ ] ID-84 +Variable [RuleWhitelistInvariantStorage.CODE_ADDRESS_TO_NOT_WHITELISTED](src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol#L17) is too similar to [RuleWhitelistInvariantStorage.TEXT_ADDRESS_TO_NOT_WHITELISTED](src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol#L11-L12) + +src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol#L17 + + + - [ ] ID-85 +Variable [RuleWhitelistInvariantStorage.CODE_ADDRESS_FROM_NOT_WHITELISTED](src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol#L16) is too similar to [RuleWhitelistInvariantStorage.TEXT_ADDRESS_FROM_NOT_WHITELISTED](src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol#L9-L10) + +src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol#L16 + + +## unused-import Impact: Informational Confidence: High - - [ ] ID-78 + - [ ] ID-86 The following unused import(s) in lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol should be removed: -import {IERC20Permit} from "../extensions/IERC20Permit.sol"; (lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol#7) ## var-read-using-this - -> It does not work without the this keyword "Undeclared identifier" - Impact: Optimization Confidence: High - - [ ] ID-79 + - [ ] ID-87 The function [RuleValidateTransfer.validateTransfer(address,address,uint256)](src/rules/validation/abstract/RuleValidateTransfer.sol#L15-L24) reads [this.detectTransferRestriction(_from,_to,_amount) == uint8(REJECTED_CODE_BASE.TRANSFER_OK)](src/rules/validation/abstract/RuleValidateTransfer.sol#L21-L23) with `this` which adds an extra STATICCALL. src/rules/validation/abstract/RuleValidateTransfer.sol#L15-L24 diff --git a/doc/surya/surya_graph/surya_graph_RuleAddressList.sol.png b/doc/surya/surya_graph/surya_graph_RuleAddressList.sol.png index 484142b..e43eaeb 100644 Binary files a/doc/surya/surya_graph/surya_graph_RuleAddressList.sol.png and b/doc/surya/surya_graph/surya_graph_RuleAddressList.sol.png differ diff --git a/doc/surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png b/doc/surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png index 63ada00..b703a28 100644 Binary files a/doc/surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png and b/doc/surya/surya_graph/surya_graph_RuleConditionalTransfer.sol.png differ diff --git a/doc/surya/surya_graph/surya_graph_RuleEngineOperation.sol.png b/doc/surya/surya_graph/surya_graph_RuleEngineOperation.sol.png index d6f49ab..2b42825 100644 Binary files a/doc/surya/surya_graph/surya_graph_RuleEngineOperation.sol.png and b/doc/surya/surya_graph/surya_graph_RuleEngineOperation.sol.png differ diff --git a/doc/surya/surya_graph/surya_graph_RuleEngineValidationCommon.sol.png b/doc/surya/surya_graph/surya_graph_RuleEngineValidationCommon.sol.png index 8f9337d..2987ded 100644 Binary files a/doc/surya/surya_graph/surya_graph_RuleEngineValidationCommon.sol.png and b/doc/surya/surya_graph/surya_graph_RuleEngineValidationCommon.sol.png differ diff --git a/doc/surya/surya_graph/surya_graph_RuleInternal.sol.png b/doc/surya/surya_graph/surya_graph_RuleInternal.sol.png index e48ebdb..c4af7de 100644 Binary files a/doc/surya/surya_graph/surya_graph_RuleInternal.sol.png and b/doc/surya/surya_graph/surya_graph_RuleInternal.sol.png differ diff --git a/doc/surya/surya_graph/surya_graph_RuleWhitelist.sol.png b/doc/surya/surya_graph/surya_graph_RuleWhitelist.sol.png index c60bea2..3dfa8a2 100644 Binary files a/doc/surya/surya_graph/surya_graph_RuleWhitelist.sol.png and b/doc/surya/surya_graph/surya_graph_RuleWhitelist.sol.png differ diff --git a/doc/surya/surya_graph/surya_graph_RuleWhitelistCommon.sol.png b/doc/surya/surya_graph/surya_graph_RuleWhitelistCommon.sol.png new file mode 100644 index 0000000..d0dceed Binary files /dev/null and b/doc/surya/surya_graph/surya_graph_RuleWhitelistCommon.sol.png differ diff --git a/doc/surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png b/doc/surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png index 2a33926..a7849b2 100644 Binary files a/doc/surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png and b/doc/surya/surya_graph/surya_graph_RuleWhitelistWrapper.sol.png differ diff --git a/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelist.sol.png b/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelist.sol.png index f84ae39..ae8f3b6 100644 Binary files a/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelist.sol.png and b/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelist.sol.png differ diff --git a/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelistCommon.sol.png b/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelistCommon.sol.png new file mode 100644 index 0000000..f75664a Binary files /dev/null and b/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelistCommon.sol.png differ diff --git a/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelistWrapper.sol.png b/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelistWrapper.sol.png index fd9f2ac..73d3cb3 100644 Binary files a/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelistWrapper.sol.png and b/doc/surya/surya_inheritance/surya_inheritance_RuleWhitelistWrapper.sol.png differ diff --git a/doc/surya/surya_report/surya_report_IRuleEngineOperation.sol.md b/doc/surya/surya_report/surya_report_IRuleEngineOperation.sol.md index 23555f3..eb41011 100644 --- a/doc/surya/surya_report/surya_report_IRuleEngineOperation.sol.md +++ b/doc/surya/surya_report/surya_report_IRuleEngineOperation.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/IRuleEngineOperation.sol | ce32a424f59bb649e17976bcc9617e0c706c0d11 | +| ./interfaces/IRuleEngineOperation.sol | 4bb16cd4f36ba8ce8133f2313fcded0796fc67b3 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_IRuleEngineValidation.sol.md b/doc/surya/surya_report/surya_report_IRuleEngineValidation.sol.md index 81d8773..0a34e51 100644 --- a/doc/surya/surya_report/surya_report_IRuleEngineValidation.sol.md +++ b/doc/surya/surya_report/surya_report_IRuleEngineValidation.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/IRuleEngineValidation.sol | 11118806381880ade78b3dbba1cea694c9a8014e | +| ./interfaces/IRuleEngineValidation.sol | ae7c36b3a2c7805ef513f79b79bd6ce9d0357847 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_IRuleOperation.sol.md b/doc/surya/surya_report/surya_report_IRuleOperation.sol.md index 57c42ab..e6dfbb1 100644 --- a/doc/surya/surya_report/surya_report_IRuleOperation.sol.md +++ b/doc/surya/surya_report/surya_report_IRuleOperation.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./interfaces/IRuleOperation.sol | 7ea885c00f24740a5d85ba1b2447a0bc0b8df410 | +| ./interfaces/IRuleOperation.sol | 0284e295bdd4e46766290c62aa04841ffba6e056 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleAddressList.sol.md b/doc/surya/surya_report/surya_report_RuleAddressList.sol.md index ce6420b..ff6c938 100644 --- a/doc/surya/surya_report/surya_report_RuleAddressList.sol.md +++ b/doc/surya/surya_report/surya_report_RuleAddressList.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/abstract/RuleAddressList/RuleAddressList.sol | 5cbdfeb513dd3181dd8654b57e32bd0f4b49f981 | +| ./rules/validation/abstract/RuleAddressList/RuleAddressList.sol | c967eb21311041eb58c7feb097a6224ec34b0c82 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleAddressListInternal.sol.md b/doc/surya/surya_report/surya_report_RuleAddressListInternal.sol.md index bbbb212..223099a 100644 --- a/doc/surya/surya_report/surya_report_RuleAddressListInternal.sol.md +++ b/doc/surya/surya_report/surya_report_RuleAddressListInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol | a9b81a37ca2d5b9f0890285be22ed09935e155e7 | +| ./rules/validation/abstract/RuleAddressList/RuleAddressListInternal.sol | c32f77690c4c1ffcf5541e91fba1c838a17890ee | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleAddressListInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleAddressListInvariantStorage.sol.md index 62de3eb..2c8378b 100644 --- a/doc/surya/surya_report/surya_report_RuleAddressListInvariantStorage.sol.md +++ b/doc/surya/surya_report/surya_report_RuleAddressListInvariantStorage.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol | f9927d2adb13a39b3f83b0c810f3fa559272c341 | +| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol | 7cbf2581ae0836b91ab89a9daf1f4d6daa64fc7a | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleBlacklist.sol.md b/doc/surya/surya_report/surya_report_RuleBlacklist.sol.md index d22d5db..0ae2161 100644 --- a/doc/surya/surya_report/surya_report_RuleBlacklist.sol.md +++ b/doc/surya/surya_report/surya_report_RuleBlacklist.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/RuleBlacklist.sol | 9bf4aefed66c48ac2b68bad9c56b9f3e01e8da24 | +| ./rules/validation/RuleBlacklist.sol | bc23ad3743afc27239d05d7787f6f48840373e20 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleBlacklistInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleBlacklistInvariantStorage.sol.md index ca7c79c..641e318 100644 --- a/doc/surya/surya_report/surya_report_RuleBlacklistInvariantStorage.sol.md +++ b/doc/surya/surya_report/surya_report_RuleBlacklistInvariantStorage.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol | cf47d03ede24ba35080106f8d4380bb651e92c39 | +| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol | ba066cb426060eaca152daa5bb489970c2f9c539 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleCommonInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleCommonInvariantStorage.sol.md index 65b2318..df9fbc9 100644 --- a/doc/surya/surya_report/surya_report_RuleCommonInvariantStorage.sol.md +++ b/doc/surya/surya_report/surya_report_RuleCommonInvariantStorage.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/abstract/RuleCommonInvariantStorage.sol | 80524d71d14976811e0e82a790c3d5497308e1c0 | +| ./rules/validation/abstract/RuleCommonInvariantStorage.sol | bd2bf75999a7920aa4d6be476762d747efa15515 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleConditionalTransfer.sol.md b/doc/surya/surya_report/surya_report_RuleConditionalTransfer.sol.md index a6b5528..553f3c9 100644 --- a/doc/surya/surya_report/surya_report_RuleConditionalTransfer.sol.md +++ b/doc/surya/surya_report/surya_report_RuleConditionalTransfer.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/operation/RuleConditionalTransfer.sol | 9e082774ea9e8c645735266d8935f0cea686ef07 | +| ./rules/operation/RuleConditionalTransfer.sol | c374bce394733d30cfdeaabb4fd96ac904c701a3 | ### Contracts Description Table @@ -17,17 +17,17 @@ |||||| | **RuleConditionalTransfer** | Implementation | RuleValidateTransfer, IRuleOperation, RuleConditionalTransferOperator, MetaTxModuleStandalone ||| | └ | | Public ❗️ | 🛑 | MetaTxModuleStandalone | +| └ | operateOnTransfer | Public ❗️ | 🛑 | onlyRole | | └ | createTransferRequest | Public ❗️ | 🛑 |NO❗️ | | └ | createTransferRequestBatch | Public ❗️ | 🛑 |NO❗️ | | └ | cancelTransferRequest | Public ❗️ | 🛑 |NO❗️ | | └ | cancelTransferRequestBatch | Public ❗️ | 🛑 |NO❗️ | -| └ | _cancelTransferRequest | Internal 🔒 | 🛑 | | | └ | getRequestTrade | Public ❗️ | |NO❗️ | | └ | getRequestByStatus | Public ❗️ | |NO❗️ | -| └ | operateOnTransfer | Public ❗️ | 🛑 | onlyRole | | └ | detectTransferRestriction | Public ❗️ | |NO❗️ | | └ | canReturnTransferRestrictionCode | External ❗️ | |NO❗️ | | └ | messageForTransferRestriction | External ❗️ | |NO❗️ | +| └ | _cancelTransferRequest | Internal 🔒 | 🛑 | | | └ | _validateBurnMint | Internal 🔒 | | | | └ | _validateApproval | Internal 🔒 | | | | └ | _msgSender | Internal 🔒 | | | diff --git a/doc/surya/surya_report/surya_report_RuleConditionalTransferInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleConditionalTransferInvariantStorage.sol.md index 3e68d6f..944844d 100644 --- a/doc/surya/surya_report/surya_report_RuleConditionalTransferInvariantStorage.sol.md +++ b/doc/surya/surya_report/surya_report_RuleConditionalTransferInvariantStorage.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol | fca0008dbf1e9645944506d01fea4281a5e5208b | +| ./rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol | 71ed84800ef21f7f0964ed6dfa744eb444cded98 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleConditionalTransferOperator.sol.md b/doc/surya/surya_report/surya_report_RuleConditionalTransferOperator.sol.md index 11d4af0..759ed25 100644 --- a/doc/surya/surya_report/surya_report_RuleConditionalTransferOperator.sol.md +++ b/doc/surya/surya_report/surya_report_RuleConditionalTransferOperator.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/operation/abstract/RuleConditionalTransferOperator.sol | 5e35d28ab99475759783fca1614544e132797487 | +| ./rules/operation/abstract/RuleConditionalTransferOperator.sol | dee2c32effd6ffa0da948f5a18219c8a7d4ebd14 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleEngine.sol.md b/doc/surya/surya_report/surya_report_RuleEngine.sol.md index 4cc45b2..1cf40f7 100644 --- a/doc/surya/surya_report/surya_report_RuleEngine.sol.md +++ b/doc/surya/surya_report/surya_report_RuleEngine.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./RuleEngine.sol | 9ac4a4a50634a369d5b88418fc8d1af7a3b1df77 | +| ./RuleEngine.sol | 6454d098574b8dc8cd532554aa71faf9cd9dd28a | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleEngineInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleEngineInvariantStorage.sol.md index ddf1dc5..aca78d7 100644 --- a/doc/surya/surya_report/surya_report_RuleEngineInvariantStorage.sol.md +++ b/doc/surya/surya_report/surya_report_RuleEngineInvariantStorage.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/RuleEngineInvariantStorage.sol | 824864b8a40f1f4ff47cc91e3226d6cd92b9ed3c | +| ./modules/RuleEngineInvariantStorage.sol | ae8100bce2e00f37166e10c998d9747a0bdf5ef4 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleEngineOperation.sol.md b/doc/surya/surya_report/surya_report_RuleEngineOperation.sol.md index 0243375..9083954 100644 --- a/doc/surya/surya_report/surya_report_RuleEngineOperation.sol.md +++ b/doc/surya/surya_report/surya_report_RuleEngineOperation.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/RuleEngineOperation.sol | 428f410167252dbe376f484fccaa796cb1309851 | +| ./modules/RuleEngineOperation.sol | 1e1185c6f479770d66aabb692a54d331cbaf8f4d | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleEngineValidation.sol.md b/doc/surya/surya_report/surya_report_RuleEngineValidation.sol.md index 7b9b7c5..01894ff 100644 --- a/doc/surya/surya_report/surya_report_RuleEngineValidation.sol.md +++ b/doc/surya/surya_report/surya_report_RuleEngineValidation.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/RuleEngineValidation.sol | 6b65517a26ad9ef8bfc88dad98a35bd8b29fcca4 | +| ./modules/RuleEngineValidation.sol | 0f30ea71d3ce862e4bbb3083e0e45670a3393000 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleEngineValidationCommon.sol.md b/doc/surya/surya_report/surya_report_RuleEngineValidationCommon.sol.md index b1d05aa..19e253b 100644 --- a/doc/surya/surya_report/surya_report_RuleEngineValidationCommon.sol.md +++ b/doc/surya/surya_report/surya_report_RuleEngineValidationCommon.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/RuleEngineValidationCommon.sol | 9c992d27ccef264c7cb0c3137f384541590f9bfd | +| ./modules/RuleEngineValidationCommon.sol | 10414c0f3b47baecd5d5e8abe9d9d05c35ca7599 | ### Contracts Description Table @@ -18,14 +18,14 @@ | **RuleEngineValidationCommon** | Implementation | AccessControl, RuleInternal, IRuleEngineValidationCommon ||| | └ | setRulesValidation | Public ❗️ | 🛑 | onlyRole | | └ | clearRulesValidation | Public ❗️ | 🛑 | onlyRole | -| └ | _clearRulesValidation | Internal 🔒 | 🛑 | | | └ | addRuleValidation | Public ❗️ | 🛑 | onlyRole | | └ | removeRuleValidation | Public ❗️ | 🛑 | onlyRole | -| └ | _removeRuleValidation | Internal 🔒 | 🛑 | | | └ | rulesCountValidation | External ❗️ | |NO❗️ | | └ | getRuleIndexValidation | External ❗️ | |NO❗️ | | └ | ruleValidation | External ❗️ | |NO❗️ | | └ | rulesValidation | External ❗️ | |NO❗️ | +| └ | _clearRulesValidation | Internal 🔒 | 🛑 | | +| └ | _removeRuleValidation | Internal 🔒 | 🛑 | | ### Legend diff --git a/doc/surya/surya_report/surya_report_RuleInternal.sol.md b/doc/surya/surya_report/surya_report_RuleInternal.sol.md index c7eb8fc..0eddb1f 100644 --- a/doc/surya/surya_report/surya_report_RuleInternal.sol.md +++ b/doc/surya/surya_report/surya_report_RuleInternal.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./modules/RuleInternal.sol | 9c97852f35d10e4504f43f5594387eb63ca8e501 | +| ./modules/RuleInternal.sol | 7bad85bfbad52abc2ab9082628bf6bba2ee116f4 | ### Contracts Description Table @@ -19,7 +19,7 @@ | └ | _setRules | Internal 🔒 | 🛑 | | | └ | _addRule | Internal 🔒 | 🛑 | | | └ | _removeRule | Internal 🔒 | 🛑 | | -| └ | getRuleIndex | Internal 🔒 | | | +| └ | _getRuleIndex | Internal 🔒 | | | ### Legend diff --git a/doc/surya/surya_report/surya_report_RuleSanctionList.sol.md b/doc/surya/surya_report/surya_report_RuleSanctionList.sol.md index 3ad459d..45eaabb 100644 --- a/doc/surya/surya_report/surya_report_RuleSanctionList.sol.md +++ b/doc/surya/surya_report/surya_report_RuleSanctionList.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/RuleSanctionList.sol | 35a93e0000480f9386935a92e2f52c2a4e10d534 | +| ./rules/validation/RuleSanctionList.sol | 44e135ac7c8e51d025a876e23e08a9fdc968a3a3 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleSanctionListInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleSanctionListInvariantStorage.sol.md index 21171bc..3f6b036 100644 --- a/doc/surya/surya_report/surya_report_RuleSanctionListInvariantStorage.sol.md +++ b/doc/surya/surya_report/surya_report_RuleSanctionListInvariantStorage.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/abstract/RuleSanctionListInvariantStorage.sol | bfafc191c7e0cb36a1580ad338f6d6b7bff00e19 | +| ./rules/validation/abstract/RuleSanctionListInvariantStorage.sol | c3a182c89805e4bd84eab1a1a8c9cad843eb6fdf | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleValidateTransfer.sol.md b/doc/surya/surya_report/surya_report_RuleValidateTransfer.sol.md index 8ba9474..3b10ec8 100644 --- a/doc/surya/surya_report/surya_report_RuleValidateTransfer.sol.md +++ b/doc/surya/surya_report/surya_report_RuleValidateTransfer.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/abstract/RuleValidateTransfer.sol | 34bc5ca27d23c60ec0ab15bbd591e704903cc583 | +| ./rules/validation/abstract/RuleValidateTransfer.sol | bdc453d5afd57fde0c8ca1baffc05c6ed4cb6d20 | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleWhitelist.sol.md b/doc/surya/surya_report/surya_report_RuleWhitelist.sol.md index f92ec99..4b5d8e8 100644 --- a/doc/surya/surya_report/surya_report_RuleWhitelist.sol.md +++ b/doc/surya/surya_report/surya_report_RuleWhitelist.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/RuleWhitelist.sol | 95fbe2f3831b9a71b1b332868ca5594f4b3d4332 | +| ./rules/validation/RuleWhitelist.sol | 23d835c06c94cfc07433db85afa3a493771d44b4 | ### Contracts Description Table @@ -15,11 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **RuleWhitelist** | Implementation | RuleValidateTransfer, RuleAddressList, RuleWhitelistInvariantStorage ||| +| **RuleWhitelist** | Implementation | RuleAddressList, RuleWhitelistCommon ||| | └ | | Public ❗️ | 🛑 | RuleAddressList | | └ | detectTransferRestriction | Public ❗️ | |NO❗️ | -| └ | canReturnTransferRestrictionCode | External ❗️ | |NO❗️ | -| └ | messageForTransferRestriction | External ❗️ | |NO❗️ | ### Legend diff --git a/doc/surya/surya_report/surya_report_RuleWhitelistCommon.sol.md b/doc/surya/surya_report/surya_report_RuleWhitelistCommon.sol.md new file mode 100644 index 0000000..f0fb30b --- /dev/null +++ b/doc/surya/surya_report/surya_report_RuleWhitelistCommon.sol.md @@ -0,0 +1,28 @@ +## Sūrya's Description Report + +### Files Description Table + + +| File Name | SHA-1 Hash | +|-------------|--------------| +| ./rules/validation/abstract/RuleWhitelistCommon.sol | 4f33cf6f0e6d78cc0f2a2ffaa19c21bb7be95efa | + + +### Contracts Description Table + + +| Contract | Type | Bases | | | +|:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| +| └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | +|||||| +| **RuleWhitelistCommon** | Implementation | RuleValidateTransfer, RuleWhitelistInvariantStorage ||| +| └ | canReturnTransferRestrictionCode | External ❗️ | |NO❗️ | +| └ | messageForTransferRestriction | External ❗️ | |NO❗️ | + + +### Legend + +| Symbol | Meaning | +|:--------:|-----------| +| 🛑 | Function can modify state | +| 💵 | Function is payable | diff --git a/doc/surya/surya_report/surya_report_RuleWhitelistInvariantStorage.sol.md b/doc/surya/surya_report/surya_report_RuleWhitelistInvariantStorage.sol.md index 8fab71d..8591a82 100644 --- a/doc/surya/surya_report/surya_report_RuleWhitelistInvariantStorage.sol.md +++ b/doc/surya/surya_report/surya_report_RuleWhitelistInvariantStorage.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol | fd28dfca118991fc5956bb5638de59a5a082ccbf | +| ./rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol | a49ed4b2f4e846464b80004e3d79c797320b6e5b | ### Contracts Description Table diff --git a/doc/surya/surya_report/surya_report_RuleWhitelistWrapper.sol.md b/doc/surya/surya_report/surya_report_RuleWhitelistWrapper.sol.md index 47a0301..71dedab 100644 --- a/doc/surya/surya_report/surya_report_RuleWhitelistWrapper.sol.md +++ b/doc/surya/surya_report/surya_report_RuleWhitelistWrapper.sol.md @@ -5,7 +5,7 @@ | File Name | SHA-1 Hash | |-------------|--------------| -| ./rules/validation/RuleWhitelistWrapper.sol | bf329dec00b1249add78824aa85a9dcdd49a8342 | +| ./rules/validation/RuleWhitelistWrapper.sol | 4868a3528d859dca93054b44d406c6c1f64baa8c | ### Contracts Description Table @@ -15,11 +15,9 @@ |:----------:|:-------------------:|:----------------:|:----------------:|:---------------:| | └ | **Function Name** | **Visibility** | **Mutability** | **Modifiers** | |||||| -| **RuleWhitelistWrapper** | Implementation | RuleEngineValidationCommon, MetaTxModuleStandalone, RuleValidateTransfer, RuleWhitelistInvariantStorage ||| +| **RuleWhitelistWrapper** | Implementation | RuleEngineValidationCommon, MetaTxModuleStandalone, RuleWhitelistCommon ||| | └ | | Public ❗️ | 🛑 | MetaTxModuleStandalone | | └ | detectTransferRestriction | Public ❗️ | |NO❗️ | -| └ | canReturnTransferRestrictionCode | External ❗️ | |NO❗️ | -| └ | messageForTransferRestriction | External ❗️ | |NO❗️ | | └ | _msgSender | Internal 🔒 | | | | └ | _msgData | Internal 🔒 | | | | └ | _contextSuffixLength | Internal 🔒 | | | diff --git a/doc/technical/general.md b/doc/technical/general.md deleted file mode 100644 index 3d09832..0000000 --- a/doc/technical/general.md +++ /dev/null @@ -1,46 +0,0 @@ -# Technical choice - -[TOC] - -## Schema - -### UML - -![uml](../schema/classDiagram.svg) - - - -## Functionality - -### Upgradeable - -The Rule Engine and the other rules are not upgradeable. The reason is the following: -If we need a new on, we just issue a new one, and tell the CMTAT token (or the RuleEngine for the rules) to use the new. This would happen if we need more than just whitelisting, for ex. - -### Urgency mechanism -* Pause - There are no functionalities to put in pause the contracts. - -* We have removed the possibility to Kill the contracts, to destroy the bytecode, from - the different contracts (RuleEngine and Rule) for the following reasons: - - * The opcode SELFDESTRUCT which the property of destroying the contract (= deletion of any storage keys or code) will be remove with the Cancun Upgrade, an upgrade of the Ethereum network. - - Therefore, when the Ethereum Network will integrate this upgrade, this functionality will no longer be available. - - See [https://eips.ethereum.org/EIPS/eip-6780](https://eips.ethereum.org/EIPS/eip-6780) & [https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md](https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md) - - * It was recommended by the audit team - - > Implementing an ability to destroy a contract is a bad practice, as it cause more risks than benefits. - - -### Gasless support - -> The gasless integration was not part of the audit performed by ABDK on the version [1.0.1](https://github.com/CMTA/RuleEngine/releases/tag/1.0.1) - -The RuleEngine contracts and the other rules support client-side gasless transactions using the [Gas Station Network](https://docs.opengsn.org/#the-problem) (GSN) pattern, the main open standard for transfering fee payment to another account than that of the transaction issuer. The contract uses the OpenZeppelin contract `ERC2771Context`, which allows a contract to get the original client with `_msgSender()` instead of the fee payer given by `msg.sender` . - -At deployment, the parameter `forwarder` inside the contract constructor has to be set with the defined address of the forwarder. Please note that the forwarder can not be changed after deployment. - -Please see the OpenGSN [documentation](https://docs.opengsn.org/contracts/#receiving-a-relayed-call) for more details on what is done to support GSN in the contract. diff --git a/doc/test/v1.0.2-archive/UML-test.svg b/doc/test/v1.0.2-archive/UML-test.svg deleted file mode 100644 index 7e69a0d..0000000 --- a/doc/test/v1.0.2-archive/UML-test.svg +++ /dev/null @@ -1,423 +0,0 @@ - - - - - - -UmlClassDiagram - - - -0 - -CMTATIntegration -test/CMTATIntegration.t.sol - -Public: -   TRANSFER_OK: uint8 -   TEXT_TRANSFER_OK: string -   ruleEngineMock: RuleEngine -   resUint256: uint256 -   resBool: bool -   ADDRESS1_BALANCE_INIT: uint256 -   ADDRESS2_BALANCE_INIT: uint256 -   ADDRESS3_BALANCE_INIT: uint256 -   FLAG: uint256 - -Public: -    setUp() -    testCannotTransferWithoutAddressWhitelisted() -    testCannotTransferWithoutFromAddressWhitelisted() -    testCannotTransferWithoutToAddressWhitelisted() -    testCanMakeATransfer() -    testDetectAndMessageWithFromNotWhitelisted() -    testDetectAndMessageWithToNotWhitelisted() -    testDetectAndMessageWithFromAndToNotWhitelisted() -    testDetectAndMessageWithAValidTransfer() -    testCanMint() - - - -1 - -<<Abstract>> -HelperContract -test/HelperContract.sol - -Public: -   ZERO_ADDRESS: address -   DEFAULT_ADMIN_ADDRESS: address -   WHITELIST_OPERATOR_ADDRESS: address -   RULE_ENGINE_OPERATOR_ADDRESS: address -   ATTACKER: address -   ADDRESS1: address -   ADDRESS2: address -   ADDRESS3: address -   RULE_ENGINE_ROLE_HASH: string -   WHITELIST_ROLE_HASH: string -   DEFAULT_ADMIN_ROLE_HASH: string -   ruleWhitelist: RuleWhitelist -   CMTAT_CONTRACT: CMTAT_STANDALONE -   RULE_ENGINE_ROLE: bytes32 -   TEXT_CODE_NOT_FOUND: string -   TEXT_ADDRESS_FROM_NOT_WHITELISTED: string -   TEXT_ADDRESS_TO_NOT_WHITELISTED: string -   CODE_ADDRESS_FROM_NOT_WHITELISTED: uint8 -   CODE_ADDRESS_TO_NOT_WHITELISTED: uint8 -   NO_ERROR: uint8 -   WHITELIST_ROLE: bytes32 - -Public: -    <<event>> AddRule(rule: IRule) -    <<event>> RemoveRule(rule: IRule) -    <<event>> ClearRules(rulesRemoved: IRule[]) -    constructor() - - - -0->1 - - - - - -9 - -RuleEngineAccessControlTest -test/RuleEngine/AccessControl/RuleEngineAccessControl.sol - -Public: -   ruleEngineMock: RuleEngine -   resUint8: uint8 -   resUint256: uint256 -   resBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testCannnotAttackerSetRules() -    testCannnotAttackerClearRules() -    testCannotAttackerAddRule() -    testCannotAttackerRemoveRule() - - - -9->1 - - - - - -10 - -RuleEngineAccessControlTest -test/RuleEngine/AccessControl/RuleEngineAccessControlOZ.t.sol - -Public: -   ruleEngineMock: RuleEngine -   resUint8: uint8 -   resUint256: uint256 -   resBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testCanGrantRoleAsAdmin() -    testRevokeRoleAsAdmin() -    testCannotGrantFromNonAdmin() -    testCannotRevokeFromNonAdmin() - - - -10->1 - - - - - -2 - -RuleEngineTest -test/RuleEngine/RuleEngine.t.sol - -Public: -   ruleEngineMock: RuleEngine -   resUint8: uint8 -   resUint256: uint256 -   resBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testCanSetRules() -    testCannotSetRuleIfARuleIsAlreadyPresent() -    testCannotSetEmptyRulesT1() -    testCannotSetEmptyRulesT2() -    testCanClearRules() -    testCanAddRule() -    testCannotAddRuleZeroAddress() -    testCannotAddARuleAlreadyPresent() -    testCanAddARuleAfterThisRuleWasRemoved() -    testCanRemoveNonExistantRule() -    testCanRemoveLatestRule() -    testCanRemoveFirstRule() -    testCanRemoveRule() -    testRuleLength() -    testGetRule() -    testGetRules() -    testCanGetRuleIndex() - - - -2->1 - - - - - -3 - -RuleEngineTest -test/RuleEngine/RuleEngineDeployment.t.sol - -Public: -   ruleEngineMock: RuleEngine -   resUint8: uint8 -   resUint256: uint256 -   resBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testRightDeployment() - - - -3->1 - - - - - -4 - -RuleEngineRestrictionTest -test/RuleEngine/RuleEngineRestriction.t.sol - -Public: -   ruleEngineMock: RuleEngine -   resUint8: uint8 -   resUint256: uint256 -   resBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 -   ruleWhitelist1: RuleWhitelist - -Public: -    setUp() -    testCanDetectTransferRestrictionOK() -    testCanDetectTransferRestrictionWithFrom() -    testCanDetectTransferRestrictionWithTo() -    testMessageForTransferRestrictionWithValidRC() -    testMessageForTransferRestrictionNoRule() -    testMessageForTransferRestrictionWithUnknownRestrictionCode() -    testValidateTransferOK() -    testValidateTransferRestricted() - - - -4->1 - - - - - -11 - -RuleWhitelistAccessControl -test/RuleWhitelist/AccessControl/RuleWhitelistAccessControl.t.sol - -Public: -   TRANSFER_OK: uint8 -   TEXT_TRANSFER_OK: string -   resUint256: uint256 -   resUint8: uint8 -   resBool: bool -   resCallBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testCannotAttackerAddAddressToTheWhitelist() -    testCannotAttackerAddAddressesToTheWhitelist() -    testCannotAttackerRemoveAddressFromTheWhitelist() -    testCannotAttackerRemoveAddressesFromTheWhitelist() - - - -11->1 - - - - - -12 - -RuleWhitelistAccessControlOZ -test/RuleWhitelist/AccessControl/RuleWhitelistAccessControlOZ.t.sol - -Public: -   TRANSFER_OK: uint8 -   TEXT_TRANSFER_OK: string -   resUint256: uint256 -   resUint8: uint8 -   resBool: bool -   resCallBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testCanGrantRoleAsAdmin() -    testRevokeRoleAsAdmin() -    testCannotGrantFromNonAdmin() -    testCannotRevokeFromNonAdmin() - - - -12->1 - - - - - -5 - -RuleWhitelistAddTest -test/RuleWhitelist/RuleWhitelistAdd.t.sol - -Public: -   TRANSFER_OK: uint8 -   TEXT_TRANSFER_OK: string -   resUint256: uint256 -   resUint8: uint8 -   resBool: bool -   resCallBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testAddAddressToTheWhitelist() -    testAddAddressesToTheWhitelist() -    testCanAddAddressZeroToTheWhitelist() -    testCanAddAddressesZeroToTheWhitelist() -    testAddAddressTwiceToTheWhitelist() -    testAddAddressesTwiceToTheWhitelist() - - - -5->1 - - - - - -6 - -RuleWhitelistRemoveTest -test/RuleWhitelist/RuleWhitelistRemove.t.sol - -Public: -   TRANSFER_OK: uint8 -   TEXT_TRANSFER_OK: string -   resUint256: uint256 -   resUint8: uint8 -   resBool: bool -   resCallBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testRemoveAddressFromTheWhitelist() -    testRemoveAddressesFromTheWhitelist() -    testRemoveAddressNotPresentFromTheWhitelist() -    testRemoveAddressesNotPresentFromTheWhitelist() - - - -6->1 - - - - - -7 - -RuleWhitelistTest -test/RuleWhitelist/Rulewhitelist.t.sol - -Public: -   resUint256: uint256 -   resUint8: uint8 -   resBool: bool -   resCallBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testReturnFalseIfAddressNotWhitelisted() -    testAddressIsIndicatedAsWhitelisted() -    testAddressesIsIndicatedAsWhitelisted() -    testCanReturnTransferRestrictionCode() -    testReturnTheRightMessageForAGivenCode() -    testValidateTransfer() -    testTransferDetectedAsInvalid() -    testNumberWhitelistedAddress() -    testDetectTransferRestrictionFrom() -    testDetectTransferRestrictionTo() -    testDetectTransferRestrictionOk() - - - -7->1 - - - - - -8 - -RuleWhitelistTest -test/RuleWhitelist/RulewhitelistDeployment.t.sol - -Public: -   resUint256: uint256 -   resUint8: uint8 -   resBool: bool -   resCallBool: bool -   resString: string -   CODE_NONEXISTENT: uint8 - -Public: -    setUp() -    testRightDeployment() - - - -8->1 - - - - - diff --git a/doc/test/v1.0.2-archive/coverage-2023-05-23.png b/doc/test/v1.0.2-archive/coverage-2023-05-23.png deleted file mode 100644 index fd893ad..0000000 Binary files a/doc/test/v1.0.2-archive/coverage-2023-05-23.png and /dev/null differ diff --git a/doc/test/v1.0.2-archive/lcov-2023-22.05.info b/doc/test/v1.0.2-archive/lcov-2023-22.05.info deleted file mode 100644 index ec07d75..0000000 --- a/doc/test/v1.0.2-archive/lcov-2023-22.05.info +++ /dev/null @@ -1,248 +0,0 @@ -TN: -SF:script/CMTATWithRuleEngineScript.s.sol -FN:14,CMTATWithRuleEngineScript.run -FNDA:0,CMTATWithRuleEngineScript.run -DA:16,0 -DA:17,0 -DA:18,0 -DA:19,0 -DA:20,0 -DA:22,0 -DA:33,0 -DA:35,0 -DA:39,0 -DA:41,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:46,0 -FNF:1 -FNH:0 -LF:14 -LH:0 -BRF:0 -BRH:0 -end_of_record -TN: -SF:script/RuleEngineScript.s.sol -FN:16,RuleEngineScript.run -FNDA:0,RuleEngineScript.run -DA:18,0 -DA:19,0 -DA:20,0 -DA:21,0 -DA:23,0 -DA:24,0 -DA:26,0 -DA:27,0 -DA:28,0 -DA:30,0 -DA:33,0 -BRDA:33,0,0,- -BRDA:33,0,1,- -DA:34,0 -FNF:1 -FNH:0 -LF:12 -LH:0 -BRF:2 -BRH:0 -end_of_record -TN: -SF:src/RuleEngine.sol -FN:43,RuleEngine.setRules -FNDA:10,RuleEngine.setRules -DA:46,9 -BRDA:46,0,0,1 -BRDA:46,0,1,8 -DA:47,8 -DA:48,15 -BRDA:48,1,0,1 -BRDA:48,1,1,14 -DA:52,14 -BRDA:52,2,0,1 -BRDA:52,2,1,13 -DA:53,13 -DA:54,13 -DA:56,13 -DA:59,6 -FN:66,RuleEngine.clearRules -FNDA:3,RuleEngine.clearRules -DA:67,2 -DA:68,2 -FN:76,RuleEngine.addRule -FNDA:9,RuleEngine.addRule -DA:77,8 -BRDA:77,3,0,1 -BRDA:77,3,1,7 -DA:81,7 -BRDA:81,4,0,1 -BRDA:81,4,1,6 -DA:82,6 -DA:83,6 -DA:84,6 -FN:97,RuleEngine.removeRule -FNDA:6,RuleEngine.removeRule -DA:101,5 -BRDA:101,5,0,1 -BRDA:101,5,1,4 -DA:102,4 -BRDA:102,6,0,- -BRDA:102,6,1,2 -DA:103,2 -DA:105,4 -DA:106,4 -DA:107,4 -FN:113,RuleEngine.rulesCount -FNDA:20,RuleEngine.rulesCount -DA:114,20 -FN:121,RuleEngine.getRuleIndex -FNDA:3,RuleEngine.getRuleIndex -DA:122,0 -DA:123,5 -BRDA:123,7,0,3 -BRDA:123,7,1,3 -DA:124,5 -DA:127,3 -DA:130,1 -FN:138,RuleEngine.rule -FNDA:1,RuleEngine.rule -DA:139,1 -FN:146,RuleEngine.rules -FNDA:4,RuleEngine.rules -DA:147,4 -FN:157,RuleEngine.detectTransferRestriction -FNDA:7,RuleEngine.detectTransferRestriction -DA:162,17 -DA:163,17 -DA:168,17 -BRDA:168,8,0,12 -BRDA:168,8,1,5 -DA:169,12 -DA:172,5 -DA:175,5 -FN:185,RuleEngine.validateTransfer -FNDA:10,RuleEngine.validateTransfer -DA:190,10 -FN:198,RuleEngine.messageForTransferRestriction -FNDA:6,RuleEngine.messageForTransferRestriction -DA:201,6 -DA:202,5 -BRDA:202,9,0,- -BRDA:202,9,1,4 -DA:203,4 -DA:207,1 -DA:210,2 -FN:216,RuleEngine._msgSender -FNDA:38,RuleEngine._msgSender -DA:222,38 -FN:228,RuleEngine._msgData -FNDA:0,RuleEngine._msgData -DA:234,0 -FNF:13 -FNH:12 -LF:43 -LH:41 -BRF:20 -BRH:18 -end_of_record -TN: -SF:src/RuleWhitelist.sol -FN:49,RuleWhitelist.addAddressesToTheWhitelist -FNDA:13,RuleWhitelist.addAddressesToTheWhitelist -DA:52,12 -DA:53,12 -DA:54,26 -BRDA:54,0,0,- -BRDA:54,0,1,24 -DA:55,24 -DA:56,24 -DA:59,26 -DA:62,12 -FN:71,RuleWhitelist.removeAddressesFromTheWhitelist -FNDA:4,RuleWhitelist.removeAddressesFromTheWhitelist -DA:74,3 -DA:75,3 -DA:76,7 -BRDA:76,1,0,- -BRDA:76,1,1,6 -DA:77,6 -DA:78,6 -DA:81,7 -DA:84,3 -FN:92,RuleWhitelist.addAddressToTheWhitelist -FNDA:22,RuleWhitelist.addAddressToTheWhitelist -DA:95,21 -BRDA:95,2,0,1 -BRDA:95,2,1,20 -DA:99,20 -DA:100,20 -FN:109,RuleWhitelist.removeAddressFromTheWhitelist -FNDA:3,RuleWhitelist.removeAddressFromTheWhitelist -DA:112,2 -BRDA:112,3,0,1 -BRDA:112,3,1,1 -DA:116,1 -DA:117,1 -FN:125,RuleWhitelist.numberWhitelistedAddress -FNDA:20,RuleWhitelist.numberWhitelistedAddress -DA:126,20 -FN:135,RuleWhitelist.addressIsWhitelisted -FNDA:50,RuleWhitelist.addressIsWhitelisted -DA:138,50 -FN:148,RuleWhitelist.validateTransfer -FNDA:3,RuleWhitelist.validateTransfer -DA:153,3 -FN:164,RuleWhitelist.detectTransferRestriction -FNDA:20,RuleWhitelist.detectTransferRestriction -DA:169,23 -BRDA:169,4,0,11 -BRDA:169,4,1,12 -DA:170,11 -DA:171,12 -BRDA:171,5,0,4 -BRDA:171,5,1,8 -DA:172,4 -DA:174,8 -FN:183,RuleWhitelist.canReturnTransferRestrictionCode -FNDA:8,RuleWhitelist.canReturnTransferRestrictionCode -DA:186,8 -FN:196,RuleWhitelist.messageForTransferRestriction -FNDA:7,RuleWhitelist.messageForTransferRestriction -DA:199,7 -BRDA:199,6,0,4 -BRDA:199,6,1,3 -DA:200,4 -DA:201,3 -BRDA:201,7,0,2 -BRDA:201,7,1,1 -DA:202,2 -DA:204,1 -FN:211,RuleWhitelist._msgSender -FNDA:52,RuleWhitelist._msgSender -DA:217,52 -FN:223,RuleWhitelist._msgData -FNDA:0,RuleWhitelist._msgData -DA:229,0 -FNF:12 -FNH:11 -LF:36 -LH:35 -BRF:16 -BRH:14 -end_of_record -TN: -SF:src/modules/MetaTxModuleStandalone.sol -FN:15,MetaTxModuleStandalone._msgSender -FNDA:90,MetaTxModuleStandalone._msgSender -DA:22,90 -FN:25,MetaTxModuleStandalone._msgData -FNDA:0,MetaTxModuleStandalone._msgData -DA:32,0 -FNF:2 -FNH:1 -LF:2 -LH:1 -BRF:0 -BRH:0 -end_of_record diff --git a/doc/test/v1.0.2-archive/test.odt b/doc/test/v1.0.2-archive/test.odt deleted file mode 100644 index aebe3af..0000000 Binary files a/doc/test/v1.0.2-archive/test.odt and /dev/null differ diff --git a/doc/test/v1.0.2-archive/test.pdf b/doc/test/v1.0.2-archive/test.pdf deleted file mode 100644 index fa300f4..0000000 Binary files a/doc/test/v1.0.2-archive/test.pdf and /dev/null differ diff --git a/foundry.toml b/foundry.toml index d7e736c..7dd1b67 100644 --- a/foundry.toml +++ b/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc = "0.8.22" +solc = "0.8.26" src = 'src' out = 'out' libs = ['lib'] diff --git a/hardhat.config.js b/hardhat.config.js index 132197f..c7dfaa4 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -2,7 +2,7 @@ require("@nomicfoundation/hardhat-foundry"); require('solidity-docgen'); module.exports = { - solidity: "0.8.22", + solidity: "0.8.26", settings: { optimizer: { enabled: true, diff --git a/package.json b/package.json index 4f28808..c148cd4 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "lint:sol:script:fix": "npx solium -d script --fix", "lint:sol:prettier": "npx prettier --write 'src/**/*.sol' 'test/**/*.sol' 'script/**/*.sol'", "uml": "npx sol2uml class src", + "uml:ruleEngine": "npx sol2uml src contracts -b RuleEngine", "uml:test": "npx sol2uml class test", "surya:report": "npx surya mdreport surya_report_ruleEngine.md src/RuleEngine.sol && npx surya mdreport surya_report_ruleWhitelist.md src/RuleWhitelist.sol", "surya:graph": "npx surya graph src/rules/operation/RuleConditionalTransfer.sol | dot -Tpng > surya_graph_conditionalTransfer.png && npx surya graph src/rules/validation/RuleBlacklist.sol| dot -Tpng > surya_graph_blacklist.png && npx surya graph src/rules/validation/RuleWhitelist.sol | dot -Tpng > surya_graph_Whitelist.png && npx surya graph src/RuleEngine.sol | dot -Tpng > surya_graph_RuleEngine.png && npx surya graph src/rules/validation/RuleSanctionList.sol | dot -Tpng > surya_graph_SanctionList.png", diff --git a/src/RuleEngine.sol b/src/RuleEngine.sol index 9e8009c..5dacf4d 100644 --- a/src/RuleEngine.sol +++ b/src/RuleEngine.sol @@ -16,6 +16,12 @@ contract RuleEngine is RuleEngineValidation, MetaTxModuleStandalone { + /** + * @notice + * Get the current version of the smart contract + */ + string public constant VERSION = "2.0.3"; + error RuleEngine_TransferInvalid(); /** @@ -142,6 +148,10 @@ contract RuleEngine is return RuleEngineOperation._operateOnTransfer(from, to, amount); } + /*////////////////////////////////////////////////////////////// + ERC-2771 + //////////////////////////////////////////////////////////////*/ + /** * @dev This surcharge is not necessary if you do not use the MetaTxModule */ diff --git a/src/modules/RuleEngineOperation.sol b/src/modules/RuleEngineOperation.sol index b238ff4..7ff4937 100644 --- a/src/modules/RuleEngineOperation.sol +++ b/src/modules/RuleEngineOperation.sol @@ -116,7 +116,7 @@ abstract contract RuleEngineOperation is function getRuleIndexOperation( IRuleOperation rule_ ) external view returns (uint256 index) { - return RuleInternal.getRuleIndex(_rulesOperation, address(rule_)); + return RuleInternal._getRuleIndex(_rulesOperation, address(rule_)); } /** diff --git a/src/modules/RuleEngineValidationCommon.sol b/src/modules/RuleEngineValidationCommon.sol index e821a64..c1cccc2 100644 --- a/src/modules/RuleEngineValidationCommon.sol +++ b/src/modules/RuleEngineValidationCommon.sol @@ -18,6 +18,9 @@ abstract contract RuleEngineValidationCommon is /// @dev Array of rules address[] internal _rulesValidation; + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ /** * @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 @@ -42,23 +45,6 @@ abstract contract RuleEngineValidationCommon is _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 @@ -88,21 +74,6 @@ abstract contract RuleEngineValidationCommon is _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 */ @@ -117,7 +88,7 @@ abstract contract RuleEngineValidationCommon is function getRuleIndexValidation( IRuleValidation rule_ ) external view returns (uint256 index) { - return RuleInternal.getRuleIndex(_rulesValidation, address(rule_)); + return RuleInternal._getRuleIndex(_rulesValidation, address(rule_)); } /** @@ -143,4 +114,39 @@ abstract contract RuleEngineValidationCommon is { return _rulesValidation; } + + /*////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /** + * @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 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_)); + } } diff --git a/src/modules/RuleInternal.sol b/src/modules/RuleInternal.sol index b6ce3cd..15bc236 100644 --- a/src/modules/RuleInternal.sol +++ b/src/modules/RuleInternal.sol @@ -81,7 +81,7 @@ 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( + function _getRuleIndex( address[] storage _rules, address rule_ ) internal view returns (uint256 index) { diff --git a/src/rules/operation/RuleConditionalTransfer.sol b/src/rules/operation/RuleConditionalTransfer.sol index 431bc38..8c45f46 100644 --- a/src/rules/operation/RuleConditionalTransfer.sol +++ b/src/rules/operation/RuleConditionalTransfer.sol @@ -11,7 +11,7 @@ import "../validation/abstract/RuleValidateTransfer.sol"; import "CMTAT/interfaces/engine/IRuleEngine.sol"; /** - * @title a whitelist manager + * @title RuleConditionalTransfer */ contract RuleConditionalTransfer is @@ -47,6 +47,47 @@ contract RuleConditionalTransfer is options = options_; } + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /** + * @notice function called by the RuleEngine + * @dev Returns true if the transfer is valid, and false otherwise. + * Add access control with the RuleEngine + */ + function operateOnTransfer( + address _from, + address _to, + uint256 _amount + ) + 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) + ) { + return true; + } + } + + // Mint & Burn + if (_validateBurnMint(_from, _to)) { + return true; + } + bytes32 key = keccak256(abi.encode(_from, _to, _amount)); + if (_validateApproval(key)) { + _updateProcessedTransfer(key); + return true; + } else { + return false; + } + } + /** * @notice Create a request of transfer for yourselves * @param to recipient of tokens @@ -66,9 +107,11 @@ contract RuleConditionalTransfer is TransferRequest memory newTransferApproval = TransferRequest({ key: key, id: requestIdLocal, - from: from, - to: to, - value: value, + keyElement: TransferRequestKeyElement({ + from: from, + to: to, + value: value + }), askTime: block.timestamp, maxTime: 0, status: STATUS.WAIT @@ -134,25 +177,6 @@ contract RuleConditionalTransfer is } } - function _cancelTransferRequest(uint256 requestId_) internal { - if (requestId_ + 1 > requestId) { - revert RuleConditionalTransfer_InvalidId(); - } - bytes32 key = IdToKey[requestId_]; - // Check Sender - if (transferRequests[key].from != _msgSender()) { - revert RuleConditionalTransfer_InvalidSender(); - } - // Check status - if ( - transferRequests[key].status != STATUS.WAIT && - transferRequests[key].status != STATUS.APPROVED - ) { - revert RuleConditionalTransfer_Wrong_Status(); - } - _resetRequestStatus(key); - } - function getRequestTrade( address from, address to, @@ -198,43 +222,6 @@ contract RuleConditionalTransfer is return requests; } - /** - * @dev Returns true if the transfer is valid, and false otherwise. - * Add access control with the RuleEngine - */ - function operateOnTransfer( - address _from, - address _to, - uint256 _amount - ) - 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) - ) { - return true; - } - } - - // Mint & Burn - if (_validateBurnMint(_from, _to)) { - return true; - } - bytes32 key = keccak256(abi.encode(_from, _to, _amount)); - if (_validateApproval(key)) { - _updateProcessedTransfer(key); - return true; - } else { - return false; - } - } - /** * @notice Check if the transfer is valid * @param _from the origin address @@ -289,6 +276,29 @@ contract RuleConditionalTransfer is } } + /*////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + + function _cancelTransferRequest(uint256 requestId_) internal { + if (requestId_ + 1 > requestId) { + revert RuleConditionalTransfer_InvalidId(); + } + bytes32 key = IdToKey[requestId_]; + // Check Sender + if (transferRequests[key].keyElement.from != _msgSender()) { + revert RuleConditionalTransfer_InvalidSender(); + } + // Check status + if ( + transferRequests[key].status != STATUS.WAIT && + transferRequests[key].status != STATUS.APPROVED + ) { + revert RuleConditionalTransfer_Wrong_Status(); + } + _resetRequestStatus(key); + } + /** * * @dev @@ -321,12 +331,14 @@ contract RuleConditionalTransfer is function _validateApproval( bytes32 key ) internal view returns (bool isValid) { + // If automatic approval is activate and time to approve the request has passed bool automaticApprovalCondition = options .automaticApproval .isActivate && ((transferRequests[key].askTime + options.automaticApproval.timeLimitBeforeAutomaticApproval) >= block.timestamp); + // If the transfer is approved and delay to perform the transfer is respected bool isTransferApproved = (transferRequests[key].status == STATUS.APPROVED) && (transferRequests[key].maxTime >= block.timestamp); @@ -337,6 +349,10 @@ contract RuleConditionalTransfer is } } + /*////////////////////////////////////////////////////////////// + ERC-2771 + //////////////////////////////////////////////////////////////*/ + /** * @dev This surcharge is not necessary if you do not use the MetaTxModule */ diff --git a/src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol b/src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol index 1abcff9..cfd5536 100644 --- a/src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol +++ b/src/rules/operation/abstract/RuleConditionalTransferInvariantStorage.sol @@ -9,6 +9,7 @@ import "src/rules/validation/RuleWhitelist.sol"; abstract contract RuleConditionalTransferInvariantStorage is RuleCommonInvariantStorage { + /* ============ Struct ============ */ /** * 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). @@ -49,45 +50,43 @@ abstract contract RuleConditionalTransferInvariantStorage is AUTOMATIC_TRANSFER automaticTransfer; } - enum STATUS { - NONE, - WAIT, - APPROVED, - DENIED, - EXECUTED, - CANCELLED - } - struct TransferRequestKeyElement { address from; address to; uint256 value; } + struct TransferRequest { bytes32 key; uint256 id; - address from; - address to; - uint256 value; + TransferRequestKeyElement keyElement; uint256 askTime; uint256 maxTime; STATUS status; } + /* ============ Enum ============ */ + enum STATUS { + NONE, + WAIT, + APPROVED, + DENIED, + EXECUTED + } - // Role + /* ============ 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 + /* ============ State variables ============ */ string constant TEXT_TRANSFER_REQUEST_NOT_APPROVED = "The request is not approved"; // Code // It is very important that each rule uses an unique code uint8 public constant CODE_TRANSFER_REQUEST_NOT_APPROVED = 51; - // error + /* ============ Custom error ============ */ error RuleConditionalTransfer_AdminWithAddressZeroNotAllowed(); error RuleConditionalTransfer_TransferAlreadyApproved(); error RuleConditionalTransfer_Wrong_Status(); @@ -100,7 +99,7 @@ abstract contract RuleConditionalTransferInvariantStorage is error RuleConditionalTransfer_InvalidLengthArray(); error RuleConditionalTransfer_EmptyArray(); - // Event + /* ============ Events ============ */ event transferProcessed( bytes32 indexed key, address indexed from, diff --git a/src/rules/operation/abstract/RuleConditionalTransferOperator.sol b/src/rules/operation/abstract/RuleConditionalTransferOperator.sol index 80bf67d..920b7b3 100644 --- a/src/rules/operation/abstract/RuleConditionalTransferOperator.sol +++ b/src/rules/operation/abstract/RuleConditionalTransferOperator.sol @@ -15,14 +15,17 @@ abstract contract RuleConditionalTransferOperator is { // Security using SafeERC20 for IERC20; - - // public variable with automatic Getter + /* ============ State Variables ============ */ OPTION public options; uint256 public requestId; mapping(uint256 => bytes32) public IdToKey; mapping(bytes32 => TransferRequest) public transferRequests; RuleWhitelist public whitelistConditionalTransfer; + /*////////////////////////////////////////////////////////////// + PUBLIC/EXTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ + /** * @notice set a whitelist. A transfer does not need of an approved request if from and to are in the whitelist */ @@ -34,8 +37,8 @@ abstract contract RuleConditionalTransferOperator is } /** - set/unset the issuance options (mint & burn) - */ + * @notice set/unset the issuance options (mint & burn) + */ function setIssuanceOptions( ISSUANCE calldata issuance_ ) public onlyRole(RULE_CONDITIONAL_TRANSFER_OPERATOR_ROLE) { @@ -270,7 +273,9 @@ abstract contract RuleConditionalTransferOperator is } } - /*** Internal functions ****/ + /*////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////*/ function _approveTransferRequestKeyElement( TransferRequestKeyElement calldata keyElement, uint256 partialValue, @@ -303,21 +308,19 @@ abstract contract RuleConditionalTransferOperator is } function _createTransferRequestWithApproval( - TransferRequestKeyElement memory keyElement + TransferRequestKeyElement memory keyElement_ ) 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) + 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, + keyElement: keyElement_, askTime: 0, maxTime: block.timestamp + options.timeLimit.timeLimitToTransfer, @@ -327,9 +330,9 @@ abstract contract RuleConditionalTransferOperator is IdToKey[requestId] = key; emit transferApproved( key, - keyElement.from, - keyElement.to, - keyElement.value, + keyElement_.from, + keyElement_.to, + keyElement_.value, requestId ); ++requestId; @@ -341,9 +344,9 @@ abstract contract RuleConditionalTransferOperator is transferRequests[key].status = STATUS.APPROVED; emit transferApproved( key, - keyElement.from, - keyElement.to, - keyElement.value, + keyElement_.from, + keyElement_.to, + keyElement_.value, transferRequests[key].id ); } @@ -353,9 +356,9 @@ abstract contract RuleConditionalTransferOperator is transferRequests[key].status = STATUS.NONE; emit transferReset( key, - transferRequests[key].from, - transferRequests[key].to, - transferRequests[key].value, + transferRequests[key].keyElement.from, + transferRequests[key].keyElement.to, + transferRequests[key].keyElement.value, transferRequests[key].id ); } @@ -391,9 +394,9 @@ abstract contract RuleConditionalTransferOperator is options.timeLimit.timeLimitToTransfer; emit transferApproved( transferRequest.key, - transferRequest.from, - transferRequest.to, - transferRequest.value, + transferRequest.keyElement.from, + transferRequest.keyElement.to, + transferRequest.keyElement.value, transferRequests[transferRequest.key].id ); if ( @@ -404,15 +407,15 @@ abstract contract RuleConditionalTransferOperator is // External call if ( options.automaticTransfer.cmtat.allowance( - transferRequest.from, + transferRequest.keyElement.from, address(this) - ) >= transferRequest.value + ) >= transferRequest.keyElement.value ) { // Will call the ruleEngine and the rule again... options.automaticTransfer.cmtat.safeTransferFrom( - transferRequest.from, - transferRequest.to, - transferRequest.value + transferRequest.keyElement.from, + transferRequest.keyElement.to, + transferRequest.keyElement.value ); } } @@ -420,9 +423,9 @@ abstract contract RuleConditionalTransferOperator is transferRequests[transferRequest.key].status = STATUS.DENIED; emit transferDenied( transferRequest.key, - transferRequest.from, - transferRequest.to, - transferRequest.value, + transferRequest.keyElement.from, + transferRequest.keyElement.to, + transferRequest.keyElement.value, transferRequests[transferRequest.key].id ); } @@ -440,9 +443,9 @@ abstract contract RuleConditionalTransferOperator is // Emit event emit transferProcessed( key, - transferRequests[key].from, - transferRequests[key].to, - transferRequests[key].value, + transferRequests[key].keyElement.from, + transferRequests[key].keyElement.to, + transferRequests[key].keyElement.value, transferRequests[key].id ); } diff --git a/src/rules/validation/RuleWhitelist.sol b/src/rules/validation/RuleWhitelist.sol index 4915ee1..cd4d198 100644 --- a/src/rules/validation/RuleWhitelist.sol +++ b/src/rules/validation/RuleWhitelist.sol @@ -4,12 +4,11 @@ pragma solidity ^0.8.20; import "./abstract/RuleAddressList/RuleAddressList.sol"; import "./abstract/RuleWhitelistCommon.sol"; + /** * @title a whitelist manager */ - -contract RuleWhitelist is RuleAddressList, RuleWhitelistCommon -{ +contract RuleWhitelist is RuleAddressList, RuleWhitelistCommon { /** * @param admin Address of the contract (Access Control) * @param forwarderIrrevocable Address of the forwarder, required for the gasless support diff --git a/src/rules/validation/RuleWhitelistWrapper.sol b/src/rules/validation/RuleWhitelistWrapper.sol index 346c151..972a1d2 100644 --- a/src/rules/validation/RuleWhitelistWrapper.sol +++ b/src/rules/validation/RuleWhitelistWrapper.sol @@ -61,6 +61,9 @@ contract RuleWhitelistWrapper is // Update if to is in the list result[1] = true; } + if (result[0] && result[1]) { + break; + } } if (!result[0]) { return CODE_ADDRESS_FROM_NOT_WHITELISTED; diff --git a/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol b/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol index 38c7093..672493f 100644 --- a/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol +++ b/src/rules/validation/abstract/RuleAddressList/RuleAddressList.sol @@ -117,6 +117,10 @@ abstract contract RuleAddressList is return isListed; } + /*////////////////////////////////////////////////////////////// + ERC-2771 + //////////////////////////////////////////////////////////////*/ + /** * @dev This surcharge is not necessary if you do not use the MetaTxModule */ diff --git a/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol index 3a4ecd9..198319d 100644 --- a/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol +++ b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleAddressListInvariantStorage.sol @@ -3,10 +3,12 @@ pragma solidity ^0.8.20; abstract contract RuleAddressListInvariantStorage { - // custom errors + /* ============ Custom errors ============ */ error RuleAddressList_AdminWithAddressZeroNotAllowed(); - // Add/Remove - bytes32 public constant ADDRESS_LIST_REMOVE_ROLE = keccak256("ADDRESS_LIST_REMOVE_ROLE"); - bytes32 public constant ADDRESS_LIST_ADD_ROLE = keccak256("ADDRESS_LIST_ADD_ROLE"); + /* ============ Role ============ */ + bytes32 public constant ADDRESS_LIST_REMOVE_ROLE = + keccak256("ADDRESS_LIST_REMOVE_ROLE"); + bytes32 public constant ADDRESS_LIST_ADD_ROLE = + keccak256("ADDRESS_LIST_ADD_ROLE"); } diff --git a/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol index 4543254..71cb25a 100644 --- a/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol +++ b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleBlacklistInvariantStorage.sol @@ -5,13 +5,13 @@ pragma solidity ^0.8.20; import "../../RuleCommonInvariantStorage.sol"; abstract contract RuleBlacklistInvariantStorage is RuleCommonInvariantStorage { - // String + /* ============ String message ============ */ string constant TEXT_ADDRESS_FROM_IS_BLACKLISTED = "The sender is not in the whitelist"; string constant TEXT_ADDRESS_TO_IS_BLACKLISTED = "The recipient is not in the whitelist"; - // Code + /* ============ Code ============ */ // 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; diff --git a/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol index fd5848b..f596f87 100644 --- a/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol +++ b/src/rules/validation/abstract/RuleAddressList/invariantStorage/RuleWhitelistInvariantStorage.sol @@ -5,13 +5,13 @@ pragma solidity ^0.8.20; import "../../RuleCommonInvariantStorage.sol"; abstract contract RuleWhitelistInvariantStorage is RuleCommonInvariantStorage { - // String + /* ============ String message ============ */ string constant TEXT_ADDRESS_FROM_NOT_WHITELISTED = "The sender is not in the whitelist"; string constant TEXT_ADDRESS_TO_NOT_WHITELISTED = "The recipient is not in the whitelist"; - // Code + /* ============ Code ============ */ // 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; diff --git a/src/rules/validation/abstract/RuleWhitelistCommon.sol b/src/rules/validation/abstract/RuleWhitelistCommon.sol index d707957..9ae43b9 100644 --- a/src/rules/validation/abstract/RuleWhitelistCommon.sol +++ b/src/rules/validation/abstract/RuleWhitelistCommon.sol @@ -7,8 +7,9 @@ import "./RuleValidateTransfer.sol"; abstract contract RuleWhitelistCommon is RuleValidateTransfer, - RuleWhitelistInvariantStorage { - /** + RuleWhitelistInvariantStorage +{ + /** * @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 diff --git a/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol index 3dcac3e..e1f16c0 100644 --- a/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol +++ b/test/RuleConditionalTransfer/RuleConditionalTransfer.t.sol @@ -121,9 +121,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.WAIT)); TransferRequest[] memory transferRequests = ruleConditionalTransfer @@ -154,9 +154,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED)); // 2 @@ -167,9 +167,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { ); assertEq(transferRequest.key, key2); assertEq(transferRequest.id, 1); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, value2); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, value2); assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED)); // 3 @@ -180,9 +180,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { ); assertEq(transferRequest.key, key3); assertEq(transferRequest.id, 2); - assertEq(transferRequest.from, ADDRESS2); - assertEq(transferRequest.to, ADDRESS1); - assertEq(transferRequest.value, value3); + assertEq(transferRequest.keyElement.from, ADDRESS2); + assertEq(transferRequest.keyElement.to, ADDRESS1); + assertEq(transferRequest.keyElement.value, value3); assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED)); // 4 @@ -193,9 +193,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { ); assertEq(transferRequest.key, key4); assertEq(transferRequest.id, 3); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, value4); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, value4); assertEq(uint256(transferRequest.status), uint256(STATUS.DENIED)); } @@ -207,9 +207,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, value5); assertEq(transferRequest.key, key5); assertEq(transferRequest.id, 4); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, value5); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, value5); assertEq(uint256(transferRequest.status), uint256(STATUS.WAIT)); } @@ -436,9 +436,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED)); } @@ -625,9 +625,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, value5); assertEq(transferRequest.key, key5); assertEq(transferRequest.id, 4); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, value5); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, value5); assertEq(uint256(transferRequest.status), uint256(STATUS.DENIED)); // new request transferRequest = ruleConditionalTransfer.getRequestTrade( @@ -637,9 +637,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { ); assertEq(transferRequest.key, key5PartialValue); assertEq(transferRequest.id, 5); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, partialValues[4]); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, partialValues[4]); assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED)); } @@ -659,9 +659,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.APPROVED)); } @@ -811,9 +811,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.DENIED)); } @@ -837,9 +837,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.DENIED)); TransferRequest[] memory transferRequests = ruleConditionalTransfer @@ -895,9 +895,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { bytes32 key = keccak256(abi.encode(ADDRESS1, ADDRESS2, value)); assertEq(transferRequest[0].key, key); assertEq(transferRequest[0].id, 1); - assertEq(transferRequest[0].from, ADDRESS1); - assertEq(transferRequest[0].to, ADDRESS2); - assertEq(transferRequest[0].value, value); + assertEq(transferRequest[0].keyElement.from, ADDRESS1); + assertEq(transferRequest[0].keyElement.to, ADDRESS2); + assertEq(transferRequest[0].keyElement.value, value); assertEq(uint256(transferRequest[0].status), uint256(STATUS.WAIT)); // third request @@ -916,9 +916,9 @@ contract RuleConditionalTransferTest is Test, HelperContract { ); assertEq(transferRequest[1].key, keyThird); assertEq(transferRequest[1].id, 2); - assertEq(transferRequest[1].from, ADDRESS1); - assertEq(transferRequest[1].to, ADDRESS2); - assertEq(transferRequest[1].value, valueThird); + assertEq(transferRequest[1].keyElement.from, ADDRESS1); + assertEq(transferRequest[1].keyElement.to, ADDRESS2); + assertEq(transferRequest[1].keyElement.value, valueThird); assertEq(uint256(transferRequest[1].status), uint256(STATUS.WAIT)); } diff --git a/test/RuleConditionalTransfer/RuleConditionalTransferReset.t.sol b/test/RuleConditionalTransfer/RuleConditionalTransferReset.t.sol index e3c7f8d..9ca291f 100644 --- a/test/RuleConditionalTransfer/RuleConditionalTransferReset.t.sol +++ b/test/RuleConditionalTransfer/RuleConditionalTransferReset.t.sol @@ -131,9 +131,9 @@ contract RuleConditionalTransferResetTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.WAIT)); TransferRequest[] memory transferRequests = ruleConditionalTransfer @@ -298,9 +298,9 @@ contract RuleConditionalTransferResetTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.NONE)); // Assert @@ -318,9 +318,9 @@ contract RuleConditionalTransferResetTest is Test, HelperContract { ); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.WAIT)); // Id different from 0 @@ -363,9 +363,9 @@ contract RuleConditionalTransferResetTest is Test, HelperContract { .getRequestTrade(ADDRESS1, ADDRESS2, defaultValue); assertEq(transferRequest.key, defaultKey); assertEq(transferRequest.id, 0); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, defaultValue); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, defaultValue); assertEq(uint256(transferRequest.status), uint256(STATUS.NONE)); transferRequest = ruleConditionalTransfer.getRequestTrade( @@ -375,9 +375,9 @@ contract RuleConditionalTransferResetTest is Test, HelperContract { ); assertEq(transferRequest.key, key2); assertEq(transferRequest.id, 1); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, value2); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, value2); assertEq(uint256(transferRequest.status), uint256(STATUS.NONE)); transferRequest = ruleConditionalTransfer.getRequestTrade( @@ -387,9 +387,9 @@ contract RuleConditionalTransferResetTest is Test, HelperContract { ); assertEq(transferRequest.key, key3Hodler); assertEq(transferRequest.id, 2); - assertEq(transferRequest.from, ADDRESS1); - assertEq(transferRequest.to, ADDRESS2); - assertEq(transferRequest.value, value3); + assertEq(transferRequest.keyElement.from, ADDRESS1); + assertEq(transferRequest.keyElement.to, ADDRESS2); + assertEq(transferRequest.keyElement.value, value3); assertEq(uint256(transferRequest.status), uint256(STATUS.NONE)); }