From 2ffe7bf2310d6dbc2c3204ff33cc530815801cd4 Mon Sep 17 00:00:00 2001 From: shendel Date: Wed, 25 Sep 2024 22:07:09 +0300 Subject: [PATCH] univ3 - mint - out of range process --- .../pages/Exchange/QuickSwap/UniV3Pools.tsx | 46 ++- .../Exchange/QuickSwap/univ3/MintPosition.tsx | 327 +++++++----------- src/front/shared/redux/actions/uniswap.ts | 28 ++ 3 files changed, 178 insertions(+), 223 deletions(-) diff --git a/src/front/shared/pages/Exchange/QuickSwap/UniV3Pools.tsx b/src/front/shared/pages/Exchange/QuickSwap/UniV3Pools.tsx index 802aad84a3..17f415f050 100644 --- a/src/front/shared/pages/Exchange/QuickSwap/UniV3Pools.tsx +++ b/src/front/shared/pages/Exchange/QuickSwap/UniV3Pools.tsx @@ -156,6 +156,24 @@ function UniV3Pools(props) { return (isWrapped) ? network.currency : token.symbol } + const renderMintPosition = () => { + return ( + + ) + } return (
{/* @@ -269,19 +287,7 @@ function UniV3Pools(props) { {currentLiquidityPair == null ? ( <> {currentAction == PositionAction.MINT_POSITION && ( - + <>{renderMintPosition()} )} {currentAction == PositionAction.LIST && (
@@ -307,19 +313,7 @@ function UniV3Pools(props) { ) : ( <> {currentAction == PositionAction.MINT_POSITION && ( - + <>{renderMintPosition()} )} {currentAction == PositionAction.LIST && ( <> diff --git a/src/front/shared/pages/Exchange/QuickSwap/univ3/MintPosition.tsx b/src/front/shared/pages/Exchange/QuickSwap/univ3/MintPosition.tsx index 4a3ae1bb71..9f6a88e9c0 100644 --- a/src/front/shared/pages/Exchange/QuickSwap/univ3/MintPosition.tsx +++ b/src/front/shared/pages/Exchange/QuickSwap/univ3/MintPosition.tsx @@ -48,6 +48,7 @@ function MintPosition(props) { userDeadline, slippage, intl, + owner, } = props console.log('>>>> MIN POSITION', props) @@ -119,170 +120,6 @@ function MintPosition(props) { ? isWrappedToken0 ? baseCurrency : token0.symbol : isWrappedToken1 ? baseCurrency : token1.symbol } - /* - getPoolAddressV3All = async (params) => { - const { baseCurrency, chainId } = params - let { tokenA, tokenB, fee } = params - */ - /* - const [ poolViewSide, setPoolViewSide ] = useState(VIEW_SIDE.A_TO_B) - - const isWrappedToken0 = actions.uniswap.isWrappedToken({ chainId, tokenAddress: token0.address }) - const isWrappedToken1 = actions.uniswap.isWrappedToken({ chainId, tokenAddress: token1.address }) - - const [ amount0, setAmount0 ] = useState(0) - const [ amount1, setAmount1 ] = useState(0) - - - const calcAmount = (amount, token) => { - if (token == TOKEN._0) { - const _amount1 = actions.uniswap.addLiquidityV3CalcAmount({ - amountIn: amount, - price: currentPrice.buyOneOfToken0, - priceHigh: priceHigh.buyOneOfToken0, - priceLow: priceLow.buyOneOfToken0, - }).toNumber() - setAmount0(amount) - setAmount1(_amount1) - } - if (token == TOKEN._1) { - const _amount0 = actions.uniswap.addLiquidityV3CalcAmount({ - amountIn: amount, - price: currentPrice.buyOneOfToken1, - priceHigh: priceLow.buyOneOfToken1, - priceLow: priceHigh.buyOneOfToken1, - }).toNumber() - setAmount0(_amount0) - setAmount1(amount) - } - } - - const posInRange = ( - poolViewSide == VIEW_SIDE.A_TO_B - ) ? ( - new BigNumber(priceHigh.buyOneOfToken1).isLessThanOrEqualTo(poolInfo.currentPrice.buyOneOfToken1) - && new BigNumber(priceLow.buyOneOfToken1).isGreaterThanOrEqualTo(poolInfo.currentPrice.buyOneOfToken1) - ) : ( - new BigNumber(priceLow.buyOneOfToken0).isLessThanOrEqualTo(poolInfo.currentPrice.buyOneOfToken0) - && new BigNumber(priceHigh.buyOneOfToken0).isGreaterThanOrEqualTo(poolInfo.currentPrice.buyOneOfToken0) - ) - - const token0IsWrapped = actions.uniswap.isWrappedToken({ chainId, tokenAddress: token0.address }) - const token1IsWrapped = actions.uniswap.isWrappedToken({ chainId, tokenAddress: token1.address }) - const hasWrappedToken = token0IsWrapped || token1IsWrapped - console.log('>>> PositionInfo', props, positionId, poolInfo, positionInfo) - console.log('>>> isWrappedToken', isWrappedToken0, isWrappedToken1, baseCurrency) - const getTokenSymbol = (tokenType) => { - return (tokenType == TOKEN._0) - ? isWrappedToken0 ? baseCurrency : token0.symbol - : isWrappedToken1 ? baseCurrency : token1.symbol - } - - const [ isFetchingBalanceAllowance, setIsFetchingBalanceAllowance ] = useState(false) - const [ doFetchBalanceAllowance, setDoFetchBalanceAllowance ] = useState(true) - const [ token0BalanceWei, setToken0BalanceWei ] = useState(new BigNumber(0)) - const [ token1BalanceWei, setToken1BalanceWei ] = useState(new BigNumber(0)) - - const [ token0AllowanceWei, setToken0AllowanceWei ] = useState(new BigNumber(0)) - const [ token1AllowanceWei, setToken1AllowanceWei ] = useState(new BigNumber(0)) - - const fromWei = (token_type:TOKEN, wei:BigNumber): Number => { - return new BigNumber(wei) - .div(new BigNumber(10).pow((token_type == TOKEN._0) ? token0.decimals : token1.decimals)) - .toNumber() - } - - const toWei = (token_type:TOKEN, amount:any): BigNumber => { - return new BigNumber(amount) - .multipliedBy(10 ** ((token_type == TOKEN._0) ? token0.decimals : token1.decimals)) - } - - const token0BalanceOk = token0BalanceWei.isGreaterThanOrEqualTo(toWei(TOKEN._0, amount0)) - const token1BalanceOk = token1BalanceWei.isGreaterThanOrEqualTo(toWei(TOKEN._1, amount1)) - const token0AllowanceOk = token0AllowanceWei.isGreaterThanOrEqualTo(toWei(TOKEN._0, amount0)) - const token1AllowanceOk = token1AllowanceWei.isGreaterThanOrEqualTo(toWei(TOKEN._1, amount1)) - const amountsNotZero = (new BigNumber(amount0).isGreaterThan(0) && new BigNumber(amount1).isGreaterThan(0)) - - useEffect(() => { - console.log('>>> check balance and approval') - if (doFetchBalanceAllowance && token0Address && token1Address && !isFetchingBalanceAllowance) { - setIsFetchingBalanceAllowance(true) - setDoFetchBalanceAllowance(false) - setToken0BalanceWei(new BigNumber(0)) - setToken1BalanceWei(new BigNumber(0)) - setToken0AllowanceWei(new BigNumber(0)) - setToken1AllowanceWei(new BigNumber(0)) - actions.uniswap.getBalanceAndAllowanceV3({ - baseCurrency, - chainId, - owner, - token0Address, - token1Address - }).then((answer) => { - setToken0BalanceWei(new BigNumber(answer.token0.balance)) - setToken0AllowanceWei(new BigNumber(answer.token0.allowance)) - setToken1BalanceWei(new BigNumber(answer.token1.balance)) - setToken1AllowanceWei(new BigNumber(answer.token1.allowance)) - setIsFetchingBalanceAllowance(false) - }).catch((err) => { - console.log('>> fail fetch balance and allowance', err) - setIsFetchingBalanceAllowance(false) - }) - } - }, [ token0Address, token1Address, doFetchBalanceAllowance, isFetchingBalanceAllowance ]) - - const [ isApproving, setIsApproving ] = useState(false) - - const handleApprove = (token_type:TOKEN) => { - setIsApproving(true) - actions.uniswap.approveTokenV3({ - baseCurrency, - chainId, - tokenAddress: (token_type == TOKEN._0) ? token0Address : token1Address, - amountWei: toWei(token_type, (token_type == TOKEN._0) ? amount0 : amount1), - waitReceipt: true, - }).then((approveTx) => { - console.log('>>> approved', approveTx) - setDoFetchBalanceAllowance(true) - setIsApproving(false) - }).catch((err) => { - console.log('Fail approve', err) - setIsApproving(false) - }) - } - - */ - const handleAddLiquidity = async () => { - /* - actions.modals.open(modals.Confirm, { - title: (), - message: (), - onAccept: () => { - setIsAddLiquidity(true) - actions.uniswap.addLiquidityV3({ - chainId, - baseCurrency, - amount0Wei: toWei(TOKEN._0, amount0), - amount1Wei: toWei(TOKEN._1, amount1), - position: positionInfo, - deadlinePeriod: userDeadline, - slippage, - waitReceipt: true - }).then(() => { - actions.modals.open(modals.AlertModal, { - message: (), - onClose: () => { - setDoPositionsUpdate(true) - setCurrentAction(PositionAction.INFO) - } - }) - }).catch((err) => { - setIsAddLiquidity(false) - }) - } - }) - */ - } const [ startPrice, setStartPrice ] = useState(0) @@ -356,15 +193,6 @@ function MintPosition(props) { setToken1HighPrice(0) }, [ activeFee ]) - const [ amount0, setAmount0 ] = useState(0) - const [ amount1, setAmount1 ] = useState(0) - - const [ token0BalanceWei, setToken0BalanceWei ] = useState(new BigNumber(0)) - const [ token1BalanceWei, setToken1BalanceWei ] = useState(new BigNumber(0)) - - const [ token0AllowanceWei, setToken0AllowanceWei ] = useState(new BigNumber(0)) - const [ token1AllowanceWei, setToken1AllowanceWei ] = useState(new BigNumber(0)) - const fromWei = (token_type:TOKEN, wei:BigNumber): Number => { return new BigNumber(wei) .div(new BigNumber(10).pow((token_type == TOKEN._0) ? token0.decimals : token1.decimals)) @@ -376,8 +204,109 @@ function MintPosition(props) { .multipliedBy(10 ** ((token_type == TOKEN._0) ? token0.decimals : token1.decimals)) } + + const [ amount0, setAmount0 ] = useState(0) + const [ amount1, setAmount1 ] = useState(0) + + const [ token0BalanceWei, setToken0BalanceWei ] = useState(new BigNumber(0)) + const [ token1BalanceWei, setToken1BalanceWei ] = useState(new BigNumber(0)) + + const [ token0AllowanceWei, setToken0AllowanceWei ] = useState(new BigNumber(0)) + const [ token1AllowanceWei, setToken1AllowanceWei ] = useState(new BigNumber(0)) + + const [ isFetchingBalanceAllowance, setIsFetchingBalanceAllowance ] = useState(false) + const [ doFetchBalanceAllowance, setDoFetchBalanceAllowance ] = useState(true) + + const token0BalanceOk = token0BalanceWei.isGreaterThanOrEqualTo(toWei(TOKEN._0, amount0)) + const token1BalanceOk = token1BalanceWei.isGreaterThanOrEqualTo(toWei(TOKEN._1, amount1)) + const token0AllowanceOk = token0AllowanceWei.isGreaterThanOrEqualTo(toWei(TOKEN._0, amount0)) + const token1AllowanceOk = token1AllowanceWei.isGreaterThanOrEqualTo(toWei(TOKEN._1, amount1)) + const amountsNotZero = (new BigNumber(amount0).isGreaterThan(0) || new BigNumber(amount1).isGreaterThan(0)) + + + useEffect(() => { + if (doFetchBalanceAllowance && token0Address && token1Address && !isFetchingBalanceAllowance) { + setIsFetchingBalanceAllowance(true) + setDoFetchBalanceAllowance(false) + setToken0BalanceWei(new BigNumber(0)) + setToken1BalanceWei(new BigNumber(0)) + setToken0AllowanceWei(new BigNumber(0)) + setToken1AllowanceWei(new BigNumber(0)) + console.log('>>> do fetch balances') + console.log({ + baseCurrency, + chainId, + owner, + token0Address, + token1Address + }) + actions.uniswap.getBalanceAndAllowanceV3({ + baseCurrency, + chainId, + owner, + token0Address, + token1Address + }).then((answer) => { + setToken0BalanceWei(new BigNumber(answer.token0.balance)) + setToken0AllowanceWei(new BigNumber(answer.token0.allowance)) + setToken1BalanceWei(new BigNumber(answer.token1.balance)) + setToken1AllowanceWei(new BigNumber(answer.token1.allowance)) + setIsFetchingBalanceAllowance(false) + }).catch((err) => { + console.log('>> fail fetch balance and allowance', err) + setIsFetchingBalanceAllowance(false) + }) + } + }, [ token0Address, token1Address, doFetchBalanceAllowance, isFetchingBalanceAllowance ]) + + + const isBaseFetching = (isFetchTokensInfo || isPoolsByFeeFetching) + const renderDepositToken0 = () => { + return ( + { setAmount0(v) }} + symbol={getTokenSymbol(TOKEN._0)} + balance={formatAmount(fromWei(TOKEN._0, token0BalanceWei))} + isBalanceUpdate={isFetchingBalanceAllowance} + onBalanceUpdate={() => { setDoFetchBalanceAllowance(true) }} + /> + ) + } + const renderDepositToken1 = () => { + return ( + { setAmount1(v) }} + symbol={getTokenSymbol(TOKEN._1)} + balance={formatAmount(fromWei(TOKEN._1, token0BalanceWei))} + isBalanceUpdate={isFetchingBalanceAllowance} + onBalanceUpdate={() => { setDoFetchBalanceAllowance(true) }} + /> + ) + } + + const posInRange = ( + viewSide == VIEW_SIDE.A_TO_B + ) ? ( + new BigNumber(token0LowerPrice).isLessThanOrEqualTo(startPrice) + && new BigNumber(token0HighPrice).isGreaterThanOrEqualTo(startPrice) + ) : ( + new BigNumber(token1LowerPrice).isLessThanOrEqualTo(startPrice) + && new BigNumber(token1HighPrice).isGreaterThanOrEqualTo(startPrice) + ) + + + + const startPriceIsLower = (viewSide == VIEW_SIDE.A_TO_B) ? new BigNumber(startPrice).isLessThan(token0LowerPrice) : new BigNumber(startPrice).isLessThan(token1LowerPrice) + const startPriceIsHigh = (viewSide == VIEW_SIDE.A_TO_B) ? new BigNumber(startPrice).isGreaterThan(token0HighPrice) : new BigNumber(startPrice).isGreaterThan(token1HighPrice) + + console.log('>>>>> IN RANGE, LOWER, HIGH', posInRange, startPriceIsLower, startPriceIsHigh) + return (
{ setCurrentAction(PositionAction.LIST) }}> @@ -473,6 +402,16 @@ function MintPosition(props) { )} />
+ {!posInRange && ( +
+
+ +
+
+ )} {!poolsByFee[activeFee] && (
@@ -487,37 +426,31 @@ function MintPosition(props) { tokenA={getTokenSymbolFromViewSideA()} tokenB={getTokenSymbolFromViewSideB()} label={( - + )} />
)}

Deposit amounts

-
- { setAmount0(v) }} - symbol={getTokenSymbol(TOKEN._0)} - balance={formatAmount(fromWei(TOKEN._0, token0BalanceWei))} - isBalanceUpdate={false} - onBalanceUpdate={() => { /* setDoFetchBalanceAllowance(true) */ }} - /> -
-
- { setAmount1(v) }} - symbol={getTokenSymbol(TOKEN._1)} - balance={formatAmount(fromWei(TOKEN._1, token1BalanceWei))} - isBalanceUpdate={false} - onBalanceUpdate={() => { /* setDoFetchBalanceAllowance(true) */ }} - /> -
+ {(viewSide == VIEW_SIDE.A_TO_B) ? ( + <> + {!startPriceIsLower && renderDepositToken0()} + {!startPriceIsHigh && renderDepositToken1()} + + ) : ( + <> + {!startPriceIsLower && renderDepositToken1()} + {!startPriceIsHigh && renderDepositToken0()} + + )}
- )}
diff --git a/src/front/shared/redux/actions/uniswap.ts b/src/front/shared/redux/actions/uniswap.ts index d652578c2b..775bd81fb4 100644 --- a/src/front/shared/redux/actions/uniswap.ts +++ b/src/front/shared/redux/actions/uniswap.ts @@ -549,6 +549,8 @@ const mintPositionV3 = async (params) => { 3 fee uint24 3000 4 sqrtPriceX96 uint160 7922421885781463580491979169 */ + + // PT-TER /* Function: mint((address,address,uint24,int24,int24,uint256,uint256,uint256,uint256,address,uint256)) @@ -573,6 +575,32 @@ const mintPositionV3 = async (params) => { 0 params.deadline uint256 1727281546 */ + + // TER-PT + // https://polygonscan.com/tx/0x638983ee1a6663a6fb4261da3fade669a5bc3fed6fbca86ceeca748cabcfca27 + /* + mint((address,address,uint24,int24,int24,uint256,uint256,uint256,uint256,address,uint256)) + # Name Type Data + 0 params.token0 address 0x7e55Cb18a6BCF2AbC1DE911aa7fECbEeB1EfD41d + 0 params.token1 address 0xD10b8A62764852C754f66ebA75556F63938E9026 + 0 params.fee uint24 + 3000 + 0 params.tickLower int24 + -58080 + 0 params.tickUpper int24 + -32220 + 0 params.amount0Desired uint256 + 99999999999999999990 + 0 params.amount1Desired uint256 + 904921544721333137 + 0 params.amount0Min uint256 + 99501152477175647832 + 0 params.amount1Min uint256 + 899908594907632377 + 0 params.recipient address 0x2A8D166495c7f854c5f2510fBD250fDab8ce58d7 + 0 params.deadline uint256 + 1727285413 + */ } const getUserPoolLiquidityV3 = async (params) => {