Skip to content

Commit

Permalink
Update to using reference amount for input of add liquidity proportional
Browse files Browse the repository at this point in the history
  • Loading branch information
MattPereira committed Sep 2, 2024
1 parent fa8242d commit c93b04d
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 216 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,21 @@ export const AddLiquidityForm: React.FC<PoolActionsProps> = ({
}));
const [tokenInputs, setTokenInputs] = useState<InputAmount[]>(initialTokenInputs);
const [addLiquidityReceipt, setAddLiquidityReceipt] = useState<PoolOperationReceipt>(null);
const [bptOut, setBptOut] = useState<InputAmount>(); // only for the proportional add liquidity case
const [referenceAmount, setReferenceAmount] = useState<InputAmount>(); // only for the proportional add liquidity case

const {
data: queryResponse,
isFetching: isQueryFetching,
error: queryError,
refetch: refetchQueryAddLiquidity,
} = useQueryAddLiquidity(pool, tokenInputs, bptOut);
} = useQueryAddLiquidity(pool, tokenInputs, referenceAmount);
const { sufficientAllowances, isApproving, approveTokens } = useApproveTokens(tokenInputs);
const { mutate: addLiquidity, isLoading: isAddLiquidityPending, error: addLiquidityError } = useAddLiquidity();
const { mutate: addLiquidity, isPending: isAddLiquidityPending, error: addLiquidityError } = useAddLiquidity();
const { refetchTokenAllowances } = useReadTokens(tokenInputs);
const queryClient = useQueryClient();

const handleInputChange = (index: number, value: string) => {
queryClient.removeQueries(["queryAddLiquidity"]);
queryClient.removeQueries({ queryKey: ["queryAddLiquidity"] });
setAddLiquidityReceipt(null);
const updatedTokens = tokenInputs.map((token, idx) => {
if (idx === index) {
Expand All @@ -63,17 +63,18 @@ export const AddLiquidityForm: React.FC<PoolActionsProps> = ({
balance: formatUnits(token.balance, token.decimals) as `${number}`,
})),
};

const referenceAmount = updatedTokens[index];
const { bptAmount, tokenAmounts } = calculateProportionalAmounts(poolStateWithBalances, referenceAmount);
setBptOut(bptAmount);
setReferenceAmount(bptAmount);
setTokenInputs(tokenAmounts);
} else {
setTokenInputs(updatedTokens);
}
};

const handleQueryAddLiquidity = () => {
queryClient.removeQueries(["queryAddLiquidity"]);
queryClient.removeQueries({ queryKey: ["queryAddLiquidity"] });
refetchQueryAddLiquidity();
setAddLiquidityReceipt(null);
};
Expand Down Expand Up @@ -105,7 +106,7 @@ export const AddLiquidityForm: React.FC<PoolActionsProps> = ({
});

const error = queryError || addLiquidityError;
const isFormEmpty = tokenInputs.every(token => token.rawAmount === 0n);
const isFormEmpty = tokenInputs.some(token => token.rawAmount === 0n);

return (
<section className="flex flex-col gap-5">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,40 @@ export const RemoveLiquidityForm: React.FC<PoolActionsProps> = ({ pool, refetchP
error: queryError,
refetch: refetchQuery,
} = useQueryRemoveLiquidity("queryRemoveAmount", pool, bptInput.rawAmount);
const { data: allowance } = useAllowanceOnToken(pool.address, BALANCER_ROUTER[chainId]);
const { mutateAsync: approveRouter, error: approveError } = useApproveOnToken(pool.address, BALANCER_ROUTER[chainId]);
const { data: allowance, refetch: refetchAllowance } = useAllowanceOnToken(pool.address, BALANCER_ROUTER[chainId]);
const {
mutate: approveRouter,
isPending: isApprovePending,
error: approveError,
} = useApproveOnToken(pool.address, BALANCER_ROUTER[chainId]);
const {
mutate: removeLiquidity,
isLoading: isRemoveLiquidityPending,
isPending: isRemoveLiquidityPending,
error: removeLiquidityError,
} = useRemoveLiquidity();

const handleAmountChange = (amount: string) => {
queryClient.removeQueries(["queryRemoveLiquidity"]);
queryClient.removeQueries({ queryKey: ["queryRemoveLiquidity"] });
setRemoveLiquidityReceipt(null);
const rawAmount = parseUnits(amount, pool.decimals);
setBptInput({ rawAmount, displayValue: amount });
};

const handleQuery = () => {
queryClient.removeQueries(["queryRemoveLiquidity"]);
queryClient.removeQueries({ queryKey: ["queryRemoveLiquidity"] });
setRemoveLiquidityReceipt(null);
refetchQuery();
};

const handleRemoveLiquidity = async () => {
if (allowance !== undefined && allowance < bptInput.rawAmount) await approveRouter();
const handleApprove = () => {
approveRouter(undefined, {
onSuccess: () => {
refetchAllowance();
},
});
};

const handleRemoveLiquidity = () => {
removeLiquidity(queryResponse, {
onSuccess: () => {
refetchPool();
Expand Down Expand Up @@ -86,6 +96,7 @@ export const RemoveLiquidityForm: React.FC<PoolActionsProps> = ({ pool, refetchP

const error = queryError || removeLiquidityError || approveError;
const isFormEmpty = bptInput.displayValue === "";
const isSufficientAllowance = allowance !== undefined && allowance >= bptInput.rawAmount;

return (
<section className="flex flex-col gap-5">
Expand All @@ -100,6 +111,8 @@ export const RemoveLiquidityForm: React.FC<PoolActionsProps> = ({ pool, refetchP

{!queryResponse || removeLiquidityReceipt || isFormEmpty ? (
<TransactionButton label="Query" onClick={handleQuery} isDisabled={isQueryFetching} isFormEmpty={isFormEmpty} />
) : !isSufficientAllowance ? (
<TransactionButton label="Approve" isDisabled={isApprovePending} onClick={handleApprove} />
) : (
<TransactionButton
label="Remove Liquidity"
Expand Down
10 changes: 5 additions & 5 deletions packages/nextjs/app/pools/_components/operations/SwapForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,18 @@ export const SwapForm: React.FC<PoolActionsProps> = ({ pool, refetchPool, tokenB
);
const {
mutateAsync: approveRouter,
isLoading: isApproveRouterPending,
isPending: isApproveRouterPending,
error: approveRouterError,
} = useApproveOnToken(tokenIn.address, PERMIT2[chainId]);
const {
mutateAsync: approvePermit2,
isLoading: isApprovePermit2Pending,
isPending: isApprovePermit2Pending,
error: approvePermit2Error,
} = useApproveOnPermit2(tokenIn.address);
const { mutate: swap, isLoading: isSwapPending, error: swapError } = useSwap(swapInput);
const { mutate: swap, isPending: isSwapPending, error: swapError } = useSwap(swapInput);

const handleQuerySwap = async () => {
queryClient.removeQueries(["querySwap"]);
queryClient.removeQueries({ queryKey: ["querySwap"] });
setSwapReceipt(null);
refetchQuerySwap();
};
Expand All @@ -107,7 +107,7 @@ export const SwapForm: React.FC<PoolActionsProps> = ({ pool, refetchPool, tokenB

const handleTokenAmountChange = (amount: string, swapConfigKey: "tokenIn" | "tokenOut") => {
// Clear previous results when the amount changes
queryClient.removeQueries(["querySwap"]);
queryClient.removeQueries({ queryKey: ["querySwap"] });
setSwapReceipt(null);
// Update the focused input amount with new value and reset the other input amount
setSwapConfig(prevConfig => ({
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/components/ScaffoldEthAppWithProviders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const queryClient = new QueryClient({
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
structuralSharing: false,
},
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { useQuery } from "@tanstack/react-query";
import { useTargetFork } from "~~/hooks/balancer";
import { Pool } from "~~/hooks/balancer/types";

export const useQueryAddLiquidity = (pool: Pool, amountsIn: InputAmount[], bptOut?: InputAmount) => {
export const useQueryAddLiquidity = (pool: Pool, amountsIn: InputAmount[], referenceAmount?: InputAmount) => {
const { rpcUrl, chainId } = useTargetFork();

const queryAddLiquidity = async () => {
Expand All @@ -21,10 +21,10 @@ export const useQueryAddLiquidity = (pool: Pool, amountsIn: InputAmount[], bptOu

// Construct the addLiquidity input object based on if pool allows unbalanced liquidity operations
const addLiquidityInput: AddLiquidityInput =
pool.poolConfig?.liquidityManagement.disableUnbalancedLiquidity && bptOut
pool.poolConfig?.liquidityManagement.disableUnbalancedLiquidity && referenceAmount
? {
kind: AddLiquidityKind.Proportional,
bptOut,
referenceAmount,
chainId,
rpcUrl,
}
Expand Down
26 changes: 21 additions & 5 deletions packages/nextjs/hooks/balancer/swap/useSwap.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import { ExactInQueryOutput, ExactOutQueryOutput, Slippage, Swap, SwapInput } from "@balancer/sdk";
import {
ExactInQueryOutput,
ExactOutQueryOutput, // Permit2Helper,
Slippage,
Swap,
SwapInput,
} from "@balancer/sdk";
import { useMutation } from "@tanstack/react-query";
import { useWalletClient } from "wagmi";
// import { useTargetFork } from "~~/hooks/balancer";
import { useTransactor } from "~~/hooks/scaffold-eth";

export const useSwap = (swapInput: SwapInput) => {
const { data: walletClient } = useWalletClient();
// const { chainId } = useTargetFork();
const writeTx = useTransactor();

const swap = new Swap(swapInput);
Expand All @@ -18,12 +22,24 @@ export const useSwap = (swapInput: SwapInput) => {
const deadline = 999999999999999999n; // Deadline for the swap, in this case infinite
const slippage = Slippage.fromPercentage("0.1"); // 0.1%

const call = swap.buildCall({
const buildCallInput = {
slippage,
deadline,
queryOutput,
wethIsEth: false,
});
};

const call = swap.buildCall(buildCallInput);

// buildCallWithPermit2 requires viem/wagmi v2 because Client types and methods change

// const permit2 = await Permit2Helper.signSwapApproval({
// ...buildCallInput,
// client: walletClient,
// owner: walletClient.account.address as `0x${string}`,
// });

// const call = swap.buildCallWithPermit2(buildCallInput, permit2);

const txHashPromise = () =>
walletClient.sendTransaction({
Expand Down
5 changes: 2 additions & 3 deletions packages/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,13 @@
"vercel:yolo": "vercel --build-env NEXT_PUBLIC_IGNORE_BUILD_ERROR=true"
},
"dependencies": {
"@apollo/client": "^3.9.7",
"@balancer/sdk": "^0.24.0",
"@balancer/sdk": "^0.25.0",
"@ethersproject/providers": "^5.7.2",
"@heroicons/react": "^2.0.11",
"@rainbow-me/rainbowkit": "1.3.5",
"@tanstack/react-query": "^5.28.6",
"@uniswap/sdk-core": "^4.0.1",
"@uniswap/v2-sdk": "^3.0.1",
"@tanstack/react-query": "^5.28.6",
"blo": "^1.0.1",
"daisyui": "4.5.0",
"graphql": "^16.8.1",
Expand Down
Loading

0 comments on commit c93b04d

Please sign in to comment.