Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
56 changes: 40 additions & 16 deletions scripts/src/client/changeVotingSetting.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
Expand All @@ -137,18 +148,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);
}

}

Expand All @@ -172,7 +197,6 @@ export class ChangeVotingSettingClient {
data: hexToBytes(encodedFunctionDataMultisig),
},
];

const encodedFunctionDataSubDAOAdmin=this.encodedFunctionData(SUB_DAO_ADMIN_ABI,'execute',[updateVotingSettingDaoAction])
const executeSubDAOAdminDaoAction: DaoAction[] = [
{
Expand Down Expand Up @@ -259,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),
Expand Down
1 change: 1 addition & 0 deletions scripts/src/client/installSubDAOPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ProposalCreationStepValue, any, unknown>) {
Expand Down
2 changes: 1 addition & 1 deletion scripts/src/client/newDao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading