From b81091e016516eb4a36d849ebc63459a92706fea Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Tue, 7 May 2024 19:22:46 -0400 Subject: [PATCH] Remove the safeSingletonContract property from FractalContracts and BaseContracts interfaces --- .../components/Signers/hooks/useAddSigner.ts | 17 +++++++------- .../Signers/hooks/useRemoveSigner.ts | 17 ++++++-------- src/hooks/DAO/useBuildDAOTx.ts | 5 +++-- src/hooks/DAO/useDeployAzorius.ts | 22 +++++++++---------- src/models/TxBuilderFactory.ts | 11 +++++++++- src/models/helpers/safeData.ts | 10 +++------ src/types/contract.ts | 2 -- src/types/fractal.ts | 2 -- 8 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/components/pages/DaoSettings/components/Signers/hooks/useAddSigner.ts b/src/components/pages/DaoSettings/components/Signers/hooks/useAddSigner.ts index fe17b479de..ca8c517167 100644 --- a/src/components/pages/DaoSettings/components/Signers/hooks/useAddSigner.ts +++ b/src/components/pages/DaoSettings/components/Signers/hooks/useAddSigner.ts @@ -1,6 +1,7 @@ import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { getAddress, isHex } from 'viem'; +import { encodeFunctionData, getAddress } from 'viem'; +import GnosisSafeL2Abi from '../../../../../../assets/abi/GnosisSafeL2'; import useSubmitProposal from '../../../../../../hooks/DAO/proposal/useSubmitProposal'; import { useFractal } from '../../../../../../providers/App/AppProvider'; import { ProposalExecuteData } from '../../../../../../types'; @@ -26,16 +27,14 @@ const useAddSigner = () => { if (!baseContracts || !daoAddress) { return; } - const { safeSingletonContract } = baseContracts; const description = 'Add Signer'; - const encodedAddOwner = safeSingletonContract.asSigner.interface.encodeFunctionData( - 'addOwnerWithThreshold', - [newSigner, BigInt(threshold)], - ); - if (!isHex(encodedAddOwner)) { - return; - } + const encodedAddOwner = encodeFunctionData({ + abi: GnosisSafeL2Abi, + functionName: 'addOwnerWithThreshold', + args: [getAddress(newSigner), BigInt(threshold)], + }); + const calldatas = [encodedAddOwner]; const proposalData: ProposalExecuteData = { diff --git a/src/components/pages/DaoSettings/components/Signers/hooks/useRemoveSigner.ts b/src/components/pages/DaoSettings/components/Signers/hooks/useRemoveSigner.ts index c18d402e35..69aeeb4ec1 100644 --- a/src/components/pages/DaoSettings/components/Signers/hooks/useRemoveSigner.ts +++ b/src/components/pages/DaoSettings/components/Signers/hooks/useRemoveSigner.ts @@ -1,6 +1,7 @@ import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { isHex, getAddress } from 'viem'; +import { getAddress, encodeFunctionData } from 'viem'; +import GnosisSafeL2Abi from '../../../../../../assets/abi/GnosisSafeL2'; import useSubmitProposal from '../../../../../../hooks/DAO/proposal/useSubmitProposal'; import { useFractal } from '../../../../../../providers/App/AppProvider'; import { ProposalExecuteData } from '../../../../../../types'; @@ -26,17 +27,13 @@ const useRemoveSigner = ({ if (!baseContracts || !daoAddress) { return; } - const { safeSingletonContract } = baseContracts; const description = 'Remove Signers'; - const encodedRemoveOwner = safeSingletonContract.asProvider.interface.encodeFunctionData( - 'removeOwner', - [prevSigner, signerToRemove, BigInt(threshold)], - ); - - if (!isHex(encodedRemoveOwner)) { - return; - } + const encodedRemoveOwner = encodeFunctionData({ + abi: GnosisSafeL2Abi, + functionName: 'removeOwner', + args: [getAddress(prevSigner), getAddress(signerToRemove), BigInt(threshold)], + }); const calldatas = [encodedRemoveOwner]; diff --git a/src/hooks/DAO/useBuildDAOTx.ts b/src/hooks/DAO/useBuildDAOTx.ts index d244a69cd2..4adee1de2e 100644 --- a/src/hooks/DAO/useBuildDAOTx.ts +++ b/src/hooks/DAO/useBuildDAOTx.ts @@ -26,6 +26,7 @@ const useBuildDAOTx = () => { keyValuePairs, fractalRegistry, safeFactory, + safe: safeSingleton, zodiacModuleProxyFactory, }, } = useNetworkConfig(); @@ -51,7 +52,6 @@ const useBuildDAOTx = () => { } const { multiSendContract, - safeSingletonContract, linearVotingMasterCopyContract, linearVotingERC721MasterCopyContract, fractalAzoriusMasterCopyContract, @@ -94,7 +94,6 @@ const useBuildDAOTx = () => { const buildrerBaseContracts: BaseContracts = { fractalModuleMasterCopyContract: fractalModuleMasterCopyContract.asSigner, - safeSingletonContract: safeSingletonContract.asSigner, multisigFreezeGuardMasterCopyContract: multisigFreezeGuardMasterCopyContract.asSigner, multiSendContract: multiSendContract.asSigner, freezeERC20VotingMasterCopyContract: freezeERC20VotingMasterCopyContract.asSigner, @@ -114,6 +113,7 @@ const useBuildDAOTx = () => { keyValuePairs, fractalRegistry, safeFactory, + safeSingleton, zodiacModuleProxyFactory, parentAddress, parentTokenAddress, @@ -167,6 +167,7 @@ const useBuildDAOTx = () => { keyValuePairs, fractalRegistry, safeFactory, + safeSingleton, zodiacModuleProxyFactory, ], ); diff --git a/src/hooks/DAO/useDeployAzorius.ts b/src/hooks/DAO/useDeployAzorius.ts index 70ac1dc968..adca323709 100644 --- a/src/hooks/DAO/useDeployAzorius.ts +++ b/src/hooks/DAO/useDeployAzorius.ts @@ -1,8 +1,9 @@ import { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import { useNavigate } from 'react-router-dom'; -import { getAddress, isHex } from 'viem'; +import { encodeFunctionData, getAddress, isHex } from 'viem'; import { usePublicClient } from 'wagmi'; +import GnosisSafeL2Abi from '../../assets/abi/GnosisSafeL2'; import { DAO_ROUTES } from '../../constants/routes'; import { TxBuilderFactory } from '../../models/TxBuilderFactory'; import { useFractal } from '../../providers/App/AppProvider'; @@ -29,6 +30,7 @@ const useDeployAzorius = () => { keyValuePairs, fractalRegistry, safeFactory, + safe: safeSingleton, zodiacModuleProxyFactory, }, addressPrefix, @@ -54,7 +56,6 @@ const useDeployAzorius = () => { } const { multiSendContract, - safeSingletonContract, linearVotingMasterCopyContract, linearVotingERC721MasterCopyContract, fractalAzoriusMasterCopyContract, @@ -78,7 +79,6 @@ const useDeployAzorius = () => { const builderBaseContracts: BaseContracts = { fractalModuleMasterCopyContract: fractalModuleMasterCopyContract.asProvider, - safeSingletonContract: safeSingletonContract.asProvider, multisigFreezeGuardMasterCopyContract: multisigFreezeGuardMasterCopyContract.asProvider, multiSendContract: multiSendContract.asProvider, freezeERC20VotingMasterCopyContract: freezeERC20VotingMasterCopyContract.asProvider, @@ -98,6 +98,7 @@ const useDeployAzorius = () => { keyValuePairs, fractalRegistry, safeFactory, + safeSingleton, zodiacModuleProxyFactory, undefined, undefined, @@ -110,14 +111,12 @@ const useDeployAzorius = () => { owners: safe.owners, }); - const encodedAddOwnerWithThreshold = - safeSingletonContract.asProvider.interface.encodeFunctionData('addOwnerWithThreshold', [ - multiSendContract.asProvider.address, - 1, - ]); - if (!isHex(encodedAddOwnerWithThreshold)) { - return; - } + const encodedAddOwnerWithThreshold = encodeFunctionData({ + abi: GnosisSafeL2Abi, + functionName: 'addOwnerWithThreshold', + args: [getAddress(multiSendContract.asProvider.address), 1n], + }); + const encodedMultisend = multiSendContract.asProvider.interface.encodeFunctionData( 'multiSend', [safeTx], @@ -162,6 +161,7 @@ const useDeployAzorius = () => { keyValuePairs, fractalRegistry, safeFactory, + safeSingleton, zodiacModuleProxyFactory, ], ); diff --git a/src/models/TxBuilderFactory.ts b/src/models/TxBuilderFactory.ts index 37c89b58de..d03b807133 100644 --- a/src/models/TxBuilderFactory.ts +++ b/src/models/TxBuilderFactory.ts @@ -1,5 +1,6 @@ import { ethers } from 'ethers'; import { PublicClient, getAddress, getContract } from 'viem'; +import GnosisSafeL2Abi from '../assets/abi/GnosisSafeL2'; import GnosisSafeProxyFactoryAbi from '../assets/abi/GnosisSafeProxyFactory'; import { GnosisSafeL2 } from '../assets/typechain-types/usul/@gnosis.pm/safe-contracts/contracts'; import { GnosisSafeL2__factory } from '../assets/typechain-types/usul/factories/@gnosis.pm/safe-contracts/contracts'; @@ -35,6 +36,7 @@ export class TxBuilderFactory extends BaseTxBuilder { private keyValuePairsAddress: string; private fractalRegistryAddress: string; private gnosisSafeProxyFactoryAddress: string; + private gnosisSafeSingletonAddress: string; private moduleProxyFactoryAddress: string; constructor( @@ -49,6 +51,7 @@ export class TxBuilderFactory extends BaseTxBuilder { keyValuePairsAddress: string, fractalRegistryAddress: string, gnosisSafeProxyFactoryAddress: string, + gnosisSafeSingletonAddress: string, moduleProxyFactoryAddress: string, parentAddress?: string, parentTokenAddress?: string, @@ -70,6 +73,7 @@ export class TxBuilderFactory extends BaseTxBuilder { this.keyValuePairsAddress = keyValuePairsAddress; this.fractalRegistryAddress = fractalRegistryAddress; this.gnosisSafeProxyFactoryAddress = gnosisSafeProxyFactoryAddress; + this.gnosisSafeSingletonAddress = gnosisSafeSingletonAddress; this.moduleProxyFactoryAddress = moduleProxyFactoryAddress; } @@ -84,10 +88,15 @@ export class TxBuilderFactory extends BaseTxBuilder { address: getAddress(this.gnosisSafeProxyFactoryAddress), client: this.publicClient, }); + const safeSingletonContract = getContract({ + abi: GnosisSafeL2Abi, + address: getAddress(this.gnosisSafeSingletonAddress), + client: this.publicClient, + }); const { predictedSafeAddress, createSafeTx } = await safeData( this.baseContracts.multiSendContract, safeProxyFactoryContract, - this.baseContracts.safeSingletonContract, + safeSingletonContract, this.daoData as SafeMultisigDAO, this.saltNum, this.fallbackHandler, diff --git a/src/models/helpers/safeData.ts b/src/models/helpers/safeData.ts index 471031b154..ec976ea0bc 100644 --- a/src/models/helpers/safeData.ts +++ b/src/models/helpers/safeData.ts @@ -14,14 +14,13 @@ import { import GnosisSafeL2Abi from '../../assets/abi/GnosisSafeL2'; import GnosisSafeProxyFactoryAbi from '../../assets/abi/GnosisSafeProxyFactory'; import { MultiSend } from '../../assets/typechain-types/usul'; -import { GnosisSafeL2 } from '../../assets/typechain-types/usul/@gnosis.pm/safe-contracts/contracts'; import { buildContractCallViem } from '../../helpers/crypto'; import { SafeMultisigDAO } from '../../types'; export const safeData = async ( multiSendContract: MultiSend, safeFactoryContract: GetContractReturnType, - safeSingletonContract: GnosisSafeL2, + safeSingletonContract: GetContractReturnType, daoData: SafeMultisigDAO, saltNum: bigint, fallbackHandler: string, @@ -52,7 +51,7 @@ export const safeData = async ( } const predictedSafeAddress = getCreate2Address({ - from: getAddress(safeFactoryContract.address), + from: safeFactoryContract.address, salt: keccak256( encodePacked( ['bytes', 'uint256'], @@ -62,10 +61,7 @@ export const safeData = async ( bytecodeHash: keccak256( encodePacked( ['bytes', 'uint256'], - [ - safeFactoryContractProxyCreationCode, - hexToBigInt(getAddress(safeSingletonContract.address)), - ], + [safeFactoryContractProxyCreationCode, hexToBigInt(safeSingletonContract.address)], ), ), }); diff --git a/src/types/contract.ts b/src/types/contract.ts index aca182226e..e349da571a 100644 --- a/src/types/contract.ts +++ b/src/types/contract.ts @@ -6,7 +6,6 @@ import { ERC721FreezeVoting, } from '@fractal-framework/fractal-contracts'; import { MultiSend } from '../assets/typechain-types/usul'; -import { GnosisSafeL2 } from '../assets/typechain-types/usul/@gnosis.pm/safe-contracts/contracts'; export interface ContractEvent { blockTimestamp: number; @@ -19,7 +18,6 @@ export type ContractConnection = { export interface BaseContracts { fractalModuleMasterCopyContract: FractalModule; - safeSingletonContract: GnosisSafeL2; multisigFreezeGuardMasterCopyContract: MultisigFreezeGuard; multiSendContract: MultiSend; freezeERC20VotingMasterCopyContract: ERC20FreezeVoting; diff --git a/src/types/fractal.ts b/src/types/fractal.ts index f1cbd99e7a..b951e736f9 100644 --- a/src/types/fractal.ts +++ b/src/types/fractal.ts @@ -20,7 +20,6 @@ import { import { Dispatch } from 'react'; import { Address } from 'viem'; import { MultiSend } from '../assets/typechain-types/usul'; -import { GnosisSafeL2 } from '../assets/typechain-types/usul/@gnosis.pm/safe-contracts/contracts'; import { FractalGovernanceActions } from '../providers/App/governance/action'; import { GovernanceContractActions } from '../providers/App/governanceContracts/action'; import { FractalGuardActions } from '../providers/App/guard/action'; @@ -332,7 +331,6 @@ export interface FractalContracts { fractalAzoriusMasterCopyContract: ContractConnection; linearVotingMasterCopyContract: ContractConnection; linearVotingERC721MasterCopyContract: ContractConnection; - safeSingletonContract: ContractConnection; fractalModuleMasterCopyContract: ContractConnection; multisigFreezeGuardMasterCopyContract: ContractConnection; azoriusFreezeGuardMasterCopyContract: ContractConnection;