1
0
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:
Matthias Kretschmann 2020-12-02 12:44:07 +01:00 committed by GitHub
parent 54feaebc5a
commit f843641a45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 162 additions and 52 deletions

View File

@ -26,13 +26,14 @@
"pool": {
"tooltips": {
"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": {
"title": "Add Liquidity",
"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",
"titleOut": "You will earn"
"titleOut": "Pool conversion"
},
"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)."

View File

@ -66,23 +66,34 @@ export default function FormAdd({
return
}
if (Number(values.amount) > Number(amountMax)) return
const poolTokens = await ocean.pool.calcPoolOutGivenSingleIn(
poolAddress,
coin === 'OCEAN' ? ocean.pool.oceanAddress : ocean.pool.dtAddress,
values.amount.toString()
`${values.amount}`
)
setNewPoolTokens(poolTokens)
setNewPoolShare(
totalBalance &&
(
setNewPoolShare(
`${
(Number(poolTokens) /
(Number(totalPoolTokens) + Number(poolTokens))) *
100
).toFixed(2)
}`
)
}
calculatePoolShares()
}, [values.amount])
}, [
values.amount,
totalBalance,
totalPoolTokens,
amountMax,
coin,
poolAddress,
ocean.pool,
setNewPoolTokens,
setNewPoolShare
])
return (
<>

View File

@ -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;
}

View 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>
</>
)
}

View File

@ -18,26 +18,6 @@
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 {
margin-left: -3rem;
margin-right: -3rem;

View File

@ -8,10 +8,10 @@ import * as Yup from 'yup'
import { Formik } from 'formik'
import FormAdd from './FormAdd'
import styles from './index.module.css'
import Token from '../Token'
import Alert from '../../../../atoms/Alert'
import TokenBalance from '../../../../../@types/TokenBalance'
import { useUserPreferences } from '../../../../../providers/UserPreferences'
import Output from './Output'
const contentQuery = graphql`
query PoolAddQuery {
@ -22,10 +22,6 @@ const contentQuery = graphql`
pool {
add {
title
output {
titleIn
titleOut
}
action
warning
}
@ -186,17 +182,15 @@ export default function Add({
)}
</div>
<div className={styles.output}>
<div>
<p>{content.output.titleIn}</p>
<Token symbol="pool shares" balance={newPoolTokens} />
<Token symbol="% of pool" balance={newPoolShare} />
</div>
<div>
<p>{content.output.titleOut}</p>
<Token symbol="% swap fee" balance={swapFee} />
</div>
</div>
<Output
newPoolTokens={newPoolTokens}
newPoolShare={newPoolShare}
swapFee={swapFee}
dtSymbol={dtSymbol}
totalPoolTokens={totalPoolTokens}
totalBalance={totalBalance}
coin={coin}
/>
<Actions
isDisabled={!isWarningAccepted}

View File

@ -46,7 +46,7 @@
}
.output {
composes: output from './Add/index.module.css';
composes: output from './Add/Output.module.css';
}
.output [class*='token'] {

View File

@ -17,7 +17,6 @@ import FormHelp from '../../../atoms/Input/Help'
import Button from '../../../atoms/Button'
import { getMaxPercentRemove } from './utils'
import { graphql, useStaticQuery } from 'gatsby'
import PriceUnit from '../../../atoms/Price/PriceUnit'
import debounce from 'lodash.debounce'
import UserLiquidity from '../../../atoms/UserLiquidity'

View File

@ -1,6 +1,6 @@
import React, { ReactElement, useEffect, useState } from '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 stylesActions from './Actions.module.css'
import PriceUnit from '../../../atoms/Price/PriceUnit'
@ -115,14 +115,11 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
price.address
)
setPoolTokens(poolTokens)
// calculate user's provided liquidity based on pool tokens
const userOceanBalance =
(Number(poolTokens) / Number(totalPoolTokens)) * price.ocean
const userDtBalance =
(Number(poolTokens) / Number(totalPoolTokens)) * price.datatoken
const userLiquidity = {
ocean: userOceanBalance,
datatoken: userDtBalance
@ -275,7 +272,12 @@ export default function Pool({ ddo }: { ddo: DDO }): ReactElement {
title={
<>
Your Liquidity
<Tooltip content={content.tooltips.liquidity} />
<Tooltip
content={content.tooltips.liquidity.replace(
'SWAPFEE',
swapFee
)}
/>
</>
}
ocean={`${userLiquidity?.ocean}`}