From 03125dacadf88667ea7a85137243dd10498cf8bd Mon Sep 17 00:00:00 2001 From: Claudia Date: Mon, 29 Apr 2024 14:35:22 +0200 Subject: [PATCH 01/16] feat: remove the ens from the registry --- .../src/framework/dao/DAOFactory.sol | 18 +++++++-- .../src/framework/dao/DAORegistry.sol | 37 +++---------------- .../plugin/repo/PluginRepoFactory.sol | 20 +++------- .../plugin/repo/PluginRepoRegistry.sol | 32 ++-------------- 4 files changed, 28 insertions(+), 79 deletions(-) diff --git a/packages/contracts/src/framework/dao/DAOFactory.sol b/packages/contracts/src/framework/dao/DAOFactory.sol index 7a0d2d743..11b731d96 100644 --- a/packages/contracts/src/framework/dao/DAOFactory.sol +++ b/packages/contracts/src/framework/dao/DAOFactory.sol @@ -39,7 +39,6 @@ contract DAOFactory is ERC165, ProtocolVersion { struct DAOSettings { address trustedForwarder; string daoURI; - string subdomain; bytes metadata; } @@ -78,7 +77,8 @@ contract DAOFactory is ERC165, ProtocolVersion { /// @param _pluginSettings The array containing references to plugins and their settings to be installed after the DAO has been created. function createDao( DAOSettings calldata _daoSettings, - PluginSettings[] calldata _pluginSettings + PluginSettings[] calldata _pluginSettings, + IDAO.Action[] calldata _actions ) external returns (DAO createdDao) { // Check if no plugin is provided. if (_pluginSettings.length == 0) { @@ -89,7 +89,7 @@ contract DAOFactory is ERC165, ProtocolVersion { createdDao = _createDAO(_daoSettings); // Register DAO. - daoRegistry.register(createdDao, msg.sender, _daoSettings.subdomain); + daoRegistry.register(createdDao, msg.sender); // Get Permission IDs bytes32 rootPermissionID = createdDao.ROOT_PERMISSION_ID(); @@ -133,6 +133,18 @@ contract DAOFactory is ERC165, ProtocolVersion { ); } + if (_actions.length > 0) { + // grant temporary execute action permission to this DAOFactory + bytes32 executeActionPermissionID = createdDao.EXECUTE_PERMISSION_ID(); + createdDao.grant(address(createdDao), address(this), executeActionPermissionID); + + // Execute actions on the newly created DAO. + createdDao.execute(bytes32("callID"), _actions, 0); + + // revoke the execute action permission + createdDao.revoke(address(createdDao), address(this), executeActionPermissionID); + } + // Set the rest of DAO's permissions. _setDAOPermissions(createdDao); diff --git a/packages/contracts/src/framework/dao/DAORegistry.sol b/packages/contracts/src/framework/dao/DAORegistry.sol index 507fed64d..785760ac6 100644 --- a/packages/contracts/src/framework/dao/DAORegistry.sol +++ b/packages/contracts/src/framework/dao/DAORegistry.sol @@ -9,7 +9,7 @@ import {ENSSubdomainRegistrar} from "../utils/ens/ENSSubdomainRegistrar.sol"; import {InterfaceBasedRegistry} from "../utils/InterfaceBasedRegistry.sol"; import {isSubdomainValid} from "../utils/RegistryUtils.sol"; -/// @title Register your unique DAO subdomain +/// @title Register your unique DAO /// @author Aragon Association - 2022-2023 /// @notice This contract provides the possibility to register a DAO. /// @custom:security-contact sirt@aragon.org @@ -17,17 +17,10 @@ contract DAORegistry is InterfaceBasedRegistry, ProtocolVersion { /// @notice The ID of the permission required to call the `register` function. bytes32 public constant REGISTER_DAO_PERMISSION_ID = keccak256("REGISTER_DAO_PERMISSION"); - /// @notice The ENS subdomain registrar registering the DAO subdomains. - ENSSubdomainRegistrar public subdomainRegistrar; - - /// @notice Thrown if the DAO subdomain doesn't match the regex `[0-9a-z\-]` - error InvalidDaoSubdomain(string subdomain); - /// @notice Emitted when a new DAO is registered. /// @param dao The address of the DAO contract. /// @param creator The address of the creator. - /// @param subdomain The DAO subdomain. - event DAORegistered(address indexed dao, address indexed creator, string subdomain); + event DAORegistered(address indexed dao, address indexed creator); /// @dev Used to disallow initializing the implementation contract by an attacker for extra safety. /// @custom:oz-upgrades-unsafe-allow constructor @@ -37,40 +30,20 @@ contract DAORegistry is InterfaceBasedRegistry, ProtocolVersion { /// @notice Initializes the contract. /// @param _managingDao the managing DAO address. - /// @param _subdomainRegistrar The `ENSSubdomainRegistrar` where `ENS` subdomain will be registered. - function initialize( - IDAO _managingDao, - ENSSubdomainRegistrar _subdomainRegistrar - ) external initializer { + function initialize(IDAO _managingDao) external initializer { __InterfaceBasedRegistry_init(_managingDao, type(IDAO).interfaceId); - subdomainRegistrar = _subdomainRegistrar; } /// @notice Registers a DAO by its address. If a non-empty subdomain name is provided that is not taken already, the DAO becomes the owner of the ENS name. /// @dev A subdomain is unique within the Aragon DAO framework and can get stored here. /// @param dao The address of the DAO contract. /// @param creator The address of the creator. - /// @param subdomain The DAO subdomain. - function register( - IDAO dao, - address creator, - string calldata subdomain - ) external auth(REGISTER_DAO_PERMISSION_ID) { + function register(IDAO dao, address creator) external auth(REGISTER_DAO_PERMISSION_ID) { address daoAddr = address(dao); _register(daoAddr); - if ((bytes(subdomain).length > 0)) { - if (!isSubdomainValid(subdomain)) { - revert InvalidDaoSubdomain({subdomain: subdomain}); - } - - bytes32 labelhash = keccak256(bytes(subdomain)); - - subdomainRegistrar.registerSubnode(labelhash, daoAddr); - } - - emit DAORegistered(daoAddr, creator, subdomain); + emit DAORegistered(daoAddr, creator); } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). diff --git a/packages/contracts/src/framework/plugin/repo/PluginRepoFactory.sol b/packages/contracts/src/framework/plugin/repo/PluginRepoFactory.sol index 1c155eaaf..8b83351ef 100644 --- a/packages/contracts/src/framework/plugin/repo/PluginRepoFactory.sol +++ b/packages/contracts/src/framework/plugin/repo/PluginRepoFactory.sol @@ -40,31 +40,25 @@ contract PluginRepoFactory is ERC165, ProtocolVersion { } /// @notice Creates a plugin repository proxy pointing to the `pluginRepoBase` implementation and registers it in the Aragon plugin registry. - /// @param _subdomain The plugin repository subdomain. /// @param _initialOwner The plugin maintainer address. - function createPluginRepo( - string calldata _subdomain, - address _initialOwner - ) external returns (PluginRepo) { - return _createPluginRepo(_subdomain, _initialOwner); + function createPluginRepo(address _initialOwner) external returns (PluginRepo) { + return _createPluginRepo(_initialOwner); } /// @notice Creates and registers a `PluginRepo` with an ENS subdomain and publishes an initial version `1.1`. - /// @param _subdomain The plugin repository subdomain. /// @param _pluginSetup The plugin factory contract associated with the plugin version. /// @param _maintainer The maintainer of the plugin repo. This address has permission to update metadata, upgrade the repo logic, and manage the repo permissions. /// @param _releaseMetadata The release metadata URI. /// @param _buildMetadata The build metadata URI. /// @dev After the creation of the `PluginRepo` and release of the first version by the factory, ownership is transferred to the `_maintainer` address. function createPluginRepoWithFirstVersion( - string calldata _subdomain, address _pluginSetup, address _maintainer, bytes memory _releaseMetadata, bytes memory _buildMetadata ) external returns (PluginRepo pluginRepo) { // Sets `address(this)` as initial owner which is later replaced with the maintainer address. - pluginRepo = _createPluginRepo(_subdomain, address(this)); + pluginRepo = _createPluginRepo(address(this)); pluginRepo.createVersion(1, _pluginSetup, _buildMetadata, _releaseMetadata); @@ -124,12 +118,8 @@ contract PluginRepoFactory is ERC165, ProtocolVersion { /// @notice Internal method creating a `PluginRepo` via the [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) proxy pattern from the provided base contract and registering it in the Aragon plugin registry. /// @dev Passing an empty `_subdomain` will cause the transaction to revert. - /// @param _subdomain The plugin repository subdomain. /// @param _initialOwner The initial owner address. - function _createPluginRepo( - string calldata _subdomain, - address _initialOwner - ) internal returns (PluginRepo pluginRepo) { + function _createPluginRepo(address _initialOwner) internal returns (PluginRepo pluginRepo) { pluginRepo = PluginRepo( createERC1967Proxy( pluginRepoBase, @@ -137,6 +127,6 @@ contract PluginRepoFactory is ERC165, ProtocolVersion { ) ); - pluginRepoRegistry.registerPluginRepo(_subdomain, address(pluginRepo)); + pluginRepoRegistry.registerPluginRepo(address(pluginRepo)); } } diff --git a/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol b/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol index f80955a62..5ed2ce3b7 100644 --- a/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol +++ b/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol @@ -18,19 +18,9 @@ contract PluginRepoRegistry is InterfaceBasedRegistry, ProtocolVersion { bytes32 public constant REGISTER_PLUGIN_REPO_PERMISSION_ID = keccak256("REGISTER_PLUGIN_REPO_PERMISSION"); - /// @notice The ENS subdomain registrar registering the PluginRepo subdomains. - ENSSubdomainRegistrar public subdomainRegistrar; - /// @notice Emitted if a new plugin repository is registered. - /// @param subdomain The subdomain of the plugin repository. /// @param pluginRepo The address of the plugin repository. - event PluginRepoRegistered(string subdomain, address pluginRepo); - - /// @notice Thrown if the plugin subdomain doesn't match the regex `[0-9a-z\-]` - error InvalidPluginSubdomain(string subdomain); - - /// @notice Thrown if the plugin repository subdomain is empty. - error EmptyPluginRepoSubdomain(); + event PluginRepoRegistered(address pluginRepo); /// @dev Used to disallow initializing the implementation contract by an attacker for extra safety. /// @custom:oz-upgrades-unsafe-allow constructor @@ -40,35 +30,19 @@ contract PluginRepoRegistry is InterfaceBasedRegistry, ProtocolVersion { /// @notice Initializes the contract by setting calling the `InterfaceBasedRegistry` base class initialize method. /// @param _dao The address of the managing DAO. - /// @param _subdomainRegistrar The `ENSSubdomainRegistrar` where `ENS` subdomain will be registered. - function initialize(IDAO _dao, ENSSubdomainRegistrar _subdomainRegistrar) external initializer { + function initialize(IDAO _dao) external initializer { bytes4 pluginRepoInterfaceId = type(IPluginRepo).interfaceId; __InterfaceBasedRegistry_init(_dao, pluginRepoInterfaceId); - - subdomainRegistrar = _subdomainRegistrar; } /// @notice Registers a plugin repository with a subdomain and address. - /// @param subdomain The subdomain of the PluginRepo. /// @param pluginRepo The address of the PluginRepo contract. function registerPluginRepo( - string calldata subdomain, address pluginRepo ) external auth(REGISTER_PLUGIN_REPO_PERMISSION_ID) { - if (!(bytes(subdomain).length > 0)) { - revert EmptyPluginRepoSubdomain(); - } - - if (!isSubdomainValid(subdomain)) { - revert InvalidPluginSubdomain({subdomain: subdomain}); - } - - bytes32 labelhash = keccak256(bytes(subdomain)); - subdomainRegistrar.registerSubnode(labelhash, pluginRepo); - _register(pluginRepo); - emit PluginRepoRegistered(subdomain, pluginRepo); + emit PluginRepoRegistered(pluginRepo); } /// @notice This empty reserved space is put in place to allow future versions to add new variables without shifting down storage in the inheritance chain (see [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). From 27cc52684f79443bfcd4069352f95d3b558f5296 Mon Sep 17 00:00:00 2001 From: Claudia Date: Mon, 29 Apr 2024 14:36:27 +0200 Subject: [PATCH 02/16] feat: update the subdomain registrar to follow new approach --- .../utils/ens/ENSSubdomainRegistrar.sol | 87 ++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol b/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol index 2d2f8f926..79daf9e87 100644 --- a/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol +++ b/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol @@ -11,6 +11,10 @@ import {ProtocolVersion} from "@aragon/osx-commons-contracts/src/utils/versionin import {DaoAuthorizableUpgradeable} from "@aragon/osx-commons-contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol"; import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol"; +import {DAORegistry} from "../../dao/DAORegistry.sol"; +import {PluginRepoRegistry} from "../../plugin/repo/PluginRepoRegistry.sol"; +import {PluginRepo} from "../../plugin/repo/PluginRepo.sol"; + /// @title ENSSubdomainRegistrar /// @author Aragon Association - 2022-2023 /// @notice This contract registers ENS subdomains under a parent domain specified in the initialization process and maintains ownership of the subdomain since only the resolver address is set. This contract must either be the domain node owner or an approved operator of the node owner. The default resolver being used is the one specified in the parent domain. @@ -33,15 +37,20 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P /// @notice The address of the ENS resolver resolving the names to an address. address public resolver; + DAORegistry public daoRegistry; + PluginRepoRegistry public pluginRepoRegistry; + /// @notice Thrown if the subnode is already registered. /// @param subnode The subnode namehash. /// @param nodeOwner The node owner address. error AlreadyRegistered(bytes32 subnode, address nodeOwner); + error NotRegistered(bytes32 subnode, address nodeOwner); /// @notice Thrown if node's resolver is invalid. /// @param node The node namehash. /// @param resolver The node resolver address. error InvalidResolver(bytes32 node, address resolver); + error Unauthorized(); /// @dev Used to disallow initializing the implementation contract by an attacker for extra safety. /// @custom:oz-upgrades-unsafe-allow constructor @@ -57,11 +66,19 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P /// @param _managingDao The interface of the DAO managing the components permissions. /// @param _ens The interface of the ENS registry to be used. /// @param _node The ENS parent domain node under which the subdomains are to be registered. - function initialize(IDAO _managingDao, ENS _ens, bytes32 _node) external initializer { + function initialize( + IDAO _managingDao, + ENS _ens, + DAORegistry _daoRegistry, + PluginRepoRegistry _pluginRepoRegistry, + bytes32 _node + ) external initializer { __DaoAuthorizableUpgradeable_init(_managingDao); ens = _ens; node = _node; + daoRegistry = _daoRegistry; + pluginRepoRegistry = _pluginRepoRegistry; address nodeResolver = ens.resolver(_node); @@ -78,6 +95,34 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P address ) internal virtual override auth(UPGRADE_REGISTRAR_PERMISSION_ID) {} + modifier isAllowed( + bool isRegistered, + bool isPlugin, + address _targetAddress + ) { + if (!isRegistered) revert Unauthorized(); + + if (isPlugin) { + if ( + !PluginRepo(_targetAddress).isGranted( + _targetAddress, + msg.sender, + PluginRepo(_targetAddress).MAINTAINER_PERMISSION_ID(), + bytes("") + ) + ) revert Unauthorized(); + } + + _; + } + + function registerSubnode( + bytes32 _label + ) external isAllowed(daoRegistry.entries(msg.sender), false, address(0)) { + // is a registered dao + _registerSubnode(_label, msg.sender); + } + /// @notice Registers a new subdomain with this registrar as the owner and set the target address in the resolver. /// @dev It reverts with no message if this contract isn't the owner nor an approved operator for the given node. /// @param _label The labelhash of the subdomain name. @@ -85,7 +130,12 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function registerSubnode( bytes32 _label, address _targetAddress - ) external auth(REGISTER_ENS_SUBDOMAIN_PERMISSION_ID) { + ) external isAllowed(daoRegistry.entries(msg.sender), true, _targetAddress) { + // is registered plugin and the caller has maintainer permission + _registerSubnode(_label, _targetAddress); + } + + function _registerSubnode(bytes32 _label, address _targetAddress) internal { bytes32 subnode = keccak256(abi.encodePacked(node, _label)); address currentOwner = ens.owner(subnode); @@ -96,6 +146,39 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P ens.setSubnodeOwner(node, _label, address(this)); ens.setResolver(subnode, resolver); Resolver(resolver).setAddr(subnode, _targetAddress); + + // TODO add the reverse registrar record as highlighted by Cristiano + } + + function unregisterSubnode( + bytes32 _label + ) external isAllowed(daoRegistry.entries(msg.sender), false, address(0)) { + // is a registered dao + _unregisterSubnode(_label); + } + + function unregisterSubnode( + bytes32 _label, + address _targetAddress + ) external isAllowed(daoRegistry.entries(msg.sender), true, _targetAddress) { + // is registered plugin and the caller has maintainer permission + _unregisterSubnode(_label); + } + + function _unregisterSubnode(bytes32 _label) internal { + // ! mock implementation, need to review the correct way to unregister a subdomain + bytes32 subnode = keccak256(abi.encodePacked(node, _label)); + address currentOwner = ens.owner(subnode); + + if (currentOwner != address(this)) { + revert NotRegistered(subnode, currentOwner); + } + + ens.setSubnodeOwner(node, _label, address(0)); + ens.setResolver(subnode, address(0)); + Resolver(resolver).setAddr(subnode, address(0)); + + // TODO unregister the reverse registrar } /// @notice Sets the default resolver contract address that the subdomains being registered will use. From ddf3c4c621033fdfcaaa8bb789028cfead729083 Mon Sep 17 00:00:00 2001 From: Claudia Date: Mon, 29 Apr 2024 14:41:00 +0200 Subject: [PATCH 03/16] feat: update tests for dao factory --- .../test/framework/dao/dao-factory.ts | 97 +++++++++++++------ packages/contracts/test/test-utils/ens.ts | 5 + packages/contracts/test/test-utils/repo.ts | 6 +- 3 files changed, 71 insertions(+), 37 deletions(-) diff --git a/packages/contracts/test/framework/dao/dao-factory.ts b/packages/contracts/test/framework/dao/dao-factory.ts index 0c65dd70c..518a60bea 100644 --- a/packages/contracts/test/framework/dao/dao-factory.ts +++ b/packages/contracts/test/framework/dao/dao-factory.ts @@ -57,6 +57,7 @@ import { PLUGIN_SETUP_PROCESSOR_PERMISSIONS, getInterfaceId, } from '@aragon/osx-commons-sdk'; +import {ENSSubdomainRegistrar} from '@aragon/osx-ethers-v1.2.0'; import {anyValue} from '@nomicfoundation/hardhat-chai-matchers/withArgs'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {expect} from 'chai'; @@ -86,7 +87,6 @@ const AddressZero = ethers.constants.AddressZero; async function extractInfoFromCreateDaoTx(tx: any): Promise<{ dao: any; creator: any; - subdomain: any; plugin: any; helpers: any; permissions: any; @@ -107,7 +107,6 @@ async function extractInfoFromCreateDaoTx(tx: any): Promise<{ return { dao: daoRegisteredEvent.args.dao, creator: daoRegisteredEvent.args.creator, - subdomain: daoRegisteredEvent.args.subdomain, plugin: installationPreparedEvent.args.plugin, helpers: installationPreparedEvent.args.preparedSetupData.helpers, permissions: installationPreparedEvent.args.preparedSetupData.permissions, @@ -123,7 +122,7 @@ async function getAnticipatedAddress(from: string) { return anticipatedAddress; } -describe('DAOFactory: ', function () { +describe.only('DAOFactory: ', function () { let daoFactory: DAOFactory; let managingDao: any; @@ -142,6 +141,8 @@ describe('DAOFactory: ', function () { let signers: SignerWithAddress[]; let ownerAddress: string; + let ensSubdomainRegistrar: ENSSubdomainRegistrar; + before(async () => { signers = await ethers.getSigners(); ownerAddress = await signers[0].getAddress(); @@ -151,28 +152,29 @@ describe('DAOFactory: ', function () { // Managing DAO managingDao = await deployNewDAO(signers[0]); - // ENS subdomain Registry - const ensSubdomainRegistrar = await deployENSSubdomainRegistrar( - signers[0], - managingDao, - registrarManagedDomain - ); - // DAO Registry const DAORegistry = new DAORegistry__factory(signers[0]); daoRegistry = await deployWithProxy(DAORegistry); await daoRegistry.initialize( - managingDao.address, - ensSubdomainRegistrar.address + managingDao.address + // ensSubdomainRegistrar.address ); // Plugin Repo Registry pluginRepoRegistry = await deployPluginRepoRegistry( managingDao, - ensSubdomainRegistrar, signers[0] ); + // ENS subdomain Registry + ensSubdomainRegistrar = await deployENSSubdomainRegistrar( + signers[0], + managingDao, + daoRegistry.address, + pluginRepoRegistry.address, + registrarManagedDomain + ); + // Plugin Setup Processor psp = await deployPluginSetupProcessor(pluginRepoRegistry); @@ -223,7 +225,7 @@ describe('DAOFactory: ', function () { pluginSetupV1Mock = await PluginUUPSUpgradeableSetupV1Mock.deploy(); const tx = await pluginRepoFactory.createPluginRepoWithFirstVersion( - 'plugin-uupsupgradeable-setup-v1-mock', + // 'plugin-uupsupgradeable-setup-v1-mock', pluginSetupV1Mock.address, ownerAddress, '0x00', @@ -288,23 +290,43 @@ describe('DAOFactory: ', function () { it('reverts if no plugin is provided', async () => { await expect( - daoFactory.createDao(daoSettings, []) + daoFactory.createDao(daoSettings, [], []) ).to.be.revertedWithCustomError(daoFactory, 'NoPluginProvided'); }); + async function createAction() { + const to = ensSubdomainRegistrar.address; + const value = 0; + const data = (ensSubdomainRegistrar.interface as any).encodeFunctionData( + 'registerSubnode(bytes32)', + [ethers.utils.formatBytes32String(daoDummySubdomain)] + ); + return {to, value, data}; + } + it('creates a dao and initializes with correct args', async () => { const dao = await getAnticipatedAddress(daoFactory.address); const factory = new DAO__factory(signers[0]); const daoContract = factory.attach(dao); - expect(await daoFactory.createDao(daoSettings, [pluginInstallationData])) + console.log('creating action'); + const action = await createAction(); + expect( + await daoFactory.createDao( + daoSettings, + [pluginInstallationData], + [action] + ) + ) .to.emit(daoContract, EVENTS.MetadataSet) .withArgs(daoSettings.metadata) .to.emit(daoContract, EVENTS.TrustedForwarderSet) .withArgs(daoSettings.trustedForwarder) .to.emit(daoContract, EVENTS.NewURI) .withArgs(daoSettings.daoURI); + + // todo check subdomain were added }); it('creates a dao with a plugin and emits correct events', async () => { @@ -321,9 +343,11 @@ describe('DAOFactory: ', function () { pluginInstallationData.data ); - const tx = await daoFactory.createDao(daoSettings, [ - pluginInstallationData, - ]); + const tx = await daoFactory.createDao( + daoSettings, + [pluginInstallationData], + [] + ); const {dao} = await extractInfoFromCreateDaoTx(tx); const pluginRepoPointer: PluginRepoPointer = [ @@ -337,7 +361,7 @@ describe('DAOFactory: ', function () { await expect(tx) .to.emit(daoRegistry, EVENTS.DAORegistered) - .withArgs(dao, ownerAddress, daoSettings.subdomain) + .withArgs(dao, ownerAddress) .to.emit(psp, EVENTS.InstallationPrepared) .withArgs( daoFactory.address, @@ -359,9 +383,11 @@ describe('DAOFactory: ', function () { }); it('creates a dao with a plugin and sets plugin permissions on dao correctly', async () => { - const tx = await daoFactory.createDao(daoSettings, [ - pluginInstallationData, - ]); + const tx = await daoFactory.createDao( + daoSettings, + [pluginInstallationData], + [] + ); const {dao, permissions} = await extractInfoFromCreateDaoTx(tx); const factory = new DAO__factory(signers[0]); @@ -381,9 +407,11 @@ describe('DAOFactory: ', function () { }); it('creates a dao and sets its own permissions correctly on itself', async () => { - const tx = await daoFactory.createDao(daoSettings, [ - pluginInstallationData, - ]); + const tx = await daoFactory.createDao( + daoSettings, + [pluginInstallationData], + [] + ); const {dao} = await extractInfoFromCreateDaoTx(tx); const factory = new DAO__factory(signers[0]); @@ -433,9 +461,11 @@ describe('DAOFactory: ', function () { }); it('revokes all temporarly granted permissions', async () => { - const tx = await daoFactory.createDao(daoSettings, [ - pluginInstallationData, - ]); + const tx = await daoFactory.createDao( + daoSettings, + [pluginInstallationData], + [] + ); const {dao} = await extractInfoFromCreateDaoTx(tx); const factory = new DAO__factory(signers[0]); @@ -518,7 +548,7 @@ describe('DAOFactory: ', function () { }; const plugins = [plugin1, plugin2]; - const tx = await daoFactory.createDao(daoSettings, plugins); + const tx = await daoFactory.createDao(daoSettings, plugins, []); // Count how often the event was emitted by inspecting the logs const receipt = await tx.wait(); @@ -561,7 +591,6 @@ describe('DAOFactory: ', function () { adminPluginSetup = await AdminPluginSetupFactory.deploy(); let tx = await pluginRepoFactory.createPluginRepoWithFirstVersion( - 'admin', adminPluginSetup.address, ownerAddress, '0x11', @@ -593,7 +622,11 @@ describe('DAOFactory: ', function () { adminPluginRepoPointer, data ); - tx = await daoFactory.createDao(daoSettings, [adminPluginInstallation]); + tx = await daoFactory.createDao( + daoSettings, + [adminPluginInstallation], + [] + ); { const installationPreparedEvent = await findEventTopicLog( diff --git a/packages/contracts/test/test-utils/ens.ts b/packages/contracts/test/test-utils/ens.ts index 8559affaa..028555f31 100644 --- a/packages/contracts/test/test-utils/ens.ts +++ b/packages/contracts/test/test-utils/ens.ts @@ -13,10 +13,13 @@ import {ensDomainHash, ensLabelHash} from '../../utils/ens'; import {deployWithProxy} from '../test-utils/proxy'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {ethers} from 'hardhat'; +import {Address} from 'hardhat-deploy/types'; export async function deployENSSubdomainRegistrar( owner: SignerWithAddress, managingDao: DAO, + daoRegistry: Address, + pluginRepoRegistry: Address, domain: string ): Promise { const ENSRegistryFactory = new ENSRegistry__factory(owner); @@ -64,6 +67,8 @@ export async function deployENSSubdomainRegistrar( await ensSubdomainRegistrar.initialize( managingDao.address, ensRegistry.address, + daoRegistry, + pluginRepoRegistry, node ); diff --git a/packages/contracts/test/test-utils/repo.ts b/packages/contracts/test/test-utils/repo.ts index b3e1da063..6834cdfd8 100644 --- a/packages/contracts/test/test-utils/repo.ts +++ b/packages/contracts/test/test-utils/repo.ts @@ -46,7 +46,6 @@ export async function deployPluginRepoFactory( export async function deployPluginRepoRegistry( managingDao: any, - ensSubdomainRegistrar: any, signer: SignerWithAddress ): Promise { const PluginRepoRegistry = new PluginRepoRegistry__factory(signer); @@ -55,10 +54,7 @@ export async function deployPluginRepoRegistry( PluginRepoRegistry ); - await pluginRepoRegistry.initialize( - managingDao.address, - ensSubdomainRegistrar.address - ); + await pluginRepoRegistry.initialize(managingDao.address); return pluginRepoRegistry; } From d01fa0756530fcfca5fee151632edf26c665c609 Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 13:34:34 +0200 Subject: [PATCH 04/16] feat: add checks for the ens reservation --- .../test/framework/dao/dao-factory.ts | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/contracts/test/framework/dao/dao-factory.ts b/packages/contracts/test/framework/dao/dao-factory.ts index 518a60bea..d6c58bf65 100644 --- a/packages/contracts/test/framework/dao/dao-factory.ts +++ b/packages/contracts/test/framework/dao/dao-factory.ts @@ -23,10 +23,13 @@ import { IProtocolVersion__factory, IERC165__factory, PluginRepoRegistry__factory, + ENSRegistry__factory, + PublicResolver__factory, } from '../../../typechain'; import {DAORegisteredEvent} from '../../../typechain/DAORegistry'; import {PluginRepoRegisteredEvent} from '../../../typechain/PluginRepoRegistry'; import {InstallationPreparedEvent} from '../../../typechain/PluginSetupProcessor'; +import {ensDomainHash, ensLabelHash} from '../../../utils/ens'; import {daoExampleURI, deployNewDAO} from '../../test-utils/dao'; import {deployENSSubdomainRegistrar} from '../../test-utils/ens'; import {deployPluginSetupProcessor} from '../../test-utils/plugin-setup-processor'; @@ -299,7 +302,7 @@ describe.only('DAOFactory: ', function () { const value = 0; const data = (ensSubdomainRegistrar.interface as any).encodeFunctionData( 'registerSubnode(bytes32)', - [ethers.utils.formatBytes32String(daoDummySubdomain)] + [ensLabelHash(daoDummySubdomain)] ); return {to, value, data}; } @@ -310,7 +313,6 @@ describe.only('DAOFactory: ', function () { const factory = new DAO__factory(signers[0]); const daoContract = factory.attach(dao); - console.log('creating action'); const action = await createAction(); expect( await daoFactory.createDao( @@ -326,7 +328,24 @@ describe.only('DAOFactory: ', function () { .to.emit(daoContract, EVENTS.NewURI) .withArgs(daoSettings.daoURI); - // todo check subdomain were added + // check the new subdomain owner is the registrar + const fullDomain = `${daoDummySubdomain}.${registrarManagedDomain}`; + const ENSRegistry = new ENSRegistry__factory(signers[0]); + const ens = ENSRegistry.attach(await ensSubdomainRegistrar.ens()); + + expect(await ens.owner(ensDomainHash(fullDomain))).to.equal( + ensSubdomainRegistrar.address + ); + + // check the new subdomain resolver target + const PublicResolverFactory = new PublicResolver__factory(signers[0]); + const resolver = PublicResolverFactory.attach( + await ensSubdomainRegistrar.resolver() + ); + + expect( + await await resolver['addr(bytes32)'](ensDomainHash(fullDomain)) + ).to.equal(daoContract.address); }); it('creates a dao with a plugin and emits correct events', async () => { From 915425e65b5a20f01586c0036cad538ed9b5276c Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 13:51:09 +0200 Subject: [PATCH 05/16] feat: add removed variable for storage layout compliance --- packages/contracts/src/framework/dao/DAORegistry.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/contracts/src/framework/dao/DAORegistry.sol b/packages/contracts/src/framework/dao/DAORegistry.sol index 785760ac6..04314a562 100644 --- a/packages/contracts/src/framework/dao/DAORegistry.sol +++ b/packages/contracts/src/framework/dao/DAORegistry.sol @@ -17,6 +17,10 @@ contract DAORegistry is InterfaceBasedRegistry, ProtocolVersion { /// @notice The ID of the permission required to call the `register` function. bytes32 public constant REGISTER_DAO_PERMISSION_ID = keccak256("REGISTER_DAO_PERMISSION"); + /// @notice The ENS subdomain registrar registering the DAO subdomains. + /// ! removed keeping it for storage layout compatibility + ENSSubdomainRegistrar public subdomainRegistrar; + /// @notice Emitted when a new DAO is registered. /// @param dao The address of the DAO contract. /// @param creator The address of the creator. From 7d45ff30e57cc37835ce0a768a5ea1ebd6175b1f Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 13:55:00 +0200 Subject: [PATCH 06/16] feat: fix dao registry tests --- .../test/framework/dao/dao-registry.ts | 248 +++++++++--------- 1 file changed, 118 insertions(+), 130 deletions(-) diff --git a/packages/contracts/test/framework/dao/dao-registry.ts b/packages/contracts/test/framework/dao/dao-registry.ts index 552a063e1..b487df8db 100644 --- a/packages/contracts/test/framework/dao/dao-registry.ts +++ b/packages/contracts/test/framework/dao/dao-registry.ts @@ -29,7 +29,7 @@ const EVENTS = { DAORegistered: 'DAORegistered', }; -describe('DAORegistry', function () { +describe.only('DAORegistry', function () { let signers: SignerWithAddress[]; let daoRegistry: DAORegistry; let managingDao: DAO; @@ -51,13 +51,6 @@ describe('DAORegistry', function () { // Managing DAO managingDao = await deployNewDAO(signers[0]); - // ENS - ensSubdomainRegistrar = await deployENSSubdomainRegistrar( - signers[0], - managingDao, - topLevelDomain - ); - // Target DAO to be used as an example DAO to be registered targetDao = await deployNewDAO(signers[0]); @@ -66,9 +59,16 @@ describe('DAORegistry', function () { daoRegistry = await deployWithProxy(Registry); - await daoRegistry.initialize( - managingDao.address, - ensSubdomainRegistrar.address + await daoRegistry.initialize(managingDao.address); + + // ENS + // ! not needed but used in previous version tets + ensSubdomainRegistrar = await deployENSSubdomainRegistrar( + signers[0], + managingDao, + daoRegistry.address, + signers[0].address, + topLevelDomain ); // Grant the `REGISTER_DAO_PERMISSION_ID` permission in the DAO registry to `signers[0]` @@ -79,37 +79,35 @@ describe('DAORegistry', function () { ); // Grant the `REGISTER_ENS_SUBDOMAIN_PERMISSION_ID` permission on the ENS subdomain registrar to the DAO registry contract - await managingDao.grant( - ensSubdomainRegistrar.address, - daoRegistry.address, - ENS_REGISTRAR_PERMISSIONS.REGISTER_ENS_SUBDOMAIN_PERMISSION_ID - ); + // await managingDao.grant( + // ensSubdomainRegistrar.address, + // daoRegistry.address, + // ENS_REGISTRAR_PERMISSIONS.REGISTER_ENS_SUBDOMAIN_PERMISSION_ID + // ); }); it('succeeds even if the dao subdomain is empty', async function () { - await expect(daoRegistry.register(targetDao.address, ownerAddress, '')).to - .not.be.reverted; + await expect(daoRegistry.register(targetDao.address, ownerAddress)).to.not + .be.reverted; }); - it('successfully sets subdomainregistrar', async () => { - expect(await daoRegistry.subdomainRegistrar()).to.equal( - ensSubdomainRegistrar.address - ); - }); + // it('successfully sets subdomainregistrar', async () => { + // expect(await daoRegistry.subdomainRegistrar()).to.equal( + // ensSubdomainRegistrar.address + // ); + // }); it('Should register a new DAO successfully', async function () { - await expect( - daoRegistry.register(targetDao.address, ownerAddress, daoSubdomain) - ) + await expect(daoRegistry.register(targetDao.address, ownerAddress)) .to.emit(daoRegistry, EVENTS.DAORegistered) - .withArgs(targetDao.address, ownerAddress, daoSubdomain); + .withArgs(targetDao.address, ownerAddress); expect(await daoRegistry.entries(targetDao.address)).to.equal(true); }); it('fails to register if the sender lacks the required role', async () => { // Register a DAO successfully - await daoRegistry.register(targetDao.address, ownerAddress, daoSubdomain); + await daoRegistry.register(targetDao.address, ownerAddress); // Revoke the permission await managingDao.revoke( @@ -120,9 +118,7 @@ describe('DAORegistry', function () { const newTargetDao = await deployNewDAO(signers[0]); - await expect( - daoRegistry.register(newTargetDao.address, ownerAddress, daoSubdomain) - ) + await expect(daoRegistry.register(newTargetDao.address, ownerAddress)) .to.be.revertedWithCustomError(daoRegistry, 'DaoUnauthorized') .withArgs( managingDao.address, @@ -133,119 +129,109 @@ describe('DAORegistry', function () { }); it('fails to register if DAO already exists', async function () { - await daoRegistry.register( - targetDao.address, - ownerAddress, - daoSubdomainEnsLabelhash - ); + await daoRegistry.register(targetDao.address, ownerAddress); - await expect( - daoRegistry.register(targetDao.address, ownerAddress, daoSubdomain) - ) + await expect(daoRegistry.register(targetDao.address, ownerAddress)) .to.be.revertedWithCustomError(daoRegistry, 'ContractAlreadyRegistered') .withArgs(targetDao.address); }); it('fails to register a DAO with the same name twice', async function () { // Register the DAO name under the top level domain - await daoRegistry.register(targetDao.address, ownerAddress, daoSubdomain); + await daoRegistry.register(targetDao.address, ownerAddress); const newTargetDao = await deployNewDAO(signers[0]); const otherOwnerAddress = await (await ethers.getSigners())[1].getAddress(); + // ! no longer valid due to ens no longer part of the DAORegistry // Try to register the DAO name under the top level domain a second time - await expect( - daoRegistry.register( - newTargetDao.address, - otherOwnerAddress, - daoSubdomain - ) - ) - .to.be.revertedWithCustomError(ensSubdomainRegistrar, 'AlreadyRegistered') - .withArgs(daoDomainHash, ensSubdomainRegistrar.address); + // await expect(daoRegistry.register(newTargetDao.address, otherOwnerAddress)) + // .to.be.revertedWithCustomError(ensSubdomainRegistrar, 'AlreadyRegistered') + // .withArgs(daoDomainHash, ensSubdomainRegistrar.address); }); // without mocking we have to repeat the tests here to make sure the validation is correct - describe('subdomain validation', () => { - it('should validate the passed subdomain correctly (< 32 bytes long subdomain)', async () => { - const baseSubdomain = 'this-is-my-super-valid-subdomain'; - - // loop through the ascii table - for (let i = 0; i < 127; i++) { - const newTargetDao = await deployNewDAO(signers[0]); - - // replace the 10th char in the baseSubdomain - const subdomainName = - baseSubdomain.substring(0, 10) + - String.fromCharCode(i) + - baseSubdomain.substring(10 + 1); - - // test success if it is a valid char [0-9a-z\-] - if ((i > 47 && i < 58) || (i > 96 && i < 123) || i === 45) { - await expect( - daoRegistry.register( - newTargetDao.address, - ownerAddress, - subdomainName - ) - ) - .to.emit(daoRegistry, EVENTS.DAORegistered) - .withArgs(newTargetDao.address, ownerAddress, subdomainName); - continue; - } - - await expect( - daoRegistry.register( - newTargetDao.address, - ownerAddress, - subdomainName - ) - ) - .to.be.revertedWithCustomError(daoRegistry, 'InvalidDaoSubdomain') - .withArgs(subdomainName); - } - }).timeout(120000); - - it('should validate the passed subdomain correctly (> 32 bytes long subdomain)', async () => { - const baseSubdomain = - 'this-is-my-super-looooooooooooooooooooooooooong-valid-subdomain'; - - // loop through the ascii table - for (let i = 0; i < 127; i++) { - const newTargetDao = await deployNewDAO(signers[0]); - - // replace the 40th char in the baseSubdomain - const subdomainName = - baseSubdomain.substring(0, 40) + - String.fromCharCode(i) + - baseSubdomain.substring(40 + 1); - - // test success if it is a valid char [0-9a-z\-] - if ((i > 47 && i < 58) || (i > 96 && i < 123) || i === 45) { - await expect( - daoRegistry.register( - newTargetDao.address, - ownerAddress, - subdomainName - ) - ) - .to.emit(daoRegistry, EVENTS.DAORegistered) - .withArgs(newTargetDao.address, ownerAddress, subdomainName); - continue; - } - - await expect( - daoRegistry.register( - newTargetDao.address, - ownerAddress, - subdomainName - ) - ) - .to.be.revertedWithCustomError(daoRegistry, 'InvalidDaoSubdomain') - .withArgs(subdomainName); - } - }).timeout(120000); - }); + // ! not needed as ENS no longer part of the DAORegistry + // describe('subdomain validation', () => { + // it('should validate the passed subdomain correctly (< 32 bytes long subdomain)', async () => { + // const baseSubdomain = 'this-is-my-super-valid-subdomain'; + + // // loop through the ascii table + // for (let i = 0; i < 127; i++) { + // const newTargetDao = await deployNewDAO(signers[0]); + + // // replace the 10th char in the baseSubdomain + // const subdomainName = + // baseSubdomain.substring(0, 10) + + // String.fromCharCode(i) + + // baseSubdomain.substring(10 + 1); + + // // test success if it is a valid char [0-9a-z\-] + // if ((i > 47 && i < 58) || (i > 96 && i < 123) || i === 45) { + // await expect( + // daoRegistry.register( + // newTargetDao.address, + // ownerAddress, + // subdomainName + // ) + // ) + // .to.emit(daoRegistry, EVENTS.DAORegistered) + // .withArgs(newTargetDao.address, ownerAddress, subdomainName); + // continue; + // } + + // await expect( + // daoRegistry.register( + // newTargetDao.address, + // ownerAddress, + // subdomainName + // ) + // ) + // .to.be.revertedWithCustomError(daoRegistry, 'InvalidDaoSubdomain') + // .withArgs(subdomainName); + // } + // }).timeout(120000); + + // it('should validate the passed subdomain correctly (> 32 bytes long subdomain)', async () => { + // const baseSubdomain = + // 'this-is-my-super-looooooooooooooooooooooooooong-valid-subdomain'; + + // // loop through the ascii table + // for (let i = 0; i < 127; i++) { + // const newTargetDao = await deployNewDAO(signers[0]); + + // // replace the 40th char in the baseSubdomain + // const subdomainName = + // baseSubdomain.substring(0, 40) + + // String.fromCharCode(i) + + // baseSubdomain.substring(40 + 1); + + // // test success if it is a valid char [0-9a-z\-] + // if ((i > 47 && i < 58) || (i > 96 && i < 123) || i === 45) { + // await expect( + // daoRegistry.register( + // newTargetDao.address, + // ownerAddress, + // subdomainName + // ) + // ) + // .to.emit(daoRegistry, EVENTS.DAORegistered) + // .withArgs(newTargetDao.address, ownerAddress, subdomainName); + // continue; + // } + + // await expect( + // daoRegistry.register( + // newTargetDao.address, + // ownerAddress, + // subdomainName + // ) + // ) + // .to.be.revertedWithCustomError(daoRegistry, 'InvalidDaoSubdomain') + // .withArgs(subdomainName); + // } + // }).timeout(120000); + // }); describe('Protocol version', async () => { it('returns the current protocol version', async () => { @@ -272,6 +258,9 @@ describe('DAORegistry', function () { }); it('upgrades to a new implementation', async () => { + // remove ensSubdomainRegistrar since is no longer needed + delete initArgs.ensSubdomainRegistrar; + await deployAndUpgradeSelfCheck( signers[0], signers[1], @@ -305,7 +294,6 @@ describe('DAORegistry', function () { const toProtocolVersion = await getProtocolVersion( currentContractFactory.attach(toImplementation) ); - expect(fromProtocolVersion).to.not.deep.equal(toProtocolVersion); expect(fromProtocolVersion).to.deep.equal([1, 0, 0]); expect(toProtocolVersion).to.deep.equal(osxContractsVersion()); From dffb9a3145d761d94e265fc9016c429bb4fdd6a6 Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 13:56:40 +0200 Subject: [PATCH 07/16] feat: add removed variable for storage layout compatibility --- .../src/framework/plugin/repo/PluginRepoRegistry.sol | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol b/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol index 5ed2ce3b7..0e436131c 100644 --- a/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol +++ b/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol @@ -18,6 +18,10 @@ contract PluginRepoRegistry is InterfaceBasedRegistry, ProtocolVersion { bytes32 public constant REGISTER_PLUGIN_REPO_PERMISSION_ID = keccak256("REGISTER_PLUGIN_REPO_PERMISSION"); + /// @notice The ENS subdomain registrar registering the PluginRepo subdomains. + /// ! removed keeping it for storage layout compatibility + ENSSubdomainRegistrar public subdomainRegistrar; + /// @notice Emitted if a new plugin repository is registered. /// @param pluginRepo The address of the plugin repository. event PluginRepoRegistered(address pluginRepo); From d65d50450fa2a2e93d2dd02377deae83bb433af5 Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 13:58:07 +0200 Subject: [PATCH 08/16] ci: comment updated for clarification --- packages/contracts/src/framework/dao/DAORegistry.sol | 2 +- .../contracts/src/framework/plugin/repo/PluginRepoRegistry.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/contracts/src/framework/dao/DAORegistry.sol b/packages/contracts/src/framework/dao/DAORegistry.sol index 04314a562..61b20a196 100644 --- a/packages/contracts/src/framework/dao/DAORegistry.sol +++ b/packages/contracts/src/framework/dao/DAORegistry.sol @@ -18,7 +18,7 @@ contract DAORegistry is InterfaceBasedRegistry, ProtocolVersion { bytes32 public constant REGISTER_DAO_PERMISSION_ID = keccak256("REGISTER_DAO_PERMISSION"); /// @notice The ENS subdomain registrar registering the DAO subdomains. - /// ! removed keeping it for storage layout compatibility + /// ! removed, but keeping it for storage layout compatibility ENSSubdomainRegistrar public subdomainRegistrar; /// @notice Emitted when a new DAO is registered. diff --git a/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol b/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol index 0e436131c..b62d9b41e 100644 --- a/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol +++ b/packages/contracts/src/framework/plugin/repo/PluginRepoRegistry.sol @@ -19,7 +19,7 @@ contract PluginRepoRegistry is InterfaceBasedRegistry, ProtocolVersion { keccak256("REGISTER_PLUGIN_REPO_PERMISSION"); /// @notice The ENS subdomain registrar registering the PluginRepo subdomains. - /// ! removed keeping it for storage layout compatibility + /// ! removed, but keeping it for storage layout compatibility ENSSubdomainRegistrar public subdomainRegistrar; /// @notice Emitted if a new plugin repository is registered. From 4e778d7c7ca6e0c924a3fc22f6ea363d19bf909e Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 14:47:21 +0200 Subject: [PATCH 09/16] feat: have a single registry on the ens registrar --- .../utils/ens/ENSSubdomainRegistrar.sol | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol b/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol index 79daf9e87..a3d7833e5 100644 --- a/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol +++ b/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol @@ -11,8 +11,7 @@ import {ProtocolVersion} from "@aragon/osx-commons-contracts/src/utils/versionin import {DaoAuthorizableUpgradeable} from "@aragon/osx-commons-contracts/src/permission/auth/DaoAuthorizableUpgradeable.sol"; import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol"; -import {DAORegistry} from "../../dao/DAORegistry.sol"; -import {PluginRepoRegistry} from "../../plugin/repo/PluginRepoRegistry.sol"; +import {InterfaceBasedRegistry} from "../../utils/InterfaceBasedRegistry.sol"; import {PluginRepo} from "../../plugin/repo/PluginRepo.sol"; /// @title ENSSubdomainRegistrar @@ -37,8 +36,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P /// @notice The address of the ENS resolver resolving the names to an address. address public resolver; - DAORegistry public daoRegistry; - PluginRepoRegistry public pluginRepoRegistry; + InterfaceBasedRegistry public registry; /// @notice Thrown if the subnode is already registered. /// @param subnode The subnode namehash. @@ -69,16 +67,14 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function initialize( IDAO _managingDao, ENS _ens, - DAORegistry _daoRegistry, - PluginRepoRegistry _pluginRepoRegistry, + InterfaceBasedRegistry _registry, bytes32 _node ) external initializer { __DaoAuthorizableUpgradeable_init(_managingDao); ens = _ens; node = _node; - daoRegistry = _daoRegistry; - pluginRepoRegistry = _pluginRepoRegistry; + registry = _registry; address nodeResolver = ens.resolver(_node); @@ -118,7 +114,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function registerSubnode( bytes32 _label - ) external isAllowed(daoRegistry.entries(msg.sender), false, address(0)) { + ) external isAllowed(registry.entries(msg.sender), false, address(0)) { // is a registered dao _registerSubnode(_label, msg.sender); } @@ -130,7 +126,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function registerSubnode( bytes32 _label, address _targetAddress - ) external isAllowed(daoRegistry.entries(msg.sender), true, _targetAddress) { + ) external isAllowed(registry.entries(msg.sender), true, _targetAddress) { // is registered plugin and the caller has maintainer permission _registerSubnode(_label, _targetAddress); } @@ -152,7 +148,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function unregisterSubnode( bytes32 _label - ) external isAllowed(daoRegistry.entries(msg.sender), false, address(0)) { + ) external isAllowed(registry.entries(msg.sender), false, address(0)) { // is a registered dao _unregisterSubnode(_label); } @@ -160,7 +156,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function unregisterSubnode( bytes32 _label, address _targetAddress - ) external isAllowed(daoRegistry.entries(msg.sender), true, _targetAddress) { + ) external isAllowed(registry.entries(msg.sender), true, _targetAddress) { // is registered plugin and the caller has maintainer permission _unregisterSubnode(_label); } From 1d0ac615ef82489fcfafd4ad4605e309277f87d9 Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 14:49:44 +0200 Subject: [PATCH 10/16] feat: fix tests --- packages/contracts/test/framework/dao/dao-factory.ts | 1 - packages/contracts/test/framework/dao/dao-registry.ts | 1 - packages/contracts/test/test-utils/ens.ts | 7 +++---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/contracts/test/framework/dao/dao-factory.ts b/packages/contracts/test/framework/dao/dao-factory.ts index d6c58bf65..a23c1f797 100644 --- a/packages/contracts/test/framework/dao/dao-factory.ts +++ b/packages/contracts/test/framework/dao/dao-factory.ts @@ -174,7 +174,6 @@ describe.only('DAOFactory: ', function () { signers[0], managingDao, daoRegistry.address, - pluginRepoRegistry.address, registrarManagedDomain ); diff --git a/packages/contracts/test/framework/dao/dao-registry.ts b/packages/contracts/test/framework/dao/dao-registry.ts index b487df8db..49d3ca8df 100644 --- a/packages/contracts/test/framework/dao/dao-registry.ts +++ b/packages/contracts/test/framework/dao/dao-registry.ts @@ -67,7 +67,6 @@ describe.only('DAORegistry', function () { signers[0], managingDao, daoRegistry.address, - signers[0].address, topLevelDomain ); diff --git a/packages/contracts/test/test-utils/ens.ts b/packages/contracts/test/test-utils/ens.ts index 028555f31..9af24a289 100644 --- a/packages/contracts/test/test-utils/ens.ts +++ b/packages/contracts/test/test-utils/ens.ts @@ -18,8 +18,7 @@ import {Address} from 'hardhat-deploy/types'; export async function deployENSSubdomainRegistrar( owner: SignerWithAddress, managingDao: DAO, - daoRegistry: Address, - pluginRepoRegistry: Address, + registry: Address, domain: string ): Promise { const ENSRegistryFactory = new ENSRegistry__factory(owner); @@ -67,8 +66,8 @@ export async function deployENSSubdomainRegistrar( await ensSubdomainRegistrar.initialize( managingDao.address, ensRegistry.address, - daoRegistry, - pluginRepoRegistry, + registry, + node ); From fa46269d4a67c6c42a27d22b1041471c1987d363 Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 14:56:40 +0200 Subject: [PATCH 11/16] ci: update msg.sender for meta transactions --- .../framework/utils/ens/ENSSubdomainRegistrar.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol b/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol index a3d7833e5..d4b07e184 100644 --- a/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol +++ b/packages/contracts/src/framework/utils/ens/ENSSubdomainRegistrar.sol @@ -102,7 +102,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P if ( !PluginRepo(_targetAddress).isGranted( _targetAddress, - msg.sender, + _msgSender(), PluginRepo(_targetAddress).MAINTAINER_PERMISSION_ID(), bytes("") ) @@ -114,9 +114,9 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function registerSubnode( bytes32 _label - ) external isAllowed(registry.entries(msg.sender), false, address(0)) { + ) external isAllowed(registry.entries(_msgSender()), false, address(0)) { // is a registered dao - _registerSubnode(_label, msg.sender); + _registerSubnode(_label, _msgSender()); } /// @notice Registers a new subdomain with this registrar as the owner and set the target address in the resolver. @@ -126,7 +126,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function registerSubnode( bytes32 _label, address _targetAddress - ) external isAllowed(registry.entries(msg.sender), true, _targetAddress) { + ) external isAllowed(registry.entries(_targetAddress), true, _targetAddress) { // is registered plugin and the caller has maintainer permission _registerSubnode(_label, _targetAddress); } @@ -148,7 +148,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function unregisterSubnode( bytes32 _label - ) external isAllowed(registry.entries(msg.sender), false, address(0)) { + ) external isAllowed(registry.entries(_msgSender()), false, address(0)) { // is a registered dao _unregisterSubnode(_label); } @@ -156,7 +156,7 @@ contract ENSSubdomainRegistrar is UUPSUpgradeable, DaoAuthorizableUpgradeable, P function unregisterSubnode( bytes32 _label, address _targetAddress - ) external isAllowed(registry.entries(msg.sender), true, _targetAddress) { + ) external isAllowed(registry.entries(_targetAddress), true, _targetAddress) { // is registered plugin and the caller has maintainer permission _unregisterSubnode(_label); } From 50066d8cb3e2a9f5a66f4d0746b2b781f14330ef Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 16:04:23 +0200 Subject: [PATCH 12/16] feat: update the deploy scripts, changed the order and dependencies, added function to set plugin repo subdomain after it is created and registered --- packages/contracts/deploy/helpers.ts | 34 ++++++- ...{10_dao-registry.ts => 00_dao-registry.ts} | 11 ++- ...onclude.ts => 01_dao-registry_conclude.ts} | 0 ...registry.ts => 10_plugin-repo-registry.ts} | 11 ++- ...ts => 11_plugin-repo-registry_conclude.ts} | 0 ...{00_ens_registry.ts => 20_ens_registry.ts} | 0 ...ens_subdomains.ts => 21_ens_subdomains.ts} | 0 ...rars.ts => 22_ens_subdomain_registrars.ts} | 25 ++++- ...{09_ens_conclude.ts => 29_ens_conclude.ts} | 0 .../new/10_framework/99_verifiy_step.ts | 94 ++++++++++++------- ...register-management-dao-on-dao-registry.ts | 5 +- 11 files changed, 130 insertions(+), 50 deletions(-) rename packages/contracts/deploy/new/10_framework/{10_dao-registry.ts => 00_dao-registry.ts} (84%) rename packages/contracts/deploy/new/10_framework/{11_dao-registry_conclude.ts => 01_dao-registry_conclude.ts} (100%) rename packages/contracts/deploy/new/10_framework/{20_plugin-repo-registry.ts => 10_plugin-repo-registry.ts} (85%) rename packages/contracts/deploy/new/10_framework/{21_plugin-repo-registry_conclude.ts => 11_plugin-repo-registry_conclude.ts} (100%) rename packages/contracts/deploy/new/10_framework/{00_ens_registry.ts => 20_ens_registry.ts} (100%) rename packages/contracts/deploy/new/10_framework/{01_ens_subdomains.ts => 21_ens_subdomains.ts} (100%) rename packages/contracts/deploy/new/10_framework/{02_ens_subdomain_registrars.ts => 22_ens_subdomain_registrars.ts} (85%) rename packages/contracts/deploy/new/10_framework/{09_ens_conclude.ts => 29_ens_conclude.ts} (100%) diff --git a/packages/contracts/deploy/helpers.ts b/packages/contracts/deploy/helpers.ts index 912853157..e5df0ca39 100644 --- a/packages/contracts/deploy/helpers.ts +++ b/packages/contracts/deploy/helpers.ts @@ -7,12 +7,14 @@ import { } from '../typechain'; import {VersionCreatedEvent} from '../typechain/PluginRepo'; import {PluginRepoRegisteredEvent} from '../typechain/PluginRepoRegistry'; +import {ensLabelHash} from '../utils/ens'; import {isLocal, pluginDomainEnv} from '../utils/environment'; import { getNetworkNameByAlias, getLatestNetworkDeployment, } from '@aragon/osx-commons-configs'; import {findEvent, findEventTopicLog, Operation} from '@aragon/osx-commons-sdk'; +import {ENSSubdomainRegistrar__factory} from '@aragon/osx-ethers-v1.2.0'; import {SignerWithAddress} from '@nomiclabs/hardhat-ethers/signers'; import {Contract} from 'ethers'; import {ethers} from 'hardhat'; @@ -158,6 +160,25 @@ export async function detemineDeployerNextAddress( return futureAddress; } +export async function registerPluginRepoSubdomain( + hre: HardhatRuntimeEnvironment, + repoAddress: string, + subdomain: string, + ensRegistrar: any +): Promise { + const [deployer] = await ethers.getSigners(); + + const ensRegistrarContract = ENSSubdomainRegistrar__factory.connect( + ensRegistrar, + deployer + ); + + await ensRegistrarContract.registerSubnode( + ensLabelHash(subdomain), + repoAddress + ); +} + export async function createPluginRepo( hre: HardhatRuntimeEnvironment, pluginName: string, @@ -191,10 +212,7 @@ export async function createPluginRepo( const {deployer} = await hre.getNamedAccounts(); - const tx = await pluginRepoFactoryContract.createPluginRepo( - subdomain, - deployer - ); + const tx = await pluginRepoFactoryContract.createPluginRepo(deployer); console.log( `Creating & registering repo for ${pluginName} with tx ${tx.hash}` ); @@ -209,6 +227,14 @@ export async function createPluginRepo( hre.aragonPluginRepos[pluginName] = repoAddress; + // register subdomain + await registerPluginRepoSubdomain( + hre, + repoAddress, + subdomain, + await getContractAddress('PluginENSSubdomainRegistrarProxy', hre) + ); + console.log( `Created & registered repo for ${pluginName} at address: ${repoAddress}` //, with contentURI ${ethers.utils.toUtf8String(releaseMetadata)}` ); diff --git a/packages/contracts/deploy/new/10_framework/10_dao-registry.ts b/packages/contracts/deploy/new/10_framework/00_dao-registry.ts similarity index 84% rename from packages/contracts/deploy/new/10_framework/10_dao-registry.ts rename to packages/contracts/deploy/new/10_framework/00_dao-registry.ts index 01660a7d5..b1c99b560 100644 --- a/packages/contracts/deploy/new/10_framework/10_dao-registry.ts +++ b/packages/contracts/deploy/new/10_framework/00_dao-registry.ts @@ -15,10 +15,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); // Get DAO's `ENSSubdomainRegistrar` contract. - const ensSubdomainRegistrarAddress = await getContractAddress( - 'DAOENSSubdomainRegistrarProxy', - hre - ); + //! no longer neede + // const ensSubdomainRegistrarAddress = await getContractAddress( + // 'DAOENSSubdomainRegistrarProxy', + // hre + // ); await deploy('DAORegistryProxy', { contract: daoRegistryArtifact, @@ -32,7 +33,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { execute: { init: { methodName: 'initialize', - args: [managementDAOAddress, ensSubdomainRegistrarAddress], + args: [managementDAOAddress], }, }, }, diff --git a/packages/contracts/deploy/new/10_framework/11_dao-registry_conclude.ts b/packages/contracts/deploy/new/10_framework/01_dao-registry_conclude.ts similarity index 100% rename from packages/contracts/deploy/new/10_framework/11_dao-registry_conclude.ts rename to packages/contracts/deploy/new/10_framework/01_dao-registry_conclude.ts diff --git a/packages/contracts/deploy/new/10_framework/20_plugin-repo-registry.ts b/packages/contracts/deploy/new/10_framework/10_plugin-repo-registry.ts similarity index 85% rename from packages/contracts/deploy/new/10_framework/20_plugin-repo-registry.ts rename to packages/contracts/deploy/new/10_framework/10_plugin-repo-registry.ts index 32f6b96ff..92152c5b1 100644 --- a/packages/contracts/deploy/new/10_framework/20_plugin-repo-registry.ts +++ b/packages/contracts/deploy/new/10_framework/10_plugin-repo-registry.ts @@ -15,10 +15,11 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { ); // Get DAO's `ENSSubdomainRegistrar` address. - const ensSubdomainRegistrarAddress = await getContractAddress( - 'PluginENSSubdomainRegistrarProxy', - hre - ); + // ! no longer needed + // const ensSubdomainRegistrarAddress = await getContractAddress( + // 'PluginENSSubdomainRegistrarProxy', + // hre + // ); await deploy('PluginRepoRegistryProxy', { contract: pluginRepoRegistryArtifact, @@ -32,7 +33,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { execute: { init: { methodName: 'initialize', - args: [managementDAOAddress, ensSubdomainRegistrarAddress], + args: [managementDAOAddress], }, }, }, diff --git a/packages/contracts/deploy/new/10_framework/21_plugin-repo-registry_conclude.ts b/packages/contracts/deploy/new/10_framework/11_plugin-repo-registry_conclude.ts similarity index 100% rename from packages/contracts/deploy/new/10_framework/21_plugin-repo-registry_conclude.ts rename to packages/contracts/deploy/new/10_framework/11_plugin-repo-registry_conclude.ts diff --git a/packages/contracts/deploy/new/10_framework/00_ens_registry.ts b/packages/contracts/deploy/new/10_framework/20_ens_registry.ts similarity index 100% rename from packages/contracts/deploy/new/10_framework/00_ens_registry.ts rename to packages/contracts/deploy/new/10_framework/20_ens_registry.ts diff --git a/packages/contracts/deploy/new/10_framework/01_ens_subdomains.ts b/packages/contracts/deploy/new/10_framework/21_ens_subdomains.ts similarity index 100% rename from packages/contracts/deploy/new/10_framework/01_ens_subdomains.ts rename to packages/contracts/deploy/new/10_framework/21_ens_subdomains.ts diff --git a/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts b/packages/contracts/deploy/new/10_framework/22_ens_subdomain_registrars.ts similarity index 85% rename from packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts rename to packages/contracts/deploy/new/10_framework/22_ens_subdomain_registrars.ts index 003b5018d..fff42c89e 100644 --- a/packages/contracts/deploy/new/10_framework/02_ens_subdomain_registrars.ts +++ b/packages/contracts/deploy/new/10_framework/22_ens_subdomain_registrars.ts @@ -6,6 +6,8 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { + console.log('Registrar'); + const {deployments, ethers, network} = hre; const {deploy} = deployments; @@ -26,6 +28,9 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { const daoNode = ethers.utils.namehash(daoDomain); const pluginNode = ethers.utils.namehash(pluginDomain); + // Get DAO's `DAORegistry` address. + const daoRegistry = await getContractAddress('DAORegistryProxy', hre); + await deploy('DAOENSSubdomainRegistrarProxy', { contract: ensSubdomainRegistrarArtifact, from: deployer.address, @@ -38,7 +43,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { execute: { init: { methodName: 'initialize', - args: [managementDAOAddress, ensRegistryAddress, daoNode], + args: [ + managementDAOAddress, + ensRegistryAddress, + daoRegistry, + daoNode, + ], }, }, }, @@ -50,6 +60,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { hre ); + // Get DAO's `PluginRepoRegistry` address. + const pluginRepoRegistry = await getContractAddress( + 'PluginRepoRegistryProxy', + hre + ); + await deploy('PluginENSSubdomainRegistrarProxy', { contract: ensSubdomainRegistrarArtifact, from: deployer.address, @@ -62,7 +78,12 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { execute: { init: { methodName: 'initialize', - args: [managementDAOAddress, ensRegistryAddress, pluginNode], + args: [ + managementDAOAddress, + ensRegistryAddress, + pluginRepoRegistry, + pluginNode, + ], }, }, }, diff --git a/packages/contracts/deploy/new/10_framework/09_ens_conclude.ts b/packages/contracts/deploy/new/10_framework/29_ens_conclude.ts similarity index 100% rename from packages/contracts/deploy/new/10_framework/09_ens_conclude.ts rename to packages/contracts/deploy/new/10_framework/29_ens_conclude.ts diff --git a/packages/contracts/deploy/new/10_framework/99_verifiy_step.ts b/packages/contracts/deploy/new/10_framework/99_verifiy_step.ts index 30a961aaf..57b465966 100644 --- a/packages/contracts/deploy/new/10_framework/99_verifiy_step.ts +++ b/packages/contracts/deploy/new/10_framework/99_verifiy_step.ts @@ -24,6 +24,25 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { hre ); + // VERIFYING DAO REGISTRY + const DAORegistryAddress = await getContractAddress('DAORegistryProxy', hre); + const DAORegistry = DAORegistry__factory.connect( + DAORegistryAddress, + deployer + ); + + await checkSetManagementDao(DAORegistry, managementDAOAddress); + // ! not nedded as the registry no longer has the subdomain registrar + // // scope to reuse same const again + // { + // const SubdomainRegistrarAddress = await DAORegistry.subdomainRegistrar(); + // if (SubdomainRegistrarAddress !== DAOENSSubdomainRegistrarAddress) { + // throw new Error( + // `${DAORegistry} has wrong SubdomainRegistrarAddress set. Expected ${DAOENSSubdomainRegistrarAddress} to be ${SubdomainRegistrarAddress}` + // ); + // } + // } + // VERIFYING DAO ENS SUBDOMAIN REGISTRAR const DAOENSSubdomainRegistrarAddress = await getContractAddress( 'DAOENSSubdomainRegistrarProxy', @@ -33,6 +52,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { DAOENSSubdomainRegistrarAddress, deployer ); + await checkSetManagementDao(DAOENSSubdomainRegistrar, managementDAOAddress); // scope to reuse same const again { @@ -57,6 +77,42 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { } } + // check is the correct registry + { + const SubdomainRegistry = await DAOENSSubdomainRegistrar.registry(); + console.log('SubdomainRegistry', SubdomainRegistry); + console.log('DAORegistryAddress', DAORegistryAddress); + + if (SubdomainRegistry !== DAORegistryAddress) { + throw new Error( + `${DAOENSSubdomainRegistrar} has wrong Registry set. Expected ${DAORegistryAddress} to be ${SubdomainRegistry}` + ); + } + } + + // VERIFYING PLUGIN REPO REGISTRY + const PluginRepoRegistryAddress = await getContractAddress( + 'PluginRepoRegistryProxy', + hre + ); + const PluginRepoRegistry = PluginRepoRegistry__factory.connect( + PluginRepoRegistryAddress, + deployer + ); + await checkSetManagementDao(PluginRepoRegistry, managementDAOAddress); + + // ! not needed as the registry no longer has the subdomain registrar + // scope to reuse same const again + // { + // const SubdomainRegistrarAddress = + // await PluginRepoRegistry.subdomainRegistrar(); + // if (SubdomainRegistrarAddress !== PluginENSSubdomainRegistrarAddress) { + // throw new Error( + // `${PluginRepoRegistry} has wrong SubdomainRegistrarAddress set. Expected ${PluginENSSubdomainRegistrarAddress} to be ${SubdomainRegistrarAddress}` + // ); + // } + // } + // VERIFYING PLUGIN ENS SUBDOMAIN REGISTRAR const PluginENSSubdomainRegistrarAddress = await getContractAddress( 'PluginENSSubdomainRegistrarProxy', @@ -93,40 +149,14 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { } } - // VERIFYING DAO REGISTRY - const DAORegistryAddress = await getContractAddress('DAORegistryProxy', hre); - const DAORegistry = DAORegistry__factory.connect( - DAORegistryAddress, - deployer - ); - await checkSetManagementDao(DAORegistry, managementDAOAddress); - // scope to reuse same const again - { - const SubdomainRegistrarAddress = await DAORegistry.subdomainRegistrar(); - if (SubdomainRegistrarAddress !== DAOENSSubdomainRegistrarAddress) { - throw new Error( - `${DAORegistry} has wrong SubdomainRegistrarAddress set. Expected ${DAOENSSubdomainRegistrarAddress} to be ${SubdomainRegistrarAddress}` - ); - } - } - - // VERIFYING PLUGIN REPO REGISTRY - const PluginRepoRegistryAddress = await getContractAddress( - 'PluginRepoRegistryProxy', - hre - ); - const PluginRepoRegistry = PluginRepoRegistry__factory.connect( - PluginRepoRegistryAddress, - deployer - ); - await checkSetManagementDao(PluginRepoRegistry, managementDAOAddress); - // scope to reuse same const again + // check is the correct registry { - const SubdomainRegistrarAddress = - await PluginRepoRegistry.subdomainRegistrar(); - if (SubdomainRegistrarAddress !== PluginENSSubdomainRegistrarAddress) { + const SubdomainRegistry = await PluginENSSubdomainRegistrar.registry(); + console.log('SubdomainRegistry', SubdomainRegistry); + console.log('PluginRepoRegistryAddress', PluginRepoRegistryAddress); + if (SubdomainRegistry !== PluginRepoRegistryAddress) { throw new Error( - `${PluginRepoRegistry} has wrong SubdomainRegistrarAddress set. Expected ${PluginENSSubdomainRegistrarAddress} to be ${SubdomainRegistrarAddress}` + `${PluginENSSubdomainRegistrar} has wrong Registry set. Expected ${PluginRepoRegistryAddress} to be ${SubdomainRegistry}` ); } } diff --git a/packages/contracts/deploy/new/40_finalize-management-dao/20_register-management-dao-on-dao-registry.ts b/packages/contracts/deploy/new/40_finalize-management-dao/20_register-management-dao-on-dao-registry.ts index 38d56eed5..07a432d7c 100644 --- a/packages/contracts/deploy/new/40_finalize-management-dao/20_register-management-dao-on-dao-registry.ts +++ b/packages/contracts/deploy/new/40_finalize-management-dao/20_register-management-dao-on-dao-registry.ts @@ -1,4 +1,5 @@ import {DAO__factory, DAORegistry__factory} from '../../../typechain'; +import {ensLabelHash} from '../../../utils/ens'; import { daoDomainEnv, managementDaoSubdomainEnv, @@ -10,6 +11,7 @@ import { MANAGEMENT_DAO_METADATA, uploadToIPFS, } from '../../helpers'; +import {ENSSubdomainRegistrar__factory} from '@aragon/osx-ethers-v1.2.0'; import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; @@ -55,8 +57,7 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { // Register `managementDAO` on `DAORegistry`. const registerTx = await daoRegistryContract.register( managementDAOAddress, - deployer.address, - daoSubdomain + deployer.address ); await registerTx.wait(); console.log( From 9dadeb5b55fb53fb1b4c94ea77976f2d17a2429f Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 16:04:36 +0200 Subject: [PATCH 13/16] feat: check test --- packages/contracts/test/deploy/managing-dao.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/contracts/test/deploy/managing-dao.ts b/packages/contracts/test/deploy/managing-dao.ts index a82fdcbc5..a6f4949fc 100644 --- a/packages/contracts/test/deploy/managing-dao.ts +++ b/packages/contracts/test/deploy/managing-dao.ts @@ -34,7 +34,7 @@ async function deployAll() { await initializeDeploymentFixture('New'); } -describe('Management DAO', function () { +describe.only('Management DAO', function () { let deployer: SignerWithAddress; let approvers: SignerWithAddress[]; let minApprovals: number; From 59423dfe4cf3c05f8c592a26ef7eb400088faa4d Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 16:13:19 +0200 Subject: [PATCH 14/16] ci: rmv new line --- packages/contracts/test/test-utils/ens.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/contracts/test/test-utils/ens.ts b/packages/contracts/test/test-utils/ens.ts index 9af24a289..adce365bf 100644 --- a/packages/contracts/test/test-utils/ens.ts +++ b/packages/contracts/test/test-utils/ens.ts @@ -67,7 +67,6 @@ export async function deployENSSubdomainRegistrar( managingDao.address, ensRegistry.address, registry, - node ); From bb64b6b862c179745cbc9e6e42847486e1e07095 Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 16:15:39 +0200 Subject: [PATCH 15/16] ci: remove logs --- .../deploy/new/10_framework/22_ens_subdomain_registrars.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/contracts/deploy/new/10_framework/22_ens_subdomain_registrars.ts b/packages/contracts/deploy/new/10_framework/22_ens_subdomain_registrars.ts index fff42c89e..b1f4edf42 100644 --- a/packages/contracts/deploy/new/10_framework/22_ens_subdomain_registrars.ts +++ b/packages/contracts/deploy/new/10_framework/22_ens_subdomain_registrars.ts @@ -6,8 +6,6 @@ import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types'; const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) { - console.log('Registrar'); - const {deployments, ethers, network} = hre; const {deploy} = deployments; From fd1e11f832b721c6f590708b6fd49340b76cfef1 Mon Sep 17 00:00:00 2001 From: Claudia Date: Tue, 30 Apr 2024 16:16:14 +0200 Subject: [PATCH 16/16] ci: remove not needed imports --- .../20_register-management-dao-on-dao-registry.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/contracts/deploy/new/40_finalize-management-dao/20_register-management-dao-on-dao-registry.ts b/packages/contracts/deploy/new/40_finalize-management-dao/20_register-management-dao-on-dao-registry.ts index 07a432d7c..5c7a25835 100644 --- a/packages/contracts/deploy/new/40_finalize-management-dao/20_register-management-dao-on-dao-registry.ts +++ b/packages/contracts/deploy/new/40_finalize-management-dao/20_register-management-dao-on-dao-registry.ts @@ -1,5 +1,4 @@ import {DAO__factory, DAORegistry__factory} from '../../../typechain'; -import {ensLabelHash} from '../../../utils/ens'; import { daoDomainEnv, managementDaoSubdomainEnv, @@ -11,7 +10,6 @@ import { MANAGEMENT_DAO_METADATA, uploadToIPFS, } from '../../helpers'; -import {ENSSubdomainRegistrar__factory} from '@aragon/osx-ethers-v1.2.0'; import {DeployFunction} from 'hardhat-deploy/types'; import {HardhatRuntimeEnvironment} from 'hardhat/types';