diff --git a/src/components/v3/IncreaseLiquidityV3/index.tsx b/src/components/v3/IncreaseLiquidityV3/index.tsx
index 9ac6c9f27..fb0e7ef12 100644
--- a/src/components/v3/IncreaseLiquidityV3/index.tsx
+++ b/src/components/v3/IncreaseLiquidityV3/index.tsx
@@ -32,6 +32,7 @@ import { ApprovalState, useApproveCallback } from 'hooks/useV3ApproveCallback';
import {
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
UNI_NFT_POSITION_MANAGER_ADDRESS,
+ ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
} from 'constants/v3/addresses';
import { useUSDCValue } from 'hooks/v3/useUSDCPrice';
import CurrencyInputPanel from 'components/v3/CurrencyInputPanel';
@@ -50,6 +51,7 @@ import { unwrappedToken } from 'utils/unwrappedToken';
import { useWeb3Modal } from '@web3modal/ethers5/react';
import { TransactionType } from 'models/enums';
import { wrappedCurrency } from 'utils/wrappedCurrency';
+import { GlobalConst } from 'constants/index';
interface IncreaseLiquidityV3Props {
positionDetails: PositionPool;
@@ -110,6 +112,7 @@ export default function IncreaseLiquidityV3({
depositBDisabled,
ticksAtLimit,
feeTier,
+ liquidityRangeType,
} = useV3DerivedMintInfo(
baseCurrency ?? undefined,
quoteCurrency ?? undefined,
@@ -120,9 +123,13 @@ export default function IncreaseLiquidityV3({
const positionManagerAddress = useMemo(() => {
if (positionDetails.isUni) {
return UNI_NFT_POSITION_MANAGER_ADDRESS[chainId];
+ } else if (
+ liquidityRangeType === GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
+ ) {
+ return ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId];
}
return NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId];
- }, [chainId, positionDetails]);
+ }, [chainId, positionDetails, liquidityRangeType]);
const { onFieldAInput, onFieldBInput } = useV3MintActionHandlers(noLiquidity);
diff --git a/src/config/layerx.json b/src/config/layerx.json
index a2d13d0ff..52ebbf50d 100644
--- a/src/config/layerx.json
+++ b/src/config/layerx.json
@@ -99,10 +99,14 @@
"ichi": {
"available": false
},
+ "algebraIntegral": {
+ "available": true
+ },
"lpLock": {
"available": false
},
"maxChunks": 20,
"blocksPerFetch": 25,
- "poolInitCodeHash": "0xbce37a54eab2fcd71913a0d40723e04238970e7fc1159bfd58ad5b79531697e7"
+ "poolInitCodeHash": "0xbce37a54eab2fcd71913a0d40723e04238970e7fc1159bfd58ad5b79531697e7",
+ "algebraIntegralPoolInitCodeHash": "0x4b9e4a8044ce5695e06fce9421a63b6f5c3db8a561eebb30ea4c775469e36eaf"
}
diff --git a/src/constants/index.ts b/src/constants/index.ts
index b02350879..3bfe65f26 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -328,6 +328,7 @@ export const GlobalConst = {
UNIPILOT_RANGE: '2',
DEFIEDGE_RANGE: '3',
STEER_RANGE: '4',
+ ALGEBRA_INTEGRAL: '5',
},
walletName: {
METAMASK: 'Metamask',
diff --git a/src/constants/v3/addresses.ts b/src/constants/v3/addresses.ts
index da991b984..5b03ec60a 100644
--- a/src/constants/v3/addresses.ts
+++ b/src/constants/v3/addresses.ts
@@ -150,6 +150,9 @@ export const POOL_DEPLOYER_ADDRESS: AddressMap = {
[ChainId.ZKEVM]: '0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270',
[ChainId.LAYERX]: '0x56c2162254b0E4417288786eE402c2B41d4e181e',
};
+export const ALGEBRA_INTEGRAL_POOL_DEPLOYER_ADDRESS: AddressMap = {
+ [ChainId.LAYERX]: '0x9815e9311a13E5b0DC93E6255b8B45Cd8b6c9773',
+};
export const QUOTER_ADDRESSES: AddressMap = {
[ChainId.MATIC]: '0xa15F0D7377B2A0C0c10db057f641beD21028FC89',
@@ -182,6 +185,10 @@ export const SWAP_ROUTER_ADDRESS: AddressMap = {
[ChainId.MATIC]: '0xfaa746afc5ff7d5ef0aa469bb26ddd6cd8f13911',
};
+export const ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES: AddressMap = {
+ [ChainId.LAYERX]: '0x60cdF877e536F6384D8D5aA20c266A8Ad5AE0a4c',
+};
+
export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES: AddressMap = {
[ChainId.MATIC]: '0x8eF88E4c7CfbbaC1C163f7eddd4B578792201de6',
[ChainId.DOGECHAIN]: '0x0b012055F770AE7BB7a8303968A7Fb6088A2296e',
diff --git a/src/hooks/v3/usePools.ts b/src/hooks/v3/usePools.ts
index 37a265e54..d978fe77c 100644
--- a/src/hooks/v3/usePools.ts
+++ b/src/hooks/v3/usePools.ts
@@ -1,6 +1,7 @@
import {
POOL_DEPLOYER_ADDRESS,
UNI_V3_FACTORY_ADDRESS,
+ ALGEBRA_INTEGRAL_POOL_DEPLOYER_ADDRESS,
} from 'constants/v3/addresses';
import { Currency, Token } from '@uniswap/sdk-core';
import { useMemo } from 'react';
@@ -32,6 +33,7 @@ export function usePools(
FeeAmount | undefined,
][],
isUni?: boolean,
+ isAlgebraIntegral?: boolean,
): [PoolState, Pool | null][] {
const { chainId } = useActiveWeb3React();
@@ -57,6 +59,8 @@ export function usePools(
const poolDeployerAddress =
chainId && value && value[2]
? UNI_V3_FACTORY_ADDRESS[chainId]
+ : isAlgebraIntegral
+ ? ALGEBRA_INTEGRAL_POOL_DEPLOYER_ADDRESS[chainId]
: POOL_DEPLOYER_ADDRESS[chainId];
if (!poolDeployerAddress || !value) return undefined;
@@ -67,7 +71,7 @@ export function usePools(
fee: value[2],
});
});
- }, [chainId, transformed]);
+ }, [chainId, transformed, isAlgebraIntegral]);
const globalState0s = useMultipleContractSingleData(
poolAddresses,
@@ -173,6 +177,7 @@ export function usePool(
currencyB: Currency | undefined,
feeAmount?: FeeAmount,
isUni?: boolean,
+ isAlgebraIntegral?: boolean,
): [PoolState, Pool | null] {
const poolKeys: [
Currency | undefined,
@@ -184,7 +189,7 @@ export function usePool(
feeAmount,
]);
- return usePools(poolKeys, isUni)[0];
+ return usePools(poolKeys, isUni, isAlgebraIntegral)[0];
}
export function useTokensSymbols(token0: string, token1: string) {
diff --git a/src/pages/PoolsPage/v3/SupplyLiquidityV3/components/PresetRanges/index.tsx b/src/pages/PoolsPage/v3/SupplyLiquidityV3/components/PresetRanges/index.tsx
index d90079b85..8302b6e34 100644
--- a/src/pages/PoolsPage/v3/SupplyLiquidityV3/components/PresetRanges/index.tsx
+++ b/src/pages/PoolsPage/v3/SupplyLiquidityV3/components/PresetRanges/index.tsx
@@ -60,6 +60,7 @@ interface IPresetRanges {
isDefiedge?: boolean;
isSteer?: boolean;
steerPairs?: SteerVault[];
+ isAlgebraIntegral?: boolean;
}
enum PresetProfits {
@@ -86,6 +87,7 @@ export function PresetRanges({
isDefiedge = false,
defiedgeStrategies,
isSteer = false,
+ isAlgebraIntegral = false,
steerPairs,
}: IPresetRanges) {
const { chainId } = useActiveWeb3React();
@@ -317,6 +319,10 @@ export function PresetRanges({
: [];
}
+ // if (isAlgebraIntegral) {
+ // return [];
+ // }
+
if (isStablecoinPair)
return [
{
@@ -377,6 +383,7 @@ export function PresetRanges({
isDefiedge,
isSteer,
isStablecoinPair,
+ isAlgebraIntegral,
t,
gammaPair,
gammaValues,
diff --git a/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/AddLiquidityButton/index.tsx b/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/AddLiquidityButton/index.tsx
index d6d3b6a69..78de20e58 100644
--- a/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/AddLiquidityButton/index.tsx
+++ b/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/AddLiquidityButton/index.tsx
@@ -40,6 +40,7 @@ import { CurrencyAmount } from '@uniswap/sdk-core';
import {
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
UNI_NFT_POSITION_MANAGER_ADDRESS,
+ ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
} from 'constants/v3/addresses';
import {
calculateGasMargin,
@@ -106,9 +107,14 @@ export function AddLiquidityButton({
const positionManagerAddress = useMemo(() => {
if (mintInfo.feeTier && mintInfo.feeTier.id.includes('uni')) {
return UNI_NFT_POSITION_MANAGER_ADDRESS[chainId];
+ } else if (
+ mintInfo.liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
+ ) {
+ return ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId];
}
return NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId];
- }, [chainId, mintInfo.feeTier]);
+ }, [chainId, mintInfo.feeTier, mintInfo.liquidityRangeType]);
const wethContract = useWETHContract();
const deadline = useTransactionDeadline();
@@ -721,6 +727,138 @@ export function AddLiquidityButton({
setTxPending(false);
setAddLiquidityErrorMessage(t('errorInTx'));
}
+ } else if (
+ mintInfo.liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
+ ) {
+ if (mintInfo.position && account && deadline) {
+ if (!positionManager) return;
+ const useNative = baseCurrency.isNative
+ ? baseCurrency
+ : quoteCurrency.isNative
+ ? quoteCurrency
+ : undefined;
+
+ let callParams;
+ if (mintInfo.feeTier && mintInfo.feeTier.id.includes('uni')) {
+ callParams = UniV3NonFunPosMan.addCallParameters(mintInfo.position, {
+ slippageTolerance: allowedSlippagePercent,
+ recipient: account,
+ deadline: deadline.toString(),
+ useNative,
+ createPool: mintInfo.noLiquidity,
+ });
+ } else if (
+ mintInfo.liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
+ ) {
+ callParams = NonFunPosMan.addCallParameters(mintInfo.position, {
+ slippageTolerance: allowedSlippagePercent,
+ recipient: account,
+ deadline: deadline.toString(),
+ useNative,
+ createPool: mintInfo.noLiquidity,
+ });
+ } else {
+ callParams = NonFunPosMan.addCallParameters(mintInfo.position, {
+ slippageTolerance: allowedSlippagePercent,
+ recipient: account,
+ deadline: deadline.toString(),
+ useNative,
+ createPool: mintInfo.noLiquidity,
+ });
+ }
+ const { calldata, value } = callParams;
+
+ const txn: { to: string; data: string; value: string } = {
+ to: positionManagerAddress,
+ data: calldata,
+ value,
+ };
+
+ setRejected && setRejected(false);
+
+ setAttemptingTxn(true);
+
+ library
+ .getSigner()
+ .estimateGas(txn)
+ .then((estimate) => {
+ const newTxn = {
+ ...txn,
+ gasLimit: calculateGasMarginV3(chainId, estimate),
+ };
+
+ return library
+ .getSigner()
+ .sendTransaction(newTxn)
+ .then(async (response: TransactionResponse) => {
+ setAttemptingTxn(false);
+ setTxPending(true);
+ const summary = mintInfo.noLiquidity
+ ? t('createPoolandaddLiquidity', {
+ symbolA: baseCurrency?.symbol,
+ symbolB: quoteCurrency?.symbol,
+ })
+ : t('addLiquidityWithTokens', {
+ symbolA: baseCurrency?.symbol,
+ symbolB: quoteCurrency?.symbol,
+ });
+ addTransaction(response, {
+ summary,
+ type: TransactionType.ADDED_LIQUIDITY,
+ tokens: [
+ ((baseCurrency as unknown) as any)?.address ??
+ wrappedCurrency(Token.ETHER[chainId], chainId),
+ ((quoteCurrency as unknown) as any)?.address ??
+ wrappedCurrency(Token.ETHER[chainId], chainId),
+ ],
+ });
+
+ dispatch(setAddLiquidityTxHash({ txHash: response.hash }));
+
+ try {
+ const receipt = await response.wait();
+ finalizedTransaction(receipt, {
+ summary,
+ });
+ setTxPending(false);
+ handleAddLiquidity();
+ } catch (error) {
+ console.error('Failed to send transaction', error);
+ setTxPending(false);
+ setAddLiquidityErrorMessage(
+ error?.code === 'ACTION_REJECTED'
+ ? t('txRejected')
+ : t('errorInTx'),
+ );
+ }
+ })
+ .catch((err) => {
+ console.error('Failed to send transaction', err);
+ setAttemptingTxn(false);
+ setAddLiquidityErrorMessage(
+ err?.code === 'ACTION_REJECTED'
+ ? t('txRejected')
+ : t('errorInTx'),
+ );
+ });
+ })
+ .catch((error) => {
+ console.error('Failed to send transaction', error);
+ // we only care if the error is something _other_ than the user rejected the tx
+ setRejected && setRejected(true);
+ setAttemptingTxn(false);
+ setAddLiquidityErrorMessage(
+ error?.code === 'ACTION_REJECTED'
+ ? t('txRejected')
+ : t('errorInTx'),
+ );
+ if (error?.code !== 'ACTION_REJECTED') {
+ console.error(error);
+ }
+ });
+ }
} else {
if (mintInfo.position && account && deadline) {
if (!positionManager) return;
diff --git a/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/EnterAmounts/index.tsx b/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/EnterAmounts/index.tsx
index a48cd06cb..e0ef2d735 100644
--- a/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/EnterAmounts/index.tsx
+++ b/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/EnterAmounts/index.tsx
@@ -14,6 +14,7 @@ import { useUSDCValue } from 'hooks/v3/useUSDCPrice';
import {
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
UNI_NFT_POSITION_MANAGER_ADDRESS,
+ ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
} from 'constants/v3/addresses';
import { halfAmountSpend, maxAmountSpend } from 'utils/v3/maxAmountSpend';
import { tryParseAmount } from 'state/swap/v3/hooks';
@@ -128,13 +129,17 @@ export function EnterAmounts({
isWithNative && currencyB && currencyB.isNative
? currencyB.wrapped
: currencyB;
-
const positionManagerAddress = useMemo(() => {
if (mintInfo.feeTier && mintInfo.feeTier.id.includes('uni')) {
return UNI_NFT_POSITION_MANAGER_ADDRESS[chainId];
+ } else if (
+ mintInfo.liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
+ ) {
+ return ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId];
}
return NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId];
- }, [chainId, mintInfo.feeTier]);
+ }, [chainId, mintInfo.feeTier, mintInfo.liquidityRangeType]);
const steerPeripheryContract = useSteerPeripheryContract();
const [approvalA, approveACallback] = useApproveCallback(
@@ -153,6 +158,9 @@ export function EnterAmounts({
: mintInfo.liquidityRangeType ===
GlobalConst.v3LiquidityRangeType.STEER_RANGE
? steerPeripheryContract?.address
+ : mintInfo.liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
+ ? ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId]
: positionManagerAddress
: undefined,
);
@@ -172,6 +180,9 @@ export function EnterAmounts({
: mintInfo.liquidityRangeType ===
GlobalConst.v3LiquidityRangeType.STEER_RANGE
? steerPeripheryContract?.address
+ : mintInfo.liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
+ ? ALGEBRA_INTEGRAL_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId]
: positionManagerAddress
: undefined,
);
diff --git a/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/SelectRange/index.tsx b/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/SelectRange/index.tsx
index eacf77266..2ff4ebd21 100644
--- a/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/SelectRange/index.tsx
+++ b/src/pages/PoolsPage/v3/SupplyLiquidityV3/containers/SelectRange/index.tsx
@@ -39,6 +39,7 @@ import { Trans, useTranslation } from 'react-i18next';
import { useSteerVaults } from 'hooks/v3/useSteerData';
import { useUnipilotFarmData } from 'hooks/v3/useUnipilotFarms';
import { useGammaData } from 'hooks/v3/useGammaData';
+import { getConfig } from 'config/index';
interface IRangeSelector {
currencyA: Currency | null | undefined;
@@ -65,6 +66,8 @@ export function SelectRange({
);
const { chainId } = useActiveWeb3React();
const chainIdToUse = chainId ? chainId : ChainId.MATIC;
+ const config = getConfig(chainId);
+ const algebraIntegralAvailable = config?.['algebraIntegral']?.['available'];
const dispatch = useAppDispatch();
const activePreset = useActivePreset();
@@ -234,7 +237,9 @@ export function SelectRange({
onLeftRangeInput(
preset
? liquidityRangeType !==
- GlobalConst.v3LiquidityRangeType.MANUAL_RANGE
+ GlobalConst.v3LiquidityRangeType.MANUAL_RANGE &&
+ liquidityRangeType !==
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
? String(Number(priceObj.toSignificant()) * preset.min)
: priceObj
.quote(
@@ -257,7 +262,9 @@ export function SelectRange({
onRightRangeInput(
preset
? liquidityRangeType !==
- GlobalConst.v3LiquidityRangeType.MANUAL_RANGE
+ GlobalConst.v3LiquidityRangeType.MANUAL_RANGE &&
+ liquidityRangeType !==
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL
? String(Number(priceObj.toSignificant()) * preset.max)
: priceObj
.quote(
@@ -415,6 +422,7 @@ export function SelectRange({
const steerVaultExists = steerVaultsForPair.length > 0;
const [isAutomatic, setIsAutoMatic] = useState(false);
+ const [isAlgebraIntegral, setIsAlgebraIntegral] = useState(false);
const selectVaultEnabled =
(gammaPairExists && unipilotVaultExists) ||
@@ -430,6 +438,8 @@ export function SelectRange({
defiedgeStrategyExists ||
steerVaultExists;
+ const algebraIntegralEnabled = automaticEnabled || algebraIntegralAvailable;
+
const enabledVaults = useMemo(() => {
const vaults: string[] = [];
if (gammaPairExists) {
@@ -485,6 +495,10 @@ export function SelectRange({
);
}
}
+ } else if (isAlgebraIntegral) {
+ onChangeLiquidityRangeType(
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL,
+ );
} else {
onChangeLiquidityRangeType(GlobalConst.v3LiquidityRangeType.MANUAL_RANGE);
}
@@ -492,6 +506,7 @@ export function SelectRange({
defiedgeStrategyExists,
gammaPairExists,
isAutomatic,
+ isAlgebraIntegral,
onChangeLiquidityRangeType,
selectVaultEnabled,
steerVaultExists,
@@ -553,20 +568,34 @@ export function SelectRange({
return (
{t('selectRange')}
- {automaticEnabled && (
+ {algebraIntegralEnabled && (
-
+ {automaticEnabled && (
+
+ )}
+ {algebraIntegralAvailable && (
+
+ )}
)}
-
{!!liquidityRangeType && (
)}
@@ -682,7 +715,9 @@ export function SelectRange({
)}
- {liquidityRangeType === GlobalConst.v3LiquidityRangeType.MANUAL_RANGE && (
+ {(liquidityRangeType === GlobalConst.v3LiquidityRangeType.MANUAL_RANGE ||
+ liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL) && (
<>
{mintInfo.price && (
@@ -778,7 +813,6 @@ export function SelectRange({
)}
>
)}
-
{openSettingsModal && (
@@ -433,8 +434,10 @@ export function SupplyLiquidityV3() {
{mintInfo.noLiquidity &&
baseCurrency &&
quoteCurrency &&
- liquidityRangeType ===
- GlobalConst.v3LiquidityRangeType.MANUAL_RANGE && (
+ (liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.MANUAL_RANGE ||
+ liquidityRangeType ===
+ GlobalConst.v3LiquidityRangeType.ALGEBRA_INTEGRAL) && (