Skip to content

Commit

Permalink
[HOTFIX]: lock/unlock glm multisig fix (#365)
Browse files Browse the repository at this point in the history
  • Loading branch information
aziolek authored Jul 29, 2024
2 parents acb887a + 0d5115b commit 2fa4d30
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 8 deletions.
22 changes: 22 additions & 0 deletions client/src/api/calls/safeTransactions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { GenericAbortSignal } from 'axios';

import env from 'env';
import apiService from 'services/apiService';

export type Response = {
results: {
safeTxHash: string;
transactionHash?: string;
}[];
};

export async function apiGetSafeTransactions(
address: string,
signal?: GenericAbortSignal,
): Promise<Response> {
return apiService
.get(`${env.safeEndpoint}api/v1/safes/${address}/all-transactions/`, {
signal,
})
.then(({ data }) => data);
}
52 changes: 46 additions & 6 deletions client/src/components/Earn/EarnGlmLock/EarnGlmLock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { FC, useEffect, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useAccount, useWalletClient, usePublicClient, useWaitForTransactionReceipt } from 'wagmi';

import { apiGetSafeTransactions } from 'api/calls/safeTransactions';
import EarnGlmLockBudget from 'components/Earn/EarnGlmLock/EarnGlmLockBudget';
import EarnGlmLockNotification from 'components/Earn/EarnGlmLock/EarnGlmLockNotification';
import EarnGlmLockStepper from 'components/Earn/EarnGlmLock/EarnGlmLockStepper';
Expand All @@ -16,8 +17,11 @@ import useMediaQuery from 'hooks/helpers/useMediaQuery';
import useLock from 'hooks/mutations/useLock';
import useUnlock from 'hooks/mutations/useUnlock';
import useDepositValue from 'hooks/queries/useDepositValue';
import useEstimatedEffectiveDeposit from 'hooks/queries/useEstimatedEffectiveDeposit';
import useHistory from 'hooks/queries/useHistory';
import useIsContract from 'hooks/queries/useIsContract';
import useProjectsEpoch from 'hooks/queries/useProjectsEpoch';
import useLockedSummaryLatest from 'hooks/subgraph/useLockedSummaryLatest';
import toastService from 'services/toastService';
import useTransactionLocalStore from 'store/transactionLocal/store';
import { parseUnitsBigInt } from 'utils/parseUnitsBigInt';
Expand Down Expand Up @@ -52,12 +56,16 @@ const EarnGlmLock: FC<EarnGlmLockProps> = ({ currentMode, onCurrentModeChange, o
*/
const [valueToDepose, setValueToDepose] = useState<bigint>(BigInt(0));
const [step, setStep] = useState<Step>(1);
const [intervalId, setIntervalId] = useState<null | NodeJS.Timeout>(null);
const [isCryptoOrFiatInputFocused, setIsCryptoOrFiatInputFocused] = useState<boolean>(true);
const buttonUseMaxRef = useRef<HTMLButtonElement>(null);

const { data: availableFundsGlm } = useAvailableFundsGlm();
const { data: projectsEpoch } = useProjectsEpoch();
const { data: depositsValue } = useDepositValue();
const { refetch: refetchHistory } = useHistory();
const { data: depositsValue, refetch: refetchDeposit } = useDepositValue();
const { refetch: refetchEstimatedEffectiveDeposit } = useEstimatedEffectiveDeposit();
const { refetch: refetchLockedSummaryLatest } = useLockedSummaryLatest();

useEffect(() => {
if (transactionReceipt && !isLoadingTransactionReceipt) {
Expand Down Expand Up @@ -106,19 +114,40 @@ const EarnGlmLock: FC<EarnGlmLockProps> = ({ currentMode, onCurrentModeChange, o
};

const onSuccess = async ({ hash, value }): Promise<void> => {
if (isContract) {
const id = setInterval(async () => {
const nextSafeTransactions = await apiGetSafeTransactions(address!);
const safeTransaction = nextSafeTransactions.results.find(
t => t.safeTxHash === hash && t.transactionHash,
);

if (safeTransaction) {
clearInterval(id);
Promise.all([
refetchDeposit(),
refetchEstimatedEffectiveDeposit(),
refetchLockedSummaryLatest(),
refetchHistory(),
]).then(() => {
setTransactionHashForEtherscan(safeTransaction.transactionHash);
setStep(3);
});
}
}, 2000);
setIntervalId(id);
return;
}
addTransactionPending({
eventData: {
amount: value,
transactionHash: hash,
},
isMultisig: isContract,
isMultisig: !!isContract,
// GET /history uses seconds. Normalization here.
timestamp: Math.floor(Date.now() / 1000).toString(),
type: currentMode,
});
if (!isContract) {
setTransactionHashForEtherscan(hash);
}
setTransactionHashForEtherscan(hash);
};

const onReset: OnReset = ({ setFieldValue, newMode = 'lock' }) => {
Expand Down Expand Up @@ -159,6 +188,15 @@ const EarnGlmLock: FC<EarnGlmLockProps> = ({ currentMode, onCurrentModeChange, o
const isLockingApproved = approvalState === ApprovalState.APPROVED;
const isApprovalKnown = approvalState !== ApprovalState.UNKNOWN;

useEffect(() => {
return () => {
if (!intervalId) {
return;
}
clearInterval(intervalId);
};
}, [intervalId]);

return (
<Formik
initialValues={formInitialValues(currentMode)}
Expand Down Expand Up @@ -191,7 +229,9 @@ const EarnGlmLock: FC<EarnGlmLockProps> = ({ currentMode, onCurrentModeChange, o
buttonUseMaxRef={buttonUseMaxRef}
className={styles.element}
currentMode={currentMode}
isLoading={isLoadingTransactionReceipt || props.isSubmitting}
isLoading={
isLoadingTransactionReceipt || props.isSubmitting || (!!isContract && step === 2)
}
onClose={onCloseModal}
onInputsFocusChange={setIsCryptoOrFiatInputFocused}
onReset={onReset}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ const ModalOnboarding = (): ReactElement => {
const { isAllocateOnboardingAlwaysVisible } = useSettingsStore(state => ({
isAllocateOnboardingAlwaysVisible: state.data.isAllocateOnboardingAlwaysVisible,
}));
const isContract = useIsContract();
const { data: isContract } = useIsContract();

const [isUserTOSAcceptedInitial, setIsUserTOSAcceptedInitial] = useState(isUserTOSAccepted);

Expand Down
2 changes: 1 addition & 1 deletion client/src/hooks/queries/useIsContract.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { UseQueryResult } from '@tanstack/react-query';
import { useAccount, useBytecode } from 'wagmi';

export default function useIsContract(): UseQueryResult<boolean | undefined, unknown> {
export default function useIsContract(): UseQueryResult<string | undefined, unknown> {
const { address } = useAccount();

return useBytecode({
Expand Down

0 comments on commit 2fa4d30

Please sign in to comment.