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": { "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)."

View File

@ -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 (
<> <>

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

View File

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

View File

@ -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'] {

View File

@ -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'

View File

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