Skip to content

Commit 5b3eaff

Browse files
committed
feat: supply and borrow position splitted approve flow working
1 parent 2407330 commit 5b3eaff

File tree

8 files changed

+114
-42
lines changed

8 files changed

+114
-42
lines changed

pages/v3-migration.page.tsx

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,64 @@
1+
import { useEffect } from 'react';
12
import { MigrateV3Modal } from 'src/components/transactions/MigrateV3/MigrateV3Modal';
23
import { StakeModal } from 'src/components/transactions/Stake/StakeModal';
34
import { StakeCooldownModal } from 'src/components/transactions/StakeCooldown/StakeCooldownModal';
45
import { StakeRewardClaimModal } from 'src/components/transactions/StakeRewardClaim/StakeRewardClaimModal';
56
import { UnStakeModal } from 'src/components/transactions/UnStake/UnStakeModal';
7+
import { useCurrentTimestamp } from 'src/hooks/useCurrentTimestamp';
68
import { useModalContext } from 'src/hooks/useModal';
79
import { useUserReserves } from 'src/hooks/useUserReserves';
810
import { MainLayout } from 'src/layouts/MainLayout';
9-
import { useRootStore } from 'src/store/root';
11+
import { usePoolDataV3Subscription, useRootStore } from 'src/store/root';
12+
import { selectCurrentMarketV2Reserves } from 'src/store/v3MigrationSelectors';
1013

1114
export default function V3Migration() {
1215
const { user, borrowPositions } = useUserReserves();
1316
const { openV3Migration } = useModalContext();
1417

15-
const toggleSelectedSupplyPosition = useRootStore((state) => state.toggleMigrationSelectedAsset);
18+
const toggleSelectedSupplyPosition = useRootStore(
19+
(state) => state.toggleMigrationSelectedSupplyAsset
20+
);
21+
const selectedSupplyAssets = useRootStore((state) => state.selectedMigrationSupplyAssets);
22+
23+
const toggleSelectedBorrowPosition = useRootStore(
24+
(state) => state.toggleMigrationSelectedBorrowAsset
25+
);
26+
const selectedBorrowAssets = useRootStore((state) => state.selectedMigrationBorrowAssets);
1627
const testMigration = useRootStore((state) => state._testMigration);
17-
const selectedAssets = useRootStore((state) => state.selectedMigrationAssets);
28+
29+
const currentTimestamp = useCurrentTimestamp(5);
30+
const currentV2SuppliedPositions = useRootStore((state) =>
31+
selectCurrentMarketV2Reserves(state, currentTimestamp)
32+
);
33+
34+
// start refreshing v3 market at the same time
35+
usePoolDataV3Subscription();
36+
37+
// always switch to default v2 in that case for polygon fork
38+
useEffect(() => {}, []);
1839

1940
return (
2041
<div>
2142
<button onClick={() => testMigration()}>test migration</button>
2243
<div>supply</div>
2344
{user.userReservesData.map((reserve) => (
24-
<div
45+
<button
2546
key={reserve.underlyingAsset}
2647
onClick={() => toggleSelectedSupplyPosition(reserve.underlyingAsset)}
27-
style={{ color: selectedAssets[reserve.underlyingAsset] ? 'red' : 'black' }}
48+
style={{ color: selectedSupplyAssets[reserve.underlyingAsset] ? 'red' : 'black' }}
2849
>
2950
{reserve.underlyingAsset}:<b>{reserve.underlyingBalanceUSD}</b>
30-
</div>
51+
</button>
3152
))}
3253
<div>borrow</div>
3354
{borrowPositions.map((reserve) => (
34-
<div key={reserve.underlyingAsset}>{reserve.variableBorrowsUSD}</div>
55+
<button
56+
key={reserve.underlyingAsset}
57+
onClick={() => toggleSelectedBorrowPosition(reserve.underlyingAsset)}
58+
style={{ color: selectedBorrowAssets[reserve.underlyingAsset] ? 'red' : 'black' }}
59+
>
60+
{reserve.variableBorrowsUSD}
61+
</button>
3562
))}
3663
<button onClick={openV3Migration}>Migrate</button>
3764
</div>

src/components/transactions/MigrateV3/MigrateV3Actions.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const MigrateV3Actions = () => {
1111
const { approval, action } = useTransactionHandler({
1212
handleGetTxns: async () => migrateWithoutPermits(),
1313
handleGetPermitTxns: async (signatures, deadline) => migrateWithPermits(signatures, deadline),
14-
tryPermit: false,
14+
tryPermit: true,
1515
});
1616

1717
const handleApproval = () => {

src/helpers/useTransactionHandler.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export const useTransactionHandler = ({
112112
};
113113

114114
const approval = async (approvals?: Approval[]) => {
115+
console.log(approvalTxes, 'approvalTxes');
115116
if (approvalTxes) {
116117
console.log(approvalTxes, 'approvalTxes');
117118
if (usePermit && approvals && approvals?.length > 0) {
@@ -189,7 +190,7 @@ export const useTransactionHandler = ({
189190
(param) =>
190191
new Promise<TransactionResponse>(async (resolve, reject) => {
191192
delete param.gasPrice;
192-
console.log;
193+
console.log(params, 'params');
193194
processTx({
194195
tx: () => sendTx(param),
195196
successCallback: (txnResponse: TransactionResponse) => {
@@ -269,8 +270,11 @@ export const useTransactionHandler = ({
269270
if ((!usePermit || !approvalTxes) && actionTx) {
270271
try {
271272
setMainTxState({ ...mainTxState, loading: true });
273+
console.log(actionTx, 'actionTx');
272274
const params = await actionTx.tx();
273-
delete params.gasPrice;
275+
console.log(params, 'actionTx');
276+
// delete params.gasPrice;
277+
console.log(params);
274278
return processTx({
275279
tx: () => sendTx(params),
276280
successCallback: (txnResponse: TransactionResponse) => {
@@ -293,6 +297,7 @@ export const useTransactionHandler = ({
293297
});
294298
} catch (error) {
295299
const parsedError = getErrorTextFromError(error, TxAction.GAS_ESTIMATION, false);
300+
console.log(error, parsedError);
296301
setTxError(parsedError);
297302
setMainTxState({
298303
txHash: undefined,

src/store/poolSelectors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export const selectUserNonEmtpySummaryAndIncentive = (
104104
};
105105

106106
export const selectUserBorrowPositions = (state: RootStore, currentTimestamp: number) => {
107-
const user = selectUserNonEmtpySummaryAndIncentive(state, currentTimestamp);
107+
const user = selectUserSummaryAndIncentives(state, currentTimestamp);
108108
const borrowedPositions = user.userReservesData.filter(
109109
(reserve) => reserve.variableBorrows != '0' || reserve.stableBorrows != '0'
110110
);

src/store/poolSlice.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ import { RepayActionProps } from 'src/components/transactions/Repay/RepayActions
3434
import { SupplyActionProps } from 'src/components/transactions/Supply/SupplyActions';
3535
import { SwapActionProps } from 'src/components/transactions/Swap/SwapActions';
3636
import { getRepayCallData, getSwapCallData } from 'src/hooks/useSwap';
37+
import { MarketDataType, marketsData } from 'src/ui-config/marketsConfig';
38+
import { availableMarkets, networkConfigs } from 'src/utils/marketsAndNetworksConfig';
3739
import { optimizedPath } from 'src/utils/utils';
3840
import { StateCreator } from 'zustand';
3941

@@ -54,7 +56,8 @@ export interface PoolSlice {
5456
}
5557
>
5658
>;
57-
refreshPoolData: () => Promise<void>;
59+
refreshPoolData: (marketData?: MarketDataType) => Promise<void>;
60+
refreshPoolV3Data: () => Promise<void>;
5861
// methods
5962
useOptimizedPath: () => boolean | undefined;
6063
mint: (args: Omit<FaucetParamsType, 'userAddress'>) => Promise<EthereumTransactionTypeExtended[]>;
@@ -119,10 +122,11 @@ export const createPoolSlice: StateCreator<
119122
}
120123
return {
121124
data: new Map(),
122-
refreshPoolData: async () => {
125+
refreshPoolData: async (marketData?: MarketDataType) => {
123126
const account = get().account;
124-
const currentMarketData = get().currentMarketData;
125127
const currentChainId = get().currentChainId;
128+
const currentMarketData = marketData || get().currentMarketData;
129+
console.log(get().currentMarketData, 'currentMarketData');
126130
const poolDataProviderContract = new UiPoolDataProvider({
127131
uiPoolDataProviderAddress: currentMarketData.addresses.UI_POOL_DATA_PROVIDER,
128132
provider: get().jsonRpcProvider(),
@@ -193,6 +197,12 @@ export const createPoolSlice: StateCreator<
193197
console.log('error fetching pool data', e);
194198
}
195199
},
200+
refreshPoolV3Data: async () => {
201+
// how to determine which v2 markets to pool? for now always fetch polygon fork
202+
const v3MarketData = marketsData[availableMarkets[11]];
203+
console.log(marketsData);
204+
// get().refreshPoolData(availableMarkets);
205+
},
196206
mint: async (args) => {
197207
if (!get().currentMarketData.addresses.FAUCET)
198208
throw Error('currently selected market does not have a faucet attached');

src/store/root.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ export const usePoolDataSubscription = createSingletonSubscriber(() => {
6767
return useRootStore.getState().refreshPoolData();
6868
}, 60000);
6969

70+
export const usePoolDataV3Subscription = createSingletonSubscriber(() => {
71+
return useRootStore.getState().refreshPoolV3Data();
72+
}, 60000);
73+
7074
export const useIncentiveDataSubscription = createSingletonSubscriber(() => {
7175
return useRootStore.getState().refreshIncentiveData();
7276
}, 60000);

src/store/v3MigrationSelectors.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ import { RootStore } from './root';
44
export const selectedUserReservesForMigration = (store: RootStore, timestamp: number) => {
55
const user = selectUserNonEmtpySummaryAndIncentive(store, timestamp);
66
const selectedUserReserves = user.userReservesData.filter(
7-
(userReserve) => store.selectedMigrationAssets[userReserve.underlyingAsset]
7+
(userReserve) => store.selectedMigrationSupplyAssets[userReserve.underlyingAsset]
88
);
99
return selectedUserReserves;
1010
};
11+
12+
export const selectCurrentMarketV2Reserves = (store: RootStore, timestamp: number) => {
13+
const currentChainId = store.currentChainId;
14+
return store.data.get(currentChainId);
15+
};
16+
// export const selectUserApprovalsReservesForMigration = (store: RootStore, timestamp: number) => {
17+
18+
// };

src/store/v3MigrationSlice.ts

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ import { selectedUserReservesForMigration } from './v3MigrationSelectors';
1717

1818
export type V3MigrationSlice = {
1919
//STATE
20-
selectedMigrationAssets: Record<string, boolean>;
20+
selectedMigrationSupplyAssets: Record<string, boolean>;
21+
selectedMigrationBorrowAssets: Record<string, boolean>;
2122
migrationServiceInstances: Record<string, V3MigrationHelperService>;
2223
timestamp: number;
2324
// ACTIONS
@@ -27,14 +28,15 @@ export type V3MigrationSlice = {
2728
}
2829
) => Promise<string>;
2930
getApprovePermitsForSelectedAssets: () => Approval[];
30-
toggleMigrationSelectedAsset: (assetName: string) => void;
31+
toggleMigrationSelectedSupplyAsset: (assetName: string) => void;
32+
toggleMigrationSelectedBorrowAsset: (assetName: string) => void;
3133
getMigratorAddress: () => string;
3234
getMigrationServiceInstance: () => V3MigrationHelperService;
3335
migrateWithPermits: (
3436
signature: SignatureLike[],
3537
deadline: BigNumberish
3638
) => EthereumTransactionTypeExtended[];
37-
migrateWithoutPermits: () => EthereumTransactionTypeExtended[];
39+
migrateWithoutPermits: () => Promise<EthereumTransactionTypeExtended[]>;
3840
_testMigration: () => void;
3941
// migrateSelectedPositions: () => void;
4042
};
@@ -46,7 +48,8 @@ export const createV3MigrationSlice: StateCreator<
4648
V3MigrationSlice
4749
> = (set, get) => {
4850
return {
49-
selectedMigrationAssets: {},
51+
selectedMigrationSupplyAssets: {},
52+
selectedMigrationBorrowAssets: {},
5053
migrationServiceInstances: {},
5154
timestamp: 0,
5255
generatePermitPayloadForMigrationAsset: async ({ amount, underlyingAsset, deadline }) => {
@@ -96,28 +99,41 @@ export const createV3MigrationSlice: StateCreator<
9699
};
97100
return JSON.stringify(typeData);
98101
},
99-
toggleMigrationSelectedAsset: (assetName: string) => {
102+
toggleMigrationSelectedSupplyAsset: (assetName: string) => {
100103
set((state) =>
101104
produce(state, (draft) => {
102-
if (draft.selectedMigrationAssets[assetName]) {
103-
delete draft.selectedMigrationAssets[assetName];
105+
if (draft.selectedMigrationSupplyAssets[assetName]) {
106+
delete draft.selectedMigrationSupplyAssets[assetName];
104107
} else {
105-
draft.selectedMigrationAssets[assetName] = true;
108+
draft.selectedMigrationSupplyAssets[assetName] = true;
109+
}
110+
})
111+
);
112+
},
113+
toggleMigrationSelectedBorrowAsset: (assetName: string) => {
114+
set((state) =>
115+
produce(state, (draft) => {
116+
if (draft.selectedMigrationBorrowAssets[assetName]) {
117+
delete draft.selectedMigrationBorrowAssets[assetName];
118+
} else {
119+
draft.selectedMigrationBorrowAssets[assetName] = true;
106120
}
107121
})
108122
);
109123
},
110124
getApprovePermitsForSelectedAssets: () => {
111125
const timestamp = dayjs().unix();
112126
set({ timestamp });
113-
return selectedUserReservesForMigration(get(), timestamp).map(({ reserve }): Approval => {
114-
return {
115-
// TODO: should we allow spending of exact ammount of the reserver?
116-
amount: reserve.totalLiquidity,
117-
underlyingAsset: reserve.aTokenAddress,
118-
permitType: 'MIGRATOR',
119-
};
120-
});
127+
return selectedUserReservesForMigration(get(), timestamp).map(
128+
({ reserve, underlyingBalance }): Approval => {
129+
return {
130+
// TODO: should we allow spending of exact ammount of the reserver?
131+
amount: underlyingBalance,
132+
underlyingAsset: reserve.aTokenAddress,
133+
permitType: 'MIGRATOR',
134+
};
135+
}
136+
);
121137
},
122138
migrateWithoutPermits: () => {
123139
const timestamp = dayjs().unix();
@@ -126,17 +142,18 @@ export const createV3MigrationSlice: StateCreator<
126142
aToken: string;
127143
deadline: number;
128144
amount: string;
129-
}[] = selectedUserReservesForMigration(get(), timestamp).map(({ reserve }) => {
130-
const deadline = Math.floor(Date.now() / 1000 + 3600);
131-
return {
132-
amount: reserve.totalLiquidity,
133-
aToken: reserve.aTokenAddress,
134-
// TODO: fow how long to approve?
135-
deadline,
136-
};
137-
});
145+
}[] = selectedUserReservesForMigration(get(), timestamp).map(
146+
({ reserve, underlyingBalance }) => {
147+
const deadline = Math.floor(Date.now() / 1000 + 3600);
148+
return {
149+
amount: underlyingBalance,
150+
aToken: reserve.aTokenAddress,
151+
// TODO: fow how long to approve?
152+
deadline,
153+
};
154+
}
155+
);
138156
const user = get().account;
139-
console.log(assets, user);
140157
return get().getMigrationServiceInstance().migrateNoBorrow({ assets, user });
141158
},
142159
migrateWithPermits: (signatures: SignatureLike[], deadline: BigNumberish) => {
@@ -149,13 +166,14 @@ export const createV3MigrationSlice: StateCreator<
149166
}));
150167
// branch out into flashloan or migrate no borrow
151168
// move that to separate instance and save cache the Migrator instance
169+
console.log(permits, 'permits');
152170
const migratorHelperInstance = get().getMigrationServiceInstance();
153171
const user = get().account;
154172
const assets = permits.map((permit) => permit.aToken);
155-
console.log('migrateNoBorrowWith permits');
156173
return migratorHelperInstance.migrateNoBorrowWithPermits({
157174
user,
158175
assets,
176+
deadline,
159177
signedPermits: permits,
160178
});
161179
},

0 commit comments

Comments
 (0)