Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix check for existing pool #11

Merged
merged 1 commit into from
Oct 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion packages/nextjs/app/cow/_components/PoolConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ export const PoolConfiguration = () => {
const availableTokens = tokenList.filter(
token => token.address !== token1?.address && token.address !== token2?.address,
);
const { existingPool } = useCheckIfPoolExists(token1?.address, token2?.address);

const proposedPoolTokenMap = new Map<string, string>();
if (token1?.address) proposedPoolTokenMap.set(token1.address.toLowerCase(), token1Weight);
if (token2?.address) proposedPoolTokenMap.set(token2.address.toLowerCase(), token2Weight);

const { existingPool } = useCheckIfPoolExists(proposedPoolTokenMap);
const { balance: balance1 } = useReadToken(token1?.address);
const { balance: balance2 } = useReadToken(token2?.address);

Expand Down
10 changes: 4 additions & 6 deletions packages/nextjs/hooks/cow/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ export type ExistingPool = {
id: Address;
address: Address;
type: "string";
allTokens: [
{
address: Address;
weight: string;
},
];
allTokens: {
address: Address;
weight: string;
}[];
dynamicData: {
swapFee: string;
};
Expand Down
45 changes: 28 additions & 17 deletions packages/nextjs/hooks/cow/useCheckIfPoolExists.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { type ExistingPool } from "./types";
import { useQuery } from "@tanstack/react-query";
import { Address } from "viem";
import { useApiConfig } from "~~/hooks/balancer";

/**
* Fetch CoW AMMs to see if user is trying to create a duplicate pool
* with same two tokens, weights, and swap fees
* with same two tokens and weights
*/
export const useCheckIfPoolExists = (token1: Address | undefined, token2: Address | undefined) => {
export const useCheckIfPoolExists = (proposedPoolTokenMap: Map<string, string>) => {
const { url, chainName } = useApiConfig();

const query = `
Expand All @@ -28,11 +27,7 @@ export const useCheckIfPoolExists = (token1: Address | undefined, token2: Addres
}
`;

const {
data: existingPools,
// isLoading,
// isError,
} = useQuery<ExistingPool[]>({
const { data: existingPools } = useQuery<ExistingPool[]>({
queryKey: ["existingPools", chainName],
queryFn: async () => {
const response = await fetch(url, {
Expand All @@ -50,17 +45,22 @@ export const useCheckIfPoolExists = (token1: Address | undefined, token2: Addres
},
});

const existingPool = existingPools?.find(pool => {
if (!token1 || !token2) return false;
const existingPool = existingPools?.find(existingPool => {
if (proposedPoolTokenMap.size !== existingPool.allTokens.length) return false;

const poolTokenAddresses = pool.allTokens.map(token => token.address);
const hasOnlyTwoTokens = poolTokenAddresses.length === 2;
const selectedToken1 = token1.toLowerCase() ?? "";
const selectedToken2 = token2.toLowerCase() ?? "";
const includesToken1 = poolTokenAddresses.includes(selectedToken1);
const includesToken2 = poolTokenAddresses.includes(selectedToken2);
const existingPoolTokens = existingPool.allTokens;

return hasOnlyTwoTokens && includesToken1 && includesToken2;
// Check if existing pool has all the same tokens with the same weights as potential new pool
return existingPoolTokens.every(existingToken => {
const existingPoolTokenWeight = normalizeWeight(existingToken.weight);
const existingPoolTokenAddress = existingToken.address.toLowerCase();
const proposedPoolTokenWeight = proposedPoolTokenMap.get(existingPoolTokenAddress);

// If proposed pool token map doesnt include token from existing pool, it's not an exact match
if (proposedPoolTokenWeight === undefined) return false;

return existingPoolTokenWeight === proposedPoolTokenWeight;
});
});

// Don't prevent pool duplication on testnet since limited number of faucet tokens
Expand All @@ -70,3 +70,14 @@ export const useCheckIfPoolExists = (token1: Address | undefined, token2: Addres

return { existingPool };
};

/**
* API returns weights like "0.5" but we are using "50" for this pool creation UI codebase
* "0.5" -> "50"
* "0.8" -> "80"
* "0.2" -> "20"
*/
function normalizeWeight(weight: string): string {
const numWeight = parseFloat(weight);
return numWeight < 1 ? (numWeight * 100).toString() : weight;
}
Loading