Skip to content

Commit 07fc1f2

Browse files
maxsam4adamdossa
authored andcommitted
Datastore (#522)
* Test cases for data store * Rebase conflicts resolved * wip ds proxy * DS deployment * Fixed create instance helper * tests fixed * Added KYC TM module * Added array operation * Added features * Added batch functions * Removed multi delete * Removed overloaded external functions * Added test cases * Code cleanup and comments * Added test cases for security token * Added more test cases for data store * minor fixes * Small update to setSecurityToken * Fix
1 parent 40d5b38 commit 07fc1f2

File tree

16 files changed

+1279
-7
lines changed

16 files changed

+1279
-7
lines changed

contracts/datastore/DataStore.sol

Lines changed: 363 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,363 @@
1+
pragma solidity ^0.5.0;
2+
3+
import "../interfaces/ISecurityToken.sol";
4+
import "../interfaces/IOwnable.sol";
5+
import "../interfaces/IDataStore.sol";
6+
import "./DataStoreStorage.sol";
7+
8+
/**
9+
* @title Data store contract that stores data for all the modules in a central contract.
10+
*/
11+
contract DataStore is DataStoreStorage, IDataStore {
12+
//NB To modify a specific element of an array, First push a new element to the array and then delete the old element.
13+
//Whenver an element is deleted from an Array, last element of that array is moved to the index of deleted element.
14+
//Delegate with MANAGEDATA permission can modify data.
15+
16+
event SecurityTokenChanged(address indexed _oldSecurityToken, address indexed _newSecurityToken);
17+
18+
modifier onlyAuthorized() {
19+
bool isOwner = msg.sender == IOwnable(address(securityToken)).owner();
20+
require(isOwner ||
21+
securityToken.isModule(msg.sender, DATA_KEY) ||
22+
securityToken.checkPermission(msg.sender, address(this), MANAGEDATA),
23+
"Unauthorized"
24+
);
25+
_;
26+
}
27+
28+
modifier validKey(bytes32 _key) {
29+
require(_key != bytes32(0), "Missing key");
30+
_;
31+
}
32+
33+
modifier validArrayLength(uint256 _keyLength, uint256 _dataLength) {
34+
require(_keyLength == _dataLength, "Array length mismatch");
35+
_;
36+
}
37+
38+
modifier onlyOwner() {
39+
require(msg.sender == IOwnable(address(securityToken)).owner(), "Unauthorized");
40+
_;
41+
}
42+
43+
/**
44+
* @dev Changes security token atatched to this data store
45+
* @param _securityToken address of the security token
46+
*/
47+
function setSecurityToken(address _securityToken) external onlyOwner {
48+
require(_securityToken != address(0), "Invalid address");
49+
emit SecurityTokenChanged(address(securityToken), _securityToken);
50+
securityToken = ISecurityToken(_securityToken);
51+
}
52+
53+
/**
54+
* @dev Stores a uint256 data against a key
55+
* @param _key Unique key to identify the data
56+
* @param _data Data to be stored against the key
57+
*/
58+
function setUint256(bytes32 _key, uint256 _data) external onlyAuthorized {
59+
_setData(_key, _data);
60+
}
61+
62+
function setBytes32(bytes32 _key, bytes32 _data) external onlyAuthorized {
63+
_setData(_key, _data);
64+
}
65+
66+
function setAddress(bytes32 _key, address _data) external onlyAuthorized {
67+
_setData(_key, _data);
68+
}
69+
70+
function setString(bytes32 _key, string calldata _data) external onlyAuthorized {
71+
_setData(_key, _data);
72+
}
73+
74+
function setBytes(bytes32 _key, bytes calldata _data) external onlyAuthorized {
75+
_setData(_key, _data);
76+
}
77+
78+
function setBool(bytes32 _key, bool _data) external onlyAuthorized {
79+
_setData(_key, _data);
80+
}
81+
82+
/**
83+
* @dev Stores a uint256 array against a key
84+
* @param _key Unique key to identify the array
85+
* @param _data Array to be stored against the key
86+
*/
87+
function setUint256Array(bytes32 _key, uint256[] calldata _data) external onlyAuthorized {
88+
_setData(_key, _data);
89+
}
90+
91+
function setBytes32Array(bytes32 _key, bytes32[] calldata _data) external onlyAuthorized {
92+
_setData(_key, _data);
93+
}
94+
95+
function setAddressArray(bytes32 _key, address[] calldata _data) external onlyAuthorized {
96+
_setData(_key, _data);
97+
}
98+
99+
function setBoolArray(bytes32 _key, bool[] calldata _data) external onlyAuthorized {
100+
_setData(_key, _data);
101+
}
102+
103+
/**
104+
* @dev Inserts a uint256 element to the array identified by the key
105+
* @param _key Unique key to identify the array
106+
* @param _data Element to push into the array
107+
*/
108+
function insertUint256(bytes32 _key, uint256 _data) external onlyAuthorized {
109+
_insertData(_key, _data);
110+
}
111+
112+
function insertBytes32(bytes32 _key, bytes32 _data) external onlyAuthorized {
113+
_insertData(_key, _data);
114+
}
115+
116+
function insertAddress(bytes32 _key, address _data) external onlyAuthorized {
117+
_insertData(_key, _data);
118+
}
119+
120+
function insertBool(bytes32 _key, bool _data) external onlyAuthorized {
121+
_insertData(_key, _data);
122+
}
123+
124+
/**
125+
* @dev Deletes an element from the array identified by the key.
126+
* When an element is deleted from an Array, last element of that array is moved to the index of deleted element.
127+
* @param _key Unique key to identify the array
128+
* @param _index Index of the element to delete
129+
*/
130+
function deleteUint256(bytes32 _key, uint256 _index) external onlyAuthorized {
131+
_deleteUint(_key, _index);
132+
}
133+
134+
function deleteBytes32(bytes32 _key, uint256 _index) external onlyAuthorized {
135+
_deleteBytes32(_key, _index);
136+
}
137+
138+
function deleteAddress(bytes32 _key, uint256 _index) external onlyAuthorized {
139+
_deleteAddress(_key, _index);
140+
}
141+
142+
function deleteBool(bytes32 _key, uint256 _index) external onlyAuthorized {
143+
_deleteBool(_key, _index);
144+
}
145+
146+
/**
147+
* @dev Stores multiple uint256 data against respective keys
148+
* @param _keys Array of keys to identify the data
149+
* @param _data Array of data to be stored against the respective keys
150+
*/
151+
function setUint256Multi(bytes32[] calldata _keys, uint256[] calldata _data) external onlyAuthorized validArrayLength(_keys.length, _data.length) {
152+
for (uint256 i = 0; i < _keys.length; i++) {
153+
_setData(_keys[i], _data[i]);
154+
}
155+
}
156+
157+
function setBytes32Multi(bytes32[] calldata _keys, bytes32[] calldata _data) external onlyAuthorized validArrayLength(_keys.length, _data.length) {
158+
for (uint256 i = 0; i < _keys.length; i++) {
159+
_setData(_keys[i], _data[i]);
160+
}
161+
}
162+
163+
function setAddressMulti(bytes32[] calldata _keys, address[] calldata _data) external onlyAuthorized validArrayLength(_keys.length, _data.length) {
164+
for (uint256 i = 0; i < _keys.length; i++) {
165+
_setData(_keys[i], _data[i]);
166+
}
167+
}
168+
169+
function setBoolMulti(bytes32[] calldata _keys, bool[] calldata _data) external onlyAuthorized validArrayLength(_keys.length, _data.length) {
170+
for (uint256 i = 0; i < _keys.length; i++) {
171+
_setData(_keys[i], _data[i]);
172+
}
173+
}
174+
175+
/**
176+
* @dev Inserts multiple uint256 elements to the array identified by the respective keys
177+
* @param _keys Array of keys to identify the data
178+
* @param _data Array of data to be inserted in arrays of the respective keys
179+
*/
180+
function insertUint256Multi(bytes32[] calldata _keys, uint256[] calldata _data) external onlyAuthorized validArrayLength(_keys.length, _data.length) {
181+
for (uint256 i = 0; i < _keys.length; i++) {
182+
_insertData(_keys[i], _data[i]);
183+
}
184+
}
185+
186+
function insertBytes32Multi(bytes32[] calldata _keys, bytes32[] calldata _data) external onlyAuthorized validArrayLength(_keys.length, _data.length) {
187+
for (uint256 i = 0; i < _keys.length; i++) {
188+
_insertData(_keys[i], _data[i]);
189+
}
190+
}
191+
192+
function insertAddressMulti(bytes32[] calldata _keys, address[] calldata _data) external onlyAuthorized validArrayLength(_keys.length, _data.length) {
193+
for (uint256 i = 0; i < _keys.length; i++) {
194+
_insertData(_keys[i], _data[i]);
195+
}
196+
}
197+
198+
function insertBoolMulti(bytes32[] calldata _keys, bool[] calldata _data) external onlyAuthorized validArrayLength(_keys.length, _data.length) {
199+
for (uint256 i = 0; i < _keys.length; i++) {
200+
_insertData(_keys[i], _data[i]);
201+
}
202+
}
203+
204+
function getUint256(bytes32 _key) external view returns(uint256) {
205+
return uintData[_key];
206+
}
207+
208+
function getBytes32(bytes32 _key) external view returns(bytes32) {
209+
return bytes32Data[_key];
210+
}
211+
212+
function getAddress(bytes32 _key) external view returns(address) {
213+
return addressData[_key];
214+
}
215+
216+
function getString(bytes32 _key) external view returns(string memory) {
217+
return stringData[_key];
218+
}
219+
220+
function getBytes(bytes32 _key) external view returns(bytes memory) {
221+
return bytesData[_key];
222+
}
223+
224+
function getBool(bytes32 _key) external view returns(bool) {
225+
return boolData[_key];
226+
}
227+
228+
function getUint256Array(bytes32 _key) external view returns(uint256[] memory) {
229+
return uintArrayData[_key];
230+
}
231+
232+
function getBytes32Array(bytes32 _key) external view returns(bytes32[] memory) {
233+
return bytes32ArrayData[_key];
234+
}
235+
236+
function getAddressArray(bytes32 _key) external view returns(address[] memory) {
237+
return addressArrayData[_key];
238+
}
239+
240+
function getBoolArray(bytes32 _key) external view returns(bool[] memory) {
241+
return boolArrayData[_key];
242+
}
243+
244+
function getUint256ArrayLength(bytes32 _key) external view returns(uint256) {
245+
return uintArrayData[_key].length;
246+
}
247+
248+
function getBytes32ArrayLength(bytes32 _key) external view returns(uint256) {
249+
return bytes32ArrayData[_key].length;
250+
}
251+
252+
function getAddressArrayLength(bytes32 _key) external view returns(uint256) {
253+
return addressArrayData[_key].length;
254+
}
255+
256+
function getBoolArrayLength(bytes32 _key) external view returns(uint256) {
257+
return boolArrayData[_key].length;
258+
}
259+
260+
function getUint256ArrayElement(bytes32 _key, uint256 _index) external view returns(uint256) {
261+
return uintArrayData[_key][_index];
262+
}
263+
264+
function getBytes32ArrayElement(bytes32 _key, uint256 _index) external view returns(bytes32) {
265+
return bytes32ArrayData[_key][_index];
266+
}
267+
268+
function getAddressArrayElement(bytes32 _key, uint256 _index) external view returns(address) {
269+
return addressArrayData[_key][_index];
270+
}
271+
272+
function getBoolArrayElement(bytes32 _key, uint256 _index) external view returns(bool) {
273+
return boolArrayData[_key][_index];
274+
}
275+
276+
function _setData(bytes32 _key, uint256 _data) internal validKey(_key) {
277+
uintData[_key] = _data;
278+
}
279+
280+
function _setData(bytes32 _key, bytes32 _data) internal validKey(_key) {
281+
bytes32Data[_key] = _data;
282+
}
283+
284+
function _setData(bytes32 _key, address _data) internal validKey(_key) {
285+
addressData[_key] = _data;
286+
}
287+
288+
function _setData(bytes32 _key, string memory _data) internal validKey(_key) {
289+
stringData[_key] = _data;
290+
}
291+
292+
function _setData(bytes32 _key, bytes memory _data) internal validKey(_key) {
293+
bytesData[_key] = _data;
294+
}
295+
296+
function _setData(bytes32 _key, bool _data) internal validKey(_key) {
297+
boolData[_key] = _data;
298+
}
299+
300+
function _setData(bytes32 _key, uint256[] memory _data) internal validKey(_key) {
301+
uintArrayData[_key] = _data;
302+
}
303+
304+
function _setData(bytes32 _key, bytes32[] memory _data) internal validKey(_key) {
305+
bytes32ArrayData[_key] = _data;
306+
}
307+
308+
function _setData(bytes32 _key, address[] memory _data) internal validKey(_key) {
309+
addressArrayData[_key] = _data;
310+
}
311+
312+
function _setData(bytes32 _key, bool[] memory _data) internal validKey(_key) {
313+
boolArrayData[_key] = _data;
314+
}
315+
316+
function _insertData(bytes32 _key, uint256 _data) internal validKey(_key) {
317+
uintArrayData[_key].push(_data);
318+
}
319+
320+
function _insertData(bytes32 _key, bytes32 _data) internal validKey(_key) {
321+
bytes32ArrayData[_key].push(_data);
322+
}
323+
324+
function _insertData(bytes32 _key, address _data) internal validKey(_key) {
325+
addressArrayData[_key].push(_data);
326+
}
327+
328+
function _insertData(bytes32 _key, bool _data) internal validKey(_key) {
329+
boolArrayData[_key].push(_data);
330+
}
331+
332+
function _deleteUint(bytes32 _key, uint256 _index) internal validKey(_key) {
333+
require(uintArrayData[_key].length > _index, "Invalid Index"); //Also prevents undeflow
334+
if(uintArrayData[_key].length - 1 != _index) {
335+
uintArrayData[_key][_index] = uintArrayData[_key][uintArrayData[_key].length - 1];
336+
}
337+
uintArrayData[_key].length--;
338+
}
339+
340+
function _deleteBytes32(bytes32 _key, uint256 _index) internal validKey(_key) {
341+
require(bytes32ArrayData[_key].length > _index, "Invalid Index"); //Also prevents undeflow
342+
if(bytes32ArrayData[_key].length - 1 != _index) {
343+
bytes32ArrayData[_key][_index] = bytes32ArrayData[_key][bytes32ArrayData[_key].length - 1];
344+
}
345+
bytes32ArrayData[_key].length--;
346+
}
347+
348+
function _deleteAddress(bytes32 _key, uint256 _index) internal validKey(_key) {
349+
require(addressArrayData[_key].length > _index, "Invalid Index"); //Also prevents undeflow
350+
if(addressArrayData[_key].length - 1 != _index) {
351+
addressArrayData[_key][_index] = addressArrayData[_key][addressArrayData[_key].length - 1];
352+
}
353+
addressArrayData[_key].length--;
354+
}
355+
356+
function _deleteBool(bytes32 _key, uint256 _index) internal validKey(_key) {
357+
require(boolArrayData[_key].length > _index, "Invalid Index"); //Also prevents undeflow
358+
if(boolArrayData[_key].length - 1 != _index) {
359+
boolArrayData[_key][_index] = boolArrayData[_key][boolArrayData[_key].length - 1];
360+
}
361+
boolArrayData[_key].length--;
362+
}
363+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
pragma solidity ^0.5.0;
2+
3+
import "../proxy/DataStoreProxy.sol";
4+
5+
contract DataStoreFactory {
6+
7+
address public implementation;
8+
9+
constructor(address _implementation) public {
10+
require(_implementation != address(0), "Address should not be 0x");
11+
implementation = _implementation;
12+
}
13+
14+
function generateDataStore(address _securityToken) public returns (address) {
15+
DataStoreProxy dsProxy = new DataStoreProxy(_securityToken, implementation);
16+
return address(dsProxy);
17+
}
18+
}

0 commit comments

Comments
 (0)