Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
1c79698
Improve docs
ernestognw Sep 15, 2023
0218e2c
Make role's admin role more specific
ernestognw Sep 15, 2023
7f3c162
First pass through tests
ernestognw Sep 15, 2023
d27cbdc
Add _canCallSelf
ernestognw Sep 15, 2023
327a5b5
Merge branch 'audit/wip/2a-2b' into access-manager/tests
ernestognw Sep 15, 2023
febdf2a
AccessManager _canCallSelf and _canCallExecuting
ernestognw Sep 18, 2023
acfc3aa
AccessManager _canCallSelf and _canCallExecuting
ernestognw Sep 18, 2023
64a1c6e
Codespell
ernestognw Sep 18, 2023
4a8920e
Merge branch 'audit/wip/2a-2b' into access-manager/coverage-review
ernestognw Sep 18, 2023
62ff89b
Testing preview
ernestognw Sep 18, 2023
1152dbb
Merge branch 'master' into access-manager/tests
ernestognw Sep 19, 2023
d4c6480
Checkpoint
ernestognw Sep 19, 2023
6adcbf3
Finish role admin functions
ernestognw Sep 19, 2023
9d601a7
Checkpoint
ernestognw Sep 19, 2023
e2190d6
Checkpoint
ernestognw Sep 20, 2023
4c08a9d
Removed on:
ernestognw Sep 20, 2023
1d118eb
Define common admin ops path
ernestognw Sep 20, 2023
778ac91
Checkpoint
ernestognw Sep 21, 2023
3aeb3c8
Checkpoint
ernestognw Sep 21, 2023
61eea90
Update contracts/access/manager/AccessManager.sol
ernestognw Sep 21, 2023
ba8b3ca
Remove .call(this)
ernestognw Sep 23, 2023
8e3583b
Improve test names
ernestognw Sep 23, 2023
dce308e
Improve test names
ernestognw Sep 23, 2023
d0b3824
Checkpoint
ernestognw Sep 25, 2023
3a216f7
Finish execute
ernestognw Sep 25, 2023
fb0374f
Finish AccessManager tests
ernestognw Sep 25, 2023
856aa0c
Make selector decoding consistent
ernestognw Sep 25, 2023
242b19e
Merge branch 'master' into access-manager/tests
ernestognw Sep 25, 2023
d8dfe3b
Fix codespell
ernestognw Sep 25, 2023
1b66afe
Cherry pick from #4624
ernestognw Sep 26, 2023
3112045
Revert _setGrantDelay PUBLIC_ROLE case
ernestognw Sep 27, 2023
51e499b
Revert canCall hasRole path return
ernestognw Sep 27, 2023
47995ef
Update contracts/access/manager/AccessManager.sol
ernestognw Sep 27, 2023
e9cc80c
Update contracts/access/manager/AccessManager.sol
ernestognw Sep 27, 2023
bd4ab08
Update contracts/access/manager/AccessManager.sol
ernestognw Sep 27, 2023
a870c6b
Update contracts/access/manager/IAccessManager.sol
ernestognw Sep 27, 2023
d4dafda
Update test/access/manager/AccessManager.test.js
ernestognw Sep 27, 2023
04c5a9b
Implement suggestion for writing the _consumingSchedule variable
ernestognw Sep 27, 2023
9c0b8ad
Update test/helpers/access-manager.js
ernestognw Sep 27, 2023
854fbfe
Lint
ernestognw Sep 27, 2023
91cea51
Update contracts/access/manager/AccessManager.sol
ernestognw Sep 27, 2023
efce54a
Update contracts/access/manager/AccessManager.sol
ernestognw Sep 27, 2023
e955172
Update contracts/utils/types/Time.sol
ernestognw Sep 27, 2023
c0e69ee
Lint
ernestognw Sep 27, 2023
ea0973a
Recovered 100% tests coverage
ernestognw Sep 27, 2023
ee5315a
Remove console
ernestognw Sep 27, 2023
172b11f
Fix .only
ernestognw Sep 28, 2023
42e8a1a
execute+schedule tweaks
frangio Sep 29, 2023
180ef6c
fix tests
frangio Sep 30, 2023
9edb313
refactor
frangio Sep 30, 2023
7cb374d
trigger ci
frangio Oct 2, 2023
41b6880
Merge branch 'master' into access-manager/tests
ernestognw Oct 3, 2023
58e9545
Merge branch 'master' into access-manager/tests
frangio Oct 3, 2023
9d493af
fix upgradeable tests
frangio Oct 3, 2023
9291007
replace syntax `foo: function () {` -> `foo() {
frangio Oct 3, 2023
2ab4382
replace syntax (continued)
frangio Oct 3, 2023
eb914a2
lint
frangio Oct 3, 2023
da3d343
Fix consumingScheduleOp
ernestognw Oct 4, 2023
033337b
Fix consumeScheduleOp again
ernestognw Oct 4, 2023
a1011be
Apply review suggestions
ernestognw Oct 4, 2023
74009db
Check also for AccessManagedUpgradeable artifact
ernestognw Oct 4, 2023
1f4e7ca
Lint
ernestognw Oct 4, 2023
6e397cc
Merge branch 'master' into access-manager/tests
ernestognw Oct 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
AccessManager _canCallSelf and _canCallExecuting
  • Loading branch information
ernestognw committed Sep 18, 2023
commit febdf2ab51d2bb21bc29f81d28ee9157d6d3ca6d
42 changes: 28 additions & 14 deletions contracts/access/manager/AccessManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ contract AccessManager is Context, Multicall, IAccessManager {
* to identify the indirect workflow, and will consider calls that require a delay to be forbidden.
*
* NOTE: This function doesn't not report the permissions of this manager itself. These are defined by the
* {_canCallAdmin} function instead.
* {_canCallSelf} function instead.
*/
function canCall(
address caller,
Expand All @@ -156,11 +156,12 @@ contract AccessManager is Context, Multicall, IAccessManager {
} else if (caller == address(this)) {
// Caller is AccessManager, this means the call was sent through {execute} and it already checked
// permissions. We verify that the call "identifier", which is set during {execute}, is correct.
return (_executionId == _hashExecutionId(target, selector), 0);
return _canCallExecuting(target, selector);
} else {
uint64 roleId = getTargetFunctionRole(target, selector);
(immediate, delay) = hasRole(roleId, caller);
return immediate ? (delay == 0, delay) : (false, 0);
bool inRole;
(inRole, delay) = hasRole(roleId, caller);
return inRole ? (delay == 0, delay) : (false, 0);
}
}

Expand Down Expand Up @@ -443,6 +444,9 @@ contract AccessManager is Context, Multicall, IAccessManager {
* @dev Internal version of {setRoleAdmin} without access control.
*
* Emits a {RoleAdminChanged} event.
*
* NOTE: Setting the admin role as the `PUBLIC_ROLE` is allowed, but it will effectively allow
* anyone to set grant or revoke such role.
*/
function _setRoleAdmin(uint64 roleId, uint64 admin) internal virtual {
if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) {
Expand All @@ -458,6 +462,9 @@ contract AccessManager is Context, Multicall, IAccessManager {
* @dev Internal version of {setRoleGuardian} without access control.
*
* Emits a {RoleGuardianChanged} event.
*
* NOTE: Setting the guardian role as the `PUBLIC_ROLE` is allowed, but it will effectively allow
* anyone to cancel any scheduled operation for such role.
*/
function _setRoleGuardian(uint64 roleId, uint64 guardian) internal virtual {
if (roleId == ADMIN_ROLE || roleId == PUBLIC_ROLE) {
Expand Down Expand Up @@ -502,7 +509,7 @@ contract AccessManager is Context, Multicall, IAccessManager {
}

/**
* @dev Internal version of {setFunctionAllowedRole} without access control.
* @dev Internal version of {setTargetFunctionRole} without access control.
*
* Emits a {TargetFunctionRoleUpdated} event.
*/
Expand Down Expand Up @@ -792,7 +799,7 @@ contract AccessManager is Context, Multicall, IAccessManager {
*/
function _checkAuthorized() private {
address caller = _msgSender();
(bool immediate, uint32 delay) = _canCallAdmin(caller, _msgData());
(bool immediate, uint32 delay) = _canCallSelf(caller, _msgData());
if (!immediate) {
if (delay == 0) {
(, uint64 requiredRole, ) = _getAdminRestrictions(_msgData());
Expand All @@ -809,7 +816,7 @@ contract AccessManager is Context, Multicall, IAccessManager {
* Returns:
* - bool restricted: does this data match a restricted operation
* - uint64: which role is this operation restricted to
* - uint32: minimum delay to enforce for that operation (on top of the admin's execution delay)
* - uint32: minimum delay to enforce for that operation (max between operation's delay and admin's execution delay)
*/
function _getAdminRestrictions(
bytes calldata data
Expand Down Expand Up @@ -855,7 +862,7 @@ contract AccessManager is Context, Multicall, IAccessManager {

// =================================================== HELPERS ====================================================
/**
* @dev An extended version of {canCall} for internal usage that checks {_canCallAdmin}
* @dev An extended version of {canCall} for internal usage that checks {_canCallSelf}
* when the target is this contract.
*
* Returns:
Expand All @@ -868,7 +875,7 @@ contract AccessManager is Context, Multicall, IAccessManager {
bytes calldata data
) private view returns (bool immediate, uint32 delay) {
if (target == address(this)) {
return _canCallAdmin(caller, data);
return _canCallSelf(caller, data);
} else {
bytes4 selector = bytes4(data);
return canCall(caller, target, selector);
Expand All @@ -877,12 +884,12 @@ contract AccessManager is Context, Multicall, IAccessManager {

/**
* @dev A version of {canCall} that checks for admin restructions in this contract.
*
* Returns:
* - bool immediate: whether the operation can be executed immediately (with no delay)
* - uint32 delay: the execution delay
*/
function _canCallAdmin(address caller, bytes calldata data) private view returns (bool immediate, uint32 delay) {
function _canCallSelf(address caller, bytes calldata data) private view returns (bool immediate, uint32 delay) {
if (caller == address(this)) {
return _canCallExecuting(address(this), bytes4(data));
}

(bool enabled, uint64 roleId, uint32 operationDelay) = _getAdminRestrictions(data);
if (!enabled) {
return (false, 0);
Expand All @@ -898,6 +905,13 @@ contract AccessManager is Context, Multicall, IAccessManager {
return (delay == 0, delay);
}

/**
* @dev A version of {canCall} that only checks if the current call is being executed via {executed}.
*/
function _canCallExecuting(address target, bytes4 selector) private view returns (bool immediate, uint32 delay) {
return (_executionId == _hashExecutionId(target, selector), 0);
}

/**
* @dev Returns true if a schedule timepoint is past its expiration deadline.
*/
Expand Down
45 changes: 45 additions & 0 deletions test/helpers/access-manager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
const { MAX_UINT64 } = require('./constants');

function buildBaseRoles() {
const roles = {
ADMIN: {
id: web3.utils.toBN(0),
},
SOME_ADMIN: {
id: web3.utils.toBN(17),
},
SOME_GUARDIAN: {
id: web3.utils.toBN(35),
},
SOME: {
id: web3.utils.toBN(42),
},
PUBLIC: {
id: MAX_UINT64,
},
};

// Names
Object.assign(roles, Object.fromEntries(Object.entries(roles).map(([k, v]) => [k, { ...v, name: k }])));

// Defaults
for (const role of Object.keys(roles)) {
roles[role].admin = roles.ADMIN;
roles[role].guardian = roles.ADMIN;
}

// Admins
roles.SOME.admin = roles.SOME_ADMIN;

// Guardians
roles.SOME.guardian = roles.SOME_GUARDIAN;

return roles;
}

const formatAccess = access => [access[0], access[1].toString()];

module.exports = {
buildBaseRoles,
formatAccess,
};