mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
More helpful output for Add Liquidity (#277)
* prototype * add copy * value update fixes * calculation fun * move copy * move copy * cleanup * use Decimal * fix Co-authored-by: alexcos20 <alex.coseru@gmail.com>
This commit is contained in:
parent
54feaebc5a
commit
f843641a45
@ -26,13 +26,14 @@
|
|||||||
"pool": {
|
"pool": {
|
||||||
"tooltips": {
|
"tooltips": {
|
||||||
"price": "Explain how this price is determined...",
|
"price": "Explain how this price is determined...",
|
||||||
"liquidity": "Explain what this represents, advantage of providing liquidity..."
|
"liquidity": "Providing liquidity will earn you SWAPFEE% on every transaction in this pool, proportionally to your share of the pool."
|
||||||
},
|
},
|
||||||
"add": {
|
"add": {
|
||||||
"title": "Add Liquidity",
|
"title": "Add Liquidity",
|
||||||
"output": {
|
"output": {
|
||||||
|
"help": "Providing liquidity will earn you SWAPFEE% on every transaction in this pool, proportionally to your share of the pool. Your token input will be converted based on the weight of the pool.",
|
||||||
"titleIn": "You will receive",
|
"titleIn": "You will receive",
|
||||||
"titleOut": "You will earn"
|
"titleOut": "Pool conversion"
|
||||||
},
|
},
|
||||||
"action": "Approve & Supply",
|
"action": "Approve & Supply",
|
||||||
"warning": "Use at your own risk. Please familiarize yourself [with the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13) and the [Terms of Use](/terms)."
|
"warning": "Use at your own risk. Please familiarize yourself [with the risks](https://blog.oceanprotocol.com/on-staking-on-data-in-ocean-market-3d8e09eb0a13) and the [Terms of Use](/terms)."
|
||||||
|
@ -66,23 +66,34 @@ export default function FormAdd({
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (Number(values.amount) > Number(amountMax)) return
|
if (Number(values.amount) > Number(amountMax)) return
|
||||||
|
|
||||||
const poolTokens = await ocean.pool.calcPoolOutGivenSingleIn(
|
const poolTokens = await ocean.pool.calcPoolOutGivenSingleIn(
|
||||||
poolAddress,
|
poolAddress,
|
||||||
coin === 'OCEAN' ? ocean.pool.oceanAddress : ocean.pool.dtAddress,
|
coin === 'OCEAN' ? ocean.pool.oceanAddress : ocean.pool.dtAddress,
|
||||||
values.amount.toString()
|
`${values.amount}`
|
||||||
)
|
)
|
||||||
setNewPoolTokens(poolTokens)
|
setNewPoolTokens(poolTokens)
|
||||||
setNewPoolShare(
|
|
||||||
totalBalance &&
|
totalBalance &&
|
||||||
(
|
setNewPoolShare(
|
||||||
|
`${
|
||||||
(Number(poolTokens) /
|
(Number(poolTokens) /
|
||||||
(Number(totalPoolTokens) + Number(poolTokens))) *
|
(Number(totalPoolTokens) + Number(poolTokens))) *
|
||||||
100
|
100
|
||||||
).toFixed(2)
|
}`
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
calculatePoolShares()
|
calculatePoolShares()
|
||||||
}, [values.amount])
|
}, [
|
||||||
|
values.amount,
|
||||||
|
totalBalance,
|
||||||
|
totalPoolTokens,
|
||||||
|
amountMax,
|
||||||
|
coin,
|
||||||
|
poolAddress,
|
||||||
|
ocean.pool,
|
||||||
|
setNewPoolTokens,
|
||||||
|
setNewPoolShare
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
.output {
|
||||||
|
display: grid;
|
||||||
|
gap: var(--spacer);
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
padding-bottom: calc(var(--spacer) / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.output p {
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
|
margin-bottom: calc(var(--spacer) / 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.output div:first-child [class*='token'] {
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.output div:first-child [class*='token'] > figure {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help {
|
||||||
|
text-align: center;
|
||||||
|
}
|
100
src/components/organisms/AssetActions/Pool/Add/Output.tsx
Normal file
100
src/components/organisms/AssetActions/Pool/Add/Output.tsx
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
import { FormikContextType, useFormikContext } from 'formik'
|
||||||
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
|
import { FormAddLiquidity } from '.'
|
||||||
|
import TokenBalance from '../../../../../@types/TokenBalance'
|
||||||
|
import FormHelp from '../../../../atoms/Input/Help'
|
||||||
|
import Token from '../Token'
|
||||||
|
import styles from './Output.module.css'
|
||||||
|
import Decimal from 'decimal.js'
|
||||||
|
|
||||||
|
const contentQuery = graphql`
|
||||||
|
query PoolAddOutputQuery {
|
||||||
|
content: allFile(filter: { relativePath: { eq: "price.json" } }) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
childContentJson {
|
||||||
|
pool {
|
||||||
|
add {
|
||||||
|
output {
|
||||||
|
help
|
||||||
|
titleIn
|
||||||
|
titleOut
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export default function Output({
|
||||||
|
newPoolTokens,
|
||||||
|
newPoolShare,
|
||||||
|
swapFee,
|
||||||
|
dtSymbol,
|
||||||
|
totalPoolTokens,
|
||||||
|
totalBalance,
|
||||||
|
coin
|
||||||
|
}: {
|
||||||
|
newPoolTokens: string
|
||||||
|
newPoolShare: string
|
||||||
|
swapFee: string
|
||||||
|
dtSymbol: string
|
||||||
|
totalPoolTokens: string
|
||||||
|
totalBalance: TokenBalance
|
||||||
|
coin: string
|
||||||
|
}): ReactElement {
|
||||||
|
const data = useStaticQuery(contentQuery)
|
||||||
|
const {
|
||||||
|
help,
|
||||||
|
titleIn,
|
||||||
|
titleOut
|
||||||
|
} = data.content.edges[0].node.childContentJson.pool.add.output
|
||||||
|
|
||||||
|
// Connect with form
|
||||||
|
const { values }: FormikContextType<FormAddLiquidity> = useFormikContext()
|
||||||
|
|
||||||
|
const [poolOcean, setPoolOcean] = useState('0')
|
||||||
|
const [poolDatatoken, setPoolDatatoken] = useState('0')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!values.amount || !totalBalance || !totalPoolTokens) return
|
||||||
|
const newPoolSupply = new Decimal(totalPoolTokens).plus(newPoolTokens)
|
||||||
|
const ratio = new Decimal(newPoolTokens).div(newPoolSupply)
|
||||||
|
const newOceanReserve =
|
||||||
|
coin === 'OCEAN'
|
||||||
|
? new Decimal(totalBalance.ocean).plus(values.amount)
|
||||||
|
: new Decimal(totalBalance.ocean)
|
||||||
|
const newDtReserve =
|
||||||
|
coin === 'OCEAN'
|
||||||
|
? new Decimal(totalBalance.datatoken)
|
||||||
|
: new Decimal(totalBalance.datatoken).plus(values.amount)
|
||||||
|
const poolOcean = newOceanReserve.mul(ratio).toString()
|
||||||
|
const poolDatatoken = newDtReserve.mul(ratio).toString()
|
||||||
|
setPoolOcean(poolOcean)
|
||||||
|
setPoolDatatoken(poolDatatoken)
|
||||||
|
}, [values.amount, coin, totalBalance, totalPoolTokens, newPoolShare])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FormHelp className={styles.help}>
|
||||||
|
{help.replace('SWAPFEE', swapFee)}
|
||||||
|
</FormHelp>
|
||||||
|
<div className={styles.output}>
|
||||||
|
<div>
|
||||||
|
<p>{titleIn}</p>
|
||||||
|
<Token symbol="pool shares" balance={newPoolTokens} />
|
||||||
|
<Token symbol="% of pool" balance={newPoolShare} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>{titleOut}</p>
|
||||||
|
<Token symbol="OCEAN" balance={poolOcean} />
|
||||||
|
<Token symbol={dtSymbol} balance={poolDatatoken} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
@ -18,26 +18,6 @@
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.output {
|
|
||||||
display: grid;
|
|
||||||
gap: var(--spacer);
|
|
||||||
grid-template-columns: 1fr 1fr;
|
|
||||||
padding-bottom: calc(var(--spacer) / 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
.output p {
|
|
||||||
font-weight: var(--font-weight-bold);
|
|
||||||
margin-bottom: calc(var(--spacer) / 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
.output [class*='token'] {
|
|
||||||
white-space: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
.output [class*='token'] > figure {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.warning {
|
.warning {
|
||||||
margin-left: -3rem;
|
margin-left: -3rem;
|
||||||
margin-right: -3rem;
|
margin-right: -3rem;
|
||||||
|
@ -8,10 +8,10 @@ import * as Yup from 'yup'
|
|||||||
import { Formik } from 'formik'
|
import { Formik } from 'formik'
|
||||||
import FormAdd from './FormAdd'
|
import FormAdd from './FormAdd'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import Token from '../Token'
|
|
||||||
import Alert from '../../../../atoms/Alert'
|
import Alert from '../../../../atoms/Alert'
|
||||||
import TokenBalance from '../../../../../@types/TokenBalance'
|
import TokenBalance from '../../../../../@types/TokenBalance'
|
||||||
import { useUserPreferences } from '../../../../../providers/UserPreferences'
|
import { useUserPreferences } from '../../../../../providers/UserPreferences'
|
||||||
|
import Output from './Output'
|
||||||
|
|
||||||
const contentQuery = graphql`
|
const contentQuery = graphql`
|
||||||
query PoolAddQuery {
|
query PoolAddQuery {
|
||||||
@ -22,10 +22,6 @@ const contentQuery = graphql`
|
|||||||
pool {
|
pool {
|
||||||
add {
|
add {
|
||||||
title
|
title
|
||||||
output {
|
|
||||||
titleIn
|
|
||||||
titleOut
|
|
||||||
}
|
|
||||||
action
|
action
|
||||||
warning
|
warning
|
||||||
}
|
}
|
||||||
@ -186,17 +182,15 @@ export default function Add({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.output}>
|
<Output
|
||||||
<div>
|
newPoolTokens={newPoolTokens}
|
||||||
<p>{content.output.titleIn}</p>
|
newPoolShare={newPoolShare}
|
||||||
<Token symbol="pool shares" balance={newPoolTokens} />
|
swapFee={swapFee}
|
||||||
<Token symbol="% of pool" balance={newPoolShare} />
|
dtSymbol={dtSymbol}
|
||||||
</div>
|
totalPoolTokens={totalPoolTokens}
|
||||||
<div>
|
totalBalance={totalBalance}
|
||||||
<p>{content.output.titleOut}</p>
|
coin={coin}
|
||||||
<Token symbol="% swap fee" balance={swapFee} />
|
/>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Actions
|
<Actions
|
||||||
isDisabled={!isWarningAccepted}
|
isDisabled={!isWarningAccepted}
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.output {
|
.output {
|
||||||
composes: output from './Add/index.module.css';
|
composes: output from './Add/Output.module.css';
|
||||||
}
|
}
|
||||||
|
|
||||||
.output [class*='token'] {
|
.output [class*='token'] {
|
||||||
|
@ -17,7 +17,6 @@ import FormHelp from '../../../atoms/Input/Help'
|
|||||||
import Button from '../../../atoms/Button'
|
import Button from '../../../atoms/Button'
|
||||||
import { getMaxPercentRemove } from './utils'
|
import { getMaxPercentRemove } from './utils'
|
||||||
import { graphql, useStaticQuery } from 'gatsby'
|
import { graphql, useStaticQuery } from 'gatsby'
|
||||||
import PriceUnit from '../../../atoms/Price/PriceUnit'
|
|
||||||
import debounce from 'lodash.debounce'
|
import debounce from 'lodash.debounce'
|
||||||
import UserLiquidity from '../../../atoms/UserLiquidity'
|
import UserLiquidity from '../../../atoms/UserLiquidity'
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, { ReactElement, useEffect, useState } from 'react'
|
import React, { ReactElement, useEffect, useState } from 'react'
|
||||||
import { useOcean, useMetadata, usePricing } from '@oceanprotocol/react'
|
import { useOcean, useMetadata, usePricing } from '@oceanprotocol/react'
|
||||||
import { BestPrice, DDO, Logger } from '@oceanprotocol/lib'
|
import { DDO, Logger } from '@oceanprotocol/lib'
|
||||||
import styles from './index.module.css'
|
import styles from './index.module.css'
|
||||||
import stylesActions from './Actions.module.css'
|
import stylesActions from './Actions.module.css'
|
||||||
import PriceUnit from '../../../atoms/Price/PriceUnit'
|
import PriceUnit from '../../../atoms/Price/PriceUnit'
|
||||||
@ -115,14 +115,11 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
|
|||||||
price.address
|
price.address
|
||||||
)
|
)
|
||||||
setPoolTokens(poolTokens)
|
setPoolTokens(poolTokens)
|
||||||
|
|
||||||
// calculate user's provided liquidity based on pool tokens
|
// calculate user's provided liquidity based on pool tokens
|
||||||
const userOceanBalance =
|
const userOceanBalance =
|
||||||
(Number(poolTokens) / Number(totalPoolTokens)) * price.ocean
|
(Number(poolTokens) / Number(totalPoolTokens)) * price.ocean
|
||||||
|
|
||||||
const userDtBalance =
|
const userDtBalance =
|
||||||
(Number(poolTokens) / Number(totalPoolTokens)) * price.datatoken
|
(Number(poolTokens) / Number(totalPoolTokens)) * price.datatoken
|
||||||
|
|
||||||
const userLiquidity = {
|
const userLiquidity = {
|
||||||
ocean: userOceanBalance,
|
ocean: userOceanBalance,
|
||||||
datatoken: userDtBalance
|
datatoken: userDtBalance
|
||||||
@ -275,7 +272,12 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
|
|||||||
title={
|
title={
|
||||||
<>
|
<>
|
||||||
Your Liquidity
|
Your Liquidity
|
||||||
<Tooltip content={content.tooltips.liquidity} />
|
<Tooltip
|
||||||
|
content={content.tooltips.liquidity.replace(
|
||||||
|
'SWAPFEE',
|
||||||
|
swapFee
|
||||||
|
)}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
ocean={`${userLiquidity?.ocean}`}
|
ocean={`${userLiquidity?.ocean}`}
|
||||||
|
Loading…
Reference in New Issue
Block a user