Skip to content

Commit

Permalink
Remove fractalAzoriusMasterCopyContract from AzoriusContracts, Fracta…
Browse files Browse the repository at this point in the history
…lContracts
  • Loading branch information
adamgall committed May 8, 2024
1 parent 9a9b0e5 commit ec6bbc5
Show file tree
Hide file tree
Showing 14 changed files with 219 additions and 220 deletions.
30 changes: 14 additions & 16 deletions src/components/pages/DaoHierarchy/useFetchNodes.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useQuery } from '@apollo/client';
import { useCallback, useEffect, useState } from 'react';
import { getAddress, zeroAddress } from 'viem';
import { getAddress, getContract, zeroAddress } from 'viem';
import { usePublicClient } from 'wagmi';
import { DAOQueryDocument } from '../../../../.graphclient';
import AzoriusAbi from '../../../assets/abi/Azorius';
import { logError } from '../../../helpers/errorLogging';
import { useFractalModules } from '../../../hooks/DAO/loaders/useFractalModules';
import { useAsyncRetry } from '../../../hooks/utils/useAsyncRetry';
Expand All @@ -23,6 +25,7 @@ export function useFetchNodes(address?: string) {
const { requestWithRetries } = useAsyncRetry();

const { subgraph } = useNetworkConfig();
const publicClient = usePublicClient();
const { data, error } = useQuery(DAOQueryDocument, {
variables: { daoAddress: address },
skip: address === safe?.address || !address, // If address === safe.address - we already have hierarchy obtained in the context
Expand All @@ -38,11 +41,8 @@ export function useFetchNodes(address?: string) {
const getDAOOwner = useCallback(
async (safeInfo?: Partial<SafeInfoResponseWithGuard>) => {
if (safeInfo && safeInfo.guard && baseContracts) {
const {
multisigFreezeGuardMasterCopyContract,
azoriusFreezeGuardMasterCopyContract,
fractalAzoriusMasterCopyContract,
} = baseContracts;
const { multisigFreezeGuardMasterCopyContract, azoriusFreezeGuardMasterCopyContract } =
baseContracts;
if (safeInfo.guard !== zeroAddress) {
const guard = multisigFreezeGuardMasterCopyContract.asProvider.attach(safeInfo.guard);
const guardOwner = await guard.owner();
Expand All @@ -53,15 +53,13 @@ export function useFetchNodes(address?: string) {
const modules = await lookupModules(safeInfo.modules || []);
if (!modules) return;
const azoriusModule = getAzoriusModuleFromModules(modules);
if (
azoriusModule &&
azoriusFreezeGuardMasterCopyContract &&
fractalAzoriusMasterCopyContract
) {
const azoriusContract = fractalAzoriusMasterCopyContract?.asProvider.attach(
azoriusModule.moduleAddress,
);
const azoriusGuardAddress = await azoriusContract.getGuard();
if (azoriusModule && azoriusFreezeGuardMasterCopyContract && publicClient) {
const azoriusContract = getContract({
abi: AzoriusAbi,
address: getAddress(azoriusModule.moduleAddress),
client: publicClient,
});
const azoriusGuardAddress = await azoriusContract.read.getGuard();
if (azoriusGuardAddress !== zeroAddress) {
const guard =
azoriusFreezeGuardMasterCopyContract.asProvider.attach(azoriusGuardAddress);
Expand All @@ -75,7 +73,7 @@ export function useFetchNodes(address?: string) {
}
return undefined;
},
[baseContracts, lookupModules],
[baseContracts, lookupModules, publicClient],
);

const fetchDAOInfo = useCallback(
Expand Down
24 changes: 14 additions & 10 deletions src/hooks/DAO/loaders/useFractalGuardContracts.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import {
Azorius,
AzoriusFreezeGuard,
MultisigFreezeGuard,
} from '@fractal-framework/fractal-contracts';
import { AzoriusFreezeGuard, MultisigFreezeGuard } from '@fractal-framework/fractal-contracts';
import { useCallback, useEffect, useRef } from 'react';
import { getAddress, zeroAddress } from 'viem';
import { getAddress, getContract, zeroAddress } from 'viem';
import { usePublicClient } from 'wagmi';
import AzoriusAbi from '../../../assets/abi/Azorius';
import { useFractal } from '../../../providers/App/AppProvider';
import { GuardContractAction } from '../../../providers/App/guardContracts/action';
import { useNetworkConfig } from '../../../providers/NetworkConfig/NetworkConfigProvider';
Expand All @@ -31,6 +29,8 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:

const { getZodiacModuleProxyMasterCopyData } = useMasterCopy();

const publicClient = usePublicClient();

const loadFractalGuardContracts = useCallback(
async (
_daoAddress: string,
Expand All @@ -52,9 +52,13 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
const azoriusModule = _fractalModules?.find(
module => module.moduleType === FractalModuleType.AZORIUS,
);
if (!!azoriusModule && azoriusModule.moduleContract) {
const azoriusGuardAddress = await (azoriusModule.moduleContract as Azorius).getGuard();

if (azoriusModule && publicClient) {
const azoriusContract = getContract({
abi: AzoriusAbi,
address: getAddress(azoriusModule.moduleAddress),
client: publicClient,
});
const azoriusGuardAddress = await azoriusContract.read.getGuard();
if (azoriusGuardAddress === zeroAddress) {
return {
freezeGuardContractAddress: '',
Expand Down Expand Up @@ -109,7 +113,7 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
};
}
},
[baseContracts, getZodiacModuleProxyMasterCopyData],
[baseContracts, getZodiacModuleProxyMasterCopyData, publicClient],
);

const setGuardContracts = useCallback(async () => {
Expand Down
17 changes: 3 additions & 14 deletions src/hooks/DAO/loaders/useFractalModules.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { useCallback } from 'react';
import { getAddress, getContract } from 'viem';
import { getAddress } from 'viem';
import { usePublicClient } from 'wagmi';
import FractalModuleAbi from '../../../assets/abi/FractalModule';
import { useFractal } from '../../../providers/App/AppProvider';
import { FractalModuleData, FractalModuleType } from '../../../types';
import { useMasterCopy } from '../../utils/useMasterCopy';

export const useFractalModules = () => {
const { baseContracts } = useFractal();
const { getZodiacModuleProxyMasterCopyData } = useMasterCopy();
const publicClient = usePublicClient();
const lookupModules = useCallback(
Expand All @@ -20,26 +17,18 @@ export const useFractalModules = () => {

let safeModule: FractalModuleData;

if (masterCopyData.isAzorius && baseContracts) {
if (masterCopyData.isAzorius && publicClient) {
safeModule = {
moduleContract:
baseContracts.fractalAzoriusMasterCopyContract.asSigner.attach(moduleAddress),
moduleAddress: moduleAddress,
moduleType: FractalModuleType.AZORIUS,
};
} else if (masterCopyData.isFractalModule && publicClient) {
safeModule = {
moduleContract: getContract({
abi: FractalModuleAbi,
address: getAddress(moduleAddress),
client: publicClient,
}),
moduleAddress: moduleAddress,
moduleType: FractalModuleType.FRACTAL,
};
} else {
safeModule = {
moduleContract: undefined,
moduleAddress: moduleAddress,
moduleType: FractalModuleType.UNKNOWN,
};
Expand All @@ -50,7 +39,7 @@ export const useFractalModules = () => {
);
return modules;
},
[baseContracts, getZodiacModuleProxyMasterCopyData, publicClient],
[getZodiacModuleProxyMasterCopyData, publicClient],
);
return lookupModules;
};
174 changes: 90 additions & 84 deletions src/hooks/DAO/loaders/useGovernanceContracts.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Azorius } from '@fractal-framework/fractal-contracts';
import { useCallback, useEffect, useRef } from 'react';
import { getContract, getAddress } from 'viem';
import { usePublicClient } from 'wagmi';
import AzoriusAbi from '../../../assets/abi/Azorius';
import LinearERC20VotingAbi from '../../../assets/abi/LinearERC20Voting';
import LockReleaseAbi from '../../../assets/abi/LockRelease';
import VotesERC20WrapperAbi from '../../../assets/abi/VotesERC20Wrapper';
Expand All @@ -28,96 +28,102 @@ export const useGovernanceContracts = () => {
}
const { fractalAzoriusMasterCopyContract } = baseContracts;
const azoriusModule = getAzoriusModuleFromModules(fractalModules);
const azoriusModuleContract = azoriusModule?.moduleContract as Azorius;

if (!!azoriusModuleContract) {
const azoriusContract = fractalAzoriusMasterCopyContract.asProvider.attach(
azoriusModuleContract.address,
);
let ozLinearVotingContractAddress: string | undefined;
let erc721LinearVotingContractAddress: string | undefined;
let votesTokenContractAddress: string | undefined;
let underlyingTokenAddress: string | undefined;
let lockReleaseContractAddress: string | undefined;

// @dev assumes the first strategy is the voting contract
const votingStrategyAddress = (await azoriusContract.getStrategies(SENTINEL_ADDRESS, 0))[1];

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

if (isOzLinearVoting) {
ozLinearVotingContractAddress = votingStrategyAddress;

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

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

underlyingTokenAddress = await possibleERC20Wrapper.read.underlying().catch(() => {
// if the underlying token is not an ERC20Wrapper, this will throw an error,
// so we catch it and return undefined
return undefined;
});
const possibleLockRelease = getContract({
address: getAddress(govTokenAddress),
abi: LockReleaseAbi,
client: { public: publicClient },
});

let lockedTokenAddress = undefined;
try {
lockedTokenAddress = await possibleLockRelease.read.token();
} catch {
// no-op
// if the underlying token is not an ERC20Wrapper, this will throw an error,
// so we catch it and do nothing
}

if (lockedTokenAddress) {
lockReleaseContractAddress = govTokenAddress;
// @dev if the underlying token is an ERC20Wrapper, we use the underlying token as the token contract
votesTokenContractAddress = lockedTokenAddress;
} else {
// @dev if the no underlying token, we use the governance token as the token contract
votesTokenContractAddress = govTokenAddress;
}
} else if (isOzLinearVotingERC721) {
// @dev for use with the ERC721 voting contract
erc721LinearVotingContractAddress = votingStrategyAddress;

if (!azoriusModule) {
action.dispatch({
type: GovernanceContractAction.SET_GOVERNANCE_CONTRACT,
payload: {},
});
return;
}

const azoriusModuleContract = getContract({
abi: AzoriusAbi,
address: getAddress(azoriusModule.moduleAddress),
client: publicClient,
});

const azoriusContract = fractalAzoriusMasterCopyContract.asProvider.attach(
azoriusModuleContract.address,
);
let ozLinearVotingContractAddress: string | undefined;
let erc721LinearVotingContractAddress: string | undefined;
let votesTokenContractAddress: string | undefined;
let underlyingTokenAddress: string | undefined;
let lockReleaseContractAddress: string | undefined;

// @dev assumes the first strategy is the voting contract
const votingStrategyAddress = (await azoriusContract.getStrategies(SENTINEL_ADDRESS, 0))[1];

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

if (isOzLinearVoting) {
ozLinearVotingContractAddress = votingStrategyAddress;

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

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

underlyingTokenAddress = await possibleERC20Wrapper.read.underlying().catch(() => {
// if the underlying token is not an ERC20Wrapper, this will throw an error,
// so we catch it and return undefined
return undefined;
});
const possibleLockRelease = getContract({
address: getAddress(govTokenAddress),
abi: LockReleaseAbi,
client: { public: publicClient },
});

let lockedTokenAddress = undefined;
try {
lockedTokenAddress = await possibleLockRelease.read.token();
} catch {
// no-op
// if the underlying token is not an ERC20Wrapper, this will throw an error,
// so we catch it and do nothing
}

if (votesTokenContractAddress || erc721LinearVotingContractAddress) {
action.dispatch({
type: GovernanceContractAction.SET_GOVERNANCE_CONTRACT,
payload: {
ozLinearVotingContractAddress,
erc721LinearVotingContractAddress,
azoriusContractAddress: azoriusModuleContract.address,
votesTokenContractAddress,
underlyingTokenAddress,
lockReleaseContractAddress,
},
});
if (lockedTokenAddress) {
lockReleaseContractAddress = govTokenAddress;
// @dev if the underlying token is an ERC20Wrapper, we use the underlying token as the token contract
votesTokenContractAddress = lockedTokenAddress;
} else {
// @dev if the no underlying token, we use the governance token as the token contract
votesTokenContractAddress = govTokenAddress;
}
// else this has no governance token and can be assumed is a multi-sig
} else {
} else if (isOzLinearVotingERC721) {
// @dev for use with the ERC721 voting contract
erc721LinearVotingContractAddress = votingStrategyAddress;
}

if (votesTokenContractAddress || erc721LinearVotingContractAddress) {
action.dispatch({
type: GovernanceContractAction.SET_GOVERNANCE_CONTRACT,
payload: {},
payload: {
ozLinearVotingContractAddress,
erc721LinearVotingContractAddress,
azoriusContractAddress: azoriusModuleContract.address,
votesTokenContractAddress,
underlyingTokenAddress,
lockReleaseContractAddress,
},
});
}
// else this has no governance token and can be assumed is a multi-sig
}, [action, getZodiacModuleProxyMasterCopyData, baseContracts, fractalModules, publicClient]);

useEffect(() => {
Expand Down
Loading

0 comments on commit ec6bbc5

Please sign in to comment.