Skip to content

Commit

Permalink
add create amm unbalanced amm warning
Browse files Browse the repository at this point in the history
  • Loading branch information
yvesfracari committed Jun 13, 2024
1 parent 5b75e94 commit 0b52527
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter } from "next/navigation";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { useForm, useWatch } from "react-hook-form";
import { Address } from "viem";
import { useAccount } from "wagmi";
import { z } from "zod";

import { Button } from "#/components";
import { AlertCard } from "#/components/AlertCard";
import { Input } from "#/components/Input";
import { PriceOracleForm } from "#/components/PriceOracleForm";
import { TokenAmountInput } from "#/components/TokenAmountInput";
Expand All @@ -20,11 +21,12 @@ import {
} from "#/components/ui/accordion";
import { Form } from "#/components/ui/form";
import { useManagedTransaction } from "#/hooks/tx-manager/useManagedTransaction";
import { useDebounce } from "#/hooks/useDebounce";
import { ConstantProductFactoryABI } from "#/lib/abis/ConstantProductFactory";
import { COW_CONSTANT_PRODUCT_FACTORY } from "#/lib/contracts";
import { IToken } from "#/lib/fetchAmmData";
import { ammFormSchema } from "#/lib/schema";
import { getNewMinTradeToken0 } from "#/lib/tokenUtils";
import { fetchTokenUsdPrice, getNewMinTradeToken0 } from "#/lib/tokenUtils";
import { buildTxCreateAMMArgs } from "#/lib/transactionFactory";
import { cn } from "#/lib/utils";
import { ChainId, publicClientsFromIds } from "#/utils/chainsPublicClients";
Expand Down Expand Up @@ -75,6 +77,13 @@ export function CreateAMMForm({ userId }: { userId: string }) {
writeContract(buildTxCreateAMMArgs({ data }));
}
};
const [token0UsdPrice, setToken0UsdPrice] = useState<number>();
const [token1UsdPrice, setToken1UsdPrice] = useState<number>();
const [amountUsdDiff, setAmountUsdDiff] = useState<number>();
const debouncedAmountUsdDiff = useDebounce<number | undefined>(
amountUsdDiff,
300
);

useEffect(() => {
setValue("safeAddress", safeAddress as string);
Expand All @@ -99,6 +108,38 @@ export function CreateAMMForm({ userId }: { userId: string }) {
onTxStatusFinal();
}
}, [status]);
async function updateTokenUsdPrice(
token: IToken,
setAmountUsd: (value: number) => void
) {
const amountUsd = await fetchTokenUsdPrice({
chainId: chainId as ChainId,
tokenDecimals: token.decimals,
tokenAddress: token.address as Address,
});
setAmountUsd(amountUsd);
}

useEffect(() => {
if (token0) {
updateTokenUsdPrice(token0, setToken0UsdPrice);
}
}, [token0]);

useEffect(() => {
if (token1) {
updateTokenUsdPrice(token1, setToken1UsdPrice);
}
}, [token1]);

useEffect(() => {
if (token0?.address == token1?.address) return;
if (token0UsdPrice && token1UsdPrice && amount0 && amount1) {
const amount0Usd = amount0 * token0UsdPrice;
const amount1Usd = amount1 * token1UsdPrice;
setAmountUsdDiff(Math.abs(amount0Usd - amount1Usd));
}
}, [amount0, amount1, token0UsdPrice, token1UsdPrice]);

return (
// @ts-ignore
Expand Down Expand Up @@ -183,6 +224,18 @@ export function CreateAMMForm({ userId }: { userId: string }) {
</AccordionItem>
</Accordion>

<span>
{amountUsdDiff} {debouncedAmountUsdDiff}
</span>
{(debouncedAmountUsdDiff || 0) > 5000 && (
<AlertCard title="Unbalanced amounts" style="warning">
<p>
The difference between the USD value of the two token amounts is
greater than $5000. This may lead to an unbalanced AMM and result in
loss of funds.
</p>
</AlertCard>
)}
<div className="flex justify-center gap-x-5 mt-2">
<Button
loading={
Expand Down
12 changes: 8 additions & 4 deletions apps/cow-amm-deployer/src/components/DepositForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Button } from "#/components";
import { TokenInfo } from "#/components/TokenInfo";
import { Form, FormMessage } from "#/components/ui/form";
import { useManagedTransaction } from "#/hooks/tx-manager/useManagedTransaction";
import { useDebounce } from "#/hooks/useDebounce";
import { ICowAmm } from "#/lib/fetchAmmData";
import { calculatePriceImpact } from "#/lib/priceImpact";
import { getDepositSchema } from "#/lib/schema";
Expand Down Expand Up @@ -58,6 +59,9 @@ export function DepositForm({
amount1: Number(amount1),
});

const debouncedPriceImpact = useDebounce<number>(priceImpact, 300);
const debouncedDepositUsdValue = useDebounce<number>(depositUsdValue, 300);

const onSubmit = async (data: z.output<typeof schema>) => {
const txArgs = buildDepositAmmArgs({
cowAmm: ammData,
Expand Down Expand Up @@ -120,12 +124,12 @@ export function DepositForm({
</FormMessage>
)
}
{depositUsdValue > 5000 && priceImpact > 0.1 && (
{debouncedDepositUsdValue > 5000 && debouncedPriceImpact > 0.1 && (
<AlertCard style="warning" title="High Price Impact">
<p>
The price impact of this deposit is{" "}
{formatNumber(priceImpact * 100, 2)}%. Deposits with high price
impact may result in lost funds.
{formatNumber(debouncedPriceImpact * 100, 2)}%. Deposits with high
price impact may result in lost funds.
</p>
</AlertCard>
)}
Expand All @@ -140,7 +144,7 @@ export function DepositForm({
className="w-full mt-2"
disabled={!amount0 && !amount1}
>
Deposit ${formatNumber(depositUsdValue, 2)}
Deposit ${formatNumber(debouncedDepositUsdValue, 2)}
</Button>
</Form>
);
Expand Down
17 changes: 17 additions & 0 deletions apps/cow-amm-deployer/src/hooks/useDebounce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useEffect, useState } from "react";

export function useDebounce<T>(value: T, delay: number) {
const [debouncedValue, setDebouncedValue] = useState<T>(value);

useEffect(() => {
const handler = setTimeout(() => {
setDebouncedValue(value);
}, delay);

return () => {
clearTimeout(handler);
};
}, [value, delay]);

return debouncedValue;
}

0 comments on commit 0b52527

Please sign in to comment.