@@ -11,18 +11,18 @@ library AccountPermissionsStorage {
1111 bytes32 public constant ACCOUNT_PERMISSIONS_STORAGE_POSITION = keccak256 ("account.permissions.storage " );
1212
1313 struct Data {
14+ /// @dev The set of all admins of the wallet.
15+ EnumerableSet.AddressSet allAdmins;
16+ /// @dev The set of all signers with permission to use the account.
17+ EnumerableSet.AddressSet allSigners;
1418 /// @dev Map from address => whether the address is an admin.
1519 mapping (address => bool ) isAdmin;
16- /// @dev Map from keccak256 hash of a role => active restrictions for that role .
17- mapping (bytes32 => IAccountPermissions.RoleStatic) roleRestrictions ;
18- /// @dev Map from address => the role held by that address .
19- mapping (address => bytes32 ) roleOfAccount ;
20+ /// @dev Map from signer address => active restrictions for that signer .
21+ mapping (address => IAccountPermissions.SignerPermissionsStatic) signerPermissions ;
22+ /// @dev Map from signer address => approved target the signer can call using the account contract .
23+ mapping (address => EnumerableSet.AddressSet) approvedTargets ;
2024 /// @dev Mapping from a signed request UID => whether the request is processed.
2125 mapping (bytes32 => bool ) executed;
22- /// @dev Map from keccak256 hash of a role to its approved targets.
23- mapping (bytes32 => EnumerableSet.AddressSet) approvedTargets;
24- /// @dev map from keccak256 hash of a role to its members' data. See {RoleMembers}.
25- mapping (bytes32 => EnumerableSet.AddressSet) roleMembers;
2626 }
2727
2828 function accountPermissionsStorage () internal pure returns (Data storage accountPermissionsData ) {
@@ -39,7 +39,7 @@ abstract contract AccountPermissions is IAccountPermissions, EIP712 {
3939
4040 bytes32 private constant TYPEHASH =
4141 keccak256 (
42- "RoleRequest(bytes32 role ,address target,uint8 action ,uint128 validityStartTimestamp ,uint128 validityEndTimestamp ,bytes32 uid) "
42+ "SignerPermissionRequest(address signer ,address[] approvedTargets,uint256 nativeTokenLimitPerTransaction ,uint128 permissionStartTimestamp ,uint128 permissionEndTimestamp,uint128 reqValidityStartTimestamp,uint128 reqValidityEndTimestamp ,bytes32 uid) "
4343 );
4444
4545 modifier onlyAdmin () virtual {
@@ -56,61 +56,45 @@ abstract contract AccountPermissions is IAccountPermissions, EIP712 {
5656 _setAdmin (_account, _isAdmin);
5757 }
5858
59- /// @notice Sets the restrictions for a given role.
60- function setRoleRestrictions (RoleRestrictions calldata _restrictions ) external virtual onlyAdmin {
61- bytes32 role = _restrictions.role;
59+ /// @notice Sets the permissions for a given signer.
60+ function setPermissionsForSigner (SignerPermissionRequest calldata _req , bytes calldata _signature ) external {
61+ address targetSigner = _req.signer;
62+ require (! isAdmin (targetSigner), "AccountPermissions: signer is already an admin " );
6263
63- require (role != bytes32 (0 ), "AccountPermissions: role cannot be empty " );
64+ require (
65+ _req.reqValidityStartTimestamp <= block .timestamp && block .timestamp < _req.reqValidityEndTimestamp,
66+ "AccountPermissions: invalid request validity period "
67+ );
68+
69+ (bool success , address signer ) = verifySignerPermissionRequest (_req, _signature);
70+ require (success, "AccountPermissions: invalid signature " );
6471
6572 AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
66- data.roleRestrictions[role] = RoleStatic (
67- role,
68- _restrictions.maxValuePerTransaction,
69- _restrictions.startTimestamp,
70- _restrictions.endTimestamp
73+
74+ data.allSigners.add (targetSigner);
75+ data.executed[_req.uid] = true ;
76+
77+ data.signerPermissions[targetSigner] = SignerPermissionsStatic (
78+ _req.nativeTokenLimitPerTransaction,
79+ _req.permissionStartTimestamp,
80+ _req.permissionEndTimestamp
7181 );
7282
73- address [] memory currentTargets = data.approvedTargets[role ].values ();
83+ address [] memory currentTargets = data.approvedTargets[targetSigner ].values ();
7484 uint256 currentLen = currentTargets.length ;
7585
7686 for (uint256 i = 0 ; i < currentLen; i += 1 ) {
77- data.approvedTargets[role ].remove (currentTargets[i]);
87+ data.approvedTargets[targetSigner ].remove (currentTargets[i]);
7888 }
7989
80- uint256 len = _restrictions .approvedTargets.length ;
90+ uint256 len = _req .approvedTargets.length ;
8191 for (uint256 i = 0 ; i < len; i += 1 ) {
82- data.approvedTargets[role ].add (_restrictions .approvedTargets[i]);
92+ data.approvedTargets[targetSigner ].add (_req .approvedTargets[i]);
8393 }
8494
85- emit RoleUpdated (_restrictions.role, _restrictions);
86- }
87-
88- /// @notice Grant / revoke a role from a given signer.
89- function changeRole (RoleRequest calldata _req , bytes calldata _signature ) external virtual {
90- require (_req.role != bytes32 (0 ), "AccountPermissions: role cannot be empty " );
91- require (
92- _req.validityStartTimestamp < block .timestamp && block .timestamp < _req.validityEndTimestamp,
93- "AccountPermissions: invalid validity period "
94- );
95-
96- (bool success , address signer ) = verifyRoleRequest (_req, _signature);
95+ _afterSignerPermissionsUpdate (_req);
9796
98- require (success, "AccountPermissions: invalid signature " );
99-
100- AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
101- data.executed[_req.uid] = true ;
102-
103- if (_req.action == RoleAction.GRANT) {
104- data.roleOfAccount[_req.target] = _req.role;
105- data.roleMembers[_req.role].add (_req.target);
106- } else {
107- delete data.roleOfAccount[_req.target];
108- data.roleMembers[_req.role].remove (_req.target);
109- }
110-
111- emit RoleAssignment (_req.role, _req.target, signer, _req);
112-
113- _afterChangeRole (_req);
97+ emit SignerPermissionsUpdated (signer, targetSigner, _req);
11498 }
11599
116100 /*///////////////////////////////////////////////////////////////
@@ -123,45 +107,34 @@ abstract contract AccountPermissions is IAccountPermissions, EIP712 {
123107 return data.isAdmin[_account];
124108 }
125109
126- /// @notice Returns the role held by a given account along with its restrictions .
127- function getRoleRestrictionsForAccount (address _account ) external view virtual returns (RoleRestrictions memory ) {
110+ /// @notice Returns whether the given account is an active signer on the account .
111+ function isActiveSigner (address signer ) public view returns (bool ) {
128112 AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
129- bytes32 role = data.roleOfAccount[_account];
130- RoleStatic memory roleRestrictions = data.roleRestrictions[role];
113+ SignerPermissionsStatic memory permissions = data.signerPermissions[signer];
131114
132115 return
133- RoleRestrictions (
134- role,
135- data.approvedTargets[role].values (),
136- roleRestrictions.maxValuePerTransaction,
137- roleRestrictions.startTimestamp,
138- roleRestrictions.endTimestamp
139- );
116+ permissions.startTimestamp <= block .timestamp &&
117+ block .timestamp < permissions.endTimestamp &&
118+ data.approvedTargets[signer].length () > 0 ;
140119 }
141120
142- /// @notice Returns the role restrictions for a given role .
143- function getRoleRestrictions ( bytes32 _role ) external view virtual returns (RoleRestrictions memory ) {
121+ /// @notice Returns the restrictions under which a signer can use the smart wallet .
122+ function getPermissionsForSigner ( address signer ) external view returns (SignerPermissions memory ) {
144123 AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
145- RoleStatic memory roleRestrictions = data.roleRestrictions[_role ];
124+ SignerPermissionsStatic memory permissions = data.signerPermissions[signer ];
146125
147126 return
148- RoleRestrictions (
149- _role ,
150- data.approvedTargets[_role ].values (),
151- roleRestrictions.maxValuePerTransaction ,
152- roleRestrictions .startTimestamp,
153- roleRestrictions .endTimestamp
127+ SignerPermissions (
128+ signer ,
129+ data.approvedTargets[signer ].values (),
130+ permissions.nativeTokenLimitPerTransaction ,
131+ permissions .startTimestamp,
132+ permissions .endTimestamp
154133 );
155134 }
156135
157- /// @notice Returns all accounts that have a role.
158- function getAllRoleMembers (bytes32 _role ) external view virtual returns (address [] memory ) {
159- AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
160- return data.roleMembers[_role].values ();
161- }
162-
163136 /// @dev Verifies that a request is signed by an authorized account.
164- function verifyRoleRequest (RoleRequest calldata req , bytes calldata signature )
137+ function verifySignerPermissionRequest (SignerPermissionRequest calldata req , bytes calldata signature )
165138 public
166139 view
167140 virtual
@@ -172,23 +145,94 @@ abstract contract AccountPermissions is IAccountPermissions, EIP712 {
172145 success = ! data.executed[req.uid] && isAdmin (signer);
173146 }
174147
148+ /// @notice Returns all active and inactive signers of the account.
149+ function getAllSigners () external view returns (SignerPermissions[] memory signers ) {
150+ AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
151+ address [] memory allSigners = data.allSigners.values ();
152+
153+ uint256 len = allSigners.length ;
154+ signers = new SignerPermissions [](len);
155+ for (uint256 i = 0 ; i < len; i += 1 ) {
156+ address signer = allSigners[i];
157+ SignerPermissionsStatic memory permissions = data.signerPermissions[signer];
158+
159+ signers[i] = SignerPermissions (
160+ signer,
161+ data.approvedTargets[signer].values (),
162+ permissions.nativeTokenLimitPerTransaction,
163+ permissions.startTimestamp,
164+ permissions.endTimestamp
165+ );
166+ }
167+ }
168+
169+ /// @notice Returns all signers with active permissions to use the account.
170+ function getAllActiveSigners () external view returns (SignerPermissions[] memory signers ) {
171+ AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
172+ address [] memory allSigners = data.allSigners.values ();
173+
174+ uint256 len = allSigners.length ;
175+ uint256 numOfActiveSigners = 0 ;
176+ bool [] memory isSignerActive = new bool [](len);
177+
178+ for (uint256 i = 0 ; i < len; i += 1 ) {
179+ address signer = allSigners[i];
180+
181+ bool isActive = isActiveSigner (signer);
182+ isSignerActive[i] = isActive;
183+ if (isActive) {
184+ numOfActiveSigners++ ;
185+ }
186+ }
187+
188+ signers = new SignerPermissions [](numOfActiveSigners);
189+ uint256 index = 0 ;
190+ for (uint256 i = 0 ; i < len; i += 1 ) {
191+ if (! isSignerActive[i]) {
192+ continue ;
193+ }
194+ address signer = allSigners[i];
195+ SignerPermissionsStatic memory permissions = data.signerPermissions[signer];
196+
197+ signers[index++ ] = SignerPermissions (
198+ signer,
199+ data.approvedTargets[signer].values (),
200+ permissions.nativeTokenLimitPerTransaction,
201+ permissions.startTimestamp,
202+ permissions.endTimestamp
203+ );
204+ }
205+ }
206+
207+ /// @notice Returns all admins of the account.
208+ function getAllAdmins () external view returns (address [] memory ) {
209+ AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
210+ return data.allAdmins.values ();
211+ }
212+
175213 /*///////////////////////////////////////////////////////////////
176214 Internal functions
177215 //////////////////////////////////////////////////////////////*/
178216
179217 /// @notice Runs after every `changeRole` run.
180- function _afterChangeRole (RoleRequest calldata _req ) internal virtual ;
218+ function _afterSignerPermissionsUpdate (SignerPermissionRequest calldata _req ) internal virtual ;
181219
182220 /// @notice Makes the given account an admin.
183221 function _setAdmin (address _account , bool _isAdmin ) internal virtual {
184222 AccountPermissionsStorage.Data storage data = AccountPermissionsStorage.accountPermissionsStorage ();
185223 data.isAdmin[_account] = _isAdmin;
186224
225+ if (_isAdmin) {
226+ data.allAdmins.add (_account);
227+ } else {
228+ data.allAdmins.remove (_account);
229+ }
230+
187231 emit AdminUpdated (_account, _isAdmin);
188232 }
189233
190234 /// @dev Returns the address of the signer of the request.
191- function _recoverAddress (RoleRequest calldata _req , bytes calldata _signature )
235+ function _recoverAddress (SignerPermissionRequest calldata _req , bytes calldata _signature )
192236 internal
193237 view
194238 virtual
@@ -198,15 +242,17 @@ abstract contract AccountPermissions is IAccountPermissions, EIP712 {
198242 }
199243
200244 /// @dev Encodes a request for recovery of the signer in `recoverAddress`.
201- function _encodeRequest (RoleRequest calldata _req ) internal pure virtual returns (bytes memory ) {
245+ function _encodeRequest (SignerPermissionRequest calldata _req ) internal pure virtual returns (bytes memory ) {
202246 return
203247 abi.encode (
204248 TYPEHASH,
205- _req.role,
206- _req.target,
207- _req.action,
208- _req.validityStartTimestamp,
209- _req.validityEndTimestamp,
249+ _req.signer,
250+ _req.approvedTargets,
251+ _req.nativeTokenLimitPerTransaction,
252+ _req.permissionStartTimestamp,
253+ _req.permissionEndTimestamp,
254+ _req.reqValidityStartTimestamp,
255+ _req.reqValidityEndTimestamp,
210256 _req.uid
211257 );
212258 }
0 commit comments