From 54b701b04143cf588471b51e1a5d382d919bbad7 Mon Sep 17 00:00:00 2001 From: alikhabazian Date: Sun, 3 Dec 2023 21:17:21 +0330 Subject: [PATCH 1/4] first run --- scripts/src/client/newDao.ts | 2 +- scripts/src/test/SubDAOPlugin.test.ts | 383 ++++++++------------------ 2 files changed, 113 insertions(+), 272 deletions(-) diff --git a/scripts/src/client/newDao.ts b/scripts/src/client/newDao.ts index 69bf72b..cdb334a 100644 --- a/scripts/src/client/newDao.ts +++ b/scripts/src/client/newDao.ts @@ -30,7 +30,7 @@ export async function createNewDAO(network:AllowedNetwork,metadata:DaoMetadata, } const createDaoParams: CreateDaoParams = { metadataUri, - ensSubdomain: ensSubdomain, // my-org.dao.eth + ensSubdomain: ensSubdomain.split('.')[0], // my-org.dao.eth plugins: plugins, // plugin array cannot be empty or the transaction will fail. you need at least one governance mechanism to create your DAO. }; const estimatedGas: GasFeeEstimation = await client.estimation.createDao(createDaoParams); diff --git a/scripts/src/test/SubDAOPlugin.test.ts b/scripts/src/test/SubDAOPlugin.test.ts index 1e6e67e..82957ee 100644 --- a/scripts/src/test/SubDAOPlugin.test.ts +++ b/scripts/src/test/SubDAOPlugin.test.ts @@ -4,9 +4,15 @@ import { ApplyInstallationParams, DaoAction, MetadataAbiInput, - PrepareInstallationParams, + PrepareInstallationParams, ProposalMetadata, } from '@aragon/sdk-client-common'; -import { VoteValues } from '@aragon/sdk-client'; +import { + DaoMetadata, + MultisigPluginSettings, + TokenVotingPluginInstall, + VoteValues, + VotingMode +} from '@aragon/sdk-client'; import { Client, TokenVotingClient } from '../lib/sdk'; import { getWallet } from '../lib/helpers'; import { AllowedNetwork } from '../lib/constants'; @@ -14,281 +20,116 @@ const log = console.log; import { ethers } from 'ethers'; import { hexToBytes } from './../lib/helpers'; -import { getVotingPluginAddress } from './../client/installSubDAOPlugin'; +import {getVotingPluginAddress, installSubDaoPlugin} from './../client/installSubDAOPlugin'; +import {createNewDAO} from "../client/newDao"; +import {ChangeVotingSettingClient} from "../client/changeVotingSetting"; + + +function convertTODecimal(value:number,decimal:number){ + return value*Math.pow(10,decimal); +} + + +const network: AllowedNetwork = 'goerli'; +//TODO +const porposalMetadata:ProposalMetadata = { + title: 'Create dao', + summary: 'Create dao', + description: `By installing this plugin, the plugin will grant the execution access of child da to parent`, + resources: [ + { + url: 'https://patterns.community', + name: 'Pattern', + }, + ], + media: { + header: 'https://assets-global.website-files.com/65410dc30116ce87ecbef5cd/654f75bc7db9aa282ca87e21_Logo%2Btext%20White.png', + logo: 'https://assets-global.website-files.com/65410dc30116ce87ecbef5cd/654f75bc7db9aa282ca87e21_Logo%2Btext%20White.png', + }, +}; +const createDAOMetadata: DaoMetadata = { + name: "My DAO", + description: "This is a description", + avatar: "https://images.freeimages.com/images/large-previews/360/banana-1-1330048.jpg", + links: [{ + name: "Web site", + url: "https://...", + }] +} + +const tokenVotingPluginSettings:TokenVotingPluginInstall ={ + votingSettings: { + minDuration: 60 * 60 * 24 * 2, // seconds + minParticipation: 0.25, // 25% + supportThreshold: 0.5, // 50% + minProposerVotingPower: BigInt("5000"), // default 0 + votingMode: VotingMode.EARLY_EXECUTION, // default is STANDARD. other options: EARLY_EXECUTION, VOTE_REPLACEMENT + }, + newToken: { + name: "Token", // the name of your token + symbol: "TOK", // the symbol for your token. shouldn't be more than 5 letters + decimals: 18, // the number of decimals your token uses + // minter: "0x...", // optional. if you don't define any, we'll use the standard OZ ERC20 contract. Otherwise, you can define your own token minter contract address. + balances: [ + { // Defines the initial balances of the new token + address: "0x2D5240cd92F30228bcA173431323887436295818", // address of the account to receive the newly minted tokens + balance: BigInt(convertTODecimal(10,18)), // amount of tokens that address should receive + }, + ], + }, +}; + +const multisigPluginSettings :MultisigPluginSettings={ + members:["0x2D5240cd92F30228bcA173431323887436295818"], + votingSettings:{ + minApprovals: 1, + onlyListed: true, + } +} + +const parentEns=`parentdao-${new Date().getTime()}.dao.eth` +const childEns1=`child1dao-${new Date().getTime()}.dao.eth` +const childEns2=`child2dao-${new Date().getTime()}.dao.eth` +console.log('parentEns:',parentEns) +console.log('childEns1:',childEns1) +console.log('childEns2:',childEns2) + +let daoAddressParent: string; +let pluginAddressesParent: string[]; +let daoAddressChild1: string; +let pluginAddressesChild1: string[]; +let daoAddressChild2: string; +let pluginAddressesChild2: string[]; + +beforeAll( async() => { + // const{daoAddress:daoParent, pluginAddresses:pluginParent}=await createNewDAO(network,createDAOMetadata,[tokenVotingPluginSettings],parentEns); + // daoAddressParent = daoParent; + // pluginAddressesParent = pluginParent; + // //--------------------------------------------- + // const{daoAddress:daoChild1, pluginAddresses:pluginChild1}=await createNewDAO(network,createDAOMetadata,[tokenVotingPluginSettings],childEns1); + // daoAddressChild1 = daoChild1; + // pluginAddressesChild1 = pluginChild1; + // //--------------------------------------------- + // const{daoAddress:daoChild2, pluginAddresses:pluginChild2}=await createNewDAO(network,createDAOMetadata,[multisigPluginSettings],childEns2); + // daoAddressChild2 = daoChild2; + // pluginAddressesChild2= pluginChild2; + //--------------------------------------------- + // Parent DAO Contract: 0x9A3aeeF82539a6c7F1A2bb712Fe11C4a6908e3BD + // 0x1275caF82b4a1C6E1276Ab69C7f329BdbBD3510d + // 0x01ec28d9Cdda4d96EcCFd88C1B532C50272a1CEa + await installSubDaoPlugin('child1dao-1701257361998.dao.eth', 'parentdao-1701257361998.dao.eth', network); + await installSubDaoPlugin(childEns1, parentEns, network); + await installSubDaoPlugin(childEns2, parentEns, network); + //--------------------------------------------- + // const changeVotingClient = new ChangeVotingSettingClient(parentDAO, childDAO, subAdminPlugin, network); + // await changeVotingClient.initial(); + -beforeAll(() => { - // setup tests }); describe('Testing SubDAO plugin', () => { test('Add new multisig admin', async () => { - const parent = 'parentdao.dao.eth'; // parent - const child = 'mehrdadchilddao.dao.eth'; - const NETWORK: AllowedNetwork = 'goerli'; - const deployer = getWallet(); - const client = Client(NETWORK); - const tokenVotingClient = TokenVotingClient(NETWORK); - - const parentDaoDetails = await client.methods.getDao(parent); - if (!parentDaoDetails) throw new Error('DAO not found'); - const childDaoDetails = await client.methods.getDao(child); - if (!childDaoDetails) throw new Error('DAO not found'); - - const subdaoPluginContractAddress = '0xaC80199F6392609c58b6A4AF22a73b3EaBE37dcc'; - const toBeAddedApprovers = ['0x00f3eE67e37dE62b8122EC512B3eB484f9C947cF']; - - const childContractAddress = childDaoDetails.address; - - const parentContractAddress = parentDaoDetails.address; - const { votingPluginAddress: parentVotingPluginContractAddress, votingPluginType: parentVotingPluginType } = - getVotingPluginAddress(parentDaoDetails); - const { votingPluginAddress: childVotingPluginContractAddress, votingPluginType: childVotingPluginType } = - getVotingPluginAddress(childDaoDetails); - - log('Parent DAO Contract: ', parentContractAddress); - log('Parent Voting Plugin: ', parentVotingPluginContractAddress); - log('Parent Voting type: ', parentVotingPluginType); - log('Child DAO Contract: ', childContractAddress); - log('Child Voting Plugin: ', childVotingPluginContractAddress); - log('Child Voting type: ', childVotingPluginType); - log('SubDAO plugin address: ', subdaoPluginContractAddress); - log('New approvers we want to add: ', toBeAddedApprovers) - log('Child DAO plugins: ', childDaoDetails.plugins) - //addAddresses - const multisigABI = [ - { - type: 'function', - name: 'addAddresses', - inputs: [ - { - type: 'address[]', - name: '_members', - }, - ], - stateMutability: 'nonpayable', // specify the stateMutability property - outputs: [], - }, - ]; - - const multisigPluginInterface = new ethers.utils.Interface(multisigABI); - //TODO - const multisigUpdateData = multisigPluginInterface.encodeFunctionData('addAddresses', [toBeAddedApprovers]); - - //TODO - const updateVotingSettingDaoAction: DaoAction[] = [ - { - to: childVotingPluginContractAddress, //multidig address - value: BigInt(0), - data: hexToBytes(multisigUpdateData), - }, - ]; - const subdaoPluginAbi = [ - { - inputs: [ - { - internalType: 'address', - name: 'dao', - type: 'address', - }, - { - internalType: 'address', - name: 'where', - type: 'address', - }, - { - internalType: 'address', - name: 'who', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'permissionId', - type: 'bytes32', - }, - ], - name: 'DaoUnauthorized', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint8', - name: 'version', - type: 'uint8', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - inputs: [], - name: 'PARENT_PERMISSION_ID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'dao', - outputs: [ - { - internalType: 'contract IDAO', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - internalType: 'struct IDAO.Action[]', - name: '_actions', - type: 'tuple[]', - }, - ], - name: 'execute', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'contract IDAO', - name: '_childDAO', - type: 'address', - }, - { - internalType: 'address', - name: '_parentDAO', - type: 'address', - }, - ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'parentDAO', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'pluginType', - outputs: [ - { - internalType: 'enum IPlugin.PluginType', - name: '', - type: 'uint8', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes4', - name: '_interfaceId', - type: 'bytes4', - }, - ], - name: 'supportsInterface', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ]; - - - const daoInterface = new ethers.utils.Interface(subdaoPluginAbi); - const data = daoInterface.encodeFunctionData('execute', [updateVotingSettingDaoAction]); - - //TODO - const daoActions1: DaoAction[] = [ - { - to: subdaoPluginContractAddress, - value: BigInt(0), - data: hexToBytes(data), //update_multisig - }, - ]; - - - const metadataUri: string = await tokenVotingClient.methods.pinMetadata({ - title: 'Add multisig address', - summary: 'This is a test proposal', - description: 'This is the description of a long test proposal', - resources: [ - { - url: 'https://thforumurl.com', - name: 'Forum', - }, - ], - media: { - header: 'https://fileserver.com/header.png', - logo: 'https://fileserver.com/logo.png', - }, - }); - const createProposalSteps = tokenVotingClient.methods.createProposal({ - metadataUri, - pluginAddress: parentVotingPluginContractAddress, - actions: daoActions1, - creatorVote: VoteValues.YES, // creator votes yes - executeOnPass: true, // execute on pass - startDate: new Date(0), // Start immediately - endDate: new Date(0), // uses minimum voting duration - }); - - const createProposalStep1Value = await (await createProposalSteps.next()).value; - log('Transaction Hash: ', await createProposalStep1Value.txHash); - - const createProposalStep2Value = await (await createProposalSteps.next()).value; - - log("Proposal ID: ", await createProposalStep2Value.proposalId); },1000000); }); From cf4701e7a91a0b58d0e61823f21faec0b8ca836e Mon Sep 17 00:00:00 2001 From: alikhabazian Date: Mon, 4 Dec 2023 01:36:18 +0330 Subject: [PATCH 2/4] test add and remove on multisig --- scripts/src/client/changeVotingSetting.ts | 43 ++++++++++------ scripts/src/client/installSubDAOPlugin.ts | 1 + scripts/src/test/SubDAOPlugin.test.ts | 63 ++++++++++++++++++----- 3 files changed, 79 insertions(+), 28 deletions(-) diff --git a/scripts/src/client/changeVotingSetting.ts b/scripts/src/client/changeVotingSetting.ts index d5275b3..97a3591 100644 --- a/scripts/src/client/changeVotingSetting.ts +++ b/scripts/src/client/changeVotingSetting.ts @@ -1,7 +1,7 @@ //class which initial with parentAddressOrEns, childAddressOrEns, subDaoPluginAddress import {Client, MultisigClient, TokenVotingClient} from "../lib/sdk"; import {AllowedNetwork} from "../lib/constants"; -import {DaoDetails} from "@aragon/sdk-client"; +import {DaoDetails, VoteValues} from "@aragon/sdk-client"; import { getVotingPluginAddress, installSubDaoPlugin, @@ -117,7 +117,7 @@ export class ChangeVotingSettingClient { } } - private async isMember(address:string,votingAbi:any){ + async isMember(address:string,votingAbi:any){ const deployer=getWallet(); const Contract=this.connectContract(deployer,this.childVotingPluginContractAddress,votingAbi); try { @@ -137,18 +137,32 @@ export class ChangeVotingSettingClient { } private async sendProposal(proposalMetadata,daoActions:DaoAction[]){ - - const metadataUri: string = await this.parentVotingClient.methods.pinMetadata(proposalMetadata); - const createProposalSteps=this.parentVotingClient.methods.createProposal({ - metadataUri, - pluginAddress: this.parentVotingPluginContractAddress, - actions: daoActions, - approve: true, - tryExecution: true, - startDate: new Date(0), // Start immediately - endDate: new Date(new Date().setFullYear(new Date().getFullYear() + 10)), // uses minimum voting duration - }); - await iterateSteps(createProposalSteps); + if (this.parentVotingPluginType === TOKEN_VOTING_PLUGIN_ID) { + const metadataUri: string = await this.parentVotingClient.methods.pinMetadata(proposalMetadata); + const createProposalSteps = this.parentVotingClient.methods.createProposal({ + metadataUri, + pluginAddress: this.parentVotingPluginContractAddress, + actions: daoActions, + creatorVote: VoteValues.YES, // creator votes yes + executeOnPass: true, // execute on pass + startDate: new Date(0), // Start immediately + endDate: new Date(0), // uses minimum voting duration + }); + await iterateSteps(createProposalSteps); + } + else if (this.parentVotingPluginType === MULTISIG_PLUGIN_ID) { + const metadataUri: string = await this.parentVotingClient.methods.pinMetadata(proposalMetadata); + const createProposalSteps = this.parentVotingClient.methods.createProposal({ + metadataUri, + pluginAddress: this.parentVotingPluginContractAddress, + actions: daoActions, + approve: true, + tryExecution: true, + startDate: new Date(0), // Start immediately + endDate: new Date(new Date().setFullYear(new Date().getFullYear() + 10)), // uses minimum voting duration + }); + await iterateSteps(createProposalSteps); + } } @@ -172,7 +186,6 @@ export class ChangeVotingSettingClient { data: hexToBytes(encodedFunctionDataMultisig), }, ]; - const encodedFunctionDataSubDAOAdmin=this.encodedFunctionData(SUB_DAO_ADMIN_ABI,'execute',[updateVotingSettingDaoAction]) const executeSubDAOAdminDaoAction: DaoAction[] = [ { diff --git a/scripts/src/client/installSubDAOPlugin.ts b/scripts/src/client/installSubDAOPlugin.ts index 2eb5daa..a485929 100644 --- a/scripts/src/client/installSubDAOPlugin.ts +++ b/scripts/src/client/installSubDAOPlugin.ts @@ -185,6 +185,7 @@ export async function installSubDaoPlugin(childDAO: string, parentDAO: string, n }); await iterateSteps(createProposalSteps); } + return installdata.pluginAddress; } export async function iterateSteps(createProposalSteps: AsyncGenerator) { diff --git a/scripts/src/test/SubDAOPlugin.test.ts b/scripts/src/test/SubDAOPlugin.test.ts index 82957ee..3650daa 100644 --- a/scripts/src/test/SubDAOPlugin.test.ts +++ b/scripts/src/test/SubDAOPlugin.test.ts @@ -23,6 +23,7 @@ import { hexToBytes } from './../lib/helpers'; import {getVotingPluginAddress, installSubDaoPlugin} from './../client/installSubDAOPlugin'; import {createNewDAO} from "../client/newDao"; import {ChangeVotingSettingClient} from "../client/changeVotingSetting"; +import {MULTISIG_ABI} from "../lib/abis"; function convertTODecimal(value:number,decimal:number){ @@ -87,9 +88,9 @@ const multisigPluginSettings :MultisigPluginSettings={ } } -const parentEns=`parentdao-${new Date().getTime()}.dao.eth` -const childEns1=`child1dao-${new Date().getTime()}.dao.eth` -const childEns2=`child2dao-${new Date().getTime()}.dao.eth` +let parentEns=`parentdao-${new Date().getTime()}.dao.eth` +let childEns1=`child1dao-${new Date().getTime()}.dao.eth` +let childEns2=`child2dao-${new Date().getTime()}.dao.eth` console.log('parentEns:',parentEns) console.log('childEns1:',childEns1) console.log('childEns2:',childEns2) @@ -100,6 +101,10 @@ let daoAddressChild1: string; let pluginAddressesChild1: string[]; let daoAddressChild2: string; let pluginAddressesChild2: string[]; +let changeVotingClientChild1:ChangeVotingSettingClient; +let changeVotingClientChild2:ChangeVotingSettingClient; +let subAdminPluginChild1; +let subAdminPluginChild2; beforeAll( async() => { // const{daoAddress:daoParent, pluginAddresses:pluginParent}=await createNewDAO(network,createDAOMetadata,[tokenVotingPluginSettings],parentEns); @@ -113,23 +118,55 @@ beforeAll( async() => { // const{daoAddress:daoChild2, pluginAddresses:pluginChild2}=await createNewDAO(network,createDAOMetadata,[multisigPluginSettings],childEns2); // daoAddressChild2 = daoChild2; // pluginAddressesChild2= pluginChild2; + // //--------------------------------------------- + // // Parent DAO Contract: 0x9A3aeeF82539a6c7F1A2bb712Fe11C4a6908e3BD + // // 0x1275caF82b4a1C6E1276Ab69C7f329BdbBD3510d + // // 0x01ec28d9Cdda4d96EcCFd88C1B532C50272a1CEa + // subAdminPluginChild1=await installSubDaoPlugin(childEns1, parentEns, network); + // console.log('subAdminPluginChild1 finished') + // subAdminPluginChild2=await installSubDaoPlugin(childEns2, parentEns, network); + // console.log('subAdminPluginChild2 finished') //--------------------------------------------- - // Parent DAO Contract: 0x9A3aeeF82539a6c7F1A2bb712Fe11C4a6908e3BD - // 0x1275caF82b4a1C6E1276Ab69C7f329BdbBD3510d - // 0x01ec28d9Cdda4d96EcCFd88C1B532C50272a1CEa - await installSubDaoPlugin('child1dao-1701257361998.dao.eth', 'parentdao-1701257361998.dao.eth', network); - await installSubDaoPlugin(childEns1, parentEns, network); - await installSubDaoPlugin(childEns2, parentEns, network); - //--------------------------------------------- - // const changeVotingClient = new ChangeVotingSettingClient(parentDAO, childDAO, subAdminPlugin, network); - // await changeVotingClient.initial(); + parentEns="parentdao-1701631131156.dao.eth" + childEns1="child1dao-1701631131156.dao.eth" + childEns2="child2dao-1701631131156.dao.eth" + subAdminPluginChild1="0xEAbeCe53a204ed38b4f865C5E8EA3590D01A65e0" + subAdminPluginChild2="0x797959cCa7A896DC61CCC5744510F7D76FAF1526" + + //--------------------------------------------- + changeVotingClientChild1 = new ChangeVotingSettingClient(parentEns, childEns1, subAdminPluginChild1, network); + await changeVotingClientChild1.initial(); + //--------------------------------------------- + changeVotingClientChild2 = new ChangeVotingSettingClient(parentEns, childEns2, subAdminPluginChild2, network); + await changeVotingClientChild2.initial(); }); describe('Testing SubDAO plugin', () => { test('Add new multisig admin', async () => { + const newMember="0x612A6506e7cdD093598D876d19c9e231737E72Be" + await changeVotingClientChild2.multisigAddAddresses([newMember]) + expect(await changeVotingClientChild2.isMember(newMember,MULTISIG_ABI)).toBe(true) + },100000); + test('time',async()=>{ + const timeout = 20000; + + // Use a promise to create a delay using setTimeout + const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + + // Perform some asynchronous operations or await some promises here + // For example, you can use "await" with asynchronous functions or promises + + // Wait for the specified time using the delay function + await delay(timeout); + + },100000); + test('Remove old multisig admin', async () => { + const oldMember="0x612A6506e7cdD093598D876d19c9e231737E72Be" + await changeVotingClientChild2.multisigRemoveAddresses([oldMember]) + expect(await changeVotingClientChild2.isMember(oldMember,MULTISIG_ABI)).toBe(false) + },100000); - },1000000); }); From 3cb2c977a97e98a0749d1949ca44c113d6d1c517 Mon Sep 17 00:00:00 2001 From: alikhabazian Date: Mon, 4 Dec 2023 12:37:00 +0330 Subject: [PATCH 3/4] add mint token test --- scripts/src/client/changeVotingSetting.ts | 13 +++++- scripts/src/test/SubDAOPlugin.test.ts | 57 +++++++++++++++-------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/scripts/src/client/changeVotingSetting.ts b/scripts/src/client/changeVotingSetting.ts index 97a3591..fedde5d 100644 --- a/scripts/src/client/changeVotingSetting.ts +++ b/scripts/src/client/changeVotingSetting.ts @@ -128,6 +128,17 @@ export class ChangeVotingSettingClient { } } + async balanceToken(address:string){ + const deployer=getWallet(); + const Contract=this.connectContract(deployer,this.votingToken,GovernanceERC20ABI); + try { + const result = await Contract["balanceOf"](address); + return result; + } catch (error) { + console.error('Error calling contract function:', error); + } + } + private async checkIsAnyRepetetive(newApprovers:string[],votingAbi:any){ for (let approver of newApprovers) { let isMember=await this.isMember(approver,votingAbi) @@ -272,7 +283,7 @@ export class ChangeVotingSettingClient { // parent porposal -> subdao plugin -> Token address const mintDaoAction: DaoAction[]=[] for (let indexOfApprovers in newApprovers){ - let encodedFunctionDataERC20=this.encodedFunctionData(GovernanceERC20ABI,'mint',[newApprovers[indexOfApprovers],amounts[indexOfApprovers]]) + let encodedFunctionDataERC20=this.encodedFunctionData(GovernanceERC20ABI,'mint',[newApprovers[indexOfApprovers],amounts[indexOfApprovers].toString()]) let daoActionToken:DaoAction={ to:this.votingToken, value:BigInt(0), diff --git a/scripts/src/test/SubDAOPlugin.test.ts b/scripts/src/test/SubDAOPlugin.test.ts index 3650daa..6aed48c 100644 --- a/scripts/src/test/SubDAOPlugin.test.ts +++ b/scripts/src/test/SubDAOPlugin.test.ts @@ -18,7 +18,7 @@ import { getWallet } from '../lib/helpers'; import { AllowedNetwork } from '../lib/constants'; const log = console.log; -import { ethers } from 'ethers'; +import {BigNumber, ethers} from 'ethers'; import { hexToBytes } from './../lib/helpers'; import {getVotingPluginAddress, installSubDaoPlugin} from './../client/installSubDAOPlugin'; import {createNewDAO} from "../client/newDao"; @@ -144,29 +144,46 @@ beforeAll( async() => { }); +async function delayToConfirm(time:number=20000){ + const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + await delay(time); +} + describe('Testing SubDAO plugin', () => { test('Add new multisig admin', async () => { - const newMember="0x612A6506e7cdD093598D876d19c9e231737E72Be" - await changeVotingClientChild2.multisigAddAddresses([newMember]) - expect(await changeVotingClientChild2.isMember(newMember,MULTISIG_ABI)).toBe(true) - },100000); - test('time',async()=>{ - const timeout = 20000; - - // Use a promise to create a delay using setTimeout - const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); - - // Perform some asynchronous operations or await some promises here - // For example, you can use "await" with asynchronous functions or promises - - // Wait for the specified time using the delay function - await delay(timeout); - + const newMembers=["0x612A6506e7cdD093598D876d19c9e231737E72Be"] + await changeVotingClientChild2.multisigAddAddresses(newMembers) + for (let newMember of newMembers){ + expect(await changeVotingClientChild2.isMember(newMember,MULTISIG_ABI)).toBe(true) + } + await delayToConfirm(); },100000); test('Remove old multisig admin', async () => { - const oldMember="0x612A6506e7cdD093598D876d19c9e231737E72Be" - await changeVotingClientChild2.multisigRemoveAddresses([oldMember]) - expect(await changeVotingClientChild2.isMember(oldMember,MULTISIG_ABI)).toBe(false) + const oldMembers=["0x612A6506e7cdD093598D876d19c9e231737E72Be"] + await changeVotingClientChild2.multisigRemoveAddresses(oldMembers) + for (let oldMember of oldMembers) { + expect(await changeVotingClientChild2.isMember(oldMember, MULTISIG_ABI)).toBe(false) + } + await delayToConfirm(); },100000); + test('Mint new token voting', async()=>{ + const newTokenHolders=["0x612A6506e7cdD093598D876d19c9e231737E72Be"] + const amountEach=[convertTODecimal(5,18)] + let oldBalances=[] + for (let holder of newTokenHolders) { + let balance=await changeVotingClientChild1.balanceToken(holder) + oldBalances.push(balance); + } + await changeVotingClientChild1.tokenVotingIncreaseAddressVotingPower(newTokenHolders,amountEach) + let newBalances=[] + for (let holder of newTokenHolders) { + let balance=await changeVotingClientChild1.balanceToken(holder) + newBalances.push(balance); + } + for (let indexNewBalance in newBalances) { + expect(newBalances[indexNewBalance].toBigInt().toString()).toBe((oldBalances[indexNewBalance].toBigInt()+BigInt(amountEach[indexNewBalance])).toString()) + } + + },100000); }); From 007d8e9228c5241b9c79bc809b73ca186ff06937 Mon Sep 17 00:00:00 2001 From: alikhabazian Date: Mon, 4 Dec 2023 12:49:23 +0330 Subject: [PATCH 4/4] edit readme for test scenarios --- README.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1c7c2c9..3c38e9f 100644 --- a/README.md +++ b/README.md @@ -82,6 +82,22 @@ bun changevotingsetting -c [CHILD_DAO_ADDRESS_OR_ENS] -p [PARENT_DAO_ADDRESS_OR_ENS] -n [NETWORK] -s [SUB_DAO_PLUGIN_ADDRESS] -f tokenVotingIncreaseAddressVotingPower '[NEW_MEMBER_ADDRESS_1,NEW_MEMBER_ADDRESS_2,...]' '[AMOUNT_1, AMOUNT_2,...]' ``` Replace `[NETWORK]`, `[CHILD_DAO_ADDRESS_OR_ENS]`, `[PARENT_DAO_ADDRESS_OR_ENS]`, `[SUB_DAO_PLUGIN_ADDRESS]`, `NEW_MEMBER_ADDRESS_$` and `AMOUNT_$` with the appropriate values for your setup. - +## ✅ Test Scenarios To understand how to interact with the contracts, navigate to the `./scripts/tests` directory. Each test script serves as a practical guide, providing real code examples for these operations. Make sure to read through these scripts to get a clear understanding of how to effectively use the Pattern SubDAO Plugin's contract functionalities. +To execute the tests, run the following command: +```bash + bun test + ``` +This test case encompasses the creation of a parent DAO and two child DAOs. The child DAOs are uniquely configured with distinct plugins: one child DAO is equipped with a Token Voting plugin, while the other has a Multisig plugin. + +Additionally, the test case involves installing the SubDAO plugin on the child DAOs, enabling them to be effectively managed by the parent DAO. + +1. **Add New Multisig Admin:** +This test case adds a new address as an admin to the Multisig plugin of one of the child DAOs. It ensures that the address is successfully added as a multisig admin. + +2. **Remove Old Multisig Admin:** + This test case removes an existing address from the admin list of the Multisig plugin in one of the child DAOs. It checks that the address is no longer a multisig admin after removal. + +3. **Mint New Token Voting:** + This test case mints new tokens for specified addresses in the Token Voting plugin of one of the child DAOs. It verifies that the balances of the specified addresses are updated accordingly. \ No newline at end of file