diff --git a/constants/roles.ts b/constants/roles.ts new file mode 100644 index 0000000..f8618ff --- /dev/null +++ b/constants/roles.ts @@ -0,0 +1,3 @@ +import { ethers } from 'hardhat' + +export const MANAGER_ROLE = ethers.keccak256(ethers.toUtf8Bytes('MANAGER_ROLE')) diff --git a/contracts/Hub.sol b/contracts/Hub.sol index a5b8318..992b441 100644 --- a/contracts/Hub.sol +++ b/contracts/Hub.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {IHub} from "./interfaces/IHub.sol"; diff --git a/contracts/Registry.sol b/contracts/Registry.sol index 8a4359a..4303f02 100644 --- a/contracts/Registry.sol +++ b/contracts/Registry.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {IRegistry, Adapter} from "./interfaces/IRegistry.sol"; @@ -8,7 +8,7 @@ import {Roles} from "./Roles.sol"; contract Registry is IRegistry, Roles { mapping(bytes32 => Adapter) private _adapters; - function createAdapter(bytes32 adapterType_, address adapterAddress_) external OnlyManager returns (bytes32) { + function createAdapter(bytes32 adapterType_, address adapterAddress_) external onlyManager returns (bytes32) { Adapter memory adapter = Adapter({adapterType: adapterType_, adapterAddress: adapterAddress_}); bytes32 adapterId = keccak256(abi.encodePacked(adapterType_, adapterAddress_)); diff --git a/contracts/Roles.sol b/contracts/Roles.sol index cb2190d..bf99658 100644 --- a/contracts/Roles.sol +++ b/contracts/Roles.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {IRoles} from "./interfaces/IRoles.sol"; @@ -7,22 +7,37 @@ import "@openzeppelin/contracts/access/AccessControl.sol"; bytes32 constant MANAGER_ROLE = keccak256("MANAGER_ROLE"); contract Roles is AccessControl { - modifier OnlyManager() { + modifier onlyAdmin() { + if (!isAdmin(msg.sender)) { + revert IRoles.Roles_NotAdmin(); + } + _; + } + + modifier onlyManager() { if (!isManager(msg.sender)) { - revert IRoles.Roles_NotRoleManager(); + revert IRoles.Roles_NotManager(); } _; } constructor() { - _setManagerRole(msg.sender); + _setAdminRole(msg.sender); } - function _setManagerRole(address _address) internal { - _grantRole(MANAGER_ROLE, _address); + function _setAdminRole(address _address) private { + _grantRole(DEFAULT_ADMIN_ROLE, _address); + } + + function isAdmin(address _address) public view returns (bool) { + return hasRole(DEFAULT_ADMIN_ROLE, _address); } function isManager(address _address) public view returns (bool) { return hasRole(MANAGER_ROLE, _address); } + + function setManager(address _address) external onlyAdmin { + _grantRole(MANAGER_ROLE, _address); + } } diff --git a/contracts/interfaces/IAdapter.sol b/contracts/interfaces/IAdapter.sol index 965ba13..885836e 100644 --- a/contracts/interfaces/IAdapter.sol +++ b/contracts/interfaces/IAdapter.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.21; struct Adapter { diff --git a/contracts/interfaces/IApp.sol b/contracts/interfaces/IApp.sol index e4ee54e..170e6d6 100644 --- a/contracts/interfaces/IApp.sol +++ b/contracts/interfaces/IApp.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {Adapter} from "./IAdapter.sol"; diff --git a/contracts/interfaces/IHub.sol b/contracts/interfaces/IHub.sol index 1854d1c..3bfab87 100644 --- a/contracts/interfaces/IHub.sol +++ b/contracts/interfaces/IHub.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {App} from "./IApp.sol"; diff --git a/contracts/interfaces/IRegistry.sol b/contracts/interfaces/IRegistry.sol index 75ff9be..c837da1 100644 --- a/contracts/interfaces/IRegistry.sol +++ b/contracts/interfaces/IRegistry.sol @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.21; import {Adapter} from "./IAdapter.sol"; diff --git a/contracts/interfaces/IRoles.sol b/contracts/interfaces/IRoles.sol index 1e3ad94..eaf078f 100644 --- a/contracts/interfaces/IRoles.sol +++ b/contracts/interfaces/IRoles.sol @@ -1,8 +1,14 @@ -// SPDX-License-Identifier: UNLICENSED +// SPDX-License-Identifier: MIT pragma solidity 0.8.21; interface IRoles { - error Roles_NotRoleManager(); + error Roles_NotAdmin(); + + error Roles_NotManager(); + + function setManager(address _address) external; function isManager(address _address) external view returns (bool); + + function isAdmin(address _address) external view returns (bool); } diff --git a/test/hub/Hub.spec.ts b/test/hub/Hub.spec.ts index 97ed968..42989fc 100644 --- a/test/hub/Hub.spec.ts +++ b/test/hub/Hub.spec.ts @@ -6,13 +6,16 @@ import { ethers } from 'hardhat' import { deployHubFixture } from './fixture' import { VAULT_V1 } from '../registry/fixture' import { deployRegistryFixture } from '../registry/fixture' +import { MANAGER_ROLE } from '../../constants/roles' describe('Hub', function () { it('should set app data on create', async function () { - const { registryAddress, registry } = await loadFixture( + const { registryAddress, registry, owner } = await loadFixture( deployRegistryFixture ) + await registry.grantRole(MANAGER_ROLE, owner.address) + const { hub } = await loadFixture( deployHubFixture.bind(this, registryAddress) ) diff --git a/test/registry/Registry.spec.ts b/test/registry/Registry.spec.ts index 45d6ada..7e6911e 100644 --- a/test/registry/Registry.spec.ts +++ b/test/registry/Registry.spec.ts @@ -4,10 +4,13 @@ import { expect } from 'chai' import { ethers } from 'hardhat' import { deployRegistryFixture, VAULT_V1 } from './fixture' +import { MANAGER_ROLE } from '../../constants/roles' describe('Registry', function () { it('should set adapter data on create', async function () { - const { registry } = await loadFixture(deployRegistryFixture) + const { registry, owner } = await loadFixture(deployRegistryFixture) + + await registry.grantRole(MANAGER_ROLE, owner.address) const adapterType = VAULT_V1 const adapterAddress = ethers.ZeroAddress @@ -38,6 +41,6 @@ describe('Registry', function () { await expect( registry.connect(notManager).createAdapter(adapterType, adapterAddress) - ).to.be.revertedWithCustomError(registry, 'Roles_NotRoleManager') + ).to.be.revertedWithCustomError(registry, 'Roles_NotManager') }) })