@@ -8,17 +8,22 @@ import "../Module.sol";
88 */
99contract GeneralPermissionManager is IPermissionManager , Module {
1010
11- // Mapping used to hold the permissions on the modules provided to delegate
11+ // Mapping used to hold the permissions on the modules provided to delegate, module add => delegate add => permission uint8 => bool
1212 mapping (address => mapping (address => mapping (bytes32 => bool ))) public perms;
1313 // Mapping hold the delagate details
1414 mapping (address => bytes32 ) public delegateDetails;
15+ // Array to track all delegates
16+ address [] public allDelegates;
17+
18+
1519 // Permission flag
1620 bytes32 public constant CHANGE_PERMISSION = "CHANGE_PERMISSION " ;
1721
1822 /// Event emitted after any permission get changed for the delegate
19- event ChangePermission (address _delegate , address _module , bytes32 _perm , bool _valid , uint256 _timestamp );
23+ event ChangePermission (address indexed _delegate , address _module , bytes32 _perm , bool _valid , uint256 _timestamp );
2024 /// Use to notify when delegate is added in permission manager contract
21- event AddPermission (address _delegate , bytes32 _details , uint256 _timestamp );
25+ event AddDelegate (address indexed _delegate , bytes32 _details , uint256 _timestamp );
26+
2227
2328 /// @notice constructor
2429 constructor (address _securityToken , address _polyAddress ) public
@@ -27,72 +32,182 @@ contract GeneralPermissionManager is IPermissionManager, Module {
2732 }
2833
2934 /**
30- * @notice Init function i.e generalise function to maintain the structure of the module contract
31- * @return bytes4
32- */
35+ * @notice Init function i.e generalise function to maintain the structure of the module contract
36+ * @return bytes4
37+ */
3338 function getInitFunction () public pure returns (bytes4 ) {
3439 return bytes4 (0 );
3540 }
3641
3742 /**
38- * @notice use to check the permission on delegate corresponds to module contract address
39- * @param _delegate Ethereum address of the delegate
40- * @param _module Ethereum contract address of the module
41- * @param _perm Permission flag
42- * @return bool
43- */
43+ * @notice Use to check the permission on delegate corresponds to module contract address
44+ * @param _delegate Ethereum address of the delegate
45+ * @param _module Ethereum contract address of the module
46+ * @param _perm Permission flag
47+ * @return bool
48+ */
4449 function checkPermission (address _delegate , address _module , bytes32 _perm ) external view returns (bool ) {
4550 if (delegateDetails[_delegate] != bytes32 (0 )) {
4651 return perms[_module][_delegate][_perm];
47- }else
52+ } else
4853 return false ;
4954 }
5055
5156 /**
52- * @notice use to add the details of the delegate
53- * @param _delegate Ethereum address of the delegate
54- * @param _details Details about the delegate i.e `Belongs to financial firm`
55- */
56- function addPermission (address _delegate , bytes32 _details ) public withPerm (CHANGE_PERMISSION) {
57+ * @notice Use to add a delegate
58+ * @param _delegate Ethereum address of the delegate
59+ * @param _details Details about the delegate i.e `Belongs to financial firm`
60+ */
61+ function addDelegate (address _delegate , bytes32 _details ) external withPerm (CHANGE_PERMISSION) {
62+ require (_details != bytes32 (0 ), "0 value not allowed " );
5763 delegateDetails[_delegate] = _details;
58- emit AddPermission (_delegate, _details, now );
64+ allDelegates.push (_delegate);
65+ emit AddDelegate (_delegate, _details, now );
5966 }
6067
61- /**
62- * @notice Use to provide/change the permission to the delegate corresponds to the module contract
63- * @param _delegate Ethereum address of the delegate
64- * @param _module Ethereum contract address of the module
65- * @param _perm Permission flag
66- * @param _valid Bool flag use to switch on/off the permission
67- * @return bool
68- */
68+ /**
69+ * @notice use to check if an address is a delegate or not
70+ * @param _potentialDelegate the address of potential delegate
71+ * @return bool
72+ */
73+ function checkDelegate (address _potentialDelegate ) external view returns (bool ) {
74+ require (_potentialDelegate != address (0 ));
75+
76+ if (delegateDetails[_potentialDelegate] != bytes32 (0 )) {
77+ return true ;
78+ } else
79+ return false ;
80+ }
81+
82+ /**
83+ * @notice Use to provide/change the permission to the delegate corresponds to the module contract
84+ * @param _delegate Ethereum address of the delegate
85+ * @param _module Ethereum contract address of the module
86+ * @param _perm Permission flag
87+ * @param _valid Bool flag use to switch on/off the permission
88+ * @return bool
89+ */
6990 function changePermission (
7091 address _delegate ,
7192 address _module ,
7293 bytes32 _perm ,
7394 bool _valid
7495 )
75- external
96+ public
7697 withPerm (CHANGE_PERMISSION)
77- returns (bool )
7898 {
79- require (delegateDetails[_delegate] != bytes32 (0 ), "Delegate details not set " );
99+ require (delegateDetails[_delegate] != bytes32 (0 ), "Delegate is not exists " );
80100 perms[_module][_delegate][_perm] = _valid;
81101 emit ChangePermission (_delegate, _module, _perm, _valid, now );
82- return true ;
83102 }
84103
85104 /**
86- * @notice Use to get the details of the delegate
87- * @param _delegate Ethereum address of the delegate
88- * @return Details of the delegate
89- */
90- function getDelegateDetails (address _delegate ) external view returns (bytes32 ) {
91- return delegateDetails[_delegate];
105+ * @notice Use to change one or more permissions for a single delegate at once
106+ * @param _delegate Ethereum address of the delegate
107+ * @param _modules Multiple module matching the multiperms, needs to be same length
108+ * @param _perms Multiple permission flag needs to be changed
109+ * @param _valids Bool array consist the flag to switch on/off the permission
110+ * @return nothing
111+ */
112+ function changePermissionMulti (
113+ address _delegate ,
114+ address [] _modules ,
115+ bytes32 [] _perms ,
116+ bool [] _valids
117+ )
118+ external
119+ withPerm (CHANGE_PERMISSION)
120+ {
121+ require (_modules.length > 0 && _perms.length > 0 , "0 length is not allowed " );
122+ require (_modules.length == _perms.length , "Array length mismatch " );
123+ require (_valids.length == _perms.length , "Array length mismatch " );
124+ for (uint8 i = 0 ; i < _perms.length ; i++ ) {
125+ changePermission (_delegate, _modules[i], _perms[i], _valids[i]);
126+ }
92127 }
93128
94129 /**
95- * @notice Use to get the Permission flag related the `this` contract
130+ * @notice use to return all delegates with a given permission and module
131+ * @param _module Ethereum contract address of the module
132+ * @param _perm Permission flag
133+ * @return address[]
134+ */
135+ function getAllDelegatesWithPerm (address _module , bytes32 _perm ) external view returns (address []) {
136+ uint256 counter = 0 ;
137+ uint8 i = 0 ;
138+ for (i = 0 ; i < allDelegates.length ; i++ ) {
139+ if (perms[_module][allDelegates[i]][_perm]) {
140+ counter++ ;
141+ }
142+ }
143+ address [] memory allDelegatesWithPerm = new address [](counter);
144+ counter = 0 ;
145+ for (i = 0 ; i < allDelegates.length ; i++ ) {
146+ if (perms[_module][allDelegates[i]][_perm]){
147+ allDelegatesWithPerm[counter] = allDelegates[i];
148+ counter++ ;
149+ }
150+ }
151+ return allDelegatesWithPerm;
152+ }
153+
154+ /**
155+ * @notice use to return all permission of a single or multiple module
156+ * @dev possible that function get out of gas is there are lot of modules and perm related to them
157+ * @param _delegate Ethereum address of the delegate
158+ * @param _tokenAddress Ethereum address of the security token
159+ * @param _types uint8[] of types
160+ * @return address[] the address array of Modules this delegate has permission
161+ * @return bytes32[] the permission array of the corresponding Modules
162+ */
163+ function getAllModulesAndPermsFromTypes (address _delegate , uint8 [] _types , address _tokenAddress ) external view returns (address [], bytes32 []) {
164+ uint256 counter = 0 ;
165+ // loop through _types and get their modules from securityToken->getModulesByType
166+ for (uint8 i = 0 ; i < _types.length ; i++ ) {
167+ address [] memory _currentTypeModules = ISecurityToken (_tokenAddress).getModulesByType (_types[i]);
168+ // loop through each modules to get their perms from IModule->getPermissions
169+ for (uint8 j = 0 ; j < _currentTypeModules.length ; j++ ){
170+ bytes32 [] memory _allModulePerms = IModule (_currentTypeModules[j]).getPermissions ();
171+ // loop through each perm, if it is true, push results into arrays
172+ for (uint8 k = 0 ; k < _allModulePerms.length ; k++ ) {
173+ if (perms[_currentTypeModules[j]][_delegate][_allModulePerms[k]]) {
174+ counter ++ ;
175+ }
176+ }
177+ }
178+ }
179+
180+ address [] memory _allModules = new address [](counter);
181+ bytes32 [] memory _allPerms = new bytes32 [](counter);
182+ counter = 0 ;
183+
184+ for (i = 0 ; i < _types.length ; i++ ){
185+ _currentTypeModules = ISecurityToken (_tokenAddress).getModulesByType (_types[i]);
186+ for (j = 0 ; j < _currentTypeModules.length ; j++ ) {
187+ _allModulePerms = IModule (_currentTypeModules[j]).getPermissions ();
188+ for (k = 0 ; k < _allModulePerms.length ; k++ ) {
189+ if (perms[_currentTypeModules[j]][_delegate][_allModulePerms[k]]) {
190+ _allModules[counter]= _currentTypeModules[j];
191+ _allPerms[counter]= _allModulePerms[k];
192+ counter++ ;
193+ }
194+ }
195+ }
196+ }
197+
198+ return (_allModules, _allPerms);
199+ }
200+
201+ /**
202+ * @notice use to get all delegates
203+ * @return address[]
204+ */
205+ function getAllDelegates () external view returns (address []) {
206+ return allDelegates;
207+ }
208+
209+ /**
210+ * @notice Returns the Permission flag related the `this` contract
96211 * @return Array of permission flags
97212 */
98213 function getPermissions () public view returns (bytes32 []) {
0 commit comments