Skip to content

Commit

Permalink
useVotingStrategyAddress now returns function which accepts optional …
Browse files Browse the repository at this point in the history
…safe address
  • Loading branch information
adamgall committed May 29, 2024
1 parent 55f4dea commit db4b339
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 45 deletions.
11 changes: 5 additions & 6 deletions src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ERC20FreezeVoting, MultisigFreezeVoting } from '@fractal-framework/frac
import { GearFine } from '@phosphor-icons/react';
import { useMemo, useCallback, useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { Address, getAddress } from 'viem';
import { Address } from 'viem';
import { DAO_ROUTES } from '../../../../constants/routes';
import {
isWithinFreezePeriod,
Expand Down Expand Up @@ -60,7 +60,7 @@ export function ManageDAOMenu({ parentAddress, freezeGuard, guardContracts }: IM
parentAddress,
childSafeInfo: node,
});
const votingContractAddress = useVotingStrategyAddress();
const { getVotingStrategyAddress } = useVotingStrategyAddress();

useEffect(() => {
const loadGovernanceType = async () => {
Expand All @@ -71,10 +71,9 @@ export function ManageDAOMenu({ parentAddress, freezeGuard, guardContracts }: IM
} else {
if (node?.fractalModules) {
let result = GovernanceType.MULTISIG;
const votingContractAddress = await getVotingStrategyAddress();
if (votingContractAddress) {
const masterCopyData = await getZodiacModuleProxyMasterCopyData(
getAddress(votingContractAddress),
);
const masterCopyData = await getZodiacModuleProxyMasterCopyData(votingContractAddress);

if (masterCopyData.isOzLinearVoting) {
result = GovernanceType.AZORIUS_ERC20;
Expand All @@ -90,12 +89,12 @@ export function ManageDAOMenu({ parentAddress, freezeGuard, guardContracts }: IM

loadGovernanceType();
}, [
getVotingStrategyAddress,
getZodiacModuleProxyMasterCopyData,
node?.fractalModules,
node.safe,
safeAddress,
type,
votingContractAddress,
]);
const { addressPrefix } = useNetworkConfig();

Expand Down
23 changes: 11 additions & 12 deletions src/hooks/DAO/loaders/useGovernanceContracts.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useCallback, useEffect, useRef } from 'react';
import { getContract, getAddress } from 'viem';
import { getContract, Address } from 'viem';
import { usePublicClient } from 'wagmi';
import LinearERC20VotingAbi from '../../../assets/abi/LinearERC20Voting';
import LockReleaseAbi from '../../../assets/abi/LockRelease';
Expand All @@ -19,7 +19,7 @@ export const useGovernanceContracts = () => {
const { getZodiacModuleProxyMasterCopyData } = useMasterCopy();
const publicClient = usePublicClient();

const votingStrategyAddress = useVotingStrategyAddress();
const { getVotingStrategyAddress } = useVotingStrategyAddress();

const { fractalModules, isModulesLoaded, daoAddress } = node;

Expand All @@ -29,6 +29,8 @@ export const useGovernanceContracts = () => {
}
const azoriusModule = getAzoriusModuleFromModules(fractalModules);

const votingStrategyAddress = await getVotingStrategyAddress();

if (!azoriusModule || !votingStrategyAddress) {
action.dispatch({
type: GovernanceContractAction.SET_GOVERNANCE_CONTRACT_ADDRESSES,
Expand All @@ -37,31 +39,28 @@ export const useGovernanceContracts = () => {
return;
}

let ozLinearVotingContractAddress: string | undefined;
let ozLinearVotingContractAddress: Address | undefined;
let erc721LinearVotingContractAddress: string | undefined;
let votesTokenContractAddress: string | undefined;
let underlyingTokenAddress: string | undefined;
let lockReleaseContractAddress: string | undefined;

const masterCopyData = await getZodiacModuleProxyMasterCopyData(
getAddress(votingStrategyAddress),
);
const isOzLinearVoting = masterCopyData.isOzLinearVoting;
const isOzLinearVotingERC721 = masterCopyData.isOzLinearVotingERC721;
const { isOzLinearVoting, isOzLinearVotingERC721 } =
await getZodiacModuleProxyMasterCopyData(votingStrategyAddress);

if (isOzLinearVoting) {
ozLinearVotingContractAddress = votingStrategyAddress;

const ozLinearVotingContract = getContract({
abi: LinearERC20VotingAbi,
address: getAddress(ozLinearVotingContractAddress),
address: ozLinearVotingContractAddress,
client: publicClient,
});
const govTokenAddress = await ozLinearVotingContract.read.governanceToken();

const possibleERC20Wrapper = getContract({
abi: VotesERC20WrapperAbi,
address: getAddress(govTokenAddress),
address: govTokenAddress,
client: publicClient,
});

Expand All @@ -71,7 +70,7 @@ export const useGovernanceContracts = () => {
return undefined;
});
const possibleLockRelease = getContract({
address: getAddress(govTokenAddress),
address: govTokenAddress,
abi: LockReleaseAbi,
client: { public: publicClient },
});
Expand Down Expand Up @@ -115,9 +114,9 @@ export const useGovernanceContracts = () => {
action,
baseContracts,
fractalModules,
getVotingStrategyAddress,
getZodiacModuleProxyMasterCopyData,
publicClient,
votingStrategyAddress,
]);

useEffect(() => {
Expand Down
12 changes: 6 additions & 6 deletions src/hooks/DAO/proposal/useSubmitProposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function useSubmitProposal() {
const { data: walletClient } = useWalletClient();
const publicClient = usePublicClient();

const votingContractAddress = useVotingStrategyAddress();
const { getVotingStrategyAddress } = useVotingStrategyAddress();

const {
node: { safe, fractalModules },
Expand Down Expand Up @@ -278,10 +278,11 @@ export default function useSubmitProposal() {

if (safeAddress && isAddress(safeAddress)) {
// Submitting proposal to any DAO out of global context
const votingStrategyAddress = await getVotingStrategyAddress(getAddress(safeAddress));
const safeInfo = await safeAPI.getSafeInfo(getAddress(safeAddress));
const modules = await lookupModules(safeInfo.modules);
const azoriusModule = getAzoriusModuleFromModules(modules);
if (!azoriusModule) {
if (!azoriusModule || !votingStrategyAddress) {
await submitMultisigProposal({
proposalData,
pendingToastMessage,
Expand All @@ -291,7 +292,7 @@ export default function useSubmitProposal() {
successCallback,
safeAddress,
});
} else if (walletClient && votingContractAddress) {
} else {
await submitAzoriusProposal({
proposalData,
pendingToastMessage,
Expand All @@ -301,7 +302,7 @@ export default function useSubmitProposal() {
successCallback,
safeAddress,
azoriusAddress: getAddress(azoriusModule.moduleAddress),
votingStrategyAddress: votingContractAddress,
votingStrategyAddress,
});
}
} else {
Expand Down Expand Up @@ -338,15 +339,14 @@ export default function useSubmitProposal() {
[
erc721LinearVotingContractAddress,
freezeVotingContractAddress,
getVotingStrategyAddress,
globalAzoriusContract,
lookupModules,
ozLinearVotingContractAddress,
safe?.address,
safeAPI,
submitAzoriusProposal,
submitMultisigProposal,
votingContractAddress,
walletClient,
],
);

Expand Down
10 changes: 5 additions & 5 deletions src/hooks/DAO/proposal/useUserERC721VotingTokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export default function useUserERC721VotingTokens(
const safeAPI = useSafeAPI();
const publicClient = usePublicClient();

const votingContractAddress = useVotingStrategyAddress();
const { getVotingStrategyAddress } = useVotingStrategyAddress();

const azoriusGovernance = governance as AzoriusGovernance;
const { erc721Tokens } = azoriusGovernance;
Expand Down Expand Up @@ -69,11 +69,11 @@ export default function useUserERC721VotingTokens(

if (_safeAddress && daoAddress !== _safeAddress) {
// Means getting these for any safe, primary use case - calculating user voting weight for freeze voting

if (votingContractAddress) {
const votingStrategyAddress = await getVotingStrategyAddress(getAddress(_safeAddress));
if (votingStrategyAddress) {
votingContract = getContract({
abi: LinearERC721VotingAbi,
address: getAddress(votingContractAddress),
address: votingStrategyAddress,
client: publicClient,
});
const addresses = await votingContract.read.getAllTokenAddresses();
Expand Down Expand Up @@ -204,11 +204,11 @@ export default function useUserERC721VotingTokens(
daoAddress,
erc721LinearVotingContractAddress,
erc721Tokens,
getVotingStrategyAddress,
publicClient,
safeAPI,
signerOrProvider,
user.address,
votingContractAddress,
],
);

Expand Down
9 changes: 5 additions & 4 deletions src/hooks/utils/useCanUserSubmitProposal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function useCanUserCreateProposal() {
const [canUserCreateProposal, setCanUserCreateProposal] = useState<boolean>();
const publicClient = usePublicClient();

const votingContractAddress = useVotingStrategyAddress();
const { getVotingStrategyAddress } = useVotingStrategyAddress();

/**
* Performs a check whether user has access rights to create proposal for DAO
Expand All @@ -38,10 +38,11 @@ export function useCanUserCreateProposal() {
};

if (safeAddress) {
if (votingContractAddress) {
const votingStrategyAddress = await getVotingStrategyAddress(getAddress(safeAddress));
if (votingStrategyAddress) {
const votingContract = getContract({
abi: LinearERC20VotingAbi,
address: getAddress(votingContractAddress),
address: votingStrategyAddress,
client: publicClient,
});
const isProposer = await votingContract.read.isProposer([getAddress(user.address)]);
Expand Down Expand Up @@ -78,13 +79,13 @@ export function useCanUserCreateProposal() {
},
[
erc721LinearVotingContractAddress,
getVotingStrategyAddress,
ozLinearVotingContractAddress,
publicClient,
safe,
safeAPI,
type,
user.address,
votingContractAddress,
],
);
useEffect(() => {
Expand Down
41 changes: 29 additions & 12 deletions src/hooks/utils/useVotingStrategyAddress.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,40 @@
import { useEffect, useState } from 'react';
import { Address, getAddress, getContract } from 'viem';
import { usePublicClient } from 'wagmi';
import AzoriusAbi from '../../assets/abi/Azorius';
import { SENTINEL_ADDRESS } from '../../constants/common';
import { useFractal } from '../../providers/App/AppProvider';
import { useSafeAPI } from '../../providers/App/hooks/useSafeAPI';
import { FractalModuleData } from '../../types';
import { getAzoriusModuleFromModules } from '../../utils';
import { useFractalModules } from '../DAO/loaders/useFractalModules';

const useVotingStrategyAddress = () => {
const [votingStrategyAddress, setVotingStrategyAddress] = useState<Address>();

const { node } = useFractal();
const publicClient = usePublicClient();
const safeAPI = useSafeAPI();
const lookupModules = useFractalModules();

const getVotingStrategyAddress = async (safeAddress?: Address) => {
let azoriusModule: FractalModuleData | undefined;

if (safeAddress) {
if (!safeAPI) {
throw new Error('Safe API not ready');
}
const safeInfo = await safeAPI.getSafeInfo(getAddress(safeAddress));
const safeModules = await lookupModules(safeInfo.modules);
azoriusModule = getAzoriusModuleFromModules(safeModules);
if (!azoriusModule) return;
} else {
azoriusModule = getAzoriusModuleFromModules(node.fractalModules);
}

useEffect(() => {
const azoriusModule = getAzoriusModuleFromModules(node.fractalModules);
if (!azoriusModule) {
throw new Error('Azorius module not found');
}

if (!azoriusModule || !publicClient) {
return;
if (!publicClient) {
throw new Error('Public client undefined');
}

const azoriusContract = getContract({
Expand All @@ -26,12 +44,11 @@ const useVotingStrategyAddress = () => {
});

// @dev assumes the first strategy is the voting contract
azoriusContract.read.getStrategies([SENTINEL_ADDRESS, 0n]).then(strategies => {
setVotingStrategyAddress(strategies[1]);
});
}, [node.fractalModules, publicClient]);
const strategies = await azoriusContract.read.getStrategies([SENTINEL_ADDRESS, 0n]);
return strategies[1];
};

return votingStrategyAddress;
return { getVotingStrategyAddress };
};

export default useVotingStrategyAddress;

0 comments on commit db4b339

Please sign in to comment.