Skip to content

Commit

Permalink
feat: update well component queries
Browse files Browse the repository at this point in the history
  • Loading branch information
Space-Bean committed Sep 11, 2024
1 parent 17bc03f commit 2e00da5
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 44 deletions.
1 change: 1 addition & 0 deletions projects/dex-ui/src/utils/query/queryKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const queryKeys = {
wellImplementations: (addresses: string[]) => ["wells", "implementations", addresses],

// well Function
wellFunctions: (addresses: string[]) => ["wellFunctions", addresses],
wellFunctionValid: (address: string, data: string) => ["wellFunction", "isValid", address, data],
wellFunctionNames: (addresses: string[] | undefined) => ["wellFunctions", "names", addresses],

Expand Down
58 changes: 37 additions & 21 deletions projects/dex-ui/src/wells/pump/utils.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,45 @@
import { useCallback, useMemo } from "react";

import { Well } from "@beanstalk/sdk-wells";

import { MULTI_FLOW_PUMP_ADDRESS, MULTI_FLOW_PUMP_V_1PT1_ADDRESS } from "src/utils/addresses";
import useSdk from "src/utils/sdk/useSdk";

export const getIsMultiPumpWell = (well: Well | undefined) => {
let isMultiFlowPumpV1 = false;
let isMultiFlowPumpV1_1 = false;
export const useIsMultiFlowPump = (well: Well | undefined = undefined) => {
const sdk = useSdk();

for (const pump of well?.pumps || []) {
if (!isMultiFlowPumpV1 && pump.address.toLowerCase() === MULTI_FLOW_PUMP_ADDRESS) {
isMultiFlowPumpV1 = true;
}
const getIsMultiFlow = useCallback(
(_well: Well | undefined) => {
let isMultiFlowPumpV1 = false;
let isMultiFlowPumpV1_1 = false;

if (!isMultiFlowPumpV1_1 && pump.address.toLowerCase() === MULTI_FLOW_PUMP_V_1PT1_ADDRESS) {
isMultiFlowPumpV1_1 = true;
}
}
const mfPumpV1Address = sdk.wells.addresses.MULTI_FLOW_PUMP_V1.get(sdk.chainId);
const mfPumpV1_1Address = sdk.wells.addresses.MULTI_FLOW_PUMP_V1_1.get(sdk.chainId);

return {
isV1: isMultiFlowPumpV1,
isV1_1: isMultiFlowPumpV1_1,
isMultiFlow: isMultiFlowPumpV1 || isMultiFlowPumpV1_1
};
};
for (const pump of _well?.pumps || []) {
const pumpAddress = pump.address.toLowerCase();

if (pumpAddress === mfPumpV1Address) {
isMultiFlowPumpV1 = true;
}

if (pumpAddress === mfPumpV1_1Address) {
isMultiFlowPumpV1_1 = true;
}
}

return {
isV1: isMultiFlowPumpV1,
isV1_1: isMultiFlowPumpV1_1,
isMultiFlow: isMultiFlowPumpV1 || isMultiFlowPumpV1_1
};
},
[sdk]
);

export const getIsMultiFlowPumpV1pt1 = (well: Well | undefined) => {
if (!well?.pumps) return false;
return !!well.pumps.find((pump) => pump.address.toLowerCase() === MULTI_FLOW_PUMP_V_1PT1_ADDRESS);
return useMemo(() => {
return {
...getIsMultiFlow(well),
getIsMultiFlow
};
}, [well, getIsMultiFlow]);
};
5 changes: 3 additions & 2 deletions projects/dex-ui/src/wells/useMultiFlowPumpTWAReserves.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,22 @@ import { useChainScopedQuery } from "src/utils/query/useChainScopedQuery";
import useSdk from "src/utils/sdk/useSdk";
import { config } from "src/utils/wagmi/config";

import { getIsMultiPumpWell } from "./pump/utils";
import { useIsMultiFlowPump } from "./pump/utils";
import { useBeanstalkSiloWhitelist } from "./useBeanstalkSiloWhitelist";
import { useWells } from "./useWells";

export const useMultiFlowPumpTWAReserves = () => {
const { data: wells } = useWells();
const { getIsWhitelisted } = useBeanstalkSiloWhitelist();
const sdk = useSdk();
const { getIsMultiFlow } = useIsMultiFlowPump();

const query = useChainScopedQuery({
queryKey: ["wells", "multiFlowPumpTWAReserves"],

queryFn: async () => {
const whitelistedWells = (wells || []).filter(
(well) => getIsMultiPumpWell(well).isMultiFlow && getIsWhitelisted(well)
(well) => getIsMultiFlow(well).isMultiFlow && getIsWhitelisted(well)
);

const [{ timestamp: seasonTimestamp }, ...wellOracleSnapshots] = await Promise.all([
Expand Down
104 changes: 92 additions & 12 deletions projects/dex-ui/src/wells/wellFunction/useWellFunctions.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,106 @@
import { useMemo } from "react";
import { useCallback, useMemo } from "react";

import { WellFunction } from "@beanstalk/sdk-wells";
import { multicall } from "@wagmi/core";
import { ContractFunctionParameters } from "viem";

import { Well, WellFunction } from "@beanstalk/sdk-wells";

import { chunkArray } from "src/utils/array";
import { queryKeys } from "src/utils/query/queryKeys";
import { useChainScopedQuery } from "src/utils/query/useChainScopedQuery";
import { config } from "src/utils/wagmi/config";
import { useWells } from "src/wells/useWells";

type WellFunctionDataMap = Record<
string,
{
name: string;
symbol: string;
}
>;

export const useWellFunctions = () => {
const { data: wells } = useWells();

return useMemo(() => {
if (!wells || !wells.length) return [];
const addresses = getWFAddresses(wells);

const wellFunctionMap: Record<string, WellFunction> = {};
const selectData = useCallback(
(data: WellFunctionDataMap) => {
if (!data) return [];

for (const well of wells) {
if (!well.wellFunction) continue;
const address = well.wellFunction.address.toLowerCase();
// apply the changes to all wells
for (const well of wells) {
const wf = well.wellFunction;
if (!wf || !!(wf.name && wf.symbol)) continue;

if (!(address in wellFunctionMap)) {
wellFunctionMap[address] = well.wellFunction;
const { name, symbol } = data[wf.address.toLowerCase()];
if (name && symbol) {
wf.name = name;
wf.symbol = symbol;
}
}

return Object.values(mapWellFunctions(wells));
},
[wells]
);

const query = useChainScopedQuery({
queryKey: queryKeys.wellFunctions(addresses),
queryFn: async () => {
const { contracts, chunkSize } = buildMulticall(addresses);

const results = await multicall(config, { contracts, allowFailure: false }).then((r) =>
chunkArray(r, chunkSize)
);

return addresses.reduce<Record<string, { name: string; symbol: string }>>(
(prev, wfAddress, i) => {
const [name, symbol] = results[i];
prev[wfAddress] = { name, symbol };
return prev;
},
{}
);
},
select: selectData,
enabled: !!wells.length
});

return useMemo(() => query.data || [], [query.data]);
};

const mapWellFunctions = (wells: Well[]) => {
return wells.reduce<Record<string, WellFunction>>((prev, well) => {
if (!well.wellFunction) return prev;
const address = well.wellFunction.address.toLowerCase();

if (!prev[address]) {
prev[address] = well.wellFunction;
}
return prev;
}, {});
};

const getWFAddresses = (wells: Well[]) => {
const set = new Set<string>(wells.map((well) => well.wellFunction?.address?.toLowerCase() || ""));
set.delete("");
return Array.from(set);
};

const buildMulticall = (addresses: string[]) => {
const calls: ContractFunctionParameters<typeof WellFunction.abi>[][] = addresses.map(
(address) => {
const contract = {
address: address as `0x${string}`,
abi: WellFunction.abi
};
return [
{ ...contract, functionName: "name", args: [] },
{ ...contract, functionName: "symbol", args: [] }
];
}
);

return Object.values(wellFunctionMap);
}, [wells]);
return { contracts: calls.flat(), chunkSize: 2 };
};
31 changes: 22 additions & 9 deletions projects/dex-ui/src/wells/wellFunction/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import { useMemo } from "react";

import { Well, WellFunction } from "@beanstalk/sdk-wells";
import { CONSTANT_PRODUCT_2_ADDRESS, CONSTANT_PRODUCT_2_V2_ADDRESS } from "src/utils/addresses";

const cp2Addresses = [CONSTANT_PRODUCT_2_V2_ADDRESS, CONSTANT_PRODUCT_2_ADDRESS];
import useSdk from "src/utils/sdk/useSdk";

export const useIsConstantProduct2 = (param: Well | WellFunction | undefined | null) => {
const sdk = useSdk();

return useMemo(() => {
const addresses = sdk.wells.addresses;
const cp2V1 = addresses.CONSTANT_PRODUCT_2_V1;
const cp2V2 = addresses.CONSTANT_PRODUCT_2_V2;
const cp2 = [cp2V1, cp2V2];

export const isConstantProduct2 = (param: Well | WellFunction | undefined | null) => {
if (!param) return false;
if (!param) return false;

if (param instanceof Well) {
const wf = param.wellFunction?.address;
return Boolean(wf && cp2Addresses.includes(wf.toLowerCase()));
}
const wf = param instanceof Well ? param.wellFunction : param;

return cp2Addresses.includes(param.address.toLowerCase());
return (
wf &&
cp2.some((_address) => {
const address = _address.get(sdk.chainId) || "";
return address.toLowerCase() === wf.address.toLowerCase();
})
);
}, [param, sdk.chainId, sdk.wells.addresses]);
};

0 comments on commit 2e00da5

Please sign in to comment.