From 23a6e999313400a484768e5c105e1cf928962a66 Mon Sep 17 00:00:00 2001 From: Ruggero Cino Date: Mon, 20 Jan 2025 16:06:26 +0100 Subject: [PATCH] Update App to deploy DAOs with OSx 1.4 and updated plugins --- .../createDaoDialog/utils/createDaoUtils.ts | 81 +++++++++++++------ .../utils/multisigInstallationAbi.ts | 20 +++++ .../utils/tokenInstallationAbi.ts | 40 +++++++++ .../transactions/transactionsService.ts | 20 ++--- src/utils/constants/api.ts | 2 +- 5 files changed, 130 insertions(+), 33 deletions(-) create mode 100644 src/containers/createDaoDialog/utils/multisigInstallationAbi.ts create mode 100644 src/containers/createDaoDialog/utils/tokenInstallationAbi.ts diff --git a/src/containers/createDaoDialog/utils/createDaoUtils.ts b/src/containers/createDaoDialog/utils/createDaoUtils.ts index 66ea4f01f..9498b6dba 100644 --- a/src/containers/createDaoDialog/utils/createDaoUtils.ts +++ b/src/containers/createDaoDialog/utils/createDaoUtils.ts @@ -1,16 +1,21 @@ import { DaoMetadata, - MultisigClient, - TokenVotingClient, TokenVotingPluginInstall, VotingMode, + votingSettingsToContract, } from '@aragon/sdk-client'; +import {AddressZero, HashZero} from '@ethersproject/constants'; import { DAORegistry__factory, PluginSetupProcessor__factory, } from '@aragon/osx-ethers'; -import {parseUnits} from 'ethers/lib/utils'; -import {PluginInstallItem} from '@aragon/sdk-client-common'; +import {defaultAbiCoder, parseUnits} from 'ethers/lib/utils'; +import { + getNamedTypesFromMetadata, + hexToBytes, + MetadataAbiInput, + PluginInstallItem, +} from '@aragon/sdk-client-common'; import {SupportedNetworks as SdkSupportedNetworks} from '@aragon/osx-commons-configs'; import { GaslessPluginVotingSettings, @@ -21,8 +26,12 @@ import {getSupportedNetworkByChainId} from 'utils/constants'; import {getSecondsFromDHM} from 'utils/date'; import {translateToNetworkishName} from 'utils/library'; import {CreateDaoFormData} from 'utils/types'; -import {TransactionReceipt} from 'viem'; +import {TransactionReceipt, zeroAddress} from 'viem'; import {id} from '@ethersproject/hash'; +import {multisigInstallationAbi} from './multisigInstallationAbi'; +import {ContractTokenVotingInitParams} from '@aragon/sdk-client/dist/tokenVoting/internal/types'; +import {BigNumber} from 'ethers'; +import {tokenInstallationAbi} from './tokenInstallationAbi'; class CreateDaoUtils { defaultTokenDecimals = 18; @@ -155,10 +164,9 @@ class CreateDaoUtils { private getTokenVotingPlugin = ( formValues: Omit ) => { - const {tokenType, isCustomToken, blockchain} = formValues; + const {tokenType, isCustomToken} = formValues; const votingSettings = this.getVoteSettings(formValues); - const network = this.networkToSdkNetwork(blockchain.id); const useExistingToken = (tokenType === 'governance-ERC20' || tokenType === 'ERC-20') && @@ -172,25 +180,23 @@ class CreateDaoUtils { params.newToken = this.getNewErc20PluginParams(formValues); } - const plugin = TokenVotingClient.encoding.getPluginInstallItem( - params, - network + const args = this.tokenVotingInitParamsToContract(params); + const hexBytes = defaultAbiCoder.encode( + getNamedTypesFromMetadata(tokenInstallationAbi as MetadataAbiInput[]), + [...args, {target: zeroAddress, operation: 0}, HashZero] ); - return plugin; + return { + data: hexToBytes(hexBytes), + id: '0x6241ad0D3f162028d2e0000f1A878DBc4F5c4aD0', + }; }; private getMultisigPlugin = ( formValues: Omit ) => { - const { - blockchain, - multisigWallets, - multisigMinimumApprovals, - eligibilityType, - } = formValues; - - const network = this.networkToSdkNetwork(blockchain.id); + const {multisigWallets, multisigMinimumApprovals, eligibilityType} = + formValues; const params = { members: multisigWallets.map(wallet => wallet.address), @@ -200,12 +206,20 @@ class CreateDaoUtils { }, }; - const multisigPlugin = MultisigClient.encoding.getPluginInstallItem( - params, - network + const hexBytes = defaultAbiCoder.encode( + getNamedTypesFromMetadata(multisigInstallationAbi as MetadataAbiInput[]), + [ + params.members, + [params.votingSettings.onlyListed, params.votingSettings.minApprovals], + {target: zeroAddress, operation: 0}, + HashZero, + ] ); - return multisigPlugin; + return { + data: hexToBytes(hexBytes), + id: '0xA0901B5BC6e04F14a9D0d094653E047644586DdE', + }; }; private getGasslessPlugin = ( @@ -307,6 +321,27 @@ class CreateDaoUtils { ); } }; + + private tokenVotingInitParamsToContract( + params: TokenVotingPluginInstall + ): ContractTokenVotingInitParams { + let token: [string, string, string] = ['', '', '']; + let balances: [string[], BigNumber[]] = [[], []]; + if (params.newToken) { + token = [AddressZero, params.newToken.name, params.newToken.symbol]; + balances = [ + params.newToken.balances.map(balance => balance.address), + params.newToken.balances.map(({balance}) => BigNumber.from(balance)), + ]; + } else if (params.useToken) { + token = [ + params.useToken?.tokenAddress, + params.useToken.wrappedToken.name, + params.useToken.wrappedToken.symbol, + ]; + } + return [votingSettingsToContract(params.votingSettings), token, balances]; + } } export const createDaoUtils = new CreateDaoUtils(); diff --git a/src/containers/createDaoDialog/utils/multisigInstallationAbi.ts b/src/containers/createDaoDialog/utils/multisigInstallationAbi.ts new file mode 100644 index 000000000..87aa94076 --- /dev/null +++ b/src/containers/createDaoDialog/utils/multisigInstallationAbi.ts @@ -0,0 +1,20 @@ +export const multisigInstallationAbi = [ + {name: 'members', type: 'address[]'}, + { + name: 'multisigSettings', + type: 'tuple', + components: [ + {name: 'onlyListed', type: 'bool'}, + {name: 'minApprovals', type: 'uint16'}, + ], + }, + { + name: 'targetConfig', + type: 'tuple', + components: [ + {name: 'target', type: 'address'}, + {name: 'operation', type: 'uint8'}, + ], + }, + {name: 'pluginMetadata', type: 'bytes'}, +]; diff --git a/src/containers/createDaoDialog/utils/tokenInstallationAbi.ts b/src/containers/createDaoDialog/utils/tokenInstallationAbi.ts new file mode 100644 index 000000000..62615598d --- /dev/null +++ b/src/containers/createDaoDialog/utils/tokenInstallationAbi.ts @@ -0,0 +1,40 @@ +export const tokenInstallationAbi = [ + { + name: 'votingSettings', + type: 'tuple', + components: [ + {name: 'votingMode', type: 'uint8'}, + {name: 'supportThreshold', type: 'uint32'}, + {name: 'minParticipation', type: 'uint32'}, + {name: 'minDuration', type: 'uint64'}, + {name: 'minProposerVotingPower', type: 'uint256'}, + ], + }, + { + name: 'tokenSettings', + type: 'tuple', + components: [ + {name: 'addr', type: 'address'}, + {name: 'name', type: 'string'}, + {name: 'symbol', type: 'string'}, + ], + }, + { + name: 'mintSettings', + type: 'tuple', + components: [ + {name: 'receivers', type: 'address[]'}, + {name: 'amounts', type: 'uint256[]'}, + ], + }, + { + name: 'targetConfig', + type: 'tuple', + components: [ + {name: 'target', type: 'address'}, + {name: 'operation', type: 'uint8'}, + ], + }, + {name: 'minApprovals', type: 'uint256'}, + {name: 'pluginMetadata', type: 'bytes'}, +]; diff --git a/src/services/transactions/transactionsService.ts b/src/services/transactions/transactionsService.ts index 7cbb5bd03..087052d61 100644 --- a/src/services/transactions/transactionsService.ts +++ b/src/services/transactions/transactionsService.ts @@ -1,9 +1,9 @@ import { DAOFactory, DAOFactory__factory, - PluginRepo__factory, TokenVoting__factory, Multisig__factory, + PluginRepo__factory, } from '@aragon/osx-ethers'; import {VocdoniVoting__factory} from '@vocdoni/gasless-voting-ethers'; import {toUtf8Bytes} from 'ethers/lib/utils'; @@ -21,7 +21,7 @@ import { import {ITransaction} from './domain/transaction'; import {decodeProposalId, hexToBytes} from '@aragon/sdk-client-common'; import {isMultisigClient, isTokenVotingClient} from 'hooks/usePluginClient'; -import {FrameworkContractsNames} from '@aragon/osx-commons-configs'; +// import {FrameworkContractsNames} from '@aragon/osx-commons-configs'; class TransactionsService { buildCreateDaoTransaction = async ( @@ -37,9 +37,9 @@ class TransactionsService { } = params; const signer = client.web3.getConnectedSigner(); - const daoFactoryAddress = client.web3.getAddress( - FrameworkContractsNames.DAO_FACTORY - ); + + //const daoFactoryAddress = client.web3.getAddress(FrameworkContractsNames.DAO_FACTORY); + const daoFactoryAddress = '0x20A8bDAbF02fcAca65CB799C0ed9CE4Ff25F3a90'; const daoFactoryInstance = DAOFactory__factory.connect( daoFactoryAddress, @@ -51,14 +51,16 @@ class TransactionsService { for (const plugin of plugins) { const repo = PluginRepo__factory.connect(plugin.id, signer); - const currentRelease = await repo.latestRelease(); - const latestVersion = - await repo['getLatestVersion(uint8)'](currentRelease); + // const currentRelease = await repo.latestRelease(); + // const latestVersion = + // await repo['getLatestVersion(uint8)'](currentRelease); + const latestVersion = {release: 1, build: 5}; pluginInstallationData.push({ pluginSetupRef: { pluginSetupRepo: repo.address, - versionTag: latestVersion.tag, + versionTag: latestVersion, + // versionTag: latestVersion.tag, }, data: plugin.data, }); diff --git a/src/utils/constants/api.ts b/src/utils/constants/api.ts index 8debc900a..4299eced3 100644 --- a/src/utils/constants/api.ts +++ b/src/utils/constants/api.ts @@ -32,7 +32,7 @@ export const SUBGRAPH_API_URL: SubgraphNetworkUrl = { polygon: 'https://subgraph.satsuma-prod.com/qHR2wGfc5RLi6/aragon/osx-polygon/version/1.4.2/api', sepolia: - 'https://subgraph.satsuma-prod.com/qHR2wGfc5RLi6/aragon/osx-sepolia/version/1.4.2/api', + 'https://subgraph.satsuma-prod.com/qHR2wGfc5RLi6/aragon/dev-sepolia/api', zksyncMainnet: 'https://subgraph.satsuma-prod.com/qHR2wGfc5RLi6/aragon/osx-zksync-era/version/1.4.3/api', zksyncSepolia: