Skip to content

Commit

Permalink
AccessController support gobal permission (storyprotocol#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
kingster-will authored Jan 21, 2024
1 parent 3a25b85 commit a009d6e
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 0 deletions.
16 changes: 16 additions & 0 deletions contracts/AccessController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ contract AccessController is IAccessController {
MODULE_REGISTRY = moduleRegistry_;
}

/// @notice Sets the permission for all IPAccounts
function setGlobalPermission(address signer_, address to_, bytes4 func_, uint8 permission_) external {
// TODO: access controller can only be called by protocol admin
if (signer_ == address(0)) {
revert Errors.AccessController__SignerIsZeroAddress();
}
// permission must be one of ABSTAIN, ALLOW, DENY
if (permission_ > 2) {
revert Errors.AccessController__PermissionIsNotValid();
}
permissions[address(0)][signer_][to_][func_] = permission_;
}

/// @notice Sets the permission for a specific function call
/// @dev By default, all policies are set to ABSTAIN, which means that the permission is not set
/// Owner of ipAccount by default has permission sets the permission
Expand Down Expand Up @@ -130,6 +143,9 @@ contract AccessController is IAccessController {
}
// If module level permission is ABSTAIN, check transaction signer level permission
if (permissions[ipAccount_][signer_][to_][bytes4(0)] == AccessPermission.ABSTAIN) {
if (permissions[address(0)][signer_][to_][func_] == AccessPermission.ALLOW) {
return true;
}
// Return true if the ipAccount allow the signer can call all functions of all modules
// Otherwise, return false
return permissions[ipAccount_][signer_][address(0)][bytes4(0)] == AccessPermission.ALLOW;
Expand Down
8 changes: 8 additions & 0 deletions contracts/interfaces/IAccessController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ interface IAccessController {
/// @param permission_ The permission level
function setPermission(address ipAccount_, address signer_, address to_, bytes4 func_, uint8 permission_) external;

/// @notice Sets the permission for all IPAccounts
/// @dev Only the protocol admin can set the global permission
/// @param signer_ The account that signs the transaction
/// @param to_ The recipient(modules) of the transaction
/// @param func_ The function selector
/// @param permission_ The permission level
function setGlobalPermission(address signer_, address to_, bytes4 func_, uint8 permission_) external;

/// @notice Gets the permission for a specific function call
/// @param ipAccount_ The account that owns the IP
/// @param signer_ The account that signs the transaction
Expand Down
40 changes: 40 additions & 0 deletions test/foundry/AccessController.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ contract AccessControllerTest is Test {
);
}


function test_AccessController_functionWildcardOverrideToAddressWildcard_allowOverrideDeny() public {
moduleRegistry.registerModule("MockModule", address(mockModule));
address signer = vm.addr(2);
Expand Down Expand Up @@ -863,4 +864,43 @@ contract AccessControllerTest is Test {
vm.expectRevert("Invalid signer");
mockOrchestratorModule.workflowFailure(payable(address(ipAccount)));
}

function test_AccessController_OrchestratorModuleWithGlobalPermission() public {
MockOrchestratorModule mockOrchestratorModule = new MockOrchestratorModule(
address(ipAccountRegistry),
address(moduleRegistry)
);
moduleRegistry.registerModule("MockOrchestratorModule", address(mockOrchestratorModule));

MockModule module1WithPermission = new MockModule(
address(ipAccountRegistry),
address(moduleRegistry),
"Module1WithPermission"
);
moduleRegistry.registerModule("Module1WithPermission", address(module1WithPermission));

MockModule module2WithPermission = new MockModule(
address(ipAccountRegistry),
address(moduleRegistry),
"Module2WithPermission"
);
moduleRegistry.registerModule("Module2WithPermission", address(module2WithPermission));

accessController.setGlobalPermission(
address(mockOrchestratorModule),
address(module1WithPermission),
mockModule.executeSuccessfully.selector,
AccessPermission.ALLOW
);

accessController.setGlobalPermission(
address(mockOrchestratorModule),
address(module2WithPermission),
mockModule.executeNoReturn.selector,
AccessPermission.ALLOW
);

vm.prank(owner);
mockOrchestratorModule.workflowPass(payable(address(ipAccount)));
}
}
3 changes: 3 additions & 0 deletions test/foundry/mocks/MockAccessController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ contract MockAccessController is IAccessController {
function setAllowed(bool _isAllowed) external {
isAllowed = _isAllowed;
}
function setGlobalPermission(address signer_, address to_, bytes4 func_, uint8 permission_) external{

}

function setPermission(address, address, address, bytes4, uint8) external pure {

}
Expand Down

0 comments on commit a009d6e

Please sign in to comment.