Skip to content

Commit 5b0df8c

Browse files
0xghostedDevelopers
andauthored
Fix/v3.7 patch (#2953)
Co-authored-by: Developers <deverlopers@aave.com>
1 parent 838e627 commit 5b0df8c

7 files changed

Lines changed: 108 additions & 8 deletions

File tree

‎pages/api/preflight-compliance.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,19 @@ type ComplianceApiResponse = {
88
result: boolean;
99
lastChecked: string;
1010
nextCheck: string;
11+
useV37?: {
12+
wethGateway: string;
13+
uiPoolDataProvider: string;
14+
};
1115
};
1216

1317
type PreflightResponse = {
1418
result: boolean;
1519
nextCheck: string;
20+
useV37?: {
21+
wethGateway: string;
22+
uiPoolDataProvider: string;
23+
};
1624
};
1725

1826
type ErrorResponse = {
@@ -77,6 +85,7 @@ export default async function handler(
7785
return res.status(200).json({
7886
result: data.result,
7987
nextCheck: data.nextCheck,
88+
useV37: data.useV37,
8089
});
8190
} catch (error) {
8291
console.error('Compliance API error:', error);

‎src/components/transactions/Withdraw/WithdrawActions.tsx‎

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { ProtocolAction } from '@aave/contract-helpers';
1+
import { gasLimitRecommendations, ProtocolAction } from '@aave/contract-helpers';
22
import { valueToBigNumber } from '@aave/math-utils';
33
import { Trans } from '@lingui/macro';
44
import { BoxProps } from '@mui/material';
5+
import { BigNumber } from 'ethers';
6+
import { parseEther } from 'ethers/lib/utils';
57
import { useTransactionHandler } from 'src/helpers/useTransactionHandler';
68
import { ComputedReserveData } from 'src/hooks/app-data-provider/useAppDataProvider';
79
import { useRootStore } from 'src/store/root';
10+
import { useShallow } from 'zustand/shallow';
811

912
import { TxActionsWrapper } from '../TxActionsWrapper';
1013

@@ -15,6 +18,7 @@ export interface WithdrawActionsProps extends BoxProps {
1518
isWrongNetwork: boolean;
1619
symbol: string;
1720
blocked: boolean;
21+
nativeBalance: string;
1822
}
1923

2024
export const WithdrawActions = ({
@@ -24,19 +28,42 @@ export const WithdrawActions = ({
2428
isWrongNetwork,
2529
symbol,
2630
blocked,
31+
nativeBalance,
2732
sx,
2833
}: WithdrawActionsProps) => {
29-
const withdraw = useRootStore((state) => state.withdraw);
34+
const [withdraw, v37Overrides] = useRootStore(
35+
useShallow((state) => [state.withdraw, state.v37Overrides])
36+
);
3037

3138
const { action, loadingTxns, mainTxState, approvalTxState, approval, requiresApproval } =
3239
useTransactionHandler({
3340
tryPermit: false,
34-
handleGetTxns: async () =>
35-
withdraw({
41+
handleGetTxns: async () => {
42+
const txs = await withdraw({
3643
reserve: poolAddress,
3744
amount: amountToWithdraw,
3845
aTokenAddress: poolReserve.aTokenAddress,
39-
}),
46+
});
47+
48+
if (!v37Overrides) return txs;
49+
50+
const mappedTxs = txs.map((tx) => ({
51+
...tx,
52+
tx: async () => {
53+
const txData = await tx.tx();
54+
if (tx.txType === 'ERC20_APPROVAL') return txData;
55+
const balance = parseEther(nativeBalance);
56+
const gasBuffer = parseEther('0.05');
57+
const value = balance.gt(gasBuffer) ? balance.sub(gasBuffer).toString() : '0';
58+
return {
59+
...txData,
60+
value,
61+
gasLimit: BigNumber.from(gasLimitRecommendations[ProtocolAction.withdraw].recommended),
62+
};
63+
},
64+
}));
65+
return mappedTxs;
66+
},
4067
skip: !amountToWithdraw || parseFloat(amountToWithdraw) === 0 || blocked,
4168
deps: [amountToWithdraw, poolAddress],
4269
eventTxInfo: {

‎src/components/transactions/Withdraw/WithdrawModalContent.tsx‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export const WithdrawModalContent = ({
3939
setUnwrap: setWithdrawUnWrapped,
4040
symbol,
4141
isWrongNetwork,
42+
nativeBalance,
4243
user,
4344
}: ModalWrapperProps & {
4445
unwrap: boolean;
@@ -225,6 +226,7 @@ export const WithdrawModalContent = ({
225226
isWrongNetwork={isWrongNetwork}
226227
symbol={symbol}
227228
blocked={blockingError !== undefined || (displayRiskCheckbox && !riskCheckboxAccepted)}
229+
nativeBalance={nativeBalance}
228230
sx={displayRiskCheckbox ? { mt: 0 } : {}}
229231
/>
230232
</>

‎src/hooks/compliance/compliance.tsx‎

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
'use client';
22

33
import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
4+
import { useRootStore } from 'src/store/root';
45
import { useAccount } from 'wagmi';
56

67
import { checkCompliance } from './service-compliance';
78
import { useLocalStorageState } from './useLocalStorageState';
89

9-
const STORAGE_KEY = 'compliance-state';
10+
const STORAGE_KEY = 'compliance-state-v2';
1011
const MIN_REFRESH_MS = 60 * 1000; // 1 minute minimum between checks
1112

1213
export type ComplianceStatus = 'idle' | 'loading' | 'compliant' | 'non-compliant' | 'error';
@@ -29,6 +30,10 @@ type PersistedComplianceState = {
2930
[address: string]: {
3031
result: boolean;
3132
nextCheck: string;
33+
useV37?: {
34+
wethGateway: string;
35+
uiPoolDataProvider: string;
36+
};
3237
};
3338
};
3439

@@ -45,6 +50,7 @@ const isExpired = (nextCheck: string | null): boolean => {
4550

4651
export const ComplianceProvider = ({ children }: { children: React.ReactNode }) => {
4752
const { address, isConnected } = useAccount();
53+
const setV37Overrides = useRootStore((state) => state.setV37Overrides);
4854

4955
const [cache, setCache] = useLocalStorageState<PersistedComplianceState>(STORAGE_KEY, {
5056
defaultValue: {},
@@ -90,12 +96,22 @@ export const ComplianceProvider = ({ children }: { children: React.ReactNode })
9096
errorMessage: undefined,
9197
});
9298

99+
if (response.data.useV37) {
100+
setV37Overrides({
101+
WETH_GATEWAY: response.data.useV37.wethGateway,
102+
UI_POOL_DATA_PROVIDER: response.data.useV37.uiPoolDataProvider,
103+
});
104+
} else {
105+
setV37Overrides(null);
106+
}
107+
93108
// Update cache for this address
94109
setCache((prev) => ({
95110
...prev,
96111
[walletAddress.toLowerCase()]: {
97112
result: response.data!.result,
98113
nextCheck: response.data!.nextCheck,
114+
useV37: response.data!.useV37,
99115
},
100116
}));
101117

@@ -126,7 +142,7 @@ export const ComplianceProvider = ({ children }: { children: React.ReactNode })
126142
isCheckingRef.current = false;
127143
}
128144
},
129-
[setCache]
145+
[setCache, setV37Overrides]
130146
);
131147

132148
const recheck = useCallback(async () => {
@@ -159,6 +175,15 @@ export const ComplianceProvider = ({ children }: { children: React.ReactNode })
159175
nextCheck: cached.nextCheck,
160176
});
161177

178+
if (cached.useV37) {
179+
setV37Overrides({
180+
WETH_GATEWAY: cached.useV37.wethGateway,
181+
UI_POOL_DATA_PROVIDER: cached.useV37.uiPoolDataProvider,
182+
});
183+
} else {
184+
setV37Overrides(null);
185+
}
186+
162187
// Schedule refresh at nextCheck time
163188
if (cached.result) {
164189
const msUntilNextCheck = Math.max(

‎src/hooks/compliance/service-compliance.ts‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
export type ComplianceResult = {
22
result: boolean;
33
nextCheck: string;
4+
useV37?: {
5+
wethGateway: string;
6+
uiPoolDataProvider: string;
7+
};
48
};
59

610
export type ComplianceCheckResponse = {
@@ -20,6 +24,7 @@ export const checkCompliance = async (address: string): Promise<ComplianceCheckR
2024
data: {
2125
result: data.result,
2226
nextCheck: data.nextCheck,
27+
useV37: data.useV37,
2328
},
2429
};
2530
}

‎src/store/protocolDataSlice.ts‎

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { ChainId } from '@aave/contract-helpers';
12
import { providers, utils } from 'ethers';
23
import { permitByChainAndToken } from 'src/ui-config/permitConfig';
34
import {
@@ -13,6 +14,26 @@ import { NetworkConfig } from '../ui-config/networksConfig';
1314
import { RootStore } from './root';
1415
import { setQueryParameter } from './utils/queryParams';
1516

17+
type V37Overrides = {
18+
WETH_GATEWAY: string;
19+
UI_POOL_DATA_PROVIDER: string;
20+
};
21+
22+
const applyV37ToMarket = (
23+
market: MarketDataType,
24+
overrides: V37Overrides | null
25+
): MarketDataType => {
26+
if (!overrides || market.chainId !== ChainId.mainnet) return market;
27+
return {
28+
...market,
29+
addresses: {
30+
...market.addresses,
31+
WETH_GATEWAY: overrides.WETH_GATEWAY,
32+
UI_POOL_DATA_PROVIDER: overrides.UI_POOL_DATA_PROVIDER,
33+
},
34+
};
35+
};
36+
1637
type TypePermitParams = {
1738
reserveAddress: string;
1839
isWrappedBaseAsset: boolean;
@@ -23,8 +44,10 @@ export interface ProtocolDataSlice {
2344
currentMarketData: MarketDataType;
2445
currentChainId: number;
2546
currentNetworkConfig: NetworkConfig;
47+
v37Overrides: V37Overrides | null;
2648
jsonRpcProvider: (chainId?: number) => providers.Provider;
2749
setCurrentMarket: (market: CustomMarket, omitQueryParameterUpdate?: boolean) => void;
50+
setV37Overrides: (overrides: V37Overrides | null) => void;
2851
tryPermit: ({ reserveAddress, isWrappedBaseAsset }: TypePermitParams) => boolean;
2952
}
3053

@@ -41,10 +64,11 @@ export const createProtocolDataSlice: StateCreator<
4164
currentMarketData: marketsData[initialMarket],
4265
currentChainId: initialMarketData.chainId,
4366
currentNetworkConfig: getNetworkConfig(initialMarketData.chainId),
67+
v37Overrides: null,
4468
jsonRpcProvider: (chainId) => getProvider(chainId ?? get().currentChainId),
4569
setCurrentMarket: (market, omitQueryParameterUpdate) => {
4670
if (!availableMarkets.includes(market as CustomMarket)) return;
47-
const nextMarketData = marketsData[market];
71+
const nextMarketData = applyV37ToMarket(marketsData[market], get().v37Overrides);
4872
localStorage.setItem('selectedMarket', market);
4973
if (!omitQueryParameterUpdate) {
5074
setQueryParameter('marketName', market);
@@ -56,6 +80,13 @@ export const createProtocolDataSlice: StateCreator<
5680
currentNetworkConfig: getNetworkConfig(nextMarketData.chainId),
5781
});
5882
},
83+
setV37Overrides: (overrides) => {
84+
const currentMarket = get().currentMarket;
85+
set({
86+
v37Overrides: overrides,
87+
currentMarketData: applyV37ToMarket(marketsData[currentMarket], overrides),
88+
});
89+
},
5990
tryPermit: ({ reserveAddress, isWrappedBaseAsset }: TypePermitParams) => {
6091
const currentNetworkConfig = get().currentNetworkConfig;
6192
const currentMarketData = get().currentMarketData;

‎src/ui-config/queries.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const queryKeysFactory = {
1515
marketData.chainId,
1616
!!marketData.isFork,
1717
marketData.market,
18+
marketData.addresses.UI_POOL_DATA_PROVIDER,
1819
],
1920
user: (user: string) => [user],
2021
powers: (user: string, chainId: number, blockHash?: string) => [

0 commit comments

Comments
 (0)