@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.
- package/.github/workflows/npm-publish.yml +52 -0
- package/CODE_OF_CONDUCT.md +44 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +201 -0
- package/README.md +48 -0
- package/contracts/access/DataPrivacyFramework/DataPrivacyFramework.sol +480 -0
- package/contracts/access/DataPrivacyFramework/README.md +68 -0
- package/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc.sol +1139 -0
- package/contracts/mocks/README.md +5 -0
- package/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock.sol +9 -0
- package/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.sol +17 -0
- package/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock.sol +34 -0
- package/contracts/mocks/utils/mpc/ArithmeticTestsContract.sol +431 -0
- package/contracts/mocks/utils/mpc/BitwiseTestsContract.sol +361 -0
- package/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol +307 -0
- package/contracts/mocks/utils/mpc/Comparison2TestsContract.sol +307 -0
- package/contracts/mocks/utils/mpc/MinMaxTestsContract.sol +297 -0
- package/contracts/mocks/utils/mpc/Miscellaneous1TestsContract.sol +185 -0
- package/contracts/mocks/utils/mpc/Miscellaneous2TestsContract.sol +448 -0
- package/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol +81 -0
- package/contracts/mocks/utils/mpc/README.md +486 -0
- package/contracts/mocks/utils/mpc/ShiftTestsContract.sol +311 -0
- package/contracts/mocks/utils/mpc/StringTestsContract.sol +59 -0
- package/contracts/mocks/utils/mpc/TransferScalarTestsContract.sol +271 -0
- package/contracts/mocks/utils/mpc/TransferTestsContract.sol +715 -0
- package/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.sol +25 -0
- package/contracts/onboard/AccountOnboard.sol +21 -0
- package/contracts/onboard/README.md +65 -0
- package/contracts/package.json +11 -0
- package/contracts/token/PrivateERC20/IPrivateERC20.sol +142 -0
- package/contracts/token/PrivateERC20/PrivateERC20.sol +478 -0
- package/contracts/token/PrivateERC20/README.md +104 -0
- package/contracts/token/PrivateERC721/PrivateERC721.sol +458 -0
- package/contracts/token/PrivateERC721/README.md +282 -0
- package/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage.sol +87 -0
- package/contracts/utils/mpc/MpcCore.sol +3215 -0
- package/contracts/utils/mpc/MpcInterface.sol +41 -0
- package/contracts/utils/mpc/README.md +82 -0
- package/hardhat.config.ts +18 -0
- package/package.json +14 -0
- package/test/access/DataPrivacyFramework/DataPrivacyFramework.test.ts +780 -0
- package/test/onboard/AccountOnboard.test.ts +45 -0
- package/test/token/PrivateERC20/PrivateERC20.test.ts +546 -0
- package/test/token/PrivateERC721/PrivateERC721.test.ts +223 -0
- package/test/utils/accounts.ts +55 -0
- package/test/utils/mpc/Precompile.test.ts +113 -0
- package/test/utils/mpc/String.test.ts +227 -0
- package/tsconfig.json +11 -0
- package/typechain-types/@openzeppelin/contracts/index.ts +9 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/IERC4906.ts +462 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/index.ts +6 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721.ts +393 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721Receiver.ts +110 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/token/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/utils/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/ERC165.ts +94 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/IERC165.ts +94 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
- package/typechain-types/@openzeppelin/index.ts +5 -0
- package/typechain-types/common.ts +131 -0
- package/typechain-types/contracts/access/DataPrivacyFramework/DataPrivacyFramework.ts +598 -0
- package/typechain-types/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc.ts +598 -0
- package/typechain-types/contracts/access/DataPrivacyFramework/extensions/index.ts +4 -0
- package/typechain-types/contracts/access/DataPrivacyFramework/index.ts +6 -0
- package/typechain-types/contracts/access/index.ts +5 -0
- package/typechain-types/contracts/index.ts +13 -0
- package/typechain-types/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock.ts +598 -0
- package/typechain-types/contracts/mocks/access/DataPrivacyFramework/index.ts +4 -0
- package/typechain-types/contracts/mocks/access/index.ts +5 -0
- package/typechain-types/contracts/mocks/index.ts +11 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.ts +543 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/index.ts +4 -0
- package/typechain-types/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock.ts +576 -0
- package/typechain-types/contracts/mocks/token/PrivateERC721/index.ts +4 -0
- package/typechain-types/contracts/mocks/token/index.ts +7 -0
- package/typechain-types/contracts/mocks/utils/index.ts +5 -0
- package/typechain-types/contracts/mocks/utils/mpc/ArithmeticTestsContract.ts +354 -0
- package/typechain-types/contracts/mocks/utils/mpc/BitwiseTestsContract.ts +340 -0
- package/typechain-types/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/Comparison1TestsContract.ts +340 -0
- package/typechain-types/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/index.ts +4 -0
- package/typechain-types/contracts/mocks/utils/mpc/Comparison2TestsContract.ts +340 -0
- package/typechain-types/contracts/mocks/utils/mpc/MinMaxTestsContract.ts +321 -0
- package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous1TestsContract.ts +199 -0
- package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous2TestsContract.ts +384 -0
- package/typechain-types/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/OffboardToUserKeyTestContract.ts +218 -0
- package/typechain-types/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/index.ts +4 -0
- package/typechain-types/contracts/mocks/utils/mpc/ShiftTestsContract.ts +339 -0
- package/typechain-types/contracts/mocks/utils/mpc/StringTestsContract.ts +211 -0
- package/typechain-types/contracts/mocks/utils/mpc/TransferScalarTestsContract.ts +266 -0
- package/typechain-types/contracts/mocks/utils/mpc/TransferTestsContract.ts +288 -0
- package/typechain-types/contracts/mocks/utils/mpc/index.ts +17 -0
- package/typechain-types/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.ts +173 -0
- package/typechain-types/contracts/mocks/wallet/PrivateERC20Wallet/index.ts +4 -0
- package/typechain-types/contracts/mocks/wallet/index.ts +5 -0
- package/typechain-types/contracts/onboard/AccountOnboard.ts +135 -0
- package/typechain-types/contracts/onboard/index.ts +4 -0
- package/typechain-types/contracts/token/PrivateERC20/IPrivateERC20.ts +437 -0
- package/typechain-types/contracts/token/PrivateERC20/PrivateERC20.ts +505 -0
- package/typechain-types/contracts/token/PrivateERC20/index.ts +5 -0
- package/typechain-types/contracts/token/PrivateERC721/PrivateERC721.ts +409 -0
- package/typechain-types/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage.ts +501 -0
- package/typechain-types/contracts/token/PrivateERC721/extensions/index.ts +4 -0
- package/typechain-types/contracts/token/PrivateERC721/index.ts +6 -0
- package/typechain-types/contracts/token/index.ts +7 -0
- package/typechain-types/contracts/utils/index.ts +5 -0
- package/typechain-types/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations.ts +698 -0
- package/typechain-types/contracts/utils/mpc/MpcInterface.sol/index.ts +4 -0
- package/typechain-types/contracts/utils/mpc/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/index.ts +6 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/IERC4906__factory.ts +339 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors__factory.ts +127 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors__factory.ts +111 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors__factory.ts +128 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721Receiver__factory.ts +59 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721__factory.ts +307 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/ERC165__factory.ts +41 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/IERC165__factory.ts +41 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/index.ts +4 -0
- package/typechain-types/factories/contracts/access/DataPrivacyFramework/DataPrivacyFramework__factory.ts +621 -0
- package/typechain-types/factories/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc__factory.ts +621 -0
- package/typechain-types/factories/contracts/access/DataPrivacyFramework/extensions/index.ts +4 -0
- package/typechain-types/factories/contracts/access/DataPrivacyFramework/index.ts +5 -0
- package/typechain-types/factories/contracts/access/index.ts +4 -0
- package/typechain-types/factories/contracts/index.ts +8 -0
- package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock__factory.ts +670 -0
- package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/access/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/index.ts +7 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20Mock__factory.ts +615 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock__factory.ts +630 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC721/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/token/index.ts +5 -0
- package/typechain-types/factories/contracts/mocks/utils/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/ArithmeticTestsContract__factory.ts +374 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/BitwiseTestsContract__factory.ts +361 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/Comparison1TestsContract__factory.ts +361 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison2TestsContract__factory.ts +361 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/MinMaxTestsContract__factory.ts +337 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous1TestsContract__factory.ts +236 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous2TestsContract__factory.ts +432 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/OffboardToUserKeyTestContract__factory.ts +245 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/ShiftTestsContract__factory.ts +374 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/StringTestsContract__factory.ts +264 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferScalarTestsContract__factory.ts +360 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferTestsContract__factory.ts +441 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/index.ts +15 -0
- package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock__factory.ts +194 -0
- package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/wallet/index.ts +4 -0
- package/typechain-types/factories/contracts/onboard/AccountOnboard__factory.ts +104 -0
- package/typechain-types/factories/contracts/onboard/index.ts +4 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/IPrivateERC20__factory.ts +406 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/PrivateERC20__factory.ts +532 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/index.ts +5 -0
- package/typechain-types/factories/contracts/token/PrivateERC721/PrivateERC721__factory.ts +439 -0
- package/typechain-types/factories/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage__factory.ts +512 -0
- package/typechain-types/factories/contracts/token/PrivateERC721/extensions/index.ts +4 -0
- package/typechain-types/factories/contracts/token/PrivateERC721/index.ts +5 -0
- package/typechain-types/factories/contracts/token/index.ts +5 -0
- package/typechain-types/factories/contracts/utils/index.ts +4 -0
- package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations__factory.ts +919 -0
- package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/index.ts +4 -0
- package/typechain-types/factories/contracts/utils/mpc/index.ts +4 -0
- package/typechain-types/factories/index.ts +5 -0
- package/typechain-types/hardhat.d.ts +621 -0
- 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.
|