Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 10 additions & 5 deletions src/auth/RolesAuthority.huff
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@

/// @notice Helper to get the role for a capability
#define macro GET_ROLE_FOR_CAPABILITY() = takes (2) returns (1) {
LOAD_ELEMENT_FROM_KEYS(0x00) // [role]
[GET_ROLES_WITH_CAPABILITY_LOCATION] // [location, target, sig]
LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [role]
}

/// @notice Checks if a Role has a Capability
Expand All @@ -67,7 +68,8 @@

/// @notice Helper to get if a capability is public
#define macro IS_CAPABILITY_PUBLIC() = takes (2) returns (1) {
LOAD_ELEMENT_FROM_KEYS(0x00) // [public]
[IS_CAPABILITY_PUBLIC_LOCATION] // [location, target, sig]
LOAD_ELEMENT_FROM_KEYS_2D(0x00) // [public]
}

/// @notice Checks if an account can call a function on a given address
Expand Down Expand Up @@ -115,7 +117,8 @@
0x44 calldataload // [value]
0x24 calldataload // [sig, value]
0x04 calldataload // [target, sig, value]
STORE_ELEMENT_FROM_KEYS(0x00) // []
[IS_CAPABILITY_PUBLIC_LOCATION] // [location, target, sig, value]
STORE_ELEMENT_FROM_KEYS_2D(0x00) // []

// Emit the capability updated event
0x44 calldataload // [value]
Expand Down Expand Up @@ -158,7 +161,8 @@
// Store the new capability
0x44 calldataload // [sig, updated]
0x24 calldataload // [target, sig, updated]
STORE_ELEMENT_FROM_KEYS(0x00) // []
[GET_ROLES_WITH_CAPABILITY_LOCATION] // [location, target, sig, updated]
STORE_ELEMENT_FROM_KEYS_2D(0x00) // []

// Jump to the emit log label
emit_log jump
Expand All @@ -177,7 +181,8 @@
// Store the new capability
0x44 calldataload // [sig, capabilies]
0x24 calldataload // [target, sig, capabilies]
STORE_ELEMENT_FROM_KEYS(0x00) // []
[GET_ROLES_WITH_CAPABILITY_LOCATION] // [location, target, sig, capabilies]
STORE_ELEMENT_FROM_KEYS_2D(0x00) // []

// Emit the capability updated event
emit_log:
Expand Down
27 changes: 27 additions & 0 deletions test/auth/RolesAuthority.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,31 @@ contract RolesAuthorityTest is Test, NonMatchingSelectorsHelper {

assertEq(roleAuth.hasRole(user, role), true);
}

/// @notice Test capability maps do not collide
function testCapabilityMapsDoNotCollide() public {
address target = address(0xDEAD);
bytes4 sig = bytes4(0xdeadbeef);
address mallory = address(0xBAD);

// Grant a specific role the capability. It is NOT made public.
vm.prank(OWNER);
roleAuth.setRoleCapability(5, target, sig, true);
assertTrue(roleAuth.doesRoleHaveCapability(5, target, sig));

// A role bitmap must not be misread as "public": Mallory holds no roles...
assertFalse(roleAuth.hasRole(mallory, 5));
// ...so Mallory must not be authorized to call the capability.
assertFalse(roleAuth.canCall(mallory, target, sig));

// A user actually granted the role should be authorized.
vm.prank(OWNER);
roleAuth.setUserRole(mallory, 5, true);
assertTrue(roleAuth.canCall(mallory, target, sig));

// Toggling the distinct public-capability flag must leave the role bitmap intact.
vm.prank(OWNER);
roleAuth.setPublicCapability(target, sig, false);
assertTrue(roleAuth.doesRoleHaveCapability(5, target, sig));
}
}
Loading