Skip to content

Commit

Permalink
feat: update usedBy Field in useWhitelistedWellComponents to be dynamic
Browse files Browse the repository at this point in the history
  • Loading branch information
Space-Bean committed Jun 21, 2024
1 parent dc4b366 commit 0f4690d
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 30 deletions.
103 changes: 75 additions & 28 deletions projects/dex-ui/src/components/Create/useWhitelistedWellComponents.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ import HalbornLogo from "src/assets/images/halborn-logo.png";
import {
MULTI_FLOW_PUMP_ADDRESS,
CONSTANT_PRODUCT_2_ADDRESS,
WELL_DOT_SOL_ADDRESS
WELL_DOT_SOL_ADDRESS,
toAddressMap
} from "src/utils/addresses";
import BrendanTwitterPFP from "src/assets/images/brendan-twitter-pfp.png";
import CyrfinLogo from "src/assets/images/cyrfin-logo.svg";
import Code4renaLogo from "src/assets/images/code4rena-logo.png";
import ClockIcon from "src/assets/images/clock-icon.svg";
import { useWells } from "src/wells/useWells";
import { useWellImplementations } from "src/wells/useWellImplementations";
import { useWellFunctions } from "src/wells/wellFunction/useWellFunctions";
import { usePumps } from "src/wells/pump/usePumps";
import { AddressMap } from "src/types";

export enum WellComponentType {
WellImplementation = "WellImplementation",
Expand All @@ -36,13 +42,12 @@ export type WellComponentInfo = {
summary: string;
description: string[];
url?: string;
usedBy?: number;
usedBy: number;
type: {
type: WellComponentType;
display: string;
imgSrc?: string;
};
tokenSuffixAbbreviation?: string;
};
info: ComponentInfo[];
links: {
Expand Down Expand Up @@ -77,15 +82,15 @@ const basinAuditInfo = [
];

const WellDotSol: WellComponentInfo = {
address: WELL_DOT_SOL_ADDRESS.toLowerCase(),
address: WELL_DOT_SOL_ADDRESS,
component: {
name: "Well.sol",
summary: "A standard Well implementation that prioritizes flexibility and composability.",
description: [
"A standard Well implementation that prioritizes flexibility and composability.",
"Fits many use cases for a Liquidity Well."
],
usedBy: 1,
usedBy: 0,
type: {
type: WellComponentType.WellImplementation,
display: "💧 Well Implementation"
Expand All @@ -105,15 +110,15 @@ const WellDotSol: WellComponentInfo = {
};

const MultiFlowPump: WellComponentInfo = {
address: MULTI_FLOW_PUMP_ADDRESS.toLowerCase(),
address: MULTI_FLOW_PUMP_ADDRESS,
component: {
name: "Multi Flow",
fullName: "Multi Flow Pump",
summary: "An inter-block MEV manipulation resistant oracle implementation.",
description: [
"Comprehensive multi-block MEV manipulation-resistant Oracle implementation which serves up Well pricing data with an EMA for instantaneous prices and a TWAP for weighted averages over time."
],
usedBy: 1,
usedBy: 0,
url: "https://docs.basin.exchange/implementations/multi-flow-pump",
type: {
type: WellComponentType.Pump,
Expand All @@ -138,7 +143,7 @@ const MultiFlowPump: WellComponentInfo = {
};

const ConstantProduct2: WellComponentInfo = {
address: CONSTANT_PRODUCT_2_ADDRESS.toLowerCase(),
address: CONSTANT_PRODUCT_2_ADDRESS,
component: {
name: "Constant Product 2",
summary: "A standard x*y = k token pricing function for two tokens with no fees.",
Expand All @@ -149,8 +154,7 @@ const ConstantProduct2: WellComponentInfo = {
display: "Well Function",
imgSrc: ClockIcon
},
usedBy: 1,
tokenSuffixAbbreviation: "CP2w"
usedBy: 0
},
info: [
{ label: "Deployed By", value: "Beanstalk Farms", imgSrc: BeanstalkFarmsLogo },
Expand All @@ -166,29 +170,72 @@ const ConstantProduct2: WellComponentInfo = {
}
};

type WellComponentMap<T> = {
wellImplementations: T;
pumps: T;
wellFunctions: T;
};

const ComponentWhiteList: WellComponentMap<AddressMap<WellComponentInfo>> = {
wellImplementations: {
[WellDotSol.address]: WellDotSol
},
pumps: {
[MultiFlowPump.address]: MultiFlowPump
},
wellFunctions: {
[ConstantProduct2.address]: ConstantProduct2
}
};

export const useWhitelistedWellComponents = () => {
const { data: wells } = useWells();
const { data: implementations } = useWellImplementations();
const wellFunctions = useWellFunctions();
const pumps = usePumps();

return useMemo(() => {
const mapping = {
wellImplementations: [WellDotSol],
pumps: [MultiFlowPump],
wellFunctions: [ConstantProduct2]
} as const;

const lookup = {
wellImplementation: {
[WellDotSol.address]: WellDotSol
},
pump: {
[MultiFlowPump.address]: MultiFlowPump
},
wellFunction: {
[ConstantProduct2.address]: ConstantProduct2
// make deep copy of ComponentWhiteList
const map = JSON.parse(JSON.stringify(ComponentWhiteList)) as WellComponentMap<
AddressMap<WellComponentInfo>
>;

const pumpMap = toAddressMap(pumps, { keyLowercase: true });
const wellFunctionMap = toAddressMap(wellFunctions, { keyLowercase: true });

for (const well of wells || []) {
// increase usedBy count for each whitelisted well component
if (implementations) {
const implementation = implementations[well.address.toLowerCase()];
if (implementation in map.wellImplementations) {
map.wellImplementations[implementation].component.usedBy += 1;
}
}

well.pumps?.forEach((pump) => {
const pumpAddress = pump.address.toLowerCase();
if (pumpAddress in pumpMap) {
map.pumps[pumpAddress].component.usedBy += 1;
}
});

if (well.wellFunction) {
const wellFunctionAddress = well.wellFunction.address.toLowerCase();
if (wellFunctionAddress in wellFunctionMap) {
map.wellFunctions[wellFunctionAddress].component.usedBy += 1;
}
}
}

const components: WellComponentMap<WellComponentInfo[]> = {
wellImplementations: Object.values(map.wellImplementations),
pumps: Object.values(map.pumps),
wellFunctions: Object.values(map.wellFunctions)
};

return {
components: mapping,
lookup,
components,
lookup: map
};
}, []);
}, [implementations, pumps, wellFunctions, wells]);
};
22 changes: 21 additions & 1 deletion projects/dex-ui/src/utils/addresses.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/// All addresses are in lowercase for consistency

import { ethers } from "ethers";
import { AddressMap } from "src/types";

/// Well LP Tokens
export const BEANETH_ADDRESS = "0xbea0e11282e2bb5893bece110cf199501e872bad";
Expand All @@ -12,8 +13,9 @@ export const MULTI_FLOW_PUMP_ADDRESS = "0xba510f10e3095b83a0f33aa9ad2544e22570a8
export const CONSTANT_PRODUCT_2_ADDRESS = "0xba510c20fd2c52e4cb0d23cfc3ccd092f9165a6e";

// Well Implementation
export const WELL_DOT_SOL_ADDRESS = "0xBA510e11eEb387fad877812108a3406CA3f43a4B".toLowerCase();
export const WELL_DOT_SOL_ADDRESS = "0xba510e11eeb387fad877812108a3406ca3f43a4b";

// ---------- METHODS ----------

export const getIsValidEthereumAddress = (
address: string | undefined,
Expand All @@ -23,3 +25,21 @@ export const getIsValidEthereumAddress = (
if (enforce0Suffix && !address.startsWith("0x")) return false;
return ethers.utils.isAddress(address ?? "");
};

/**
* Converts an object or array of objects with an address property to a map of address to object.
*/
export const toAddressMap = <T extends { address: string }>(
hasAddress: T | T[],
options?: {
keyLowercase?: boolean;
}
) => {
const arr = Array.isArray(hasAddress) ? hasAddress : [hasAddress];

return arr.reduce<AddressMap<T>>((prev, curr) => {
const key = options?.keyLowercase ? curr.address.toLowerCase() : curr.address;
prev[key] = curr;
return prev;
}, {});
};
2 changes: 1 addition & 1 deletion projects/dex-ui/src/wells/useWellImplementations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export const useWellImplementations = () => {
const result = data[i];
if (result.error) return prev;
if (result.result) {
prev[curr] = result.result as string;
prev[curr.toLowerCase()] = result.result.toLowerCase() as string;
}
return prev;
}, {});
Expand Down

0 comments on commit 0f4690d

Please sign in to comment.