mirror of
https://github.com/oceanprotocol/market.git
synced 2024-11-15 09:44:53 +01:00
Merge pull request #102 from oceanprotocol/feature/remove-liquidity
Removing liquidity
This commit is contained in:
commit
7c1ecbfe51
26
content/price.json
Normal file
26
content/price.json
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"pool": {
|
||||||
|
"tooltips": {
|
||||||
|
"price": "Explain how this price is determined...",
|
||||||
|
"liquidity": "Explain what this represents, advantage of providing liquidity..."
|
||||||
|
},
|
||||||
|
"add": {
|
||||||
|
"title": "Add Liquidity",
|
||||||
|
"output": {
|
||||||
|
"titleIn": "You will receive",
|
||||||
|
"titleOut": "You will earn"
|
||||||
|
},
|
||||||
|
"action": "Supply"
|
||||||
|
},
|
||||||
|
"remove": {
|
||||||
|
"title": "Remove Liquidity",
|
||||||
|
"simple": "Set the amount of your pool shares to spend. You will get the equivalent value in OCEAN, limited to maximum amount for pool protection. If you have Datatokens left in your wallet, you can add them to the pool to increase the maximum amount.",
|
||||||
|
"advanced": "Set the amount of your pool shares to spend. You will get OCEAN and Datatokens equivalent to your pool share, without any limit. You can use these Datatokens in other DeFi tools.",
|
||||||
|
"output": {
|
||||||
|
"titleIn": "You will spend",
|
||||||
|
"titleOut": "You will receive"
|
||||||
|
},
|
||||||
|
"action": "Remove"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -4029,9 +4029,9 @@
|
|||||||
"integrity": "sha512-LING+GvW37I0L40rZdPCZ1SvcZurDSGGhT0WOVPNO8oyh2C3bXModDBNE4+gCFa8pTbQBOc4ot1/Zoj9PfT/zA=="
|
"integrity": "sha512-LING+GvW37I0L40rZdPCZ1SvcZurDSGGhT0WOVPNO8oyh2C3bXModDBNE4+gCFa8pTbQBOc4ot1/Zoj9PfT/zA=="
|
||||||
},
|
},
|
||||||
"@oceanprotocol/lib": {
|
"@oceanprotocol/lib": {
|
||||||
"version": "0.6.1",
|
"version": "0.6.2",
|
||||||
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.6.1.tgz",
|
"resolved": "https://registry.npmjs.org/@oceanprotocol/lib/-/lib-0.6.2.tgz",
|
||||||
"integrity": "sha512-nU+sBTpGdoCaZkzOBkZxwEtjSsxFQ9YDK3C3a8iuxoY60Cd1OfoiG4toBWF3yLgXaXkaiYPufZ6rL4sJKakHKg==",
|
"integrity": "sha512-hqZCzJXU+P8lnal+H329UHXfoLHAgjYw+foWxG466KcrQ66TtcdpGIMKMNev+A990P8KzueC8mC62BLGj6//Gg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@ethereum-navigator/navigator": "^0.5.0",
|
"@ethereum-navigator/navigator": "^0.5.0",
|
||||||
"@oceanprotocol/contracts": "^0.5.5",
|
"@oceanprotocol/contracts": "^0.5.5",
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
"@coingecko/cryptoformat": "^0.4.2",
|
"@coingecko/cryptoformat": "^0.4.2",
|
||||||
"@loadable/component": "5.13.1",
|
"@loadable/component": "5.13.1",
|
||||||
"@oceanprotocol/art": "^3.0.0",
|
"@oceanprotocol/art": "^3.0.0",
|
||||||
"@oceanprotocol/lib": "^0.6.1",
|
"@oceanprotocol/lib": "^0.6.2",
|
||||||
"@oceanprotocol/react": "^0.2.0",
|
"@oceanprotocol/react": "^0.2.0",
|
||||||
"@oceanprotocol/typographies": "^0.1.0",
|
"@oceanprotocol/typographies": "^0.1.0",
|
||||||
"@sindresorhus/slugify": "^1.0.0",
|
"@sindresorhus/slugify": "^1.0.0",
|
||||||
|
@ -204,6 +204,34 @@
|
|||||||
border-color: var(--brand-grey);
|
border-color: var(--brand-grey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type='range'] {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range']:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range']::-webkit-slider-thumb,
|
||||||
|
input[type='range']::-moz-range-thumb {
|
||||||
|
appearance: none;
|
||||||
|
background: var(--brand-gradient);
|
||||||
|
border: 2px solid var(--brand-grey-lighter);
|
||||||
|
width: var(--font-size-large);
|
||||||
|
height: var(--font-size-large);
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
box-shadow: 0 2px 9px 0 rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type='range']::-webkit-slider-runnable-track,
|
||||||
|
input[type='range']::-moz-range-track {
|
||||||
|
background: var(--brand-grey-lighter);
|
||||||
|
border-radius: var(--border-radius);
|
||||||
|
height: 0.3rem;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Size modifiers */
|
/* Size modifiers */
|
||||||
|
|
||||||
.small {
|
.small {
|
||||||
|
@ -11,6 +11,30 @@ import PriceUnit from '../../../atoms/Price/PriceUnit'
|
|||||||
import Actions from './Actions'
|
import Actions from './Actions'
|
||||||
import Tooltip from '../../../atoms/Tooltip'
|
import Tooltip from '../../../atoms/Tooltip'
|
||||||
import { ReactComponent as Caret } from '../../../../images/caret.svg'
|
import { ReactComponent as Caret } from '../../../../images/caret.svg'
|
||||||
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
|
|
||||||
|
const contentQuery = graphql`
|
||||||
|
query PoolAddQuery {
|
||||||
|
content: allFile(filter: { relativePath: { eq: "price.json" } }) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
childContentJson {
|
||||||
|
pool {
|
||||||
|
add {
|
||||||
|
title
|
||||||
|
output {
|
||||||
|
titleIn
|
||||||
|
titleOut
|
||||||
|
}
|
||||||
|
action
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
export default function Add({
|
export default function Add({
|
||||||
setShowAdd,
|
setShowAdd,
|
||||||
@ -29,6 +53,9 @@ export default function Add({
|
|||||||
dtSymbol: string
|
dtSymbol: string
|
||||||
dtAddress: string
|
dtAddress: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
|
const data = useStaticQuery(contentQuery)
|
||||||
|
const content = data.content.edges[0].node.childContentJson.pool.add
|
||||||
|
|
||||||
const { ocean, accountId, balance } = useOcean()
|
const { ocean, accountId, balance } = useOcean()
|
||||||
const [amount, setAmount] = useState('')
|
const [amount, setAmount] = useState('')
|
||||||
const [txId, setTxId] = useState<string>('')
|
const [txId, setTxId] = useState<string>('')
|
||||||
@ -93,7 +120,7 @@ export default function Add({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header title="Add Liquidity" backAction={() => setShowAdd(false)} />
|
<Header title={content.title} backAction={() => setShowAdd(false)} />
|
||||||
|
|
||||||
<div className={styles.addInput}>
|
<div className={styles.addInput}>
|
||||||
<div className={styles.userLiquidity}>
|
<div className={styles.userLiquidity}>
|
||||||
@ -138,12 +165,12 @@ export default function Add({
|
|||||||
|
|
||||||
<div className={styles.output}>
|
<div className={styles.output}>
|
||||||
<div>
|
<div>
|
||||||
<p>You will receive</p>
|
<p>{content.output.titleIn}</p>
|
||||||
<Token symbol="pool shares" balance={newPoolTokens} />
|
<Token symbol="pool shares" balance={newPoolTokens} />
|
||||||
<Token symbol="% of pool" balance={newPoolShare} />
|
<Token symbol="% of pool" balance={newPoolShare} />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>You will earn</p>
|
<p>{content.output.titleOut}</p>
|
||||||
<Token symbol="% swap fee" balance={swapFee} />
|
<Token symbol="% swap fee" balance={swapFee} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -151,7 +178,7 @@ export default function Add({
|
|||||||
<Actions
|
<Actions
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
loaderMessage="Adding Liquidity..."
|
loaderMessage="Adding Liquidity..."
|
||||||
actionName="Supply"
|
actionName={content.action}
|
||||||
action={handleAddLiquidity}
|
action={handleAddLiquidity}
|
||||||
txId={txId}
|
txId={txId}
|
||||||
/>
|
/>
|
||||||
|
@ -1,11 +1,66 @@
|
|||||||
.removeInput {
|
.removeInput {
|
||||||
composes: addInput from './Add.module.css';
|
composes: addInput from './Add.module.css';
|
||||||
}
|
padding-left: calc(var(--spacer) * 2);
|
||||||
|
padding-right: calc(var(--spacer) * 2);
|
||||||
.buttonMax {
|
|
||||||
composes: buttonMax from './Add.module.css';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.userLiquidity {
|
.userLiquidity {
|
||||||
composes: userLiquidity from './Add.module.css';
|
composes: userLiquidity from './Add.module.css';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.range {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.range h3 {
|
||||||
|
margin-bottom: calc(var(--spacer) / 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.range input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.range p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-left: -2rem;
|
||||||
|
margin-right: -2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.range button {
|
||||||
|
margin-top: calc(var(--spacer) / 4);
|
||||||
|
margin-bottom: 0;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 1rem;
|
||||||
|
right: 2rem;
|
||||||
|
font-size: var(--font-size-mini);
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maximum {
|
||||||
|
position: absolute;
|
||||||
|
right: -1.5rem;
|
||||||
|
bottom: 1.5rem;
|
||||||
|
font-size: var(--font-size-small);
|
||||||
|
z-index: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output {
|
||||||
|
composes: output from './Add.module.css';
|
||||||
|
}
|
||||||
|
|
||||||
|
.output [class*='token'] {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output [class*='token'] > figure {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output figure[class*='pool shares'] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
@ -1,42 +1,90 @@
|
|||||||
import React, { ReactElement, useState, ChangeEvent } from 'react'
|
import React, {
|
||||||
|
ReactElement,
|
||||||
|
useState,
|
||||||
|
ChangeEvent,
|
||||||
|
useEffect,
|
||||||
|
FormEvent
|
||||||
|
} from 'react'
|
||||||
import styles from './Remove.module.css'
|
import styles from './Remove.module.css'
|
||||||
import { useOcean } from '@oceanprotocol/react'
|
import { useOcean } from '@oceanprotocol/react'
|
||||||
import Header from './Header'
|
import Header from './Header'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
import InputElement from '../../../atoms/Input/InputElement'
|
|
||||||
import Actions from './Actions'
|
import Actions from './Actions'
|
||||||
import { Logger } from '@oceanprotocol/lib'
|
import { Logger } from '@oceanprotocol/lib'
|
||||||
|
import Token from './Token'
|
||||||
|
import FormHelp from '../../../atoms/Input/Help'
|
||||||
import Button from '../../../atoms/Button'
|
import Button from '../../../atoms/Button'
|
||||||
import PriceUnit from '../../../atoms/Price/PriceUnit'
|
import { getMaxValuesRemove } from './utils'
|
||||||
import { Balance } from '.'
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
|
|
||||||
|
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({
|
export default function Remove({
|
||||||
setShowRemove,
|
setShowRemove,
|
||||||
poolAddress,
|
poolAddress,
|
||||||
totalPoolTokens,
|
poolTokens,
|
||||||
userLiquidity
|
dtSymbol
|
||||||
}: {
|
}: {
|
||||||
setShowRemove: (show: boolean) => void
|
setShowRemove: (show: boolean) => void
|
||||||
poolAddress: string
|
poolAddress: string
|
||||||
totalPoolTokens: string
|
poolTokens: string
|
||||||
userLiquidity: Balance
|
dtSymbol: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
|
const data = useStaticQuery(contentQuery)
|
||||||
|
const content = data.content.edges[0].node.childContentJson.pool.remove
|
||||||
|
|
||||||
const { ocean, accountId } = useOcean()
|
const { ocean, accountId } = useOcean()
|
||||||
const [amount, setAmount] = useState('')
|
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<boolean>()
|
const [isLoading, setIsLoading] = useState<boolean>()
|
||||||
const [txId, setTxId] = useState<string>('')
|
const [txId, setTxId] = useState<string>()
|
||||||
|
|
||||||
async function handleRemoveLiquidity() {
|
async function handleRemoveLiquidity() {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await ocean.pool.removeOceanLiquidity(
|
const result =
|
||||||
|
isAdvanced === true
|
||||||
|
? await ocean.pool.removePoolLiquidity(
|
||||||
accountId,
|
accountId,
|
||||||
poolAddress,
|
poolAddress,
|
||||||
amount,
|
amountPoolShares
|
||||||
totalPoolTokens
|
|
||||||
)
|
)
|
||||||
setTxId(result.transactionHash)
|
: await ocean.pool.removeOceanLiquidity(
|
||||||
|
accountId,
|
||||||
|
poolAddress,
|
||||||
|
amountDatatoken,
|
||||||
|
amountPoolShares
|
||||||
|
)
|
||||||
|
|
||||||
|
setTxId(result?.transactionHash)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Logger.error(error.message)
|
Logger.error(error.message)
|
||||||
toast.error(error.message)
|
toast.error(error.message)
|
||||||
@ -45,55 +93,97 @@ export default function Remove({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAmountChange(e: ChangeEvent<HTMLInputElement>) {
|
function handleAmountPercentChange(e: ChangeEvent<HTMLInputElement>) {
|
||||||
setAmount(e.target.value)
|
setAmountPercent(e.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMax() {
|
function handleAdvancedButton(e: FormEvent<HTMLButtonElement>) {
|
||||||
setAmount(`${userLiquidity.ocean}`)
|
e.preventDefault()
|
||||||
|
setIsAdvanced(!isAdvanced)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check and set outputs when percentage changes
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ocean || !poolTokens) return
|
||||||
|
|
||||||
|
async function getValues() {
|
||||||
|
const amountPoolShares =
|
||||||
|
(Number(amountPercent) / 100) * Number(poolTokens)
|
||||||
|
setAmountPoolShares(`${amountPoolShares}`)
|
||||||
|
|
||||||
|
if (isAdvanced === true) {
|
||||||
|
setAmountMaxPercent('100')
|
||||||
|
|
||||||
|
const tokens = await ocean.pool.getTokensRemovedforPoolShares(
|
||||||
|
poolAddress,
|
||||||
|
`${amountPoolShares}`
|
||||||
|
)
|
||||||
|
setAmountOcean(tokens?.oceanAmount)
|
||||||
|
setAmountDatatoken(tokens?.dtAmount)
|
||||||
|
} else {
|
||||||
|
const { amountMaxPercent, amountOcean } = await getMaxValuesRemove(
|
||||||
|
ocean,
|
||||||
|
poolAddress,
|
||||||
|
poolTokens,
|
||||||
|
`${amountPoolShares}`
|
||||||
|
)
|
||||||
|
setAmountMaxPercent(amountMaxPercent)
|
||||||
|
setAmountOcean(amountOcean)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getValues()
|
||||||
|
}, [amountPercent, isAdvanced, ocean, poolTokens, poolAddress])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.remove}>
|
<div className={styles.remove}>
|
||||||
<Header
|
<Header title={content.title} backAction={() => setShowRemove(false)} />
|
||||||
title="Remove Liquidity"
|
|
||||||
backAction={() => setShowRemove(false)}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<form className={styles.removeInput}>
|
<form className={styles.removeInput}>
|
||||||
<div className={styles.userLiquidity}>
|
<div className={styles.range}>
|
||||||
<span>Your pool liquidity: </span>
|
<h3>{amountPercent}%</h3>
|
||||||
<PriceUnit price={`${userLiquidity.ocean}`} symbol="OCEAN" small />
|
<div className={styles.slider}>
|
||||||
</div>
|
<input
|
||||||
<InputElement
|
type="range"
|
||||||
value={amount}
|
min="0"
|
||||||
name="ocean"
|
max={amountMaxPercent}
|
||||||
type="number"
|
step={Number(amountMaxPercent) < 10 ? '1' : '10'}
|
||||||
prefix="OCEAN"
|
value={amountPercent}
|
||||||
placeholder="0"
|
onChange={handleAmountPercentChange}
|
||||||
onChange={handleAmountChange}
|
|
||||||
/>
|
/>
|
||||||
|
{isAdvanced === false && (
|
||||||
{userLiquidity.ocean > Number(amount) && (
|
<span
|
||||||
<Button
|
className={styles.maximum}
|
||||||
className={styles.buttonMax}
|
>{`${amountMaxPercent}% max.`}</span>
|
||||||
style="text"
|
|
||||||
size="small"
|
|
||||||
onClick={handleMax}
|
|
||||||
>
|
|
||||||
Use Max
|
|
||||||
</Button>
|
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FormHelp>
|
||||||
|
{isAdvanced === true ? content.advanced : content.simple}
|
||||||
|
</FormHelp>
|
||||||
|
<Button style="text" size="small" onClick={handleAdvancedButton}>
|
||||||
|
{isAdvanced === true ? 'Simple' : 'Advanced'}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{/* <Input name="dt" label={dtSymbol} type="number" placeholder="0" /> */}
|
<div className={styles.output}>
|
||||||
|
<div>
|
||||||
<p>You will receive</p>
|
<p>{content.output.titleIn}</p>
|
||||||
|
<Token symbol="pool shares" balance={amountPoolShares} noIcon />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>{content.output.titleOut}</p>
|
||||||
|
<Token symbol="OCEAN" balance={amountOcean} />
|
||||||
|
{isAdvanced === true && (
|
||||||
|
<Token symbol={dtSymbol} balance={amountDatatoken} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Actions
|
<Actions
|
||||||
isLoading={isLoading}
|
isLoading={isLoading}
|
||||||
loaderMessage="Removing Liquidity..."
|
loaderMessage="Removing Liquidity..."
|
||||||
actionName="Remove"
|
actionName={content.action}
|
||||||
action={handleRemoveLiquidity}
|
action={handleRemoveLiquidity}
|
||||||
txId={txId}
|
txId={txId}
|
||||||
/>
|
/>
|
||||||
|
@ -13,17 +13,36 @@ import Conversion from '../../../atoms/Price/Conversion'
|
|||||||
import EtherscanLink from '../../../atoms/EtherscanLink'
|
import EtherscanLink from '../../../atoms/EtherscanLink'
|
||||||
import Token from './Token'
|
import Token from './Token'
|
||||||
import TokenList from './TokenList'
|
import TokenList from './TokenList'
|
||||||
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
|
|
||||||
export interface Balance {
|
export interface Balance {
|
||||||
ocean: number
|
ocean: number
|
||||||
datatoken: number
|
datatoken: number
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
const contentQuery = graphql`
|
||||||
TODO: create tooltip copy
|
query PoolQuery {
|
||||||
*/
|
content: allFile(filter: { relativePath: { eq: "price.json" } }) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
childContentJson {
|
||||||
|
pool {
|
||||||
|
tooltips {
|
||||||
|
price
|
||||||
|
liquidity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
|
export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
|
||||||
|
const data = useStaticQuery(contentQuery)
|
||||||
|
const content = data.content.edges[0].node.childContentJson.pool
|
||||||
|
|
||||||
const { ocean, accountId } = useOcean()
|
const { ocean, accountId } = useOcean()
|
||||||
const { price } = useMetadata(ddo)
|
const { price } = useMetadata(ddo)
|
||||||
|
|
||||||
@ -128,8 +147,8 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
|
|||||||
<Remove
|
<Remove
|
||||||
setShowRemove={setShowRemove}
|
setShowRemove={setShowRemove}
|
||||||
poolAddress={price.address}
|
poolAddress={price.address}
|
||||||
totalPoolTokens={totalPoolTokens}
|
poolTokens={poolTokens}
|
||||||
userLiquidity={userLiquidity}
|
dtSymbol={dtSymbol}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
@ -137,7 +156,7 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
|
|||||||
<PriceUnit price="1" symbol={dtSymbol} /> ={' '}
|
<PriceUnit price="1" symbol={dtSymbol} /> ={' '}
|
||||||
<PriceUnit price={`${price.value}`} />
|
<PriceUnit price={`${price.value}`} />
|
||||||
<Conversion price={`${price.value}`} />
|
<Conversion price={`${price.value}`} />
|
||||||
<Tooltip content="Explain how this price is determined..." />
|
<Tooltip content={content.tooltips.price} />
|
||||||
<div className={styles.dataTokenLinks}>
|
<div className={styles.dataTokenLinks}>
|
||||||
<EtherscanLink
|
<EtherscanLink
|
||||||
network="rinkeby"
|
network="rinkeby"
|
||||||
@ -155,7 +174,7 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
|
|||||||
title={
|
title={
|
||||||
<>
|
<>
|
||||||
Your Liquidity
|
Your Liquidity
|
||||||
<Tooltip content="Explain what this represents, advantage of providing liquidity..." />
|
<Tooltip content={content.tooltips.liquidity} />
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
ocean={`${userLiquidity.ocean}`}
|
ocean={`${userLiquidity.ocean}`}
|
||||||
|
28
src/components/organisms/AssetActions/Pool/utils.ts
Normal file
28
src/components/organisms/AssetActions/Pool/utils.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { Ocean } from '@oceanprotocol/lib'
|
||||||
|
|
||||||
|
export async function getMaxValuesRemove(
|
||||||
|
ocean: Ocean,
|
||||||
|
poolAddress: string,
|
||||||
|
poolTokens: string,
|
||||||
|
amountPoolShares: string
|
||||||
|
): Promise<{ amountMaxPercent: string; amountOcean: string }> {
|
||||||
|
const amountMaxOcean = await ocean.pool.getOceanMaxRemoveLiquidity(
|
||||||
|
poolAddress
|
||||||
|
)
|
||||||
|
|
||||||
|
const amountMaxPoolShares = await ocean.pool.getPoolSharesRequiredToRemoveOcean(
|
||||||
|
poolAddress,
|
||||||
|
amountMaxOcean
|
||||||
|
)
|
||||||
|
|
||||||
|
const amountMaxPercent = `${Math.floor(
|
||||||
|
(Number(amountMaxPoolShares) / Number(poolTokens)) * 100
|
||||||
|
)}`
|
||||||
|
|
||||||
|
const amountOcean = await ocean.pool.getOceanRemovedforPoolShares(
|
||||||
|
poolAddress,
|
||||||
|
amountPoolShares
|
||||||
|
)
|
||||||
|
|
||||||
|
return { amountMaxPercent, amountOcean }
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user