import React, { ReactElement, useState, ChangeEvent, useEffect, FormEvent, useRef } from 'react' import styles from './Remove.module.css' import Header from './Header' import { toast } from 'react-toastify' import Actions from './Actions' import { Logger } from '@oceanprotocol/lib' import Token from './Token' import FormHelp from '../../../atoms/Input/Help' import Button from '../../../atoms/Button' import { getMaxPercentRemove } from './utils' import { graphql, useStaticQuery } from 'gatsby' import debounce from 'lodash.debounce' import UserLiquidity from '../../../atoms/UserLiquidity' import InputElement from '../../../atoms/Input/InputElement' import { useOcean } from '../../../../providers/Ocean' import { useWeb3 } from '../../../../providers/Web3' import Decimal from 'decimal.js' import { useAsset } from '../../../../providers/Asset' const contentQuery = graphql` query PoolRemoveQuery { content: allFile(filter: { relativePath: { eq: "price.json" } }) { edges { node { childContentJson { pool { remove { title simple advanced output { titleIn titleOut } action } } } } } } } ` export default function Remove({ setShowRemove, refreshInfo, poolAddress, poolTokens, totalPoolTokens, dtSymbol }: { setShowRemove: (show: boolean) => void refreshInfo: () => void poolAddress: string poolTokens: string totalPoolTokens: string dtSymbol: string }): ReactElement { const data = useStaticQuery(contentQuery) const content = data.content.edges[0].node.childContentJson.pool.remove const slippagePresets = ['5', '10', '15', '25', '50'] const { accountId } = useWeb3() const { ocean } = useOcean() const { isAssetNetwork } = useAsset() const [amountPercent, setAmountPercent] = useState('0') const [amountMaxPercent, setAmountMaxPercent] = useState('100') const [amountPoolShares, setAmountPoolShares] = useState('0') const [amountOcean, setAmountOcean] = useState('0') const [amountDatatoken, setAmountDatatoken] = useState('0') const [isAdvanced, setIsAdvanced] = useState(false) const [isLoading, setIsLoading] = useState() const [txId, setTxId] = useState() const [slippage, setSlippage] = useState('5') const [minOceanAmount, setMinOceanAmount] = useState('0') const [minDatatokenAmount, setMinDatatokenAmount] = useState('0') Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 }) async function handleRemoveLiquidity() { setIsLoading(true) try { const result = isAdvanced === true ? await ocean.pool.removePoolLiquidity( accountId, poolAddress, amountPoolShares, minDatatokenAmount, minOceanAmount ) : await ocean.pool.removeOceanLiquidityWithMinimum( accountId, poolAddress, amountPoolShares, minOceanAmount ) setTxId(result?.transactionHash) refreshInfo() } catch (error) { Logger.error(error.message) toast.error(error.message) } finally { setIsLoading(false) } } // Get and set max percentage useEffect(() => { if (!ocean || !poolTokens) return async function getMax() { const amountMaxPercent = isAdvanced === true ? '100' : await getMaxPercentRemove(ocean, poolAddress, poolTokens) setAmountMaxPercent(amountMaxPercent) } getMax() }, [ocean, isAdvanced, poolAddress, poolTokens]) const getValues = useRef( debounce(async (newAmountPoolShares, isAdvanced) => { if (isAdvanced === true) { const tokens = await ocean.pool.getTokensRemovedforPoolShares( poolAddress, `${newAmountPoolShares}` ) setAmountOcean(tokens?.oceanAmount) setAmountDatatoken(tokens?.dtAmount) return } const amountOcean = await ocean.pool.getOceanRemovedforPoolShares( poolAddress, newAmountPoolShares ) setAmountOcean(amountOcean) }, 150) ) // Check and set outputs when amountPoolShares changes useEffect(() => { if (!ocean || !poolTokens) return getValues.current(amountPoolShares, isAdvanced) }, [ amountPoolShares, isAdvanced, ocean, poolTokens, poolAddress, totalPoolTokens ]) useEffect(() => { const minOceanAmount = new Decimal(amountOcean) .mul(new Decimal(100).minus(new Decimal(slippage))) .dividedBy(100) .toString() const minDatatokenAmount = new Decimal(amountDatatoken) .mul(new Decimal(100).minus(new Decimal(slippage))) .dividedBy(100) .toString() setMinOceanAmount(minOceanAmount.slice(0, 18)) setMinDatatokenAmount(minDatatokenAmount.slice(0, 18)) }, [slippage, amountOcean, amountDatatoken, isAdvanced]) // Set amountPoolShares based on set slider value function handleAmountPercentChange(e: ChangeEvent) { setAmountPercent(e.target.value) if (!poolTokens) return const amountPoolShares = new Decimal(e.target.value) .dividedBy(100) .mul(new Decimal(poolTokens)) .toString() setAmountPoolShares(`${amountPoolShares.slice(0, 18)}`) } function handleMaxButton(e: ChangeEvent) { e.preventDefault() setAmountPercent(amountMaxPercent) const amountPoolShares = new Decimal(amountMaxPercent) .dividedBy(100) .mul(new Decimal(poolTokens)) .toString() setAmountPoolShares(`${amountPoolShares.slice(0, 18)}`) } function handleAdvancedButton(e: FormEvent) { e.preventDefault() setIsAdvanced(!isAdvanced) setAmountPoolShares('0') setAmountPercent('0') setAmountOcean('0') setSlippage('5') setMinOceanAmount('0') setMinDatatokenAmount('0') if (isAdvanced === true) { setAmountDatatoken('0') } } function handleSlippageChange(e: ChangeEvent) { setSlippage(e.target.value) } return (
setShowRemove(false)} />

{amountPercent}%

) => handleAmountPercentChange(e) } />
{isAdvanced === true ? content.advanced : content.simple}

{content.output.titleIn}

{content.output.titleOut} minimum

{isAdvanced === true ? ( <> ) : ( )}
Expected price impact ) => handleSlippageChange(e) } />
handleRemoveLiquidity()} successMessage="Successfully removed liquidity." isDisabled={!isAssetNetwork} txId={txId} />
) }