diff --git a/packages/nextjs/app/v3/_components/ChooseParameters.tsx b/packages/nextjs/app/v3/_components/ChooseParameters.tsx index 0091e97..504e987 100644 --- a/packages/nextjs/app/v3/_components/ChooseParameters.tsx +++ b/packages/nextjs/app/v3/_components/ChooseParameters.tsx @@ -1,41 +1,23 @@ import React from "react"; import { PoolType } from "@balancer/sdk"; import { useQueryClient } from "@tanstack/react-query"; +import { parseUnits } from "viem"; import { useAccount } from "wagmi"; import { ArrowTopRightOnSquareIcon } from "@heroicons/react/24/outline"; import { Checkbox, NumberInput, RadioInput, TextField } from "~~/components/common"; import { type HookFlags, usePoolCreationStore } from "~~/hooks/v3"; -const swapFeePercentages = ["0.1", "0.3", "1"]; -const amplificationParameters = ["10", "100", "1000"]; +type HandleNumberInputChange = ( + e: React.ChangeEvent, + field: "swapFeePercentage" | "amplificationParameter", + min: number, + max: number, +) => void; export const ChooseParameters = () => { - const { address: connectedWalletAddress } = useAccount(); - - const { - isUsingHooks, - poolType, - amplificationParameter, - swapFeePercentage, - swapFeeManager, - pauseManager, - poolHooksContract, - enableDonation, - disableUnbalancedLiquidity, - isDelegatingPauseManagement, - isDelegatingSwapFeeManagement, - updatePool, - } = usePoolCreationStore(); - - const queryClient = useQueryClient(); - const hookFlags: HookFlags | undefined = queryClient.getQueryData(["validatePoolHooks", poolHooksContract]); + const { poolType, updatePool } = usePoolCreationStore(); - const handleNumberInputChange = ( - e: React.ChangeEvent, - field: "swapFeePercentage" | "amplificationParameter", - min: number, - max: number, - ) => { + const handleNumberInputChange: HandleNumberInputChange = (e, field, min, max) => { const value = e.target.value; if (value === "") { @@ -58,270 +40,152 @@ export const ChooseParameters = () => { } }; - const MIN_SWAP_FEE_PERCENTAGE = poolType === PoolType.Stable ? 0.0001 : 0.001; - const SWAP_FEE_LINK = - poolType === PoolType.Stable - ? "https://docs-v3.balancer.fi/developer-reference/contracts/vault-config.html#minimum-swap-fee-percentage-1" - : "https://docs-v3.balancer.fi/developer-reference/contracts/vault-config.html#minimum-swap-fee-percentage"; - return (
Choose pool parameters:
-
-
- - Swap fee percentage - - -
-
- {swapFeePercentages.map(fee => ( - updatePool({ swapFeePercentage: fee })} - isPercentage={true} - /> - ))} -
- handleNumberInputChange(e, "swapFeePercentage", MIN_SWAP_FEE_PERCENTAGE, 10)} - min={MIN_SWAP_FEE_PERCENTAGE} - max={10} - step={MIN_SWAP_FEE_PERCENTAGE} - isPercentage={true} - /> -
-
-
+ {poolType === "GyroE" && } + {(poolType === PoolType.Stable || poolType === PoolType.StableSurge) && ( -
- - -
- {amplificationParameters.map(value => ( - updatePool({ amplificationParameter: value })} - isPercentage={false} - /> - ))} -
- handleNumberInputChange(e, "amplificationParameter", 0, 5000)} - min={1} - max={5000} - step={1} - /> -
-
-
+ )} + + + +
+ ); +}; -
- - { - updatePool({ isDelegatingSwapFeeManagement: true, swapFeeManager: "" }); - }} - /> - - updatePool({ - isDelegatingSwapFeeManagement: false, - swapFeeManager: connectedWalletAddress, - }) - } - /> - updatePool({ isDelegatingSwapFeeManagement: false, swapFeeManager: "" })} - /> - {!isDelegatingSwapFeeManagement && swapFeeManager !== connectedWalletAddress && ( - updatePool({ swapFeeManager: e.target.value.trim() })} +function EclpParams() { + return ( +
+ + E-CLP Parameters + + + +
+ + console.log(e.target.value.trim())} /> + console.log(e.target.value.trim())} /> + + + +
+ ); +} + +function EclpRange({ label, value, min, max }: { label: string; value: string; min: string; max: string }) { + const [rangeValue, setRangeValue] = React.useState(value); + + const handleChange = (e: React.ChangeEvent) => { + setRangeValue(e.target.value); + }; + + return ( +
+
+
{label}
+
{rangeValue}
+
+ +
+ ); +} + +function SwapFeePercentage({ handleNumberInputChange }: { handleNumberInputChange: HandleNumberInputChange }) { + const swapFeePercentages = ["0.1", "0.3", "1"]; + + const { poolType, swapFeePercentage, updatePool } = usePoolCreationStore(); + + const MIN_SWAP_FEE_PERCENTAGE = poolType === PoolType.Stable ? 0.0001 : 0.001; + + return ( +
+ + Swap fee percentage + + + +
+ {swapFeePercentages.map(fee => ( + updatePool({ swapFeePercentage: fee })} + isPercentage={true} + /> + ))} +
+ handleNumberInputChange(e, "swapFeePercentage", MIN_SWAP_FEE_PERCENTAGE, 10)} + min={MIN_SWAP_FEE_PERCENTAGE} + max={10} + step={MIN_SWAP_FEE_PERCENTAGE} + isPercentage={true} /> - )} +
+
+ ); +} -
- - { - updatePool({ isDelegatingPauseManagement: true, pauseManager: "" }); - }} - /> - - updatePool({ - isDelegatingPauseManagement: false, - pauseManager: connectedWalletAddress, - }) - } - /> - updatePool({ isDelegatingPauseManagement: false, pauseManager: "" })} - /> - {!isDelegatingPauseManagement && pauseManager !== connectedWalletAddress && ( -
- updatePool({ pauseManager: e.target.value.trim() })} - /> -
- )} +function AmplificationParameter({ handleNumberInputChange }: { handleNumberInputChange: HandleNumberInputChange }) { + const amplificationParameters = ["10", "100", "1000"]; + + const { amplificationParameter, updatePool } = usePoolCreationStore(); + + return ( +
+ -
- - - {poolType === PoolType.StableSurge ? ( -
-
- The Stable Surge pool type uses a core hooks contract - -
- updatePool({ enableDonation: !enableDonation })} - /> -
- ) : ( - <> - { - updatePool({ - isUsingHooks: false, - poolHooksContract: "", - disableUnbalancedLiquidity: false, - enableDonation: false, - }); - }} - /> - updatePool({ isUsingHooks: true })} - /> - {isUsingHooks && ( -
-
- updatePool({ poolHooksContract: e.target.value.trim() })} - /> -
-
- {hookFlags?.enableHookAdjustedAmounts ? ( -
- This hook requires unbalanced liquidity operations to be disabled - -
- ) : ( - updatePool({ disableUnbalancedLiquidity: !disableUnbalancedLiquidity })} - /> - )} - updatePool({ enableDonation: !enableDonation })} - /> -
-
- )} - - )} +
+ {amplificationParameters.map(value => ( + updatePool({ amplificationParameter: value })} + isPercentage={false} + /> + ))} +
+ handleNumberInputChange(e, "amplificationParameter", 0, 5000)} + min={1} + max={5000} + step={1} + /> +
); -}; +} function NumberParameterButton({ value, @@ -346,3 +210,208 @@ function NumberParameterButton({
); } + +function SwapFeeManger() { + const { swapFeeManager, isDelegatingSwapFeeManagement, updatePool } = usePoolCreationStore(); + + const { address: connectedWalletAddress } = useAccount(); + + return ( +
+ + { + updatePool({ isDelegatingSwapFeeManagement: true, swapFeeManager: "" }); + }} + /> + + updatePool({ + isDelegatingSwapFeeManagement: false, + swapFeeManager: connectedWalletAddress, + }) + } + /> + updatePool({ isDelegatingSwapFeeManagement: false, swapFeeManager: "" })} + /> + {!isDelegatingSwapFeeManagement && swapFeeManager !== connectedWalletAddress && ( + updatePool({ swapFeeManager: e.target.value.trim() })} + /> + )} +
+ ); +} + +function PauseManager() { + const { pauseManager, isDelegatingPauseManagement, updatePool } = usePoolCreationStore(); + + const { address: connectedWalletAddress } = useAccount(); + + return ( +
+ + { + updatePool({ isDelegatingPauseManagement: true, pauseManager: "" }); + }} + /> + + updatePool({ + isDelegatingPauseManagement: false, + pauseManager: connectedWalletAddress, + }) + } + /> + updatePool({ isDelegatingPauseManagement: false, pauseManager: "" })} + /> + {!isDelegatingPauseManagement && pauseManager !== connectedWalletAddress && ( +
+ updatePool({ pauseManager: e.target.value.trim() })} + /> +
+ )} +
+ ); +} + +function PoolHooks() { + const { isUsingHooks, poolType, poolHooksContract, enableDonation, disableUnbalancedLiquidity, updatePool } = + usePoolCreationStore(); + + const queryClient = useQueryClient(); + const hookFlags: HookFlags | undefined = queryClient.getQueryData(["validatePoolHooks", poolHooksContract]); + + return ( +
+ + + {poolType === PoolType.StableSurge ? ( +
+
+ The Stable Surge pool type uses a core hooks contract + +
+ updatePool({ enableDonation: !enableDonation })} + /> +
+ ) : ( + <> + { + updatePool({ + isUsingHooks: false, + poolHooksContract: "", + disableUnbalancedLiquidity: false, + enableDonation: false, + }); + }} + /> + updatePool({ isUsingHooks: true })} + /> + {isUsingHooks && ( +
+
+ updatePool({ poolHooksContract: e.target.value.trim() })} + /> +
+
+ {hookFlags?.enableHookAdjustedAmounts ? ( +
+ This hook requires unbalanced liquidity operations to be disabled + +
+ ) : ( + updatePool({ disableUnbalancedLiquidity: !disableUnbalancedLiquidity })} + /> + )} + updatePool({ enableDonation: !enableDonation })} + /> +
+
+ )} + + )} +
+ ); +} diff --git a/packages/nextjs/app/v3/_components/ChooseTokens.tsx b/packages/nextjs/app/v3/_components/ChooseTokens.tsx index 5f3b05a..d06ae7c 100644 --- a/packages/nextjs/app/v3/_components/ChooseTokens.tsx +++ b/packages/nextjs/app/v3/_components/ChooseTokens.tsx @@ -9,6 +9,7 @@ const MAX_TOKENS = { [PoolType.Weighted]: 8, [PoolType.Stable]: 4, // because Daniel said to "for the moment, even though it theoretically supports more" [PoolType.StableSurge]: 4, + ["GyroE"]: 2, // GyroECLP supports only 2 tokens }; export function ChooseTokens() { diff --git a/packages/nextjs/app/v3/_components/ChooseType.tsx b/packages/nextjs/app/v3/_components/ChooseType.tsx index c227f35..2e2cf7b 100644 --- a/packages/nextjs/app/v3/_components/ChooseType.tsx +++ b/packages/nextjs/app/v3/_components/ChooseType.tsx @@ -4,7 +4,7 @@ import { ArrowUpRightIcon } from "@heroicons/react/24/solid"; import { usePoolCreationStore } from "~~/hooks/v3"; import { AllowedPoolTypes } from "~~/hooks/v3/usePoolCreationStore"; -const POOL_TYPES: AllowedPoolTypes[] = [PoolType.Weighted, PoolType.Stable, PoolType.StableSurge]; +const POOL_TYPES: AllowedPoolTypes[] = [PoolType.Weighted, PoolType.Stable, PoolType.StableSurge, "GyroE"]; const POOL_TYPE_DESCRIPTIONS: Record = { [PoolType.Weighted]: @@ -13,6 +13,7 @@ const POOL_TYPE_DESCRIPTIONS: Record = { "Engineered for assets that trade near parity, Stable Pools are perfect for tightly correlated assets like Stablecoins, ensuring seamless trading with minimal slippage", [PoolType.StableSurge]: "A core stable pool that uses a stable surge hook deployed by the official stable surge factory", + GyroE: "A GyroE pool is a special type of pool that uses a GyroE hook deployed by the official GyroE factory", }; const INITIAL_DESCRIPTION = ( @@ -36,13 +37,13 @@ export function ChooseType() { return ( <>
-
+
{POOL_TYPES.map(type => (