@coti-io/coti-contracts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/.github/workflows/npm-publish.yml +52 -0
  2. package/CODE_OF_CONDUCT.md +44 -0
  3. package/CONTRIBUTING.md +101 -0
  4. package/LICENSE +201 -0
  5. package/README.md +48 -0
  6. package/contracts/access/DataPrivacyFramework/DataPrivacyFramework.sol +480 -0
  7. package/contracts/access/DataPrivacyFramework/README.md +68 -0
  8. package/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc.sol +1139 -0
  9. package/contracts/mocks/README.md +5 -0
  10. package/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock.sol +9 -0
  11. package/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.sol +17 -0
  12. package/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock.sol +34 -0
  13. package/contracts/mocks/utils/mpc/ArithmeticTestsContract.sol +431 -0
  14. package/contracts/mocks/utils/mpc/BitwiseTestsContract.sol +361 -0
  15. package/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol +307 -0
  16. package/contracts/mocks/utils/mpc/Comparison2TestsContract.sol +307 -0
  17. package/contracts/mocks/utils/mpc/MinMaxTestsContract.sol +297 -0
  18. package/contracts/mocks/utils/mpc/Miscellaneous1TestsContract.sol +185 -0
  19. package/contracts/mocks/utils/mpc/Miscellaneous2TestsContract.sol +448 -0
  20. package/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol +81 -0
  21. package/contracts/mocks/utils/mpc/README.md +486 -0
  22. package/contracts/mocks/utils/mpc/ShiftTestsContract.sol +311 -0
  23. package/contracts/mocks/utils/mpc/StringTestsContract.sol +59 -0
  24. package/contracts/mocks/utils/mpc/TransferScalarTestsContract.sol +271 -0
  25. package/contracts/mocks/utils/mpc/TransferTestsContract.sol +715 -0
  26. package/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.sol +25 -0
  27. package/contracts/onboard/AccountOnboard.sol +21 -0
  28. package/contracts/onboard/README.md +65 -0
  29. package/contracts/package.json +11 -0
  30. package/contracts/token/PrivateERC20/IPrivateERC20.sol +142 -0
  31. package/contracts/token/PrivateERC20/PrivateERC20.sol +478 -0
  32. package/contracts/token/PrivateERC20/README.md +104 -0
  33. package/contracts/token/PrivateERC721/PrivateERC721.sol +458 -0
  34. package/contracts/token/PrivateERC721/README.md +282 -0
  35. package/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage.sol +87 -0
  36. package/contracts/utils/mpc/MpcCore.sol +3215 -0
  37. package/contracts/utils/mpc/MpcInterface.sol +41 -0
  38. package/contracts/utils/mpc/README.md +82 -0
  39. package/hardhat.config.ts +18 -0
  40. package/package.json +14 -0
  41. package/test/access/DataPrivacyFramework/DataPrivacyFramework.test.ts +780 -0
  42. package/test/onboard/AccountOnboard.test.ts +45 -0
  43. package/test/token/PrivateERC20/PrivateERC20.test.ts +546 -0
  44. package/test/token/PrivateERC721/PrivateERC721.test.ts +223 -0
  45. package/test/utils/accounts.ts +55 -0
  46. package/test/utils/mpc/Precompile.test.ts +113 -0
  47. package/test/utils/mpc/String.test.ts +227 -0
  48. package/tsconfig.json +11 -0
  49. package/typechain-types/@openzeppelin/contracts/index.ts +9 -0
  50. package/typechain-types/@openzeppelin/contracts/interfaces/IERC4906.ts +462 -0
  51. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.ts +69 -0
  52. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.ts +69 -0
  53. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.ts +69 -0
  54. package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
  55. package/typechain-types/@openzeppelin/contracts/interfaces/index.ts +6 -0
  56. package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721.ts +393 -0
  57. package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721Receiver.ts +110 -0
  58. package/typechain-types/@openzeppelin/contracts/token/ERC721/index.ts +5 -0
  59. package/typechain-types/@openzeppelin/contracts/token/index.ts +5 -0
  60. package/typechain-types/@openzeppelin/contracts/utils/index.ts +5 -0
  61. package/typechain-types/@openzeppelin/contracts/utils/introspection/ERC165.ts +94 -0
  62. package/typechain-types/@openzeppelin/contracts/utils/introspection/IERC165.ts +94 -0
  63. package/typechain-types/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
  64. package/typechain-types/@openzeppelin/index.ts +5 -0
  65. package/typechain-types/common.ts +131 -0
  66. package/typechain-types/contracts/access/DataPrivacyFramework/DataPrivacyFramework.ts +598 -0
  67. package/typechain-types/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc.ts +598 -0
  68. package/typechain-types/contracts/access/DataPrivacyFramework/extensions/index.ts +4 -0
  69. package/typechain-types/contracts/access/DataPrivacyFramework/index.ts +6 -0
  70. package/typechain-types/contracts/access/index.ts +5 -0
  71. package/typechain-types/contracts/index.ts +13 -0
  72. package/typechain-types/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock.ts +598 -0
  73. package/typechain-types/contracts/mocks/access/DataPrivacyFramework/index.ts +4 -0
  74. package/typechain-types/contracts/mocks/access/index.ts +5 -0
  75. package/typechain-types/contracts/mocks/index.ts +11 -0
  76. package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.ts +543 -0
  77. package/typechain-types/contracts/mocks/token/PrivateERC20/index.ts +4 -0
  78. package/typechain-types/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock.ts +576 -0
  79. package/typechain-types/contracts/mocks/token/PrivateERC721/index.ts +4 -0
  80. package/typechain-types/contracts/mocks/token/index.ts +7 -0
  81. package/typechain-types/contracts/mocks/utils/index.ts +5 -0
  82. package/typechain-types/contracts/mocks/utils/mpc/ArithmeticTestsContract.ts +354 -0
  83. package/typechain-types/contracts/mocks/utils/mpc/BitwiseTestsContract.ts +340 -0
  84. package/typechain-types/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/Comparison1TestsContract.ts +340 -0
  85. package/typechain-types/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/index.ts +4 -0
  86. package/typechain-types/contracts/mocks/utils/mpc/Comparison2TestsContract.ts +340 -0
  87. package/typechain-types/contracts/mocks/utils/mpc/MinMaxTestsContract.ts +321 -0
  88. package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous1TestsContract.ts +199 -0
  89. package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous2TestsContract.ts +384 -0
  90. package/typechain-types/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/OffboardToUserKeyTestContract.ts +218 -0
  91. package/typechain-types/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/index.ts +4 -0
  92. package/typechain-types/contracts/mocks/utils/mpc/ShiftTestsContract.ts +339 -0
  93. package/typechain-types/contracts/mocks/utils/mpc/StringTestsContract.ts +211 -0
  94. package/typechain-types/contracts/mocks/utils/mpc/TransferScalarTestsContract.ts +266 -0
  95. package/typechain-types/contracts/mocks/utils/mpc/TransferTestsContract.ts +288 -0
  96. package/typechain-types/contracts/mocks/utils/mpc/index.ts +17 -0
  97. package/typechain-types/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.ts +173 -0
  98. package/typechain-types/contracts/mocks/wallet/PrivateERC20Wallet/index.ts +4 -0
  99. package/typechain-types/contracts/mocks/wallet/index.ts +5 -0
  100. package/typechain-types/contracts/onboard/AccountOnboard.ts +135 -0
  101. package/typechain-types/contracts/onboard/index.ts +4 -0
  102. package/typechain-types/contracts/token/PrivateERC20/IPrivateERC20.ts +437 -0
  103. package/typechain-types/contracts/token/PrivateERC20/PrivateERC20.ts +505 -0
  104. package/typechain-types/contracts/token/PrivateERC20/index.ts +5 -0
  105. package/typechain-types/contracts/token/PrivateERC721/PrivateERC721.ts +409 -0
  106. package/typechain-types/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage.ts +501 -0
  107. package/typechain-types/contracts/token/PrivateERC721/extensions/index.ts +4 -0
  108. package/typechain-types/contracts/token/PrivateERC721/index.ts +6 -0
  109. package/typechain-types/contracts/token/index.ts +7 -0
  110. package/typechain-types/contracts/utils/index.ts +5 -0
  111. package/typechain-types/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations.ts +698 -0
  112. package/typechain-types/contracts/utils/mpc/MpcInterface.sol/index.ts +4 -0
  113. package/typechain-types/contracts/utils/mpc/index.ts +5 -0
  114. package/typechain-types/factories/@openzeppelin/contracts/index.ts +6 -0
  115. package/typechain-types/factories/@openzeppelin/contracts/interfaces/IERC4906__factory.ts +339 -0
  116. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors__factory.ts +127 -0
  117. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors__factory.ts +111 -0
  118. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors__factory.ts +128 -0
  119. package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
  120. package/typechain-types/factories/@openzeppelin/contracts/interfaces/index.ts +5 -0
  121. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721Receiver__factory.ts +59 -0
  122. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721__factory.ts +307 -0
  123. package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/index.ts +5 -0
  124. package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +4 -0
  125. package/typechain-types/factories/@openzeppelin/contracts/utils/index.ts +4 -0
  126. package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/ERC165__factory.ts +41 -0
  127. package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/IERC165__factory.ts +41 -0
  128. package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
  129. package/typechain-types/factories/@openzeppelin/index.ts +4 -0
  130. package/typechain-types/factories/contracts/access/DataPrivacyFramework/DataPrivacyFramework__factory.ts +621 -0
  131. package/typechain-types/factories/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc__factory.ts +621 -0
  132. package/typechain-types/factories/contracts/access/DataPrivacyFramework/extensions/index.ts +4 -0
  133. package/typechain-types/factories/contracts/access/DataPrivacyFramework/index.ts +5 -0
  134. package/typechain-types/factories/contracts/access/index.ts +4 -0
  135. package/typechain-types/factories/contracts/index.ts +8 -0
  136. package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock__factory.ts +670 -0
  137. package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/index.ts +4 -0
  138. package/typechain-types/factories/contracts/mocks/access/index.ts +4 -0
  139. package/typechain-types/factories/contracts/mocks/index.ts +7 -0
  140. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20Mock__factory.ts +615 -0
  141. package/typechain-types/factories/contracts/mocks/token/PrivateERC20/index.ts +4 -0
  142. package/typechain-types/factories/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock__factory.ts +630 -0
  143. package/typechain-types/factories/contracts/mocks/token/PrivateERC721/index.ts +4 -0
  144. package/typechain-types/factories/contracts/mocks/token/index.ts +5 -0
  145. package/typechain-types/factories/contracts/mocks/utils/index.ts +4 -0
  146. package/typechain-types/factories/contracts/mocks/utils/mpc/ArithmeticTestsContract__factory.ts +374 -0
  147. package/typechain-types/factories/contracts/mocks/utils/mpc/BitwiseTestsContract__factory.ts +361 -0
  148. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/Comparison1TestsContract__factory.ts +361 -0
  149. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/index.ts +4 -0
  150. package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison2TestsContract__factory.ts +361 -0
  151. package/typechain-types/factories/contracts/mocks/utils/mpc/MinMaxTestsContract__factory.ts +337 -0
  152. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous1TestsContract__factory.ts +236 -0
  153. package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous2TestsContract__factory.ts +432 -0
  154. package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/OffboardToUserKeyTestContract__factory.ts +245 -0
  155. package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/index.ts +4 -0
  156. package/typechain-types/factories/contracts/mocks/utils/mpc/ShiftTestsContract__factory.ts +374 -0
  157. package/typechain-types/factories/contracts/mocks/utils/mpc/StringTestsContract__factory.ts +264 -0
  158. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferScalarTestsContract__factory.ts +360 -0
  159. package/typechain-types/factories/contracts/mocks/utils/mpc/TransferTestsContract__factory.ts +441 -0
  160. package/typechain-types/factories/contracts/mocks/utils/mpc/index.ts +15 -0
  161. package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock__factory.ts +194 -0
  162. package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/index.ts +4 -0
  163. package/typechain-types/factories/contracts/mocks/wallet/index.ts +4 -0
  164. package/typechain-types/factories/contracts/onboard/AccountOnboard__factory.ts +104 -0
  165. package/typechain-types/factories/contracts/onboard/index.ts +4 -0
  166. package/typechain-types/factories/contracts/token/PrivateERC20/IPrivateERC20__factory.ts +406 -0
  167. package/typechain-types/factories/contracts/token/PrivateERC20/PrivateERC20__factory.ts +532 -0
  168. package/typechain-types/factories/contracts/token/PrivateERC20/index.ts +5 -0
  169. package/typechain-types/factories/contracts/token/PrivateERC721/PrivateERC721__factory.ts +439 -0
  170. package/typechain-types/factories/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage__factory.ts +512 -0
  171. package/typechain-types/factories/contracts/token/PrivateERC721/extensions/index.ts +4 -0
  172. package/typechain-types/factories/contracts/token/PrivateERC721/index.ts +5 -0
  173. package/typechain-types/factories/contracts/token/index.ts +5 -0
  174. package/typechain-types/factories/contracts/utils/index.ts +4 -0
  175. package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations__factory.ts +919 -0
  176. package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/index.ts +4 -0
  177. package/typechain-types/factories/contracts/utils/mpc/index.ts +4 -0
  178. package/typechain-types/factories/index.ts +5 -0
  179. package/typechain-types/hardhat.d.ts +621 -0
  180. package/typechain-types/index.ts +72 -0
@@ -0,0 +1,480 @@
1
+ // SPDX-License-Identifier: MIT
2
+
3
+ pragma solidity ^0.8.19;
4
+
5
+ abstract contract DataPrivacyFramework {
6
+
7
+ // struct needed for avoiding "stack too deep" error
8
+ // see Condition struct for further details
9
+ struct InputData {
10
+ address caller;
11
+ string operation;
12
+ bool active;
13
+ uint256 timestampBefore;
14
+ uint256 timestampAfter;
15
+ bool falseKey;
16
+ bool trueKey;
17
+ uint256 uintParameter;
18
+ address addressParameter;
19
+ string stringParameter;
20
+ }
21
+
22
+ struct Condition {
23
+ uint256 id; // numeric ID of the condition
24
+ address caller; // caller associated with this condition
25
+ string operation; // operation associated with this condition
26
+ bool active; // indicates if the permission is active
27
+ bool falseKey; // causes the condition to never be satisfied
28
+ bool trueKey; // causes the permission to always be satisfied (but has lower priority than falseKey)
29
+ uint256 timestampBefore; // condition is valid before this timestamp
30
+ uint256 timestampAfter; // condition is valid after this timestamp
31
+ uint256 uintParameter; // parameter of type uint256 used for verifying if the caller has permission to perform the computation
32
+ address addressParameter; // parameter of type address used for verifying if the caller has permission to perform the computation
33
+ string stringParameter;// parameter of type string used for verifying if the caller has permission to perform the computation
34
+ }
35
+
36
+ enum ParameterType {
37
+ None,
38
+ UintParam,
39
+ AddressParam,
40
+ StringParam
41
+ }
42
+
43
+ address public constant ADDRESS_ALL = address(1); // used to indicate the generic address (equivalent to "*")
44
+
45
+ string public constant STRING_ALL = "*"; // used to indicate the generic string
46
+
47
+ bool public addressDefaultPermission; // TODO: Replace with more descriptive name
48
+
49
+ bool public operationDefaultPermission; // TODO: Replace with more descriptive name
50
+
51
+ mapping(string => bool) public allowedOperations;
52
+
53
+ mapping(string => bool) public restrictedOperations;
54
+
55
+ mapping(address => uint256) public activePermissions;
56
+
57
+ mapping(address => mapping(string => uint256)) public permissions; // caller => operation => idx
58
+
59
+ uint256 private _conditionsCount = 1; // we skip ID=0 to allow us to use this value to indicate a null entry
60
+
61
+ mapping(uint256 => Condition) public conditions; // idx => conditions
62
+
63
+ modifier onlyAllowedUserOperation(string memory operation, uint256 uintParameter, address addressParameter, string memory stringParameter) {
64
+ if (uintParameter != 0) {
65
+ require(this.isOperationAllowed(msg.sender, operation, uintParameter), "DPF: No Permission!");
66
+ } else if (addressParameter != address(0)) {
67
+ require(this.isOperationAllowed(msg.sender, operation, addressParameter), "DPF: No Permission!");
68
+ } else if (keccak256(abi.encodePacked(stringParameter)) != keccak256(abi.encodePacked(""))) {
69
+ require(this.isOperationAllowed(msg.sender, operation, stringParameter), "DPF: No Permission!");
70
+ } else {
71
+ require(this.isOperationAllowed(msg.sender, operation), "DPF: No Permission!");
72
+ }
73
+
74
+ _;
75
+ }
76
+
77
+ /**
78
+ * @param addressDefaultPermission_ default address permission
79
+ * @param operationDefaultPermission_ default operation permission
80
+ */
81
+ constructor(bool addressDefaultPermission_, bool operationDefaultPermission_) {
82
+ addressDefaultPermission = addressDefaultPermission_;
83
+ operationDefaultPermission = operationDefaultPermission_;
84
+
85
+ // set admin permissions
86
+ allowedOperations["admin"] = true;
87
+
88
+ setPermission(InputData(msg.sender, "admin", true, 0, 0, false, false, 0, address(0), ""));
89
+
90
+ // by default we allow all users and all operations
91
+ allowedOperations[STRING_ALL] = true;
92
+
93
+ setPermission(InputData(ADDRESS_ALL, STRING_ALL, true, 0, 0, false, false, 0, address(0), ""));
94
+ }
95
+
96
+ /**
97
+ * @notice returns the number of rows in the conditions table
98
+ */
99
+ function getConditionsCount() external view returns (uint256) {
100
+ return _conditionsCount - 1;
101
+ }
102
+
103
+ /**
104
+ * @notice downloads the entire conditions mapping with paging
105
+ * @dev start with startIdx=1 and increment by chunkSize until the size of the returned array is less than chunk size
106
+ * @dev the developer is responsible for filtering out inactive conditions and conditions that are irrelevant
107
+ * @param startIdx the index of the first condition to include in the list of returned conditions
108
+ * @param chunkSize the maximum number of conditions to return (needed to avoid running out of gas)
109
+ * @return _ array of conditions
110
+ */
111
+ function getConditions(
112
+ uint256 startIdx,
113
+ uint256 chunkSize
114
+ )
115
+ external
116
+ view
117
+ returns (Condition[] memory)
118
+ {
119
+ require(startIdx > 0, "DPF: START_IDX_ZERO");
120
+ require(chunkSize > 0, "DPF: CHUNK_SIZE_ZERO");
121
+
122
+ // reached end of table
123
+ if (startIdx >= _conditionsCount) return new Condition[](0);
124
+
125
+ // ensures that startIdx + arrSize is not larger than the maximum condition ID
126
+ uint256 arrSize = startIdx + chunkSize - 1 <= _conditionsCount - 1 ? chunkSize : _conditionsCount - startIdx;
127
+
128
+ Condition[] memory conditions_ = new Condition[](arrSize);
129
+
130
+ for (uint256 i = 0; i < arrSize; i++) {
131
+ conditions_[i] = conditions[startIdx + i];
132
+ }
133
+
134
+ return conditions_;
135
+ }
136
+
137
+ /**
138
+ * @notice determines whether the provided caller has sufficient permission to perform the given computation
139
+ * @param caller the address of the user who is seeking permission to perform some computation on private data
140
+ * @param operation the operation which the user is seeking to perform
141
+ * @return _ boolean indicating if the user has permission to perform the computation
142
+ */
143
+ function isOperationAllowed(
144
+ address caller,
145
+ string calldata operation
146
+ )
147
+ external
148
+ view
149
+ returns (bool)
150
+ {
151
+ return _isOperationAllowed(
152
+ caller,
153
+ operation,
154
+ ParameterType.None,
155
+ 0,
156
+ address(0),
157
+ ""
158
+ );
159
+ }
160
+
161
+ /**
162
+ * @notice determines whether the provided caller has sufficient permission to perform the given computation
163
+ * @param caller the address of the user who is seeking permission to perform some computation on private data
164
+ * @param operation the operation which the user is seeking to perform
165
+ * @param uintParameter parameter of type uint256 used to check for permissions
166
+ * @return _ boolean indicating if the user has permission to perform the computation
167
+ */
168
+ function isOperationAllowed(
169
+ address caller,
170
+ string calldata operation,
171
+ uint256 uintParameter
172
+ )
173
+ external
174
+ view
175
+ returns (bool)
176
+ {
177
+ return _isOperationAllowed(
178
+ caller,
179
+ operation,
180
+ ParameterType.UintParam,
181
+ uintParameter,
182
+ address(0),
183
+ ""
184
+ );
185
+ }
186
+
187
+ /**
188
+ * @notice determines whether the provided caller has sufficient permission to perform the given computation
189
+ * @param caller the address of the user who is seeking permission to perform some computation on private data
190
+ * @param operation the operation which the user is seeking to perform
191
+ * @param addressParameter parameter of type address used to check for permissions
192
+ * @return _ boolean indicating if the user has permission to perform the computation
193
+ */
194
+ function isOperationAllowed(
195
+ address caller,
196
+ string calldata operation,
197
+ address addressParameter
198
+ )
199
+ external
200
+ view
201
+ returns (bool)
202
+ {
203
+ return _isOperationAllowed(
204
+ caller,
205
+ operation,
206
+ ParameterType.AddressParam,
207
+ 0,
208
+ addressParameter,
209
+ ""
210
+ );
211
+ }
212
+
213
+ /**
214
+ * @notice determines whether the provided caller has sufficient permission to perform the given computation
215
+ * @param caller the address of the user who is seeking permission to perform some computation on private data
216
+ * @param operation the operation which the user is seeking to perform
217
+ * @param stringParameter parameter of type string used to check for permissions
218
+ * @return _ boolean indicating if the user has permission to perform the computation
219
+ */
220
+ function isOperationAllowed(
221
+ address caller,
222
+ string calldata operation,
223
+ string calldata stringParameter
224
+ )
225
+ external
226
+ view
227
+ returns (bool)
228
+ {
229
+ return _isOperationAllowed(
230
+ caller,
231
+ operation,
232
+ ParameterType.StringParam,
233
+ 0,
234
+ address(0),
235
+ stringParameter
236
+ );
237
+ }
238
+
239
+ /**
240
+ * @notice updates the default address permission
241
+ * @param defaultPermission new value of the default address permission
242
+ * @return _ boolean indicating if the update succeeded
243
+ */
244
+ function setAddressDefaultPermission(bool defaultPermission) external returns (bool) {
245
+ require(addressDefaultPermission != defaultPermission, "DPF: INVALID_PERMISSION_CHANGE");
246
+
247
+ addressDefaultPermission = defaultPermission;
248
+
249
+ return true;
250
+ }
251
+
252
+ /**
253
+ * @notice updates the default operation permission
254
+ * @param defaultPermission new value of the default operation permission
255
+ * @return _ boolean indicating if the update succeeded
256
+ */
257
+ function setOperationDefaultPermission(bool defaultPermission) external returns (bool) {
258
+ require(operationDefaultPermission != defaultPermission, "DPF: INVALID_PERMISSION_CHANGE");
259
+
260
+ operationDefaultPermission = defaultPermission;
261
+
262
+ return true;
263
+ }
264
+
265
+ /**
266
+ * @notice sets an operation as "allowed"
267
+ * @param operation the operation to allow
268
+ * @return _ boolean indicating if the update succeeded
269
+ */
270
+ function addAllowedOperation(string memory operation) public returns (bool) {
271
+ require(!allowedOperations[operation], "DPF: OPERATION_ALREADY_ALLOWED");
272
+
273
+ allowedOperations[operation] = true;
274
+
275
+ return true;
276
+ }
277
+
278
+ /**
279
+ * @notice removes an "allowed" operation
280
+ * @param operation the operation to remove
281
+ * @return _ boolean indicating if the update succeeded
282
+ */
283
+ function removeAllowedOperation(string calldata operation) external returns (bool) {
284
+ require(allowedOperations[operation], "DPF: OPERATION_NOT_ALLOWED");
285
+
286
+ allowedOperations[operation] = false;
287
+
288
+ return true;
289
+ }
290
+
291
+ /**
292
+ * @notice sets an operation as "restricted"
293
+ * @param operation the operation to restrict
294
+ * @return _ boolean indicating if the update succeeded
295
+ */
296
+ function addRestrictedOperation(string memory operation) public returns (bool) {
297
+ require(!restrictedOperations[operation], "DPF: OPERATION_ALREADY_RESTRICTED");
298
+
299
+ restrictedOperations[operation] = true;
300
+
301
+ return true;
302
+ }
303
+
304
+ /**
305
+ * @notice removes a "restricted" operation
306
+ * @param operation the operation to remove
307
+ * @return _ boolean indicating if the update succeeded
308
+ */
309
+ function removeRestrictedOperation(string calldata operation) external returns (bool) {
310
+ require(restrictedOperations[operation], "DPF: OPERATION_NOT_RESTRICTED");
311
+
312
+ restrictedOperations[operation] = false;
313
+
314
+ return true;
315
+ }
316
+
317
+ /**
318
+ * @notice creates a new permission or overwrites an existing one with the same caller and operation
319
+ * @param inputData struct containing the parameters of the new permission
320
+ * @return _ boolean indicating if the update succeeded
321
+ */
322
+ function setPermission(InputData memory inputData) public returns (bool) {
323
+ if (permissions[inputData.caller][inputData.operation] == 0) {
324
+ permissions[inputData.caller][inputData.operation] = _conditionsCount;
325
+
326
+ conditions[_conditionsCount] = Condition(
327
+ _conditionsCount,
328
+ inputData.caller,
329
+ inputData.operation,
330
+ inputData.active,
331
+ inputData.falseKey,
332
+ inputData.trueKey,
333
+ inputData.timestampBefore,
334
+ inputData.timestampAfter,
335
+ inputData.uintParameter,
336
+ inputData.addressParameter,
337
+ inputData.stringParameter
338
+ );
339
+
340
+ ++_conditionsCount;
341
+ ++activePermissions[inputData.caller];
342
+ } else {
343
+ Condition storage condition = conditions[permissions[inputData.caller][inputData.operation]];
344
+
345
+ // if there is an existing inactive permission and we are activating it then we increment activePermissions[caller]
346
+ if (inputData.active && !condition.active) {
347
+ ++activePermissions[inputData.caller];
348
+ }
349
+
350
+ // if there is an existing active permission and we are deactivating it then we decrement activePermissions[caller]
351
+ if (!inputData.active && condition.active) {
352
+ --activePermissions[inputData.caller];
353
+ }
354
+
355
+ condition.active = inputData.active;
356
+ condition.timestampBefore = inputData.timestampBefore;
357
+ condition.timestampAfter = inputData.timestampAfter;
358
+ condition.falseKey = inputData.falseKey;
359
+ condition.trueKey = inputData.trueKey;
360
+ condition.uintParameter = inputData.uintParameter;
361
+ condition.addressParameter = inputData.addressParameter;
362
+ condition.stringParameter = inputData.stringParameter;
363
+ }
364
+
365
+ return true;
366
+ }
367
+
368
+ /**
369
+ * @dev searches for a relevant and active permission and checks if the conditions are satisfied
370
+ * @param caller the address of the user who is seeking permission to perform some computation on private data
371
+ * @param operation the operation which the user is seeking to perform
372
+ * @param parameterType enum indicating the type of paramter we are using for comparison
373
+ * @param uintParameter parameter of type uint256 used to check for permissions
374
+ * @param addressParameter parameter of type address used to check for permissions
375
+ * @param stringParameter parameter of type string used to check for permissions
376
+ * @return _ boolean indicating if the caller has sufficient permission
377
+ */
378
+ function _isOperationAllowed(
379
+ address caller,
380
+ string calldata operation,
381
+ ParameterType parameterType,
382
+ uint256 uintParameter,
383
+ address addressParameter,
384
+ string memory stringParameter
385
+ ) internal view returns (bool) {
386
+ if (restrictedOperations[operation]) return false; // first we check if the operation is restricted
387
+ if (!allowedOperations[STRING_ALL] && !allowedOperations[operation]) return false; // second we check if the operation is allowed
388
+
389
+ // the provided caller has an active permission for the given operation
390
+ if (conditions[permissions[caller][operation]].active) {
391
+ return _evaluateCondition(
392
+ conditions[permissions[caller][operation]],
393
+ parameterType,
394
+ uintParameter,
395
+ addressParameter,
396
+ stringParameter
397
+ );
398
+ }
399
+
400
+ // the provided caller has an active permission for all operations
401
+ if (conditions[permissions[caller][STRING_ALL]].active) {
402
+ return _evaluateCondition(
403
+ conditions[permissions[caller][STRING_ALL]],
404
+ parameterType,
405
+ uintParameter,
406
+ addressParameter,
407
+ stringParameter
408
+ );
409
+ }
410
+
411
+ // fallback for when the provided caller has some active permissions but none are matching the given operation
412
+ if (activePermissions[caller] > 0) {
413
+ return operationDefaultPermission;
414
+ }
415
+
416
+ // all users are permitted to compute the given operation
417
+ if (conditions[permissions[ADDRESS_ALL][operation]].active) {
418
+ return _evaluateCondition(
419
+ conditions[permissions[ADDRESS_ALL][operation]],
420
+ parameterType,
421
+ uintParameter,
422
+ addressParameter,
423
+ stringParameter
424
+ );
425
+ }
426
+
427
+ // all users are permitted to compute all operations
428
+ if (conditions[permissions[ADDRESS_ALL][STRING_ALL]].active) {
429
+ return _evaluateCondition(
430
+ conditions[permissions[ADDRESS_ALL][STRING_ALL]],
431
+ parameterType,
432
+ uintParameter,
433
+ addressParameter,
434
+ stringParameter
435
+ );
436
+ }
437
+
438
+ // fallback for when no relevant permissions are found
439
+ return addressDefaultPermission;
440
+ }
441
+
442
+ /**
443
+ * @dev verifies that all conditions are satisfied
444
+ * @param condition struct containing the parameters of the condition
445
+ * @param parameterType enum indicating the type of paramter we are using for comparison
446
+ * @param uintParameter parameter of type uint256 used to check for permissions
447
+ * @param addressParameter parameter of type address used to check for permissions
448
+ * @param stringParameter parameter of type string used to check for permissions
449
+ * @return _ boolean indicating if the conditions are satisfied
450
+ */
451
+ function _evaluateCondition(
452
+ Condition memory condition,
453
+ ParameterType parameterType,
454
+ uint256 uintParameter,
455
+ address addressParameter,
456
+ string memory stringParameter
457
+ )
458
+ internal
459
+ view
460
+ returns (bool)
461
+ {
462
+ if (condition.falseKey) return false;
463
+
464
+ if (condition.trueKey) return true;
465
+
466
+ if (condition.timestampBefore > 0 && condition.timestampBefore < block.timestamp) return false;
467
+
468
+ if (condition.timestampAfter > 0 && condition.timestampAfter > block.timestamp) return false;
469
+
470
+ if (parameterType == ParameterType.UintParam && condition.uintParameter != 0 && condition.uintParameter != uintParameter) {
471
+ return false;
472
+ } else if (parameterType == ParameterType.AddressParam && condition.addressParameter != address(0) && condition.addressParameter != addressParameter) {
473
+ return false;
474
+ } else if (parameterType == ParameterType.StringParam && keccak256(abi.encodePacked(condition.stringParameter)) != keccak256(abi.encodePacked("")) && keccak256(abi.encodePacked(condition.stringParameter)) != keccak256(abi.encodePacked(stringParameter))) { // solidity does not support comparing strings so we compare the hashes instead
475
+ return false;
476
+ }
477
+
478
+ return true;
479
+ }
480
+ }
@@ -0,0 +1,68 @@
1
+ # DataPrivacyFramework
2
+
3
+ ## Overview
4
+
5
+ The `DataPrivacyFramework` is an abstract Solidity contract designed to manage conditions and operations related to data privacy. The contract handles operations such as user permissions, time-bound constraints, and condition validation based on various keys and parameters.
6
+
7
+ ## Prerequisites
8
+
9
+ - **Solidity Version:** `^0.8.19`
10
+ - **License:** MIT
11
+
12
+ ## Table of Contents
13
+ - [Data Structures](#data-structures)
14
+ - [InputData Struct](#inputdata-struct)
15
+ - [Condition Struct](#condition-struct)
16
+ - [Functions](#functions)
17
+ - [Abstract Functions](#abstract-functions)
18
+
19
+ ## Data Structures
20
+
21
+ ### InputData Struct
22
+
23
+ The `InputData` struct is a data holder that encapsulates the details of a particular operation or action requested by the caller. This struct helps in preventing the "stack too deep" error, which occurs when a function has too many local variables.
24
+
25
+ #### Fields:
26
+ - **`caller`**: (`address`) The address of the user or contract initiating the operation.
27
+ - **`operation`**: (`string`) The name or type of the operation being executed.
28
+ - **`active`**: (`bool`) A boolean flag indicating whether the operation is currently active.
29
+ - **`timestampBefore`**: (`uint256`) The operation must be executed before this timestamp.
30
+ - **`timestampAfter`**: (`uint256`) The operation must be executed after this timestamp.
31
+ - **`falseKey`**: (`bool`) A boolean flag that, if true, makes the condition unsatisfiable.
32
+ - **`trueKey`**: (`bool`) A boolean flag that, if true, makes the condition always satisfied (unless `falseKey` is true).
33
+ - **`uintParameter`**: (`uint256`) A numerical parameter relevant to the operation.
34
+ - **`addressParameter`**: (`address`) An address that may be used as a parameter for the operation.
35
+ - **`stringParameter`**: (`string`) A string-based parameter used for additional details in the operation.
36
+
37
+ ### Condition Struct
38
+
39
+ The `Condition` struct represents a privacy-related condition that can either permit or deny an operation based on various factors, such as the caller, timing constraints, and control flags (`falseKey`, `trueKey`).
40
+
41
+ #### Fields:
42
+ - **`id`**: (`uint256`) A unique identifier for the condition.
43
+ - **`caller`**: (`address`) The address associated with the condition.
44
+ - **`operation`**: (`string`) The type of operation the condition governs.
45
+ - **`active`**: (`bool`) Indicates if the condition is currently valid or active.
46
+ - **`falseKey`**: (`bool`) If set to `true`, the condition will never be satisfied.
47
+ - **`trueKey`**: (`bool`) If set to `true`, the condition will always be satisfied (unless `falseKey` is also true).
48
+ - **`timestampBefore`**: (`uint256`) The condition is only valid before this timestamp.
49
+ - **`timestampAfter`**: (`uint256`) The condition is only valid after this timestamp.
50
+
51
+ ## Functions
52
+
53
+ ### Abstract Functions
54
+
55
+ The contract is abstract, so the following functions are likely declared but not implemented within this contract. They need to be implemented in derived contracts.
56
+
57
+ #### `checkCondition`
58
+ This function checks whether the conditions of a specific operation are met, based on the values in the `Condition` struct.
59
+
60
+ ```solidity
61
+ function checkCondition(uint256 conditionId) public view virtual returns (bool);
62
+ ```
63
+
64
+ - **Parameters**:
65
+ - `conditionId`: The unique ID of the condition to check.
66
+
67
+ - **Returns**:
68
+ - `bool`: `true` if the condition is satisfied, `false` otherwise.