From dc067c81f85683a7cdad97052ad65cfc33b72279 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 02:33:45 -0400
Subject: [PATCH 01/30] remove freeze guard and freeze voting from state
---
.../MultisigProposalDetails/TxActions.tsx | 18 ++--
.../MultisigProposalDetails/index.tsx | 9 +-
src/components/Proposals/index.tsx | 4 +-
.../DaoDashboard/Info/InfoGovernance.tsx | 17 ++--
.../DaoSettings/components/Modules/index.tsx | 6 +-
.../ui/menus/ManageDAO/ManageDAOMenu.tsx | 24 ++---
.../ui/proposal/useProposalCountdown.tsx | 15 ++-
src/hooks/DAO/loaders/useFractalFreeze.ts | 96 +++++++++++--------
src/hooks/DAO/loaders/useFractalGovernance.ts | 4 +-
src/hooks/DAO/proposal/useSubmitProposal.ts | 6 +-
src/hooks/DAO/useCastFreezeVote.ts | 28 +++---
src/hooks/utils/useSafeTransactions.ts | 12 ++-
src/providers/App/guardContracts/reducer.ts | 4 +-
src/types/fractal.ts | 13 +--
14 files changed, 137 insertions(+), 119 deletions(-)
diff --git a/src/components/Proposals/MultisigProposalDetails/TxActions.tsx b/src/components/Proposals/MultisigProposalDetails/TxActions.tsx
index 9a3b96255e..30cd4ec77a 100644
--- a/src/components/Proposals/MultisigProposalDetails/TxActions.tsx
+++ b/src/components/Proposals/MultisigProposalDetails/TxActions.tsx
@@ -1,7 +1,6 @@
import { Box, Button, Text, Flex } from '@chakra-ui/react';
import { Check } from '@decent-org/fractal-ui';
import { TypedDataSigner } from '@ethersproject/abstract-signer';
-import { MultisigFreezeGuard } from '@fractal-framework/fractal-contracts';
import { SafeMultisigTransactionWithTransfersResponse } from '@safe-global/safe-service-client';
import { Signer } from 'ethers';
import { useTranslation } from 'react-i18next';
@@ -10,6 +9,7 @@ import { BACKGROUND_SEMI_TRANSPARENT } from '../../../constants/common';
import { buildSafeTransaction, buildSignatureBytes, EIP712_SAFE_TX_TYPE } from '../../../helpers';
import { logError } from '../../../helpers/errorLogging';
import { useSafeMultisigProposals } from '../../../hooks/DAO/loaders/governance/useSafeMultisigProposals';
+import useSafeContracts from '../../../hooks/safe/useSafeContracts';
import { useAsyncRequest } from '../../../hooks/utils/useAsyncRequest';
import useSignerOrProvider from '../../../hooks/utils/useSignerOrProvider';
import { useTransaction } from '../../../hooks/utils/useTransaction';
@@ -20,15 +20,10 @@ import { MultisigProposal, FractalProposalState } from '../../../types';
import ContentBox from '../../ui/containers/ContentBox';
import { ProposalCountdown } from '../../ui/proposal/ProposalCountdown';
-export function TxActions({
- proposal,
- freezeGuard,
-}: {
- proposal: MultisigProposal;
- freezeGuard: MultisigFreezeGuard;
-}) {
+export function TxActions({ proposal }: { proposal: MultisigProposal }) {
const {
node: { safe },
+ guardContracts: { freezeGuardContractAddress },
readOnly: { user },
} = useFractal();
const signerOrProvider = useSignerOrProvider();
@@ -40,7 +35,7 @@ export function TxActions({
const [asyncRequest, asyncRequestPending] = useAsyncRequest();
const [contractCall, contractCallPending] = useTransaction();
const loadSafeMultisigProposals = useSafeMultisigProposals();
-
+ const baseContracts = useSafeContracts();
if (user.votingWeight.eq(0)) return <>>;
const multisigTx = proposal.transaction as SafeMultisigTransactionWithTransfersResponse;
@@ -78,7 +73,7 @@ export function TxActions({
const timelockTransaction = async () => {
try {
- if (!multisigTx.confirmations) {
+ if (!multisigTx.confirmations || !baseContracts || !freezeGuardContractAddress) {
return;
}
const safeTx = buildSafeTransaction({
@@ -90,6 +85,9 @@ export function TxActions({
data: confirmation.signature,
})),
);
+ const freezeGuard = baseContracts.multisigFreezeGuardMasterCopyContract.asSigner.attach(
+ freezeGuardContractAddress,
+ );
contractCall({
contractFn: () =>
freezeGuard.timelockTransaction(
diff --git a/src/components/Proposals/MultisigProposalDetails/index.tsx b/src/components/Proposals/MultisigProposalDetails/index.tsx
index 5b2b1a37df..29a02ac73b 100644
--- a/src/components/Proposals/MultisigProposalDetails/index.tsx
+++ b/src/components/Proposals/MultisigProposalDetails/index.tsx
@@ -1,5 +1,4 @@
import { GridItem, Box } from '@chakra-ui/react';
-import { MultisigFreezeGuard } from '@fractal-framework/fractal-contracts';
import { BACKGROUND_SEMI_TRANSPARENT } from '../../../constants/common';
import { useFractal } from '../../../providers/App/AppProvider';
import { FractalProposal, MultisigProposal } from '../../../types';
@@ -14,7 +13,6 @@ import { TxDetails } from './TxDetails';
export function MultisigProposalDetails({ proposal }: { proposal: FractalProposal }) {
const txProposal = proposal as MultisigProposal;
const {
- guardContracts: { freezeGuardContract },
readOnly: { user },
} = useFractal();
return (
@@ -30,12 +28,7 @@ export function MultisigProposalDetails({ proposal }: { proposal: FractalProposa
- {user.address && (
-
- )}
+ {user.address && }
);
diff --git a/src/components/Proposals/index.tsx b/src/components/Proposals/index.tsx
index bc99f9488d..f324ce185e 100644
--- a/src/components/Proposals/index.tsx
+++ b/src/components/Proposals/index.tsx
@@ -65,7 +65,7 @@ export default function Proposals() {
break;
case GovernanceType.MULTISIG:
default:
- if (guardContracts.freezeGuardContract) {
+ if (guardContracts.freezeGuardContractAddress) {
options = FILTERS_MULTISIG_CHILD;
} else {
options = FILTERS_MULTISIG_BASE;
@@ -77,7 +77,7 @@ export default function Proposals() {
}
setAllOptions(options);
setFilters(options);
- }, [daoSnapshotURL, guardContracts.freezeGuardContract, type]);
+ }, [daoSnapshotURL, guardContracts.freezeGuardContractAddress, type]);
const toggleFilter = (filter: FractalProposalState) => {
setFilters(prevState => {
diff --git a/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx b/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
index 611b02fbad..20bb18f4c9 100644
--- a/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
+++ b/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
@@ -1,8 +1,8 @@
import { Box, Flex, Text } from '@chakra-ui/react';
import { Govern } from '@decent-org/fractal-ui';
-import { MultisigFreezeGuard } from '@fractal-framework/fractal-contracts';
import { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
+import useSafeContracts from '../../../../hooks/safe/useSafeContracts';
import { useTimeHelpers } from '../../../../hooks/utils/useTimeHelpers';
import { useFractal } from '../../../../providers/App/AppProvider';
import { useEthersProvider } from '../../../../providers/Ethers/hooks/useEthersProvider';
@@ -15,11 +15,12 @@ export function InfoGovernance() {
const {
node: { daoAddress },
governance,
- guardContracts: { freezeGuardType, freezeGuardContract },
+ guardContracts: { freezeGuardType, freezeGuardContractAddress },
readOnly: { dao },
} = useFractal();
const provider = useEthersProvider();
const { getTimeDuration } = useTimeHelpers();
+ const baseContracts = useSafeContracts();
const [timelockPeriod, setTimelockPeriod] = useState();
const [executionPeriod, setExecutionPeriod] = useState();
useEffect(() => {
@@ -30,10 +31,11 @@ export function InfoGovernance() {
}
};
if (freezeGuardType == FreezeGuardType.MULTISIG) {
- if (freezeGuardContract) {
- const freezeGuard = freezeGuardContract.asProvider as MultisigFreezeGuard;
- setTimelockPeriod(await formatBlocks(await freezeGuard.timelockPeriod()));
- setExecutionPeriod(await formatBlocks(await freezeGuard.executionPeriod()));
+ if (freezeGuardContractAddress && baseContracts) {
+ const freezeGuardContract =
+ baseContracts.multisigFreezeGuardMasterCopyContract.asProvider;
+ setTimelockPeriod(await formatBlocks(await freezeGuardContract.timelockPeriod()));
+ setExecutionPeriod(await formatBlocks(await freezeGuardContract.executionPeriod()));
}
} else if (dao?.isAzorius) {
const azoriusGovernance = governance as AzoriusGovernance;
@@ -54,10 +56,11 @@ export function InfoGovernance() {
setTimelockInfo();
}, [
+ baseContracts,
executionPeriod,
getTimeDuration,
governance,
- freezeGuardContract,
+ freezeGuardContractAddress,
freezeGuardType,
provider,
timelockPeriod,
diff --git a/src/components/pages/DaoSettings/components/Modules/index.tsx b/src/components/pages/DaoSettings/components/Modules/index.tsx
index 1f5cd5c3a3..0b6479813b 100644
--- a/src/components/pages/DaoSettings/components/Modules/index.tsx
+++ b/src/components/pages/DaoSettings/components/Modules/index.tsx
@@ -26,7 +26,7 @@ export function ModulesContainer() {
const { t } = useTranslation(['settings']);
const {
node: { fractalModules, isModulesLoaded, safe },
- guardContracts: { freezeGuardContract, freezeVotingContract },
+ guardContracts: { freezeGuardContractAddress, freezeVotingContractAddress },
} = useFractal();
return (
@@ -91,7 +91,9 @@ export function ModulesContainer() {
{safe.guard}
- {!!freezeGuardContract || !!freezeVotingContract ? ' (Freeze Guard)' : ''}
+ {!!freezeGuardContractAddress || !!freezeVotingContractAddress
+ ? ' (Freeze Guard)'
+ : ''}
) : (
diff --git a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
index 915ccbec71..70d3217520 100644
--- a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
+++ b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
@@ -1,9 +1,5 @@
import { VEllipsis } from '@decent-org/fractal-ui';
-import {
- ERC20FreezeVoting,
- ERC721FreezeVoting,
- MultisigFreezeVoting,
-} from '@fractal-framework/fractal-contracts';
+import { ERC20FreezeVoting, MultisigFreezeVoting } from '@fractal-framework/fractal-contracts';
import { BigNumber } from 'ethers';
import { useMemo, useCallback, useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
@@ -15,6 +11,7 @@ import {
import useSubmitProposal from '../../../../hooks/DAO/proposal/useSubmitProposal';
import useUserERC721VotingTokens from '../../../../hooks/DAO/proposal/useUserERC721VotingTokens';
import useClawBack from '../../../../hooks/DAO/useClawBack';
+import useSafeContracts from '../../../../hooks/safe/useSafeContracts';
import useBlockTimestamp from '../../../../hooks/utils/useBlockTimestamp';
import { useMasterCopy } from '../../../../hooks/utils/useMasterCopy';
import { useFractal } from '../../../../providers/App/AppProvider';
@@ -58,8 +55,8 @@ export function ManageDAOMenu({
const {
node: { safe },
governance: { type },
- baseContracts,
} = useFractal();
+ const baseContracts = useSafeContracts();
const currentTime = BigNumber.from(useBlockTimestamp());
const navigate = useNavigate();
const safeAddress = fractalNode?.daoAddress;
@@ -142,7 +139,7 @@ export function ManageDAOMenu({
const freezeOption = {
optionKey: 'optionInitiateFreeze',
onClick: () => {
- const freezeVotingContract = guardContracts?.freezeVotingContract?.asSigner;
+ const freezeVotingContract = baseContracts?.freezeMultisigVotingMasterCopyContract.asSigner;
const freezeVotingType = guardContracts?.freezeVotingType;
if (freezeVotingContract) {
if (
@@ -152,9 +149,12 @@ export function ManageDAOMenu({
(freezeVotingContract as ERC20FreezeVoting | MultisigFreezeVoting).castFreezeVote();
} else if (freezeVotingType === FreezeVotingType.ERC721) {
getUserERC721VotingTokens(undefined, parentAddress).then(tokensInfo => {
- return (freezeVotingContract as ERC721FreezeVoting)[
- 'castFreezeVote(address[],uint256[])'
- ](tokensInfo.totalVotingTokenAddresses, tokensInfo.totalVotingTokenIds);
+ const freezeERC721VotingContract =
+ baseContracts?.freezeERC721VotingMasterCopyContract.asSigner;
+ return freezeERC721VotingContract['castFreezeVote(address[],uint256[])'](
+ tokensInfo.totalVotingTokenAddresses,
+ tokensInfo.totalVotingTokenIds,
+ );
});
}
}
@@ -229,13 +229,13 @@ export function ManageDAOMenu({
safeAddress,
parentAddress,
governanceType,
- guardContracts?.freezeVotingContract?.asSigner,
- guardContracts?.freezeVotingType,
+ guardContracts,
handleClawBack,
canUserCreateProposal,
handleModifyGovernance,
handleNavigateToSettings,
getUserERC721VotingTokens,
+ baseContracts,
]);
return (
diff --git a/src/components/ui/proposal/useProposalCountdown.tsx b/src/components/ui/proposal/useProposalCountdown.tsx
index a0d46de093..8c5e153ed1 100644
--- a/src/components/ui/proposal/useProposalCountdown.tsx
+++ b/src/components/ui/proposal/useProposalCountdown.tsx
@@ -5,6 +5,7 @@ import { logError } from '../../../helpers/errorLogging';
import useSnapshotProposal from '../../../hooks/DAO/loaders/snapshot/useSnapshotProposal';
import { useDAOProposals } from '../../../hooks/DAO/loaders/useProposals';
import useUpdateProposalState from '../../../hooks/DAO/proposal/useUpdateProposalState';
+import useSafeContracts from '../../../hooks/safe/useSafeContracts';
import { useFractal } from '../../../providers/App/AppProvider';
import { useEthersProvider } from '../../../providers/Ethers/hooks/useEthersProvider';
import {
@@ -20,11 +21,12 @@ import { getTxTimelockedTimestamp } from '../../../utils/guard';
export function useProposalCountdown(proposal: FractalProposal) {
const {
governance,
- guardContracts: { freezeGuardContract, freezeGuardType },
+ guardContracts: { freezeGuardContractAddress, freezeGuardType },
governanceContracts,
action,
readOnly: { dao },
} = useFractal();
+ const baseContracts = useSafeContracts();
const provider = useEthersProvider();
const [secondsLeft, setSecondsLeft] = useState();
@@ -97,9 +99,9 @@ export function useProposalCountdown(proposal: FractalProposal) {
async function getCountdown() {
const freezeGuard =
freezeGuardType === FreezeGuardType.MULTISIG
- ? (freezeGuardContract?.asProvider as MultisigFreezeGuard)
+ ? baseContracts?.multisigFreezeGuardMasterCopyContract.asProvider
: freezeGuardType === FreezeGuardType.AZORIUS
- ? (freezeGuardContract?.asProvider as AzoriusFreezeGuard)
+ ? (baseContracts?.azoriusFreezeGuardMasterCopyContract.asProvider as AzoriusFreezeGuard)
: undefined;
const isSafeGuard = freezeGuardType === FreezeGuardType.MULTISIG;
@@ -164,7 +166,12 @@ export function useProposalCountdown(proposal: FractalProposal) {
clearInterval(countdownInterval);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [proposal.state, azoriusGovernance.votingStrategy, freezeGuardContract, freezeGuardType]);
+ }, [
+ proposal.state,
+ azoriusGovernance.votingStrategy,
+ freezeGuardContractAddress,
+ freezeGuardType,
+ ]);
return secondsLeft;
}
diff --git a/src/hooks/DAO/loaders/useFractalFreeze.ts b/src/hooks/DAO/loaders/useFractalFreeze.ts
index 3309a382c5..a24fea1a78 100644
--- a/src/hooks/DAO/loaders/useFractalFreeze.ts
+++ b/src/hooks/DAO/loaders/useFractalFreeze.ts
@@ -8,7 +8,6 @@ import { FreezeVoteCastEvent } from '@fractal-framework/fractal-contracts/dist/t
import { BigNumber, constants } from 'ethers';
import { useCallback, useEffect, useRef } from 'react';
import { useAccount } from 'wagmi';
-import { getEventRPC } from '../../../helpers';
import {
isWithinFreezeProposalPeriod,
isWithinFreezePeriod,
@@ -16,8 +15,9 @@ import {
import { useFractal } from '../../../providers/App/AppProvider';
import { FractalGuardAction } from '../../../providers/App/guard/action';
import { useEthersProvider } from '../../../providers/Ethers/hooks/useEthersProvider';
-import { ContractConnection, FractalGuardContracts, FreezeVotingType } from '../../../types';
+import { FractalGuardContracts, FreezeVotingType } from '../../../types';
import { blocksToSeconds, getTimeStamp } from '../../../utils/contract';
+import useSafeContracts from '../../safe/useSafeContracts';
import useUserERC721VotingTokens from '../proposal/useUserERC721VotingTokens';
import { FreezeGuard } from './../../../types/fractal';
@@ -34,10 +34,10 @@ export const useFractalFreeze = ({
const {
node: { daoAddress },
- baseContracts,
guardContracts,
action,
} = useFractal();
+ const baseContracts = useSafeContracts();
const { address: account } = useAccount();
const { getUserERC721VotingTokens } = useUserERC721VotingTokens(
undefined,
@@ -48,41 +48,44 @@ export const useFractalFreeze = ({
const provider = useEthersProvider();
const loadFractalFreezeGuard = useCallback(
- async ({ freezeVotingContract, freezeVotingType: freezeVotingType }: FractalGuardContracts) => {
+ async ({
+ freezeVotingContractAddress,
+ freezeVotingType: freezeVotingType,
+ }: FractalGuardContracts) => {
if (
freezeVotingType == null ||
- !freezeVotingContract ||
+ !freezeVotingContractAddress ||
!account ||
!provider ||
!baseContracts
- )
+ ) {
return;
+ }
+
+ // @dev using freeze 'multisig' contract but these functions are the same for all freeze types
+ const freezeVotingContract =
+ baseContracts.freezeMultisigVotingMasterCopyContract.asSigner.attach(
+ freezeVotingContractAddress,
+ );
let userHasVotes: boolean = false;
- const freezeCreatedBlock = await (
- freezeVotingContract!.asProvider as
- | ERC20FreezeVoting
- | ERC721FreezeVoting
- | MultisigFreezeVoting
- ).freezeProposalCreatedBlock();
-
- const freezeVotesThreshold = await freezeVotingContract!.asProvider.freezeVotesThreshold();
- const freezeProposalCreatedBlock =
- await freezeVotingContract!.asProvider.freezeProposalCreatedBlock();
+ const freezeCreatedBlock = await freezeVotingContract.freezeProposalCreatedBlock();
+
+ const freezeVotesThreshold = await freezeVotingContract.freezeVotesThreshold();
+ const freezeProposalCreatedBlock = await freezeVotingContract.freezeProposalCreatedBlock();
const freezeProposalCreatedTime = await getTimeStamp(freezeProposalCreatedBlock, provider);
- const freezeProposalVoteCount =
- await freezeVotingContract!.asProvider.freezeProposalVoteCount();
- const freezeProposalBlock = await freezeVotingContract!.asProvider.freezeProposalPeriod();
+ const freezeProposalVoteCount = await freezeVotingContract.freezeProposalVoteCount();
+ const freezeProposalBlock = await freezeVotingContract.freezeProposalPeriod();
// length of time to vote on freeze
const freezeProposalPeriod = await blocksToSeconds(freezeProposalBlock, provider);
- const freezePeriodBlock = await freezeVotingContract!.asProvider.freezePeriod();
+ const freezePeriodBlock = await freezeVotingContract.freezePeriod();
// length of time frozen for in seconds
const freezePeriod = await blocksToSeconds(freezePeriodBlock, provider);
- const userHasFreezeVoted = await freezeVotingContract!.asProvider.userHasFreezeVoted(
+ const userHasFreezeVoted = await freezeVotingContract.userHasFreezeVoted(
account || constants.AddressZero,
freezeCreatedBlock,
);
- const isFrozen = await freezeVotingContract!.asProvider.isFrozen();
+ const isFrozen = await freezeVotingContract.isFrozen();
const freezeGuard = {
freezeVotesThreshold,
@@ -94,17 +97,24 @@ export const useFractalFreeze = ({
isFrozen,
};
- const { votesTokenMasterCopyContract, safeSingletonContract } = baseContracts;
+ const {
+ votesTokenMasterCopyContract,
+ safeSingletonContract,
+ freezeERC20VotingMasterCopyContract,
+ } = baseContracts;
if (freezeVotingType === FreezeVotingType.MULTISIG) {
const safeContract = safeSingletonContract!.asProvider.attach(
- await (freezeVotingContract!.asProvider as MultisigFreezeVoting).parentGnosisSafe(),
+ await (freezeVotingContract as MultisigFreezeVoting).parentGnosisSafe(),
);
const owners = await safeContract.getOwners();
userHasVotes = owners.find(owner => owner === account) !== undefined;
} else if (freezeVotingType === FreezeVotingType.ERC20) {
+ const freezeERC20VotingContract = freezeERC20VotingMasterCopyContract.asSigner.attach(
+ freezeVotingContractAddress,
+ );
const votesTokenContract = votesTokenMasterCopyContract!.asProvider.attach(
- await (freezeVotingContract!.asProvider as ERC20FreezeVoting).votesERC20(),
+ await freezeERC20VotingContract.votesERC20(),
);
const currentTimestamp = await getTimeStamp('latest', provider);
const isFreezeActive =
@@ -156,11 +166,11 @@ export const useFractalFreeze = ({
useEffect(() => {
if (
guardContracts.freezeVotingType !== null &&
- !!guardContracts.freezeVotingContract &&
+ !!guardContracts.freezeVotingContractAddress &&
loadOnMount &&
- guardContracts.freezeVotingContract.asProvider.address !== loadKey.current
+ guardContracts.freezeVotingContractAddress !== loadKey.current
) {
- loadKey.current = guardContracts.freezeVotingContract.asProvider.address;
+ loadKey.current = guardContracts.freezeVotingContractAddress;
setFractalFreezeGuard(guardContracts);
}
if (!daoAddress) {
@@ -169,9 +179,18 @@ export const useFractalFreeze = ({
}, [setFractalFreezeGuard, guardContracts, daoAddress, loadOnMount]);
useEffect(() => {
- if (!loadOnMount || !provider) return;
- const { freezeVotingContract, freezeVotingType: freezeVotingType } = guardContracts;
- let votingRPC: MultisigFreezeVoting | ERC20FreezeVoting | ERC721FreezeVoting;
+ const { freezeVotingContractAddress, freezeVotingType: freezeVotingType } = guardContracts;
+ if (!loadOnMount || !provider || !baseContracts || !freezeVotingContractAddress) return;
+ const {
+ freezeERC721VotingMasterCopyContract,
+ freezeMultisigVotingMasterCopyContract,
+ freezeERC20VotingMasterCopyContract,
+ } = baseContracts;
+
+ // @dev using freeze 'multisig' contract but these functions are the same for all freeze types
+ let votingRPC: MultisigFreezeVoting | ERC20FreezeVoting | ERC721FreezeVoting =
+ freezeMultisigVotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress);
+
const listenerCallback: TypedListener = async (
voter: string,
votesCast,
@@ -189,27 +208,24 @@ export const useFractalFreeze = ({
});
};
- if (isFreezeSet.current && freezeVotingType !== null && freezeVotingContract) {
+ if (isFreezeSet.current && freezeVotingType !== null && freezeVotingContractAddress) {
if (freezeVotingType === FreezeVotingType.MULTISIG) {
- votingRPC = getEventRPC(
- freezeVotingContract as ContractConnection,
- );
const filter = votingRPC.filters.FreezeVoteCast();
votingRPC.on(filter, listenerCallback);
} else if (freezeVotingType === FreezeVotingType.ERC20) {
- votingRPC = getEventRPC(
- freezeVotingContract as ContractConnection,
+ votingRPC = freezeERC20VotingMasterCopyContract.asProvider.attach(
+ freezeVotingContractAddress,
);
const filter = votingRPC.filters.FreezeVoteCast();
votingRPC.on(filter, listenerCallback);
} else if (freezeVotingType === FreezeVotingType.ERC721) {
- votingRPC = getEventRPC(
- freezeVotingContract as ContractConnection,
+ votingRPC = freezeERC721VotingMasterCopyContract.asProvider.attach(
+ freezeVotingContractAddress,
);
const filter = votingRPC.filters.FreezeVoteCast();
votingRPC.on(filter, listenerCallback);
}
}
- }, [guardContracts, account, action, loadOnMount, provider]);
+ }, [guardContracts, account, action, loadOnMount, provider, baseContracts]);
return loadFractalFreezeGuard;
};
diff --git a/src/hooks/DAO/loaders/useFractalGovernance.ts b/src/hooks/DAO/loaders/useFractalGovernance.ts
index b17d4a586c..9355b5f881 100644
--- a/src/hooks/DAO/loaders/useFractalGovernance.ts
+++ b/src/hooks/DAO/loaders/useFractalGovernance.ts
@@ -83,7 +83,7 @@ export const useFractalGovernance = () => {
const newLoadKey =
(azoriusContractAddress ? '1' : '0') +
nodeHierarchy.parentAddress +
- !!guardContracts.freezeGuardContract;
+ !!guardContracts.freezeGuardContractAddress;
if (isLoaded && newLoadKey !== loadKey.current) {
loadKey.current = newLoadKey;
@@ -126,7 +126,7 @@ export const useFractalGovernance = () => {
loadERC20Token,
loadLockedVotesToken,
nodeHierarchy.parentAddress,
- guardContracts.freezeGuardContract,
+ guardContracts.freezeGuardContractAddress,
loadERC721Strategy,
loadERC721Tokens,
action,
diff --git a/src/hooks/DAO/proposal/useSubmitProposal.ts b/src/hooks/DAO/proposal/useSubmitProposal.ts
index 49be918ada..a382abf759 100644
--- a/src/hooks/DAO/proposal/useSubmitProposal.ts
+++ b/src/hooks/DAO/proposal/useSubmitProposal.ts
@@ -65,7 +65,7 @@ export default function useSubmitProposal() {
const {
node: { safe, fractalModules },
- guardContracts: { freezeVotingContract },
+ guardContracts: { freezeVotingContractAddress },
governanceContracts: { ozLinearVotingContractAddress, erc721LinearVotingContractAddress },
governance: { type },
readOnly: { user },
@@ -407,7 +407,7 @@ export default function useSubmitProposal() {
const votingStrategyAddress =
ozLinearVotingContractAddress ||
erc721LinearVotingContractAddress ||
- freezeVotingContract?.asProvider.address;
+ freezeVotingContractAddress;
if (!globalAzoriusContract || !votingStrategyAddress) {
await submitMultisigProposal({
@@ -436,7 +436,7 @@ export default function useSubmitProposal() {
},
[
globalAzoriusContract,
- freezeVotingContract,
+ freezeVotingContractAddress,
safe,
lookupModules,
submitMultisigProposal,
diff --git a/src/hooks/DAO/useCastFreezeVote.ts b/src/hooks/DAO/useCastFreezeVote.ts
index ae5513949a..937e31e7c3 100644
--- a/src/hooks/DAO/useCastFreezeVote.ts
+++ b/src/hooks/DAO/useCastFreezeVote.ts
@@ -1,12 +1,8 @@
-import {
- ERC20FreezeVoting,
- ERC721FreezeVoting,
- MultisigFreezeVoting,
-} from '@fractal-framework/fractal-contracts';
import { useCallback, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useFractal } from '../../providers/App/AppProvider';
import { FreezeVotingType } from '../../types';
+import useSafeContracts from '../safe/useSafeContracts';
import { useTransaction } from '../utils/useTransaction';
import useUserERC721VotingTokens from './proposal/useUserERC721VotingTokens';
@@ -17,11 +13,12 @@ const useCastFreezeVote = ({
}) => {
const [contractCallCastFreeze, contractCallPending] = useTransaction();
const {
- guardContracts: { freezeVotingContract, freezeVotingType },
+ guardContracts: { freezeVotingContractAddress, freezeVotingType },
node: {
nodeHierarchy: { parentAddress },
},
} = useFractal();
+ const baseContracts = useSafeContracts();
const { getUserERC721VotingTokens } = useUserERC721VotingTokens(undefined, undefined, false);
useEffect(() => {
@@ -31,18 +28,22 @@ const useCastFreezeVote = ({
const { t } = useTranslation('transaction');
const castFreezeVote = useCallback(() => {
+ if (!freezeVotingContractAddress || !baseContracts) return;
contractCallCastFreeze({
contractFn: () => {
if (freezeVotingType === FreezeVotingType.ERC721) {
+ const freezeERC721VotingContract =
+ baseContracts.freezeERC721VotingMasterCopyContract.asSigner;
return getUserERC721VotingTokens(undefined, parentAddress).then(tokensInfo =>
- (freezeVotingContract?.asSigner as ERC721FreezeVoting)[
- 'castFreezeVote(address[],uint256[])'
- ](tokensInfo.totalVotingTokenAddresses, tokensInfo.totalVotingTokenIds),
+ freezeERC721VotingContract['castFreezeVote(address[],uint256[])'](
+ tokensInfo.totalVotingTokenAddresses,
+ tokensInfo.totalVotingTokenIds,
+ ),
);
} else {
- return (
- freezeVotingContract?.asSigner as MultisigFreezeVoting | ERC20FreezeVoting
- ).castFreezeVote();
+ const freezeVotingContract =
+ baseContracts.freezeMultisigVotingMasterCopyContract.asSigner;
+ return freezeVotingContract.castFreezeVote();
}
},
pendingMessage: t('pendingCastFreezeVote'),
@@ -52,10 +53,11 @@ const useCastFreezeVote = ({
}, [
contractCallCastFreeze,
t,
- freezeVotingContract,
+ freezeVotingContractAddress,
freezeVotingType,
getUserERC721VotingTokens,
parentAddress,
+ baseContracts,
]);
return castFreezeVote;
};
diff --git a/src/hooks/utils/useSafeTransactions.ts b/src/hooks/utils/useSafeTransactions.ts
index 1caaaf525c..e9c46c08ed 100644
--- a/src/hooks/utils/useSafeTransactions.ts
+++ b/src/hooks/utils/useSafeTransactions.ts
@@ -21,6 +21,7 @@ import {
import { formatWeiToValue, isModuleTx, isMultiSigTx, parseDecodedData } from '../../utils';
import { getAverageBlockTime } from '../../utils/contract';
import { getTxTimelockedTimestamp } from '../../utils/guard';
+import useSafeContracts from '../safe/useSafeContracts';
import { useSafeDecoder } from './useSafeDecoder';
type FreezeGuardData = {
@@ -33,6 +34,7 @@ export const useSafeTransactions = () => {
const { nativeTokenSymbol } = useNetworkConfig();
const provider = useEthersProvider();
const { guardContracts } = useFractal();
+ const baseContracts = useSafeContracts();
const decode = useSafeDecoder();
const getState = useCallback(
@@ -318,10 +320,13 @@ export const useSafeTransactions = () => {
let freezeGuard: MultisigFreezeGuard | undefined;
let freezeGuardData: FreezeGuardData | undefined;
- if (guardContracts.freezeGuardContract) {
+ if (guardContracts.freezeGuardContractAddress && baseContracts) {
const blockNumber = await provider.getBlockNumber();
const averageBlockTime = await getAverageBlockTime(provider);
- freezeGuard = guardContracts.freezeGuardContract.asProvider as MultisigFreezeGuard;
+
+ freezeGuard = baseContracts.multisigFreezeGuardMasterCopyContract.asSigner.attach(
+ guardContracts.freezeGuardContractAddress,
+ );
freezeGuardData = {
guardTimelockPeriodMs: BigNumber.from(
(await freezeGuard.timelockPeriod()) * averageBlockTime * 1000,
@@ -337,12 +342,13 @@ export const useSafeTransactions = () => {
return activitiesWithState;
},
[
- guardContracts.freezeGuardContract,
+ guardContracts,
getState,
getTransferTotal,
decode,
nativeTokenSymbol,
provider,
+ baseContracts,
],
);
return { parseTransactions };
diff --git a/src/providers/App/guardContracts/reducer.ts b/src/providers/App/guardContracts/reducer.ts
index daf4ab768b..b2d528efee 100644
--- a/src/providers/App/guardContracts/reducer.ts
+++ b/src/providers/App/guardContracts/reducer.ts
@@ -4,8 +4,8 @@ import { GuardContractAction, GuardContractActions } from './action';
export const initialGuardContractsState: FractalGuardContracts = {
freezeGuardType: null,
freezeVotingType: null,
- freezeGuardContract: undefined,
- freezeVotingContract: undefined,
+ freezeGuardContractAddress: undefined,
+ freezeVotingContractAddress: undefined,
};
export const guardContractReducer = (
diff --git a/src/types/fractal.ts b/src/types/fractal.ts
index 9d8d5899fa..3bfc34debb 100644
--- a/src/types/fractal.ts
+++ b/src/types/fractal.ts
@@ -255,18 +255,9 @@ export enum FractalModuleType {
FRACTAL,
UNKNOWN,
}
-// @todo updates Fractal Guard Contract to just store addresses in the store
-// export interface FractalGuardContracts {
-// freezeGuardContractAddress?: string;
-// freezeVotingContractAddress?: string;
-// freezeGuardType: FreezeGuardType | null;
-// freezeVotingType: FreezeVotingType | null;
-// }
export interface FractalGuardContracts {
- freezeGuardContract?: ContractConnection;
- freezeVotingContract?: ContractConnection<
- ERC20FreezeVoting | ERC721FreezeVoting | MultisigFreezeVoting
- >;
+ freezeGuardContractAddress?: string;
+ freezeVotingContractAddress?: string;
freezeGuardType: FreezeGuardType | null;
freezeVotingType: FreezeVotingType | null;
}
From cb68dda631d8b1edb6b373d25182239a70f0dfcc Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 02:34:07 -0400
Subject: [PATCH 02/30] update freeze and guard loader hooks
---
src/hooks/DAO/loaders/useFractalFreeze.ts | 10 ++--
.../DAO/loaders/useFractalGuardContracts.ts | 51 ++++++++-----------
2 files changed, 27 insertions(+), 34 deletions(-)
diff --git a/src/hooks/DAO/loaders/useFractalFreeze.ts b/src/hooks/DAO/loaders/useFractalFreeze.ts
index a24fea1a78..9ef0cc7b3e 100644
--- a/src/hooks/DAO/loaders/useFractalFreeze.ts
+++ b/src/hooks/DAO/loaders/useFractalFreeze.ts
@@ -33,7 +33,6 @@ export const useFractalFreeze = ({
const isFreezeSet = useRef(false);
const {
- node: { daoAddress },
guardContracts,
action,
} = useFractal();
@@ -168,15 +167,16 @@ export const useFractalFreeze = ({
guardContracts.freezeVotingType !== null &&
!!guardContracts.freezeVotingContractAddress &&
loadOnMount &&
- guardContracts.freezeVotingContractAddress !== loadKey.current
+ guardContracts.freezeVotingContractAddress + parentSafeAddress !== loadKey.current
) {
- loadKey.current = guardContracts.freezeVotingContractAddress;
+ console.count('load freeze guard')
setFractalFreezeGuard(guardContracts);
+ loadKey.current = guardContracts.freezeVotingContractAddress + parentSafeAddress;
}
- if (!daoAddress) {
+ if (!parentSafeAddress) {
loadKey.current = undefined;
}
- }, [setFractalFreezeGuard, guardContracts, daoAddress, loadOnMount]);
+ }, [setFractalFreezeGuard, guardContracts, parentSafeAddress, loadOnMount]);
useEffect(() => {
const { freezeVotingContractAddress, freezeVotingType: freezeVotingType } = guardContracts;
diff --git a/src/hooks/DAO/loaders/useFractalGuardContracts.ts b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
index c848579476..716ccd919b 100644
--- a/src/hooks/DAO/loaders/useFractalGuardContracts.ts
+++ b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
@@ -17,7 +17,14 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
// load key for component; helps prevent unnecessary calls
const loadKey = useRef();
const {
- node: { daoAddress, safe, fractalModules, isModulesLoaded },
+ node: {
+ daoAddress,
+ safe,
+ fractalModules,
+ isModulesLoaded,
+ nodeHierarchy: { parentAddress },
+ },
+
baseContracts,
action,
} = useFractal();
@@ -35,13 +42,8 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
if (!baseContracts) {
return;
}
- const {
- freezeERC20VotingMasterCopyContract,
- freezeERC721VotingMasterCopyContract,
- freezeMultisigVotingMasterCopyContract,
- azoriusFreezeGuardMasterCopyContract,
- multisigFreezeGuardMasterCopyContract,
- } = baseContracts;
+ const { azoriusFreezeGuardMasterCopyContract, multisigFreezeGuardMasterCopyContract } =
+ baseContracts;
const { guard } = _safe;
let freezeGuardContract:
@@ -81,25 +83,9 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
? FreezeVotingType.ERC721
: FreezeVotingType.ERC20;
- const freezeVotingContract =
- freezeVotingType === FreezeVotingType.MULTISIG
- ? {
- asSigner: freezeMultisigVotingMasterCopyContract.asSigner.attach(votingAddress),
- asProvider: freezeMultisigVotingMasterCopyContract.asProvider.attach(votingAddress),
- }
- : freezeVotingType === FreezeVotingType.ERC721
- ? {
- asSigner: freezeERC721VotingMasterCopyContract.asSigner.attach(votingAddress),
- asProvider: freezeERC721VotingMasterCopyContract.asProvider.attach(votingAddress),
- }
- : {
- asSigner: freezeERC20VotingMasterCopyContract.asSigner.attach(votingAddress),
- asProvider: freezeERC20VotingMasterCopyContract.asProvider.attach(votingAddress),
- };
-
const contracts = {
- freezeGuardContract,
- freezeVotingContract,
+ freezeGuardContractAddress: freezeGuardContract.asProvider.address,
+ freezeVotingContractAddress: votingAddress,
freezeVotingType,
freezeGuardType,
};
@@ -118,13 +104,20 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
}, [action, daoAddress, safe, fractalModules, loadFractalGuardContracts]);
useEffect(() => {
- if (daoAddress && chainId + daoAddress !== loadKey.current && loadOnMount && isModulesLoaded) {
- loadKey.current = chainId + daoAddress;
+ if (
+ parentAddress &&
+ daoAddress &&
+ parentAddress + daoAddress !== loadKey.current &&
+ loadOnMount &&
+ isModulesLoaded
+ ) {
+ loadKey.current = parentAddress + daoAddress;
+ console.count('load guard contracts');
setGuardContracts();
}
if (!daoAddress) {
loadKey.current = undefined;
}
- }, [setGuardContracts, isModulesLoaded, daoAddress, loadOnMount, chainId]);
+ }, [setGuardContracts, isModulesLoaded, parentAddress, loadOnMount, chainId, daoAddress]);
return loadFractalGuardContracts;
};
From 2d86a71238455971c2d292212b76c67e7c91dbb2 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 02:34:37 -0400
Subject: [PATCH 03/30] fix bug thats been bugging me
- no conditional preventing when not on ERC721 DAO
---
src/hooks/DAO/proposal/useUserERC721VotingTokens.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hooks/DAO/proposal/useUserERC721VotingTokens.ts b/src/hooks/DAO/proposal/useUserERC721VotingTokens.ts
index 5192962dcf..5af878a5f8 100644
--- a/src/hooks/DAO/proposal/useUserERC721VotingTokens.ts
+++ b/src/hooks/DAO/proposal/useUserERC721VotingTokens.ts
@@ -213,10 +213,10 @@ export default function useUserERC721VotingTokens(
}, [getUserERC721VotingTokens, proposalId, safeAddress]);
useEffect(() => {
- if (loadOnMount) {
+ if (loadOnMount && erc721LinearVotingContractAddress) {
loadUserERC721VotingTokens();
}
- }, [loadUserERC721VotingTokens, loadOnMount]);
+ }, [loadUserERC721VotingTokens, loadOnMount, erc721LinearVotingContractAddress]);
return {
totalVotingTokenIds,
From 9cc83635308f62e79ff63fb50ceca9f4563b9918 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 02:35:15 -0400
Subject: [PATCH 04/30] pretty/lint
---
src/hooks/DAO/loaders/useFractalFreeze.ts | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/src/hooks/DAO/loaders/useFractalFreeze.ts b/src/hooks/DAO/loaders/useFractalFreeze.ts
index 9ef0cc7b3e..8826e70fd3 100644
--- a/src/hooks/DAO/loaders/useFractalFreeze.ts
+++ b/src/hooks/DAO/loaders/useFractalFreeze.ts
@@ -32,10 +32,7 @@ export const useFractalFreeze = ({
const loadKey = useRef();
const isFreezeSet = useRef(false);
- const {
- guardContracts,
- action,
- } = useFractal();
+ const { guardContracts, action } = useFractal();
const baseContracts = useSafeContracts();
const { address: account } = useAccount();
const { getUserERC721VotingTokens } = useUserERC721VotingTokens(
@@ -169,7 +166,7 @@ export const useFractalFreeze = ({
loadOnMount &&
guardContracts.freezeVotingContractAddress + parentSafeAddress !== loadKey.current
) {
- console.count('load freeze guard')
+ console.count('load freeze guard');
setFractalFreezeGuard(guardContracts);
loadKey.current = guardContracts.freezeVotingContractAddress + parentSafeAddress;
}
From 5b8075a1a5560ae670000b361ad959be9c88029b Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 02:39:36 -0400
Subject: [PATCH 05/30] fix Parent Link
---
src/components/pages/DaoDashboard/Info/ParentLink.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/pages/DaoDashboard/Info/ParentLink.tsx b/src/components/pages/DaoDashboard/Info/ParentLink.tsx
index 0a9d4b4fa9..09b696e7a0 100644
--- a/src/components/pages/DaoDashboard/Info/ParentLink.tsx
+++ b/src/components/pages/DaoDashboard/Info/ParentLink.tsx
@@ -22,7 +22,7 @@ export function ParentLink() {
Date: Fri, 22 Mar 2024 12:21:03 -0400
Subject: [PATCH 06/30] fix navigating to other DAO via DAO menu
---
src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
index 70d3217520..da5bb0a249 100644
--- a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
+++ b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
@@ -124,7 +124,7 @@ export function ManageDAOMenu({
}, [fractalNode, safe, safeAddress, type, getZodiacModuleProxyMasterCopyData, baseContracts]);
const handleNavigateToSettings = useCallback(
- () => navigate(DAO_ROUTES.settings.relative(safeAddress)),
+ () => navigate(DAO_ROUTES.settings.relative(safeAddress), { replace: true }),
[navigate, safeAddress],
);
@@ -133,7 +133,7 @@ export function ManageDAOMenu({
const options = useMemo(() => {
const createSubDAOOption = {
optionKey: 'optionCreateSubDAO',
- onClick: () => navigate(DAO_ROUTES.newSubDao.relative(safeAddress)),
+ onClick: () => navigate(DAO_ROUTES.newSubDao.relative(safeAddress), { replace: true }),
};
const freezeOption = {
From f3cee31dadb30eb6b2fba71db813c46ee0e17092 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 12:22:04 -0400
Subject: [PATCH 07/30] clean up loading conditional
---
src/hooks/DAO/loaders/useFractalGuardContracts.ts | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/src/hooks/DAO/loaders/useFractalGuardContracts.ts b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
index 716ccd919b..db133d02b3 100644
--- a/src/hooks/DAO/loaders/useFractalGuardContracts.ts
+++ b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
@@ -105,17 +105,15 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
useEffect(() => {
if (
- parentAddress &&
- daoAddress &&
- parentAddress + daoAddress !== loadKey.current &&
- loadOnMount &&
+ loadOnMount && parentAddress && daoAddress &&
+ parentAddress + daoAddress + chainId !== loadKey.current &&
isModulesLoaded
) {
- loadKey.current = parentAddress + daoAddress;
- console.count('load guard contracts');
+ loadKey.current = parentAddress + daoAddress + chainId;
setGuardContracts();
}
- if (!daoAddress) {
+
+ if (!daoAddress || !parentAddress) {
loadKey.current = undefined;
}
}, [setGuardContracts, isModulesLoaded, parentAddress, loadOnMount, chainId, daoAddress]);
From 8db23c4bd8b58deaf5be8ae90f13a872e3331fc4 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 15:56:16 -0400
Subject: [PATCH 08/30] fix verical node line
---
src/components/pages/DaoHierarchy/NodeLines.tsx | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/components/pages/DaoHierarchy/NodeLines.tsx b/src/components/pages/DaoHierarchy/NodeLines.tsx
index 1e7e29c1bd..73bc1eb2f0 100644
--- a/src/components/pages/DaoHierarchy/NodeLines.tsx
+++ b/src/components/pages/DaoHierarchy/NodeLines.tsx
@@ -25,7 +25,6 @@ export function NodeLineVertical({ isCurrentDAO, trueDepth = 0, lastChildDescend
position="absolute"
h={`calc(100% - ${NODE_HEIGHT_REM + NODE_MARGIN_TOP_REM}rem)`}
w="100%"
- zIndex={-1 - trueDepth}
bottom={0}
overflow="hidden"
>
From ea0479dcf0a2f46830ed418017efc45cb3ad1c19 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 15:56:43 -0400
Subject: [PATCH 09/30] remove unneeded dependency
---
src/components/pages/DaoHierarchy/DaoNode.tsx | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/components/pages/DaoHierarchy/DaoNode.tsx b/src/components/pages/DaoHierarchy/DaoNode.tsx
index 0712fa8899..1011d11c47 100644
--- a/src/components/pages/DaoHierarchy/DaoNode.tsx
+++ b/src/components/pages/DaoHierarchy/DaoNode.tsx
@@ -38,7 +38,7 @@ export function DaoNode({
const isCurrentDAO = daoAddress === currentDAOAddress;
useEffect(() => {
- if (daoAddress && !fractalNode) {
+ if (daoAddress) {
loadDao(utils.getAddress(daoAddress)).then(_node => {
const errorNode = _node as WithError;
if (!errorNode.error) {
@@ -80,7 +80,8 @@ export function DaoNode({
}
});
}
- }, [loadDao, daoAddress, fractalNode, depth]);
+ }, [loadDao, daoAddress, depth]);
+
return (
From f1340dee6afacd6d09f6eb4941adf12dc3e94933 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 15:58:00 -0400
Subject: [PATCH 10/30] fix subDAO loading issues
---
.../governance/useERC20LinearStrategy.ts | 13 +++---
.../governance/useERC721LinearStrategy.ts | 13 +++---
src/hooks/DAO/loaders/useFractalFreeze.ts | 1 -
src/hooks/DAO/loaders/useFractalGovernance.ts | 36 ++++++---------
.../DAO/loaders/useFractalGuardContracts.ts | 44 ++++++++++++-------
src/hooks/DAO/loaders/useFractalNode.ts | 2 +-
src/hooks/DAO/loaders/useProposals.ts | 1 +
.../daos/[daoAddress]/hierarchy/index.tsx | 11 +++--
src/providers/App/guardContracts/action.ts | 2 +-
src/providers/App/guardContracts/reducer.ts | 2 +-
src/providers/App/node/reducer.ts | 4 +-
src/types/fractal.ts | 4 +-
12 files changed, 73 insertions(+), 60 deletions(-)
diff --git a/src/hooks/DAO/loaders/governance/useERC20LinearStrategy.ts b/src/hooks/DAO/loaders/governance/useERC20LinearStrategy.ts
index 4b17f90dc6..049a774be3 100644
--- a/src/hooks/DAO/loaders/governance/useERC20LinearStrategy.ts
+++ b/src/hooks/DAO/loaders/governance/useERC20LinearStrategy.ts
@@ -14,6 +14,7 @@ import { useTimeHelpers } from '../../../utils/useTimeHelpers';
export const useERC20LinearStrategy = () => {
const {
+ governance: { type },
governanceContracts: { ozLinearVotingContractAddress, azoriusContractAddress },
action,
} = useFractal();
@@ -67,7 +68,7 @@ export const useERC20LinearStrategy = () => {
]);
useEffect(() => {
- if (!ozLinearVotingContractAddress || !baseContracts) {
+ if (!ozLinearVotingContractAddress || !baseContracts || !type) {
return;
}
const ozLinearVotingContract = baseContracts.linearVotingMasterCopyContract.asProvider.attach(
@@ -85,10 +86,10 @@ export const useERC20LinearStrategy = () => {
return () => {
ozLinearVotingContract.off(votingPeriodfilter, listener);
};
- }, [ozLinearVotingContractAddress, action, baseContracts]);
+ }, [ozLinearVotingContractAddress, action, baseContracts, type]);
useEffect(() => {
- if (!ozLinearVotingContractAddress || !baseContracts) {
+ if (!ozLinearVotingContractAddress || !baseContracts || !type) {
return;
}
const ozLinearVotingContract = baseContracts.linearVotingMasterCopyContract.asProvider.attach(
@@ -107,10 +108,10 @@ export const useERC20LinearStrategy = () => {
return () => {
ozLinearVotingContract.off(quorumNumeratorUpdatedFilter, quorumNumeratorUpdatedListener);
};
- }, [ozLinearVotingContractAddress, action, baseContracts]);
+ }, [ozLinearVotingContractAddress, action, baseContracts, type]);
useEffect(() => {
- if (!azoriusContractAddress || !baseContracts) {
+ if (!azoriusContractAddress || !baseContracts || !type) {
return;
}
const azoriusContract =
@@ -126,7 +127,7 @@ export const useERC20LinearStrategy = () => {
return () => {
azoriusContract.off(timeLockPeriodFilter, timelockPeriodListener);
};
- }, [azoriusContractAddress, action, baseContracts]);
+ }, [azoriusContractAddress, action, baseContracts, type]);
return loadERC20Strategy;
};
diff --git a/src/hooks/DAO/loaders/governance/useERC721LinearStrategy.ts b/src/hooks/DAO/loaders/governance/useERC721LinearStrategy.ts
index 97012eab3a..0a61a6e3a4 100644
--- a/src/hooks/DAO/loaders/governance/useERC721LinearStrategy.ts
+++ b/src/hooks/DAO/loaders/governance/useERC721LinearStrategy.ts
@@ -17,6 +17,7 @@ import { useTimeHelpers } from '../../../utils/useTimeHelpers';
export const useERC721LinearStrategy = () => {
const {
governanceContracts: { erc721LinearVotingContractAddress, azoriusContractAddress },
+ governance: {type},
action,
} = useFractal();
const provider = useEthersProvider();
@@ -72,7 +73,7 @@ export const useERC721LinearStrategy = () => {
]);
useEffect(() => {
- if (!erc721LinearVotingContractAddress || !baseContracts) {
+ if (!erc721LinearVotingContractAddress || !baseContracts || !type) {
return;
}
const erc721LinearVotingContract =
@@ -90,10 +91,10 @@ export const useERC721LinearStrategy = () => {
return () => {
erc721LinearVotingContract.off(votingPeriodfilter, listener);
};
- }, [erc721LinearVotingContractAddress, action, baseContracts]);
+ }, [erc721LinearVotingContractAddress, action, baseContracts, type]);
useEffect(() => {
- if (!erc721LinearVotingContractAddress || !baseContracts) {
+ if (!erc721LinearVotingContractAddress || !baseContracts || !type) {
return;
}
const erc721LinearVotingContract =
@@ -114,10 +115,10 @@ export const useERC721LinearStrategy = () => {
return () => {
erc721LinearVotingContract.off(quorumThresholdUpdatedFilter, quorumThresholdUpdatedListener);
};
- }, [erc721LinearVotingContractAddress, action, baseContracts]);
+ }, [erc721LinearVotingContractAddress, action, baseContracts, type]);
useEffect(() => {
- if (!azoriusContractAddress || !baseContracts) {
+ if (!azoriusContractAddress || !baseContracts || !type) {
return;
}
const azoriusContract =
@@ -134,7 +135,7 @@ export const useERC721LinearStrategy = () => {
return () => {
azoriusContract.off(timeLockPeriodFilter, timelockPeriodListener);
};
- }, [azoriusContractAddress, action, baseContracts]);
+ }, [azoriusContractAddress, action, baseContracts, type]);
return loadERC721Strategy;
};
diff --git a/src/hooks/DAO/loaders/useFractalFreeze.ts b/src/hooks/DAO/loaders/useFractalFreeze.ts
index 8826e70fd3..0937f777fa 100644
--- a/src/hooks/DAO/loaders/useFractalFreeze.ts
+++ b/src/hooks/DAO/loaders/useFractalFreeze.ts
@@ -166,7 +166,6 @@ export const useFractalFreeze = ({
loadOnMount &&
guardContracts.freezeVotingContractAddress + parentSafeAddress !== loadKey.current
) {
- console.count('load freeze guard');
setFractalFreezeGuard(guardContracts);
loadKey.current = guardContracts.freezeVotingContractAddress + parentSafeAddress;
}
diff --git a/src/hooks/DAO/loaders/useFractalGovernance.ts b/src/hooks/DAO/loaders/useFractalGovernance.ts
index 9355b5f881..33e1bebaf1 100644
--- a/src/hooks/DAO/loaders/useFractalGovernance.ts
+++ b/src/hooks/DAO/loaders/useFractalGovernance.ts
@@ -18,11 +18,11 @@ export const useFractalGovernance = () => {
const loadKey = useRef();
const {
- node: { daoAddress, nodeHierarchy },
+ node: { daoAddress },
governanceContracts,
action,
- guardContracts,
governance: { type },
+ guardContracts: { isGuardLoaded },
} = useFractal();
const loadDAOProposals = useDAOProposals();
@@ -68,7 +68,7 @@ export const useFractalGovernance = () => {
},
context: { chainName: subgraphChainName },
pollInterval: ONE_MINUTE,
- skip: !daoAddress,
+ skip: !daoAddress || !type,
});
useEffect(() => {
@@ -80,14 +80,7 @@ export const useFractalGovernance = () => {
ozLinearVotingContractAddress,
} = governanceContracts;
- const newLoadKey =
- (azoriusContractAddress ? '1' : '0') +
- nodeHierarchy.parentAddress +
- !!guardContracts.freezeGuardContractAddress;
-
- if (isLoaded && newLoadKey !== loadKey.current) {
- loadKey.current = newLoadKey;
-
+ if (isLoaded && !type) {
if (azoriusContractAddress) {
if (ozLinearVotingContractAddress) {
action.dispatch({
@@ -115,30 +108,27 @@ export const useFractalGovernance = () => {
});
}
}
- if (!daoAddress) {
- loadKey.current = undefined;
- }
+
}, [
governanceContracts,
- loadDAOProposals,
loadUnderlyingERC20Token,
loadERC20Strategy,
loadERC20Token,
loadLockedVotesToken,
- nodeHierarchy.parentAddress,
- guardContracts.freezeGuardContractAddress,
loadERC721Strategy,
loadERC721Tokens,
action,
- daoAddress,
+ type
]);
useEffect(() => {
- if (type) {
- // Since previous hook is the only place where governance type is set - we don't need any additional check
- // But it's better to be sure that governance type is defined before calling for proposals loading
+ const newLoadKey = (daoAddress || "0x");
+ if (type && daoAddress && daoAddress !== loadKey.current && isGuardLoaded) {
+ loadKey.current = newLoadKey;
loadDAOProposals();
}
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [type]);
+ if(!type || !daoAddress) {
+ loadKey.current = undefined;
+ }
+ }, [type, loadDAOProposals, isGuardLoaded, daoAddress]);
};
diff --git a/src/hooks/DAO/loaders/useFractalGuardContracts.ts b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
index db133d02b3..dbffcef7bb 100644
--- a/src/hooks/DAO/loaders/useFractalGuardContracts.ts
+++ b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
@@ -10,6 +10,7 @@ import {
FreezeGuardType,
FreezeVotingType,
} from '../../../types';
+import useSafeContracts from '../../safe/useSafeContracts';
import { useMasterCopy } from '../../utils/useMasterCopy';
import { FractalModuleData, FractalModuleType } from './../../../types/fractal';
@@ -17,17 +18,11 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
// load key for component; helps prevent unnecessary calls
const loadKey = useRef();
const {
- node: {
- daoAddress,
- safe,
- fractalModules,
- isModulesLoaded,
- nodeHierarchy: { parentAddress },
- },
+ node: { daoAddress, safe, fractalModules, isHierarchyLoaded },
- baseContracts,
action,
} = useFractal();
+ const baseContracts = useSafeContracts()
const { chainId } = useNetworkConfig();
@@ -56,7 +51,16 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
);
if (!!azoriusModule && azoriusModule.moduleContract) {
const azoriusGuardAddress = await azoriusModule.moduleContract.getGuard();
- if (azoriusGuardAddress === constants.AddressZero) return;
+
+ if (azoriusGuardAddress === constants.AddressZero) {
+ return {
+ freezeGuardContractAddress: '',
+ freezeVotingContractAddress: '',
+ freezeVotingType: null,
+ freezeGuardType: null,
+ };
+ }
+
freezeGuardContract = {
asSigner: azoriusFreezeGuardMasterCopyContract.asSigner.attach(azoriusGuardAddress),
asProvider: azoriusFreezeGuardMasterCopyContract.asProvider.attach(azoriusGuardAddress),
@@ -91,13 +95,20 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
};
return contracts;
+ } else {
+ return {
+ freezeGuardContractAddress: '',
+ freezeVotingContractAddress: '',
+ freezeVotingType: null,
+ freezeGuardType: null,
+ };
}
},
[baseContracts, getZodiacModuleProxyMasterCopyData],
);
const setGuardContracts = useCallback(async () => {
- if (!daoAddress || !safe || !fractalModules.length || !safe.guard) return;
+ if (!daoAddress || !safe) return;
const contracts = await loadFractalGuardContracts(daoAddress, safe, fractalModules);
if (!contracts) return;
action.dispatch({ type: GuardContractAction.SET_GUARD_CONTRACT, payload: contracts });
@@ -105,17 +116,18 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
useEffect(() => {
if (
- loadOnMount && parentAddress && daoAddress &&
- parentAddress + daoAddress + chainId !== loadKey.current &&
- isModulesLoaded
+ loadOnMount &&
+ daoAddress &&
+ daoAddress + chainId !== loadKey.current &&
+ isHierarchyLoaded && safe
) {
- loadKey.current = parentAddress + daoAddress + chainId;
+ loadKey.current = daoAddress + chainId;
setGuardContracts();
}
- if (!daoAddress || !parentAddress) {
+ if (!daoAddress) {
loadKey.current = undefined;
}
- }, [setGuardContracts, isModulesLoaded, parentAddress, loadOnMount, chainId, daoAddress]);
+ }, [setGuardContracts, isHierarchyLoaded, loadOnMount, chainId, daoAddress, safe]);
return loadFractalGuardContracts;
};
diff --git a/src/hooks/DAO/loaders/useFractalNode.ts b/src/hooks/DAO/loaders/useFractalNode.ts
index e50f5d1865..8e5afc7157 100644
--- a/src/hooks/DAO/loaders/useFractalNode.ts
+++ b/src/hooks/DAO/loaders/useFractalNode.ts
@@ -99,7 +99,6 @@ export const useFractalNode = ({ daoAddress }: { daoAddress?: string }) => {
action.resetDAO();
setErrorLoading(true);
} else {
- currentValidSafe.current = _chainId + _daoAddress;
action.dispatch({
type: NodeAction.SET_FRACTAL_MODULES,
payload: await lookupModules(safeInfo.modules),
@@ -133,6 +132,7 @@ export const useFractalNode = ({ daoAddress }: { daoAddress?: string }) => {
if (daoAddress && chainId + daoAddress !== currentValidSafe.current) {
setNodeLoading(true);
setDAO(chainId, daoAddress);
+ currentValidSafe.current = chainId + daoAddress
}
if (!daoAddress) {
currentValidSafe.current = undefined;
diff --git a/src/hooks/DAO/loaders/useProposals.ts b/src/hooks/DAO/loaders/useProposals.ts
index 245365fa3a..482af484fd 100644
--- a/src/hooks/DAO/loaders/useProposals.ts
+++ b/src/hooks/DAO/loaders/useProposals.ts
@@ -28,6 +28,7 @@ export const useDAOProposals = () => {
clearIntervals();
} else if (type === GovernanceType.MULTISIG) {
// load mulisig proposals
+ clearIntervals();
setMethodOnInterval(loadSafeMultisigProposals);
}
}, [
diff --git a/src/pages/daos/[daoAddress]/hierarchy/index.tsx b/src/pages/daos/[daoAddress]/hierarchy/index.tsx
index b24bc10323..d9b859e2aa 100644
--- a/src/pages/daos/[daoAddress]/hierarchy/index.tsx
+++ b/src/pages/daos/[daoAddress]/hierarchy/index.tsx
@@ -8,11 +8,16 @@ import { useFractal } from '../../../../providers/App/AppProvider';
export default function HierarchyPage() {
const {
- node: { daoAddress, daoName, nodeHierarchy },
+ node: {
+ daoAddress,
+ daoName,
+ nodeHierarchy: { parentAddress },
+ isHierarchyLoaded,
+ },
} = useFractal();
const { t } = useTranslation('breadcrumbs');
- if (!daoAddress) {
+ if (!daoAddress || !isHierarchyLoaded) {
return (
@@ -35,7 +40,7 @@ export default function HierarchyPage() {
]}
/>
diff --git a/src/providers/App/guardContracts/action.ts b/src/providers/App/guardContracts/action.ts
index db31db3646..3451394e20 100644
--- a/src/providers/App/guardContracts/action.ts
+++ b/src/providers/App/guardContracts/action.ts
@@ -6,5 +6,5 @@ export enum GuardContractAction {
export type GuardContractActions = {
type: GuardContractAction.SET_GUARD_CONTRACT;
- payload: FractalGuardContracts;
+ payload: Omit;
};
diff --git a/src/providers/App/guardContracts/reducer.ts b/src/providers/App/guardContracts/reducer.ts
index b2d528efee..21905c5501 100644
--- a/src/providers/App/guardContracts/reducer.ts
+++ b/src/providers/App/guardContracts/reducer.ts
@@ -14,7 +14,7 @@ export const guardContractReducer = (
) => {
switch (action.type) {
case GuardContractAction.SET_GUARD_CONTRACT:
- return action.payload;
+ return {...action.payload, isGuardLoaded: true};
default:
return state;
}
diff --git a/src/providers/App/node/reducer.ts b/src/providers/App/node/reducer.ts
index e10a7a0489..ad67816d3b 100644
--- a/src/providers/App/node/reducer.ts
+++ b/src/providers/App/node/reducer.ts
@@ -13,6 +13,8 @@ export const initialNodeState: FractalNode = {
safe: null,
fractalModules: [],
nodeHierarchy: initialNodeHierarchyState,
+ isHierarchyLoaded: false,
+ isModulesLoaded: false,
};
export function nodeReducer(state: FractalNode, action: NodeActions) {
@@ -25,7 +27,7 @@ export function nodeReducer(state: FractalNode, action: NodeActions) {
};
}
case NodeAction.SET_DAO_INFO: {
- return { ...state, ...action.payload };
+ return { ...state, ...action.payload, isHierarchyLoaded: true };
}
case NodeAction.SET_FRACTAL_MODULES: {
return { ...state, fractalModules: action.payload, isModulesLoaded: true };
diff --git a/src/types/fractal.ts b/src/types/fractal.ts
index 3bfc34debb..0b1cb964ed 100644
--- a/src/types/fractal.ts
+++ b/src/types/fractal.ts
@@ -238,11 +238,12 @@ export interface FractalNode {
fractalModules: FractalModuleData[];
nodeHierarchy: NodeHierarchy;
isModulesLoaded?: boolean;
+ isHierarchyLoaded?: boolean;
daoSnapshotURL?: string;
proposalTemplatesHash?: string;
}
-export interface Node extends Omit {}
+export interface Node extends Omit {}
export interface FractalModuleData {
moduleContract: Azorius | FractalModule | undefined;
@@ -260,6 +261,7 @@ export interface FractalGuardContracts {
freezeVotingContractAddress?: string;
freezeGuardType: FreezeGuardType | null;
freezeVotingType: FreezeVotingType | null;
+ isGuardLoaded?: boolean;
}
export interface FreezeGuard {
From 0ab0007c271de031016d86a3fe603541761174a8 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 15:58:20 -0400
Subject: [PATCH 11/30] Fix timelock execution and timer
---
.../ui/proposal/useProposalCountdown.tsx | 172 ++++++++++--------
src/hooks/utils/useSafeTransactions.ts | 15 +-
2 files changed, 100 insertions(+), 87 deletions(-)
diff --git a/src/components/ui/proposal/useProposalCountdown.tsx b/src/components/ui/proposal/useProposalCountdown.tsx
index 8c5e153ed1..b4ae3d837c 100644
--- a/src/components/ui/proposal/useProposalCountdown.tsx
+++ b/src/components/ui/proposal/useProposalCountdown.tsx
@@ -1,6 +1,6 @@
import { AzoriusFreezeGuard, MultisigFreezeGuard } from '@fractal-framework/fractal-contracts';
import { BigNumber } from 'ethers';
-import { useEffect, useRef, useState } from 'react';
+import { useCallback, useEffect, useRef, useState } from 'react';
import { logError } from '../../../helpers/errorLogging';
import useSnapshotProposal from '../../../hooks/DAO/loaders/snapshot/useSnapshotProposal';
import { useDAOProposals } from '../../../hooks/DAO/loaders/useProposals';
@@ -41,6 +41,7 @@ export function useProposalCountdown(proposal: FractalProposal) {
});
let updateStateInterval = useRef();
+ let countdownInterval = useRef();
useEffect(() => {
// if it's not a state that requires a countdown, clear the interval and return
if (
@@ -85,93 +86,106 @@ export function useProposalCountdown(proposal: FractalProposal) {
};
}, [secondsLeft, loadDAOProposals, proposal, updateProposalState, governance.type, dao]);
- useEffect(() => {
- let countdownInterval: NodeJS.Timer | undefined;
-
- // continually calculates the initial time (in ms) - the current time (in ms)
- // then converts it to seconds, all on a 1 second interval
- const startCountdown = (initialTimeMs: number) => {
- countdownInterval = setInterval(() => {
- setSecondsLeft(Math.floor((initialTimeMs - Date.now()) / 1000));
- }, 1000);
- };
-
- async function getCountdown() {
- const freezeGuard =
- freezeGuardType === FreezeGuardType.MULTISIG
- ? baseContracts?.multisigFreezeGuardMasterCopyContract.asProvider
- : freezeGuardType === FreezeGuardType.AZORIUS
- ? (baseContracts?.azoriusFreezeGuardMasterCopyContract.asProvider as AzoriusFreezeGuard)
- : undefined;
-
- const isSafeGuard = freezeGuardType === FreezeGuardType.MULTISIG;
- const isAzoriusGuard = freezeGuardType === FreezeGuardType.AZORIUS;
-
- const timeLockPeriod = azoriusGovernance.votingStrategy?.timeLockPeriod;
- const votingDeadlineMs = (proposal as AzoriusProposal).deadlineMs;
-
- // If the proposal is active and has a deadline, start the countdown (for Azorius proposals)
- if (proposal.state === FractalProposalState.ACTIVE && votingDeadlineMs) {
- startCountdown(votingDeadlineMs);
- } else if (
- // If the proposal is timelocked and has a deadline, start the countdown (for Azorius proposals)
- proposal.state === FractalProposalState.TIMELOCKED &&
- votingDeadlineMs &&
- timeLockPeriod
- ) {
- startCountdown(votingDeadlineMs + Number(timeLockPeriod.value) * 1000);
- // If the proposal is timelocked start the countdown (for safe multisig proposals with guards)
- } else if (
- proposal.state === FractalProposalState.TIMELOCKED &&
- freezeGuard &&
- isSafeGuard &&
- provider
- ) {
+ const startCountdown = useCallback((initialTimeMs: number) => {
+ countdownInterval.current = setInterval(() => {
+ setSecondsLeft(Math.floor((initialTimeMs - Date.now()) / 1000));
+ }, 1000);
+ }, []);
+
+ const getCountdown = useCallback(async () => {
+ if (!baseContracts) return;
+ const freezeGuard =
+ freezeGuardType === FreezeGuardType.MULTISIG
+ ? baseContracts.multisigFreezeGuardMasterCopyContract.asSigner.attach(
+ freezeGuardContractAddress || '0x',
+ )
+ : freezeGuardType === FreezeGuardType.AZORIUS
+ ? (baseContracts.azoriusFreezeGuardMasterCopyContract.asSigner.attach(
+ freezeGuardContractAddress || '0x',
+ ) as AzoriusFreezeGuard)
+ : undefined;
+
+ const isSafeGuard = freezeGuardType === FreezeGuardType.MULTISIG;
+ const isAzoriusGuard = freezeGuardType === FreezeGuardType.AZORIUS;
+
+ const timeLockPeriod = azoriusGovernance.votingStrategy?.timeLockPeriod;
+ const votingDeadlineMs = (proposal as AzoriusProposal).deadlineMs;
+
+ // If the proposal is active and has a deadline, start the countdown (for Azorius proposals)
+ if (proposal.state === FractalProposalState.ACTIVE && votingDeadlineMs) {
+ startCountdown(votingDeadlineMs);
+ return;
+ } else if (
+ // If the proposal is timelocked and has a deadline, start the countdown (for Azorius proposals)
+ proposal.state === FractalProposalState.TIMELOCKED &&
+ votingDeadlineMs &&
+ timeLockPeriod
+ ) {
+ startCountdown(votingDeadlineMs + Number(timeLockPeriod.value) * 1000);
+ // If the proposal is timelocked start the countdown (for safe multisig proposals with guards)
+ return;
+ } else if (
+ proposal.state === FractalProposalState.TIMELOCKED &&
+ freezeGuard &&
+ isSafeGuard &&
+ provider
+ ) {
+ const safeGuard = freezeGuard as MultisigFreezeGuard;
+ const timelockedTimestamp = await getTxTimelockedTimestamp(proposal, safeGuard, provider);
+ const guardTimeLockPeriod = await blocksToSeconds(await safeGuard.timelockPeriod(), provider);
+ startCountdown(timelockedTimestamp * 1000 + guardTimeLockPeriod * 1000);
+ // If the proposal is executable start the countdown (for safe multisig proposals with guards)
+ return;
+ } else if (proposal.state === FractalProposalState.EXECUTABLE && freezeGuard) {
+ let guardTimelockPeriod: number = 0;
+ if (isSafeGuard && provider) {
const safeGuard = freezeGuard as MultisigFreezeGuard;
- const timelockedTimestamp = await getTxTimelockedTimestamp(proposal, safeGuard, provider);
- const guardTimeLockPeriod = await blocksToSeconds(
- await safeGuard.timelockPeriod(),
- provider,
- );
- startCountdown(timelockedTimestamp * 1000 + guardTimeLockPeriod * 1000);
- // If the proposal is executable start the countdown (for safe multisig proposals with guards)
- } else if (proposal.state === FractalProposalState.EXECUTABLE && freezeGuard) {
- let guardTimelockPeriod: number = 0;
- if (isSafeGuard && provider) {
- const safeGuard = freezeGuard as MultisigFreezeGuard;
- const timelockedTimestamp =
- (await getTxTimelockedTimestamp(proposal, safeGuard, provider)) * 1000;
- const safeGuardTimelockPeriod =
- (await blocksToSeconds(await safeGuard.timelockPeriod(), provider)) * 1000;
- const guardExecutionPeriod =
- (await blocksToSeconds(await safeGuard.executionPeriod(), provider)) * 1000;
- guardTimelockPeriod =
- timelockedTimestamp + safeGuardTimelockPeriod + guardExecutionPeriod;
-
- // If the proposal is executing start the countdown (for Azorius proposals with guards)
- } else if (isAzoriusGuard && timeLockPeriod && votingDeadlineMs) {
- guardTimelockPeriod = timeLockPeriod.value.toNumber() * 1000 + votingDeadlineMs;
- }
- startCountdown(guardTimelockPeriod);
- } else if (isSnapshotProposal && proposal.state === FractalProposalState.PENDING) {
- startCountdown(snapshotProposal.startTime * 1000);
- } else if (isSnapshotProposal) {
- startCountdown(snapshotProposal.endTime * 1000);
+ const timelockedTimestamp =
+ (await getTxTimelockedTimestamp(proposal, safeGuard, provider)) * 1000;
+ const safeGuardTimelockPeriod =
+ (await blocksToSeconds(await safeGuard.timelockPeriod(), provider)) * 1000;
+ const guardExecutionPeriod =
+ (await blocksToSeconds(await safeGuard.executionPeriod(), provider)) * 1000;
+ guardTimelockPeriod = timelockedTimestamp + safeGuardTimelockPeriod + guardExecutionPeriod;
+
+ // If the proposal is executing start the countdown (for Azorius proposals with guards)
+ return;
+ } else if (isAzoriusGuard && timeLockPeriod && votingDeadlineMs) {
+ guardTimelockPeriod = timeLockPeriod.value.toNumber() * 1000 + votingDeadlineMs;
}
+ startCountdown(guardTimelockPeriod);
+ return;
+ } else if (isSnapshotProposal && proposal.state === FractalProposalState.PENDING) {
+ startCountdown(snapshotProposal.startTime * 1000);
+ return;
+ } else if (isSnapshotProposal) {
+ startCountdown(snapshotProposal.endTime * 1000);
+ return;
}
+ }, [
+ freezeGuardType,
+ baseContracts,
+ azoriusGovernance.votingStrategy,
+ provider,
+ proposal,
+ startCountdown,
+ isSnapshotProposal,
+ snapshotProposal,
+ freezeGuardContractAddress,
+ ]);
+
+ useEffect(() => {
+ if (!baseContracts) return;
+ // continually calculates the initial time (in ms) - the current time (in ms)
+ // then converts it to seconds, all on a 1 second interval
getCountdown();
return () => {
- clearInterval(countdownInterval);
+ clearInterval(countdownInterval.current);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
- }, [
- proposal.state,
- azoriusGovernance.votingStrategy,
- freezeGuardContractAddress,
- freezeGuardType,
- ]);
+ }, [proposal.state, azoriusGovernance.votingStrategy, freezeGuardType, baseContracts]);
return secondsLeft;
}
diff --git a/src/hooks/utils/useSafeTransactions.ts b/src/hooks/utils/useSafeTransactions.ts
index e9c46c08ed..3d0bf3cd0c 100644
--- a/src/hooks/utils/useSafeTransactions.ts
+++ b/src/hooks/utils/useSafeTransactions.ts
@@ -320,20 +320,19 @@ export const useSafeTransactions = () => {
let freezeGuard: MultisigFreezeGuard | undefined;
let freezeGuardData: FreezeGuardData | undefined;
+
if (guardContracts.freezeGuardContractAddress && baseContracts) {
const blockNumber = await provider.getBlockNumber();
- const averageBlockTime = await getAverageBlockTime(provider);
-
+ const averageBlockTime = BigNumber.from(Math.round(await getAverageBlockTime(provider)));
freezeGuard = baseContracts.multisigFreezeGuardMasterCopyContract.asSigner.attach(
guardContracts.freezeGuardContractAddress,
);
+
+ const timelockPeriod = BigNumber.from(await freezeGuard.timelockPeriod());
+ const executionPeriod = BigNumber.from(await freezeGuard.executionPeriod());
freezeGuardData = {
- guardTimelockPeriodMs: BigNumber.from(
- (await freezeGuard.timelockPeriod()) * averageBlockTime * 1000,
- ),
- guardExecutionPeriodMs: BigNumber.from(
- (await freezeGuard.executionPeriod()) * averageBlockTime * 1000,
- ),
+ guardTimelockPeriodMs: BigNumber.from(timelockPeriod.mul(averageBlockTime).mul(1000)),
+ guardExecutionPeriodMs: BigNumber.from(executionPeriod.mul(averageBlockTime).mul(1000)),
lastBlock: await provider.getBlock(blockNumber),
};
}
From bfb199a92e74c8d8717f80127433d1b90db42cba Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 15:59:23 -0400
Subject: [PATCH 12/30] fix display data
---
src/components/pages/DaoDashboard/Info/InfoGovernance.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx b/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
index 20bb18f4c9..122f838270 100644
--- a/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
+++ b/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
@@ -33,7 +33,7 @@ export function InfoGovernance() {
if (freezeGuardType == FreezeGuardType.MULTISIG) {
if (freezeGuardContractAddress && baseContracts) {
const freezeGuardContract =
- baseContracts.multisigFreezeGuardMasterCopyContract.asProvider;
+ baseContracts.multisigFreezeGuardMasterCopyContract.asProvider.attach(freezeGuardContractAddress);
setTimelockPeriod(await formatBlocks(await freezeGuardContract.timelockPeriod()));
setExecutionPeriod(await formatBlocks(await freezeGuardContract.executionPeriod()));
}
From 0529690b7254d1c53517efe6de4ef0f897b16aa9 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 16:05:51 -0400
Subject: [PATCH 13/30] run pretty/lint
---
src/components/pages/DaoDashboard/Info/InfoGovernance.tsx | 4 +++-
src/components/pages/DaoHierarchy/DaoNode.tsx | 1 -
.../DAO/loaders/governance/useERC721LinearStrategy.ts | 2 +-
src/hooks/DAO/loaders/useFractalGovernance.ts | 7 +++----
src/hooks/DAO/loaders/useFractalGuardContracts.ts | 5 +++--
src/hooks/DAO/loaders/useFractalNode.ts | 2 +-
src/hooks/utils/useSafeTransactions.ts | 1 -
src/providers/App/guardContracts/action.ts | 2 +-
src/providers/App/guardContracts/reducer.ts | 2 +-
src/types/fractal.ts | 3 ++-
10 files changed, 15 insertions(+), 14 deletions(-)
diff --git a/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx b/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
index 122f838270..a2362e67f4 100644
--- a/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
+++ b/src/components/pages/DaoDashboard/Info/InfoGovernance.tsx
@@ -33,7 +33,9 @@ export function InfoGovernance() {
if (freezeGuardType == FreezeGuardType.MULTISIG) {
if (freezeGuardContractAddress && baseContracts) {
const freezeGuardContract =
- baseContracts.multisigFreezeGuardMasterCopyContract.asProvider.attach(freezeGuardContractAddress);
+ baseContracts.multisigFreezeGuardMasterCopyContract.asProvider.attach(
+ freezeGuardContractAddress,
+ );
setTimelockPeriod(await formatBlocks(await freezeGuardContract.timelockPeriod()));
setExecutionPeriod(await formatBlocks(await freezeGuardContract.executionPeriod()));
}
diff --git a/src/components/pages/DaoHierarchy/DaoNode.tsx b/src/components/pages/DaoHierarchy/DaoNode.tsx
index 1011d11c47..0f2a4a490e 100644
--- a/src/components/pages/DaoHierarchy/DaoNode.tsx
+++ b/src/components/pages/DaoHierarchy/DaoNode.tsx
@@ -82,7 +82,6 @@ export function DaoNode({
}
}, [loadDao, daoAddress, depth]);
-
return (
{
const {
governanceContracts: { erc721LinearVotingContractAddress, azoriusContractAddress },
- governance: {type},
+ governance: { type },
action,
} = useFractal();
const provider = useEthersProvider();
diff --git a/src/hooks/DAO/loaders/useFractalGovernance.ts b/src/hooks/DAO/loaders/useFractalGovernance.ts
index 33e1bebaf1..7faea6934d 100644
--- a/src/hooks/DAO/loaders/useFractalGovernance.ts
+++ b/src/hooks/DAO/loaders/useFractalGovernance.ts
@@ -108,7 +108,6 @@ export const useFractalGovernance = () => {
});
}
}
-
}, [
governanceContracts,
loadUnderlyingERC20Token,
@@ -118,16 +117,16 @@ export const useFractalGovernance = () => {
loadERC721Strategy,
loadERC721Tokens,
action,
- type
+ type,
]);
useEffect(() => {
- const newLoadKey = (daoAddress || "0x");
+ const newLoadKey = daoAddress || '0x';
if (type && daoAddress && daoAddress !== loadKey.current && isGuardLoaded) {
loadKey.current = newLoadKey;
loadDAOProposals();
}
- if(!type || !daoAddress) {
+ if (!type || !daoAddress) {
loadKey.current = undefined;
}
}, [type, loadDAOProposals, isGuardLoaded, daoAddress]);
diff --git a/src/hooks/DAO/loaders/useFractalGuardContracts.ts b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
index dbffcef7bb..be37880f9b 100644
--- a/src/hooks/DAO/loaders/useFractalGuardContracts.ts
+++ b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
@@ -22,7 +22,7 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
action,
} = useFractal();
- const baseContracts = useSafeContracts()
+ const baseContracts = useSafeContracts();
const { chainId } = useNetworkConfig();
@@ -119,7 +119,8 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
loadOnMount &&
daoAddress &&
daoAddress + chainId !== loadKey.current &&
- isHierarchyLoaded && safe
+ isHierarchyLoaded &&
+ safe
) {
loadKey.current = daoAddress + chainId;
setGuardContracts();
diff --git a/src/hooks/DAO/loaders/useFractalNode.ts b/src/hooks/DAO/loaders/useFractalNode.ts
index 8e5afc7157..e2dc9a1d9c 100644
--- a/src/hooks/DAO/loaders/useFractalNode.ts
+++ b/src/hooks/DAO/loaders/useFractalNode.ts
@@ -132,7 +132,7 @@ export const useFractalNode = ({ daoAddress }: { daoAddress?: string }) => {
if (daoAddress && chainId + daoAddress !== currentValidSafe.current) {
setNodeLoading(true);
setDAO(chainId, daoAddress);
- currentValidSafe.current = chainId + daoAddress
+ currentValidSafe.current = chainId + daoAddress;
}
if (!daoAddress) {
currentValidSafe.current = undefined;
diff --git a/src/hooks/utils/useSafeTransactions.ts b/src/hooks/utils/useSafeTransactions.ts
index 3d0bf3cd0c..52ff74d277 100644
--- a/src/hooks/utils/useSafeTransactions.ts
+++ b/src/hooks/utils/useSafeTransactions.ts
@@ -320,7 +320,6 @@ export const useSafeTransactions = () => {
let freezeGuard: MultisigFreezeGuard | undefined;
let freezeGuardData: FreezeGuardData | undefined;
-
if (guardContracts.freezeGuardContractAddress && baseContracts) {
const blockNumber = await provider.getBlockNumber();
const averageBlockTime = BigNumber.from(Math.round(await getAverageBlockTime(provider)));
diff --git a/src/providers/App/guardContracts/action.ts b/src/providers/App/guardContracts/action.ts
index 3451394e20..8c990905a3 100644
--- a/src/providers/App/guardContracts/action.ts
+++ b/src/providers/App/guardContracts/action.ts
@@ -6,5 +6,5 @@ export enum GuardContractAction {
export type GuardContractActions = {
type: GuardContractAction.SET_GUARD_CONTRACT;
- payload: Omit;
+ payload: Omit;
};
diff --git a/src/providers/App/guardContracts/reducer.ts b/src/providers/App/guardContracts/reducer.ts
index 21905c5501..6c28d6674c 100644
--- a/src/providers/App/guardContracts/reducer.ts
+++ b/src/providers/App/guardContracts/reducer.ts
@@ -14,7 +14,7 @@ export const guardContractReducer = (
) => {
switch (action.type) {
case GuardContractAction.SET_GUARD_CONTRACT:
- return {...action.payload, isGuardLoaded: true};
+ return { ...action.payload, isGuardLoaded: true };
default:
return state;
}
diff --git a/src/types/fractal.ts b/src/types/fractal.ts
index 0b1cb964ed..94223dd398 100644
--- a/src/types/fractal.ts
+++ b/src/types/fractal.ts
@@ -243,7 +243,8 @@ export interface FractalNode {
proposalTemplatesHash?: string;
}
-export interface Node extends Omit {}
+export interface Node
+ extends Omit {}
export interface FractalModuleData {
moduleContract: Azorius | FractalModule | undefined;
From 881c844875589e554a4c9440fc1830df95ea6074 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Sun, 24 Mar 2024 18:16:06 -0400
Subject: [PATCH 14/30] remove extra casting
---
src/hooks/utils/useSafeTransactions.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hooks/utils/useSafeTransactions.ts b/src/hooks/utils/useSafeTransactions.ts
index 52ff74d277..f495c075a6 100644
--- a/src/hooks/utils/useSafeTransactions.ts
+++ b/src/hooks/utils/useSafeTransactions.ts
@@ -330,8 +330,8 @@ export const useSafeTransactions = () => {
const timelockPeriod = BigNumber.from(await freezeGuard.timelockPeriod());
const executionPeriod = BigNumber.from(await freezeGuard.executionPeriod());
freezeGuardData = {
- guardTimelockPeriodMs: BigNumber.from(timelockPeriod.mul(averageBlockTime).mul(1000)),
- guardExecutionPeriodMs: BigNumber.from(executionPeriod.mul(averageBlockTime).mul(1000)),
+ guardTimelockPeriodMs: timelockPeriod.mul(averageBlockTime).mul(1000),
+ guardExecutionPeriodMs: executionPeriod.mul(averageBlockTime).mul(1000),
lastBlock: await provider.getBlock(blockNumber),
};
}
From 422484bf4fa560e2d37416593966a8032d336f74 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Mon, 25 Mar 2024 16:24:55 -0400
Subject: [PATCH 15/30] remove redundent func call
---
src/hooks/DAO/loaders/useProposals.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/hooks/DAO/loaders/useProposals.ts b/src/hooks/DAO/loaders/useProposals.ts
index 482af484fd..7d487f7c94 100644
--- a/src/hooks/DAO/loaders/useProposals.ts
+++ b/src/hooks/DAO/loaders/useProposals.ts
@@ -18,6 +18,7 @@ export const useDAOProposals = () => {
const loadSafeMultisigProposals = useSafeMultisigProposals();
const loadDAOProposals = useCallback(async () => {
+ clearIntervals();
if (type === GovernanceType.AZORIUS_ERC20 || type === GovernanceType.AZORIUS_ERC721) {
// load Azorius proposals and strategies
const proposals = await loadAzoriusProposals();
@@ -25,10 +26,8 @@ export const useDAOProposals = () => {
type: FractalGovernanceAction.SET_PROPOSALS,
payload: proposals,
});
- clearIntervals();
} else if (type === GovernanceType.MULTISIG) {
// load mulisig proposals
- clearIntervals();
setMethodOnInterval(loadSafeMultisigProposals);
}
}, [
From fae4b78d3b8ffc0bf84b444e7dbbcb992f46cc93 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Mon, 25 Mar 2024 16:29:48 -0400
Subject: [PATCH 16/30] add missing attached addresses
---
src/hooks/DAO/useCastFreezeVote.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/hooks/DAO/useCastFreezeVote.ts b/src/hooks/DAO/useCastFreezeVote.ts
index 937e31e7c3..058b407cb3 100644
--- a/src/hooks/DAO/useCastFreezeVote.ts
+++ b/src/hooks/DAO/useCastFreezeVote.ts
@@ -33,7 +33,7 @@ const useCastFreezeVote = ({
contractFn: () => {
if (freezeVotingType === FreezeVotingType.ERC721) {
const freezeERC721VotingContract =
- baseContracts.freezeERC721VotingMasterCopyContract.asSigner;
+ baseContracts.freezeERC721VotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress);
return getUserERC721VotingTokens(undefined, parentAddress).then(tokensInfo =>
freezeERC721VotingContract['castFreezeVote(address[],uint256[])'](
tokensInfo.totalVotingTokenAddresses,
@@ -42,7 +42,7 @@ const useCastFreezeVote = ({
);
} else {
const freezeVotingContract =
- baseContracts.freezeMultisigVotingMasterCopyContract.asSigner;
+ baseContracts.freezeMultisigVotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress);
return freezeVotingContract.castFreezeVote();
}
},
From e2933f36c42bad5800eea268ea3d83242b40f66b Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Mon, 25 Mar 2024 16:33:38 -0400
Subject: [PATCH 17/30] fix missing attached address
---
src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
index da5bb0a249..50801f833c 100644
--- a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
+++ b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
@@ -55,6 +55,7 @@ export function ManageDAOMenu({
const {
node: { safe },
governance: { type },
+ guardContracts: { freezeVotingContractAddress },
} = useFractal();
const baseContracts = useSafeContracts();
const currentTime = BigNumber.from(useBlockTimestamp());
@@ -139,8 +140,8 @@ export function ManageDAOMenu({
const freezeOption = {
optionKey: 'optionInitiateFreeze',
onClick: () => {
- const freezeVotingContract = baseContracts?.freezeMultisigVotingMasterCopyContract.asSigner;
- const freezeVotingType = guardContracts?.freezeVotingType;
+ const freezeVotingContract = baseContracts!.freezeMultisigVotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress!);
+ const freezeVotingType = guardContracts!.freezeVotingType;
if (freezeVotingContract) {
if (
freezeVotingType === FreezeVotingType.MULTISIG ||
@@ -150,8 +151,8 @@ export function ManageDAOMenu({
} else if (freezeVotingType === FreezeVotingType.ERC721) {
getUserERC721VotingTokens(undefined, parentAddress).then(tokensInfo => {
const freezeERC721VotingContract =
- baseContracts?.freezeERC721VotingMasterCopyContract.asSigner;
- return freezeERC721VotingContract['castFreezeVote(address[],uint256[])'](
+ baseContracts!.freezeERC721VotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress!);
+ return freezeERC721VotingContract!['castFreezeVote(address[],uint256[])'](
tokensInfo.totalVotingTokenAddresses,
tokensInfo.totalVotingTokenIds,
);
@@ -236,6 +237,7 @@ export function ManageDAOMenu({
handleNavigateToSettings,
getUserERC721VotingTokens,
baseContracts,
+ freezeVotingContractAddress
]);
return (
From 5b40d562723f7f3470990610fb4d02179d87197d Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Mon, 25 Mar 2024 16:44:24 -0400
Subject: [PATCH 18/30] remove unneeded dependencies
---
src/components/ui/proposal/useProposalCountdown.tsx | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/components/ui/proposal/useProposalCountdown.tsx b/src/components/ui/proposal/useProposalCountdown.tsx
index b4ae3d837c..b3d7e832e9 100644
--- a/src/components/ui/proposal/useProposalCountdown.tsx
+++ b/src/components/ui/proposal/useProposalCountdown.tsx
@@ -184,8 +184,7 @@ export function useProposalCountdown(proposal: FractalProposal) {
return () => {
clearInterval(countdownInterval.current);
};
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [proposal.state, azoriusGovernance.votingStrategy, freezeGuardType, baseContracts]);
+ }, [baseContracts, getCountdown]);
return secondsLeft;
}
From 2b9533d6406e03e79405a52db1b0e166ac4b0e08 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Mon, 25 Mar 2024 16:45:05 -0400
Subject: [PATCH 19/30] run pretty/lint
---
src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx | 11 ++++++++---
src/hooks/DAO/useCastFreezeVote.ts | 8 ++++++--
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
index 50801f833c..e8c5177dd1 100644
--- a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
+++ b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
@@ -140,7 +140,10 @@ export function ManageDAOMenu({
const freezeOption = {
optionKey: 'optionInitiateFreeze',
onClick: () => {
- const freezeVotingContract = baseContracts!.freezeMultisigVotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress!);
+ const freezeVotingContract =
+ baseContracts!.freezeMultisigVotingMasterCopyContract.asSigner.attach(
+ freezeVotingContractAddress!,
+ );
const freezeVotingType = guardContracts!.freezeVotingType;
if (freezeVotingContract) {
if (
@@ -151,7 +154,9 @@ export function ManageDAOMenu({
} else if (freezeVotingType === FreezeVotingType.ERC721) {
getUserERC721VotingTokens(undefined, parentAddress).then(tokensInfo => {
const freezeERC721VotingContract =
- baseContracts!.freezeERC721VotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress!);
+ baseContracts!.freezeERC721VotingMasterCopyContract.asSigner.attach(
+ freezeVotingContractAddress!,
+ );
return freezeERC721VotingContract!['castFreezeVote(address[],uint256[])'](
tokensInfo.totalVotingTokenAddresses,
tokensInfo.totalVotingTokenIds,
@@ -237,7 +242,7 @@ export function ManageDAOMenu({
handleNavigateToSettings,
getUserERC721VotingTokens,
baseContracts,
- freezeVotingContractAddress
+ freezeVotingContractAddress,
]);
return (
diff --git a/src/hooks/DAO/useCastFreezeVote.ts b/src/hooks/DAO/useCastFreezeVote.ts
index 058b407cb3..44658cdfe1 100644
--- a/src/hooks/DAO/useCastFreezeVote.ts
+++ b/src/hooks/DAO/useCastFreezeVote.ts
@@ -33,7 +33,9 @@ const useCastFreezeVote = ({
contractFn: () => {
if (freezeVotingType === FreezeVotingType.ERC721) {
const freezeERC721VotingContract =
- baseContracts.freezeERC721VotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress);
+ baseContracts.freezeERC721VotingMasterCopyContract.asSigner.attach(
+ freezeVotingContractAddress,
+ );
return getUserERC721VotingTokens(undefined, parentAddress).then(tokensInfo =>
freezeERC721VotingContract['castFreezeVote(address[],uint256[])'](
tokensInfo.totalVotingTokenAddresses,
@@ -42,7 +44,9 @@ const useCastFreezeVote = ({
);
} else {
const freezeVotingContract =
- baseContracts.freezeMultisigVotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress);
+ baseContracts.freezeMultisigVotingMasterCopyContract.asSigner.attach(
+ freezeVotingContractAddress,
+ );
return freezeVotingContract.castFreezeVote();
}
},
From abecdb9df54849240e06a75082da44241be829bc Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Mon, 25 Mar 2024 16:49:15 -0400
Subject: [PATCH 20/30] switch to asProvider
---
src/hooks/DAO/loaders/useFractalFreeze.ts | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/hooks/DAO/loaders/useFractalFreeze.ts b/src/hooks/DAO/loaders/useFractalFreeze.ts
index 0937f777fa..10f6abd90c 100644
--- a/src/hooks/DAO/loaders/useFractalFreeze.ts
+++ b/src/hooks/DAO/loaders/useFractalFreeze.ts
@@ -60,7 +60,7 @@ export const useFractalFreeze = ({
// @dev using freeze 'multisig' contract but these functions are the same for all freeze types
const freezeVotingContract =
- baseContracts.freezeMultisigVotingMasterCopyContract.asSigner.attach(
+ baseContracts.freezeMultisigVotingMasterCopyContract.asProvider.attach(
freezeVotingContractAddress,
);
let userHasVotes: boolean = false;
@@ -106,7 +106,7 @@ export const useFractalFreeze = ({
const owners = await safeContract.getOwners();
userHasVotes = owners.find(owner => owner === account) !== undefined;
} else if (freezeVotingType === FreezeVotingType.ERC20) {
- const freezeERC20VotingContract = freezeERC20VotingMasterCopyContract.asSigner.attach(
+ const freezeERC20VotingContract = freezeERC20VotingMasterCopyContract.asProvider.attach(
freezeVotingContractAddress,
);
const votesTokenContract = votesTokenMasterCopyContract!.asProvider.attach(
@@ -185,7 +185,7 @@ export const useFractalFreeze = ({
// @dev using freeze 'multisig' contract but these functions are the same for all freeze types
let votingRPC: MultisigFreezeVoting | ERC20FreezeVoting | ERC721FreezeVoting =
- freezeMultisigVotingMasterCopyContract.asSigner.attach(freezeVotingContractAddress);
+ freezeMultisigVotingMasterCopyContract.asProvider.attach(freezeVotingContractAddress);
const listenerCallback: TypedListener = async (
voter: string,
From 69ed790e3daea7626c1d8a7420d302a98e048ec5 Mon Sep 17 00:00:00 2001
From: Adam Gall
Date: Mon, 25 Mar 2024 17:36:36 -0400
Subject: [PATCH 21/30] Nitpick: removed extra newline
---
src/hooks/DAO/loaders/useFractalGuardContracts.ts | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/hooks/DAO/loaders/useFractalGuardContracts.ts b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
index be37880f9b..520e9f186c 100644
--- a/src/hooks/DAO/loaders/useFractalGuardContracts.ts
+++ b/src/hooks/DAO/loaders/useFractalGuardContracts.ts
@@ -19,7 +19,6 @@ export const useFractalGuardContracts = ({ loadOnMount = true }: { loadOnMount?:
const loadKey = useRef();
const {
node: { daoAddress, safe, fractalModules, isHierarchyLoaded },
-
action,
} = useFractal();
const baseContracts = useSafeContracts();
From 057f9110150fcc4fdaa1a9e6079482c5fc42cc72 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Mon, 25 Mar 2024 18:03:04 -0400
Subject: [PATCH 22/30] asSigner -> asProvider
---
src/hooks/utils/useSafeTransactions.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hooks/utils/useSafeTransactions.ts b/src/hooks/utils/useSafeTransactions.ts
index f495c075a6..770285063a 100644
--- a/src/hooks/utils/useSafeTransactions.ts
+++ b/src/hooks/utils/useSafeTransactions.ts
@@ -323,7 +323,7 @@ export const useSafeTransactions = () => {
if (guardContracts.freezeGuardContractAddress && baseContracts) {
const blockNumber = await provider.getBlockNumber();
const averageBlockTime = BigNumber.from(Math.round(await getAverageBlockTime(provider)));
- freezeGuard = baseContracts.multisigFreezeGuardMasterCopyContract.asSigner.attach(
+ freezeGuard = baseContracts.multisigFreezeGuardMasterCopyContract.asProvider.attach(
guardContracts.freezeGuardContractAddress,
);
From 7b34ac6060f086eee17ff9b4d002aada78241ee4 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Fri, 22 Mar 2024 23:44:22 -0400
Subject: [PATCH 23/30] reduce the number of requests by adding load key
---
.../DAO/loaders/governance/useERC20Claim.ts | 25 +++++++++++++++----
1 file changed, 20 insertions(+), 5 deletions(-)
diff --git a/src/hooks/DAO/loaders/governance/useERC20Claim.ts b/src/hooks/DAO/loaders/governance/useERC20Claim.ts
index c3ad1ff3a6..16032bcb62 100644
--- a/src/hooks/DAO/loaders/governance/useERC20Claim.ts
+++ b/src/hooks/DAO/loaders/governance/useERC20Claim.ts
@@ -1,4 +1,4 @@
-import { useEffect, useCallback } from 'react';
+import { useEffect, useCallback, useRef } from 'react';
import { useFractal } from '../../../../providers/App/AppProvider';
import { FractalGovernanceAction } from '../../../../providers/App/governance/action';
import useSafeContracts from '../../../safe/useSafeContracts';
@@ -15,13 +15,19 @@ export function useERC20Claim() {
} = useFractal();
const baseContracts = useSafeContracts();
const loadTokenClaimContract = useCallback(async () => {
- if (!baseContracts || !votesTokenContractAddress) return;
+ if (!baseContracts || !votesTokenContractAddress) {
+ return;
+ }
const { claimingMasterCopyContract } = baseContracts;
+
const votesTokenContract =
baseContracts.votesTokenMasterCopyContract.asProvider.attach(votesTokenContractAddress);
+
const approvalFilter = votesTokenContract.filters.Approval();
const approvals = await votesTokenContract.queryFilter(approvalFilter);
- if (!approvals.length) return;
+ if (!approvals.length) {
+ return;
+ }
const possibleTokenClaimContract = claimingMasterCopyContract.asProvider.attach(
approvals[0].args[1],
);
@@ -39,11 +45,20 @@ export function useERC20Claim() {
payload: possibleTokenClaimContract,
});
}, [baseContracts, votesTokenContractAddress, action]);
+ const loadKey = useRef();
useEffect(() => {
- if (daoAddress) {
+ if (
+ daoAddress &&
+ votesTokenContractAddress &&
+ daoAddress + votesTokenContractAddress !== loadKey.current
+ ) {
+ loadKey.current = daoAddress + votesTokenContractAddress;
loadTokenClaimContract();
}
- }, [loadTokenClaimContract, daoAddress]);
+ if (!daoAddress || !votesTokenContractAddress) {
+ loadKey.current = undefined;
+ }
+ }, [loadTokenClaimContract, daoAddress, votesTokenContractAddress]);
return;
}
From 69cdc16b5efffef995fda9a17a86922d955ccba8 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Wed, 27 Mar 2024 13:10:00 -0400
Subject: [PATCH 24/30] add check if DAOAddress has changed
---
src/hooks/DAO/useDAOController.ts | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/src/hooks/DAO/useDAOController.ts b/src/hooks/DAO/useDAOController.ts
index 568f4e92b6..8864103263 100644
--- a/src/hooks/DAO/useDAOController.ts
+++ b/src/hooks/DAO/useDAOController.ts
@@ -1,4 +1,4 @@
-import { useEffect } from 'react';
+import { useEffect, useRef } from 'react';
import { useParams } from 'react-router-dom';
import { useFractal } from '../../providers/App/AppProvider';
import { useERC20Claim } from './loaders/governance/useERC20Claim';
@@ -11,6 +11,7 @@ import { useFractalTreasury } from './loaders/useFractalTreasury';
import { useGovernanceContracts } from './loaders/useGovernanceContracts';
export default function useDAOController() {
+ const currentDAOAddress = useRef(null);
const { daoAddress } = useParams();
const {
node: {
@@ -19,12 +20,16 @@ export default function useDAOController() {
action,
} = useFractal();
useEffect(() => {
- if (!daoAddress) {
+ if (!daoAddress || daoAddress !== currentDAOAddress.current) {
action.resetDAO();
+ currentDAOAddress.current = null;
+ }
+ if (daoAddress && !currentDAOAddress.current) {
+ currentDAOAddress.current = daoAddress;
}
}, [action, daoAddress]);
- const { nodeLoading, errorLoading } = useFractalNode({ daoAddress });
+ const { nodeLoading, errorLoading } = useFractalNode({ daoAddress: currentDAOAddress.current || '' });
useGovernanceContracts();
useFractalGuardContracts({});
useFractalFreeze({ parentSafeAddress: parentAddress });
From 09d0d8db872671e5f4b3c8f0fae33a6883d77bfc Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Wed, 27 Mar 2024 13:35:10 -0400
Subject: [PATCH 25/30] reorder if statements; fix typing
---
src/hooks/DAO/useDAOController.ts | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/hooks/DAO/useDAOController.ts b/src/hooks/DAO/useDAOController.ts
index 8864103263..e32f61c932 100644
--- a/src/hooks/DAO/useDAOController.ts
+++ b/src/hooks/DAO/useDAOController.ts
@@ -11,7 +11,7 @@ import { useFractalTreasury } from './loaders/useFractalTreasury';
import { useGovernanceContracts } from './loaders/useGovernanceContracts';
export default function useDAOController() {
- const currentDAOAddress = useRef(null);
+ const currentDAOAddress = useRef();
const { daoAddress } = useParams();
const {
node: {
@@ -20,16 +20,16 @@ export default function useDAOController() {
action,
} = useFractal();
useEffect(() => {
- if (!daoAddress || daoAddress !== currentDAOAddress.current) {
- action.resetDAO();
- currentDAOAddress.current = null;
- }
if (daoAddress && !currentDAOAddress.current) {
currentDAOAddress.current = daoAddress;
}
+ if (!daoAddress || daoAddress !== currentDAOAddress.current) {
+ action.resetDAO();
+ currentDAOAddress.current = undefined;
+ }
}, [action, daoAddress]);
- const { nodeLoading, errorLoading } = useFractalNode({ daoAddress: currentDAOAddress.current || '' });
+ const { nodeLoading, errorLoading } = useFractalNode({ daoAddress: currentDAOAddress.current });
useGovernanceContracts();
useFractalGuardContracts({});
useFractalFreeze({ parentSafeAddress: parentAddress });
From 4482e2dd37c66a1d2767713ee97c62c7135db8ca Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Wed, 27 Mar 2024 13:59:48 -0400
Subject: [PATCH 26/30] initiate freeze from heirarchy; - move freezeOption to
own memo - update logic to use prop guardcontract instead of global state
---
.../ui/menus/ManageDAO/ManageDAOMenu.tsx | 38 ++++++++++---------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
index e8c5177dd1..ec03a63fe9 100644
--- a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
+++ b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
@@ -55,7 +55,6 @@ export function ManageDAOMenu({
const {
node: { safe },
governance: { type },
- guardContracts: { freezeVotingContractAddress },
} = useFractal();
const baseContracts = useSafeContracts();
const currentTime = BigNumber.from(useBlockTimestamp());
@@ -131,18 +130,13 @@ export function ManageDAOMenu({
const handleModifyGovernance = useFractalModal(ModalType.CONFIRM_MODIFY_GOVERNANCE);
- const options = useMemo(() => {
- const createSubDAOOption = {
- optionKey: 'optionCreateSubDAO',
- onClick: () => navigate(DAO_ROUTES.newSubDao.relative(safeAddress), { replace: true }),
- };
-
- const freezeOption = {
+ const freezeOption = useMemo(
+ () => ({
optionKey: 'optionInitiateFreeze',
onClick: () => {
const freezeVotingContract =
baseContracts!.freezeMultisigVotingMasterCopyContract.asSigner.attach(
- freezeVotingContractAddress!,
+ guardContracts!.freezeVotingContractAddress!,
);
const freezeVotingType = guardContracts!.freezeVotingType;
if (freezeVotingContract) {
@@ -150,12 +144,14 @@ export function ManageDAOMenu({
freezeVotingType === FreezeVotingType.MULTISIG ||
freezeVotingType === FreezeVotingType.ERC20
) {
- (freezeVotingContract as ERC20FreezeVoting | MultisigFreezeVoting).castFreezeVote();
+ return (
+ freezeVotingContract as ERC20FreezeVoting | MultisigFreezeVoting
+ ).castFreezeVote();
} else if (freezeVotingType === FreezeVotingType.ERC721) {
getUserERC721VotingTokens(undefined, parentAddress).then(tokensInfo => {
const freezeERC721VotingContract =
baseContracts!.freezeERC721VotingMasterCopyContract.asSigner.attach(
- freezeVotingContractAddress!,
+ guardContracts!.freezeVotingContractAddress!,
);
return freezeERC721VotingContract!['castFreezeVote(address[],uint256[])'](
tokensInfo.totalVotingTokenAddresses,
@@ -165,8 +161,20 @@ export function ManageDAOMenu({
}
}
},
- };
+ }),
+ [
+ baseContracts,
+ guardContracts,
+ getUserERC721VotingTokens,
+ parentAddress,
+ ],
+ );
+ const options = useMemo(() => {
+ const createSubDAOOption = {
+ optionKey: 'optionCreateSubDAO',
+ onClick: () => navigate(DAO_ROUTES.newSubDao.relative(safeAddress), { replace: true }),
+ };
const clawBackOption = {
optionKey: 'optionInitiateClawback',
onClick: handleClawBack,
@@ -233,16 +241,12 @@ export function ManageDAOMenu({
currentTime,
navigate,
safeAddress,
- parentAddress,
governanceType,
- guardContracts,
handleClawBack,
canUserCreateProposal,
handleModifyGovernance,
handleNavigateToSettings,
- getUserERC721VotingTokens,
- baseContracts,
- freezeVotingContractAddress,
+ freezeOption,
]);
return (
From 90a8798b059d7a6a63c9c0ca8dd253001ef8c7e2 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Wed, 27 Mar 2024 14:00:51 -0400
Subject: [PATCH 27/30] run pretty/lint
---
src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
index ec03a63fe9..7dfd7e6186 100644
--- a/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
+++ b/src/components/ui/menus/ManageDAO/ManageDAOMenu.tsx
@@ -162,12 +162,7 @@ export function ManageDAOMenu({
}
},
}),
- [
- baseContracts,
- guardContracts,
- getUserERC721VotingTokens,
- parentAddress,
- ],
+ [baseContracts, guardContracts, getUserERC721VotingTokens, parentAddress],
);
const options = useMemo(() => {
From 678d48d9da1cdee4fbdbd1fd10cce14217b7e1ef Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Wed, 27 Mar 2024 22:25:09 -0400
Subject: [PATCH 28/30] Fix DAO state not reseting when switching DAOs
---
src/hooks/DAO/useDAOController.ts | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/hooks/DAO/useDAOController.ts b/src/hooks/DAO/useDAOController.ts
index 48161072a6..649bb2c6a1 100644
--- a/src/hooks/DAO/useDAOController.ts
+++ b/src/hooks/DAO/useDAOController.ts
@@ -22,10 +22,11 @@ export default function useDAOController() {
} = useFractal();
useEffect(() => {
if (daoAddress && !currentDAOAddress.current) {
- currentDAOAddress.current = daoAddress;
+ action.resetDAO().then(() => {
+ currentDAOAddress.current = daoAddress;
+ })
}
if (!daoAddress || daoAddress !== currentDAOAddress.current) {
- action.resetDAO();
currentDAOAddress.current = undefined;
}
}, [action, daoAddress]);
From c3ce72444b51c0fd1c68540e378a22b4eaa4e394 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Wed, 27 Mar 2024 22:28:29 -0400
Subject: [PATCH 29/30] fix freeze showing up when switching DAOs.
---
src/components/pages/DaoDashboard/Activities/index.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/components/pages/DaoDashboard/Activities/index.tsx b/src/components/pages/DaoDashboard/Activities/index.tsx
index aecd7dd7f8..009e63add1 100644
--- a/src/components/pages/DaoDashboard/Activities/index.tsx
+++ b/src/components/pages/DaoDashboard/Activities/index.tsx
@@ -14,6 +14,7 @@ import { useActivities } from './hooks/useActivities';
export function Activities() {
const {
+ guardContracts: { freezeVotingContractAddress },
guard,
governance: { type },
} = useFractal();
@@ -37,7 +38,7 @@ export function Activities() {
flexDirection="column"
gap="1rem"
>
- {guard.freezeProposalVoteCount?.gt(0) && }
+ {freezeVotingContractAddress && guard.freezeProposalVoteCount?.gt(0) && }
{!type ? (
) : sortedActivities.length ? (
From a48370eb4bf9df2b0580042d778e703e20804a87 Mon Sep 17 00:00:00 2001
From: David Colon <38386583+Da-Colon@users.noreply.github.com>
Date: Wed, 27 Mar 2024 22:28:44 -0400
Subject: [PATCH 30/30] run pretty/lint
---
src/hooks/DAO/useDAOController.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/hooks/DAO/useDAOController.ts b/src/hooks/DAO/useDAOController.ts
index 649bb2c6a1..f769dc91c1 100644
--- a/src/hooks/DAO/useDAOController.ts
+++ b/src/hooks/DAO/useDAOController.ts
@@ -24,7 +24,7 @@ export default function useDAOController() {
if (daoAddress && !currentDAOAddress.current) {
action.resetDAO().then(() => {
currentDAOAddress.current = daoAddress;
- })
+ });
}
if (!daoAddress || daoAddress !== currentDAOAddress.current) {
currentDAOAddress.current = undefined;