mirror of
https://github.com/oceanprotocol/market.git
synced 2024-12-02 05:57:29 +01:00
Restore trade tab (#1047)
* get swap fee, max values * use baseToken instead of ocean * build fixes * set form trade tx - WIP * use pool info * logs deleted * merge fixes * use local ocean.js, get spot price * handle value changes, logs deleted * fixes after v4 merge * valid user liquidity displayed * get correct token amount * more fixes * form trade fixes * positive input values fix * use proper swap functions * use appConfig's marketFeeAddress * remove redundant setters * use consumeMarketPoolSwapFee * use poolInfo, remove log * code fixes * some more fixes * fees fix * use poolInfo data * various fixes * fixes and cleanup * fix build * partial decimal fix * add swap fee * fix sub updates * remove console * fix package * fix package-lock * remove ssh * fix blockies and package * fix comments * remove unused var Co-authored-by: ClaudiaHolhos <claudia@oceanprotocol.com> Co-authored-by: mihaisc <mihai@oceanprotocol.com>
This commit is contained in:
parent
b63c644962
commit
8a5bddbf6e
4611
package-lock.json
generated
4611
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -21,7 +21,7 @@
|
|||||||
"@coingecko/cryptoformat": "^0.4.4",
|
"@coingecko/cryptoformat": "^0.4.4",
|
||||||
"@loadable/component": "^5.15.2",
|
"@loadable/component": "^5.15.2",
|
||||||
"@oceanprotocol/art": "^3.2.0",
|
"@oceanprotocol/art": "^3.2.0",
|
||||||
"@oceanprotocol/lib": "^1.0.0-next.21",
|
"@oceanprotocol/lib": "^1.0.0-next.24",
|
||||||
"@oceanprotocol/typographies": "^0.1.0",
|
"@oceanprotocol/typographies": "^0.1.0",
|
||||||
"@portis/web3": "^4.0.6",
|
"@portis/web3": "^4.0.6",
|
||||||
"@tippyjs/react": "^4.2.6",
|
"@tippyjs/react": "^4.2.6",
|
||||||
@ -34,7 +34,6 @@
|
|||||||
"decimal.js": "^10.3.1",
|
"decimal.js": "^10.3.1",
|
||||||
"dom-confetti": "^0.2.2",
|
"dom-confetti": "^0.2.2",
|
||||||
"dotenv": "^15.0.0",
|
"dotenv": "^15.0.0",
|
||||||
"ethereum-blockies": "github:MyEtherWallet/blockies",
|
|
||||||
"filesize": "^8.0.6",
|
"filesize": "^8.0.6",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
@ -43,6 +42,7 @@
|
|||||||
"jwt-decode": "^3.1.2",
|
"jwt-decode": "^3.1.2",
|
||||||
"lodash.debounce": "^4.0.8",
|
"lodash.debounce": "^4.0.8",
|
||||||
"lodash.omit": "^4.5.0",
|
"lodash.omit": "^4.5.0",
|
||||||
|
"myetherwallet-blockies": "^0.1.1",
|
||||||
"next": "^12.1.0",
|
"next": "^12.1.0",
|
||||||
"query-string": "^7.1.0",
|
"query-string": "^7.1.0",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
@ -10,9 +10,9 @@ export const poolDataQuery = gql`
|
|||||||
poolData: pool(id: $pool) {
|
poolData: pool(id: $pool) {
|
||||||
id
|
id
|
||||||
totalShares
|
totalShares
|
||||||
liquidityProviderFee
|
liquidityProviderSwapFee
|
||||||
opcFee
|
opcFee
|
||||||
marketSwapFee
|
publishMarketSwapFee
|
||||||
spotPrice
|
spotPrice
|
||||||
baseToken {
|
baseToken {
|
||||||
address
|
address
|
||||||
|
@ -5,12 +5,13 @@ import {
|
|||||||
} from 'src/@types/subgraph/PoolData'
|
} from 'src/@types/subgraph/PoolData'
|
||||||
|
|
||||||
export interface PoolInfo {
|
export interface PoolInfo {
|
||||||
poolFee: string
|
liquidityProviderSwapFee: string
|
||||||
marketFee: string
|
publishMarketSwapFee: string
|
||||||
opfFee: string
|
opcFee: string
|
||||||
weightBaseToken: string
|
weightBaseToken: string
|
||||||
weightDt: string
|
weightDt: string
|
||||||
datatokenSymbol: string
|
datatokenSymbol: string
|
||||||
|
datatokenAddress: string
|
||||||
baseTokenSymbol: string
|
baseTokenSymbol: string
|
||||||
baseTokenAddress: string
|
baseTokenAddress: string
|
||||||
totalPoolTokens: string
|
totalPoolTokens: string
|
||||||
|
@ -118,11 +118,6 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!poolData) return
|
if (!poolData) return
|
||||||
|
|
||||||
// Fees - this will be renamed again in subgraph
|
|
||||||
const poolFee = getFee(poolData.liquidityProviderFee)
|
|
||||||
const marketFee = getFee(poolData.marketSwapFee)
|
|
||||||
const opfFee = getFee(poolData.opcFee)
|
|
||||||
|
|
||||||
// Total Liquidity
|
// Total Liquidity
|
||||||
const totalLiquidityInOcean = isValidNumber(poolData.spotPrice)
|
const totalLiquidityInOcean = isValidNumber(poolData.spotPrice)
|
||||||
? new Decimal(poolData.baseTokenLiquidity).add(
|
? new Decimal(poolData.baseTokenLiquidity).add(
|
||||||
@ -131,12 +126,13 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
|
|||||||
: new Decimal(0)
|
: new Decimal(0)
|
||||||
|
|
||||||
const newPoolInfo = {
|
const newPoolInfo = {
|
||||||
poolFee,
|
liquidityProviderSwapFee: getFee(poolData.liquidityProviderSwapFee),
|
||||||
marketFee,
|
publishMarketSwapFee: getFee(poolData.publishMarketSwapFee),
|
||||||
opfFee,
|
opcFee: getFee(poolData.opcFee),
|
||||||
weightBaseToken: getWeight(poolData.baseTokenWeight),
|
weightBaseToken: getWeight(poolData.baseTokenWeight),
|
||||||
weightDt: getWeight(poolData.datatokenWeight),
|
weightDt: getWeight(poolData.datatokenWeight),
|
||||||
datatokenSymbol: poolData.datatoken.symbol,
|
datatokenSymbol: poolData.datatoken.symbol,
|
||||||
|
datatokenAddress: poolData.datatoken.address,
|
||||||
baseTokenSymbol: poolData.baseToken.symbol,
|
baseTokenSymbol: poolData.baseToken.symbol,
|
||||||
baseTokenAddress: poolData.baseToken.address,
|
baseTokenAddress: poolData.baseToken.address,
|
||||||
totalPoolTokens: poolData.totalShares,
|
totalPoolTokens: poolData.totalShares,
|
||||||
@ -193,6 +189,7 @@ function PoolProvider({ children }: { children: ReactNode }): ReactElement {
|
|||||||
if (
|
if (
|
||||||
!poolData ||
|
!poolData ||
|
||||||
!poolInfo?.totalPoolTokens ||
|
!poolInfo?.totalPoolTokens ||
|
||||||
|
!poolInfoUser?.poolShares ||
|
||||||
!asset?.chainId ||
|
!asset?.chainId ||
|
||||||
!accountId ||
|
!accountId ||
|
||||||
!poolInfoUser
|
!poolInfoUser
|
||||||
|
2
src/@types/node_modules.d.ts
vendored
2
src/@types/node_modules.d.ts
vendored
@ -1,3 +1,3 @@
|
|||||||
declare module 'ethereum-blockies' {
|
declare module 'myetherwallet-blockies' {
|
||||||
export function toDataUrl(address: string): string
|
export function toDataUrl(address: string): string
|
||||||
}
|
}
|
||||||
|
1
src/@utils/constants.ts
Normal file
1
src/@utils/constants.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const MAX_DECIMALS = 5
|
@ -112,9 +112,10 @@ export async function setNftMetadata(
|
|||||||
'0x' + metadataHash,
|
'0x' + metadataHash,
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
LoggerInstance.log(
|
||||||
console.log('[setNftMetadata] est Gas set metadata --', estGasSetMetadata)
|
'[setNftMetadata] est Gas set metadata --',
|
||||||
|
estGasSetMetadata
|
||||||
|
)
|
||||||
const setMetadataTx = await nft.setMetadata(
|
const setMetadataTx = await nft.setMetadata(
|
||||||
asset.nftAddress,
|
asset.nftAddress,
|
||||||
accountId,
|
accountId,
|
||||||
|
@ -46,7 +46,6 @@ export default function FilesInput(props: InputProps): ReactElement {
|
|||||||
props.value.length > 0 &&
|
props.value.length > 0 &&
|
||||||
typeof props.value[0] === 'string'
|
typeof props.value[0] === 'string'
|
||||||
) {
|
) {
|
||||||
console.log('loadFileInfo eff')
|
|
||||||
loadFileInfo(props.value[0].toString())
|
loadFileInfo(props.value[0].toString())
|
||||||
}
|
}
|
||||||
}, [loadFileInfo, props])
|
}, [loadFileInfo, props])
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { toDataUrl } from 'ethereum-blockies'
|
import { toDataUrl } from 'myetherwallet-blockies'
|
||||||
import React, { ReactElement } from 'react'
|
import React, { ReactElement } from 'react'
|
||||||
import styles from './Blockies.module.css'
|
import styles from './Blockies.module.css'
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ export default function Pool(): ReactElement {
|
|||||||
baseToken: new Decimal(poolData?.baseTokenLiquidity).toString(),
|
baseToken: new Decimal(poolData?.baseTokenLiquidity).toString(),
|
||||||
datatoken: new Decimal(poolData?.datatokenLiquidity).toString()
|
datatoken: new Decimal(poolData?.datatokenLiquidity).toString()
|
||||||
}}
|
}}
|
||||||
swapFee={poolInfo?.poolFee}
|
swapFee={poolInfo?.liquidityProviderSwapFee}
|
||||||
datatokenSymbol={poolInfo?.datatokenSymbol}
|
datatokenSymbol={poolInfo?.datatokenSymbol}
|
||||||
tokenInAddress={poolInfo?.baseTokenAddress}
|
tokenInAddress={poolInfo?.baseTokenAddress}
|
||||||
tokenInSymbol={poolInfo?.baseTokenSymbol}
|
tokenInSymbol={poolInfo?.baseTokenSymbol}
|
||||||
@ -98,7 +98,7 @@ export default function Pool(): ReactElement {
|
|||||||
<Tooltip
|
<Tooltip
|
||||||
content={content.pool.tooltips.liquidity.replace(
|
content={content.pool.tooltips.liquidity.replace(
|
||||||
'SWAPFEE',
|
'SWAPFEE',
|
||||||
poolInfo?.poolFee
|
poolInfo?.liquidityProviderSwapFee
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
{poolInfoUser?.poolShare && (
|
{poolInfoUser?.poolShare && (
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
import React, { ReactElement, useState } from 'react'
|
import React, { ReactElement, useState } from 'react'
|
||||||
import { Asset, LoggerInstance } from '@oceanprotocol/lib'
|
import {
|
||||||
|
AmountsInMaxFee,
|
||||||
|
AmountsOutMaxFee,
|
||||||
|
LoggerInstance,
|
||||||
|
Pool,
|
||||||
|
TokenInOutMarket
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
import * as Yup from 'yup'
|
import * as Yup from 'yup'
|
||||||
import { Formik } from 'formik'
|
import { Formik } from 'formik'
|
||||||
import Actions from '../Pool/Actions'
|
import Actions from '../Pool/Actions'
|
||||||
@ -15,36 +21,33 @@ import { FormTradeData } from './_types'
|
|||||||
import { initialValues } from './_constants'
|
import { initialValues } from './_constants'
|
||||||
import content from '../../../../../content/price.json'
|
import content from '../../../../../content/price.json'
|
||||||
import { AssetExtended } from 'src/@types/AssetExtended'
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
import { usePool } from '@context/Pool'
|
||||||
|
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
||||||
|
|
||||||
export default function FormTrade({
|
export default function FormTrade({
|
||||||
asset,
|
asset,
|
||||||
balance,
|
balance
|
||||||
maxDt,
|
|
||||||
maxOcean
|
|
||||||
}: {
|
}: {
|
||||||
asset: AssetExtended
|
asset: AssetExtended
|
||||||
balance: PoolBalance
|
balance: PoolBalance
|
||||||
maxDt: string
|
|
||||||
maxOcean: string
|
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { accountId } = useWeb3()
|
const { web3, accountId } = useWeb3()
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
const { debug } = useUserPreferences()
|
const { debug } = useUserPreferences()
|
||||||
|
const { appConfig } = useSiteMetadata()
|
||||||
|
const { poolInfo } = usePool()
|
||||||
const [txId, setTxId] = useState<string>()
|
const [txId, setTxId] = useState<string>()
|
||||||
const [coinFrom, setCoinFrom] = useState<string>('OCEAN')
|
const [coinFrom, setCoinFrom] = useState<string>('OCEAN')
|
||||||
|
|
||||||
const [maximumOcean, setMaximumOcean] = useState(maxOcean)
|
const [maximumBaseToken, setMaximumBaseToken] = useState('0')
|
||||||
const [maximumDt, setMaximumDt] = useState(maxDt)
|
const [maximumDt, setMaximumDt] = useState('0')
|
||||||
const [isWarningAccepted, setIsWarningAccepted] = useState(false)
|
const [isWarningAccepted, setIsWarningAccepted] = useState(false)
|
||||||
|
|
||||||
const tokenAddress = ''
|
|
||||||
const tokenSymbol = ''
|
|
||||||
|
|
||||||
const validationSchema: Yup.SchemaOf<FormTradeData> = Yup.object()
|
const validationSchema: Yup.SchemaOf<FormTradeData> = Yup.object()
|
||||||
.shape({
|
.shape({
|
||||||
ocean: Yup.number()
|
baseToken: Yup.number()
|
||||||
.max(
|
.max(
|
||||||
Number(maximumOcean),
|
Number(maximumBaseToken),
|
||||||
(param) => `Must be less or equal to ${param.max}`
|
(param) => `Must be less or equal to ${param.max}`
|
||||||
)
|
)
|
||||||
.min(0.001, (param) => `Must be more or equal to ${param.min}`)
|
.min(0.001, (param) => `Must be more or equal to ${param.min}`)
|
||||||
@ -64,32 +67,81 @@ export default function FormTrade({
|
|||||||
.defined()
|
.defined()
|
||||||
|
|
||||||
async function handleTrade(values: FormTradeData) {
|
async function handleTrade(values: FormTradeData) {
|
||||||
|
if (!web3 || !asset || !poolInfo || !values) return
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const impact = new Decimal(
|
const poolInstance = new Pool(web3)
|
||||||
new Decimal(100).sub(new Decimal(values.slippage))
|
let tx
|
||||||
).div(100)
|
if (values.output === 'exactIn') {
|
||||||
const precision = 15
|
const tokenInOutMarket: TokenInOutMarket = {
|
||||||
// const tx =
|
tokenIn:
|
||||||
// values.type === 'buy'
|
values.type === 'sell'
|
||||||
// ? await ocean.pool.buyDTWithExactOcean(
|
? poolInfo.datatokenAddress
|
||||||
// accountId,
|
: poolInfo.baseTokenAddress,
|
||||||
// price.address,
|
tokenOut:
|
||||||
// new Decimal(values.datatoken)
|
values.type === 'sell'
|
||||||
// .mul(impact)
|
? poolInfo.baseTokenAddress
|
||||||
// .toFixed(precision)
|
: poolInfo.datatokenAddress,
|
||||||
// .toString(),
|
marketFeeAddress: appConfig.marketFeeAddress
|
||||||
// new Decimal(values.ocean).toFixed(precision).toString()
|
}
|
||||||
// )
|
|
||||||
// : await ocean.pool.sellDT(
|
const amountsInOutMaxFee: AmountsInMaxFee = {
|
||||||
// accountId,
|
tokenAmountIn:
|
||||||
// price.address,
|
values.type === 'sell' ? values.datatoken : values.baseToken,
|
||||||
// new Decimal(values.datatoken).toFixed(precision).toString(),
|
minAmountOut: new Decimal(
|
||||||
// new Decimal(values.ocean)
|
values.type === 'sell' ? values.baseToken : values.datatoken
|
||||||
// .mul(impact)
|
)
|
||||||
// .toFixed(precision)
|
.mul(
|
||||||
// .toString()
|
new Decimal(1)
|
||||||
// )
|
.minus(new Decimal(values.slippage).div(new Decimal(100)))
|
||||||
// setTxId(tx?.transactionHash)
|
.toString()
|
||||||
|
)
|
||||||
|
.toString(),
|
||||||
|
swapMarketFee: appConfig.consumeMarketPoolSwapFee
|
||||||
|
}
|
||||||
|
tx = await poolInstance.swapExactAmountIn(
|
||||||
|
accountId,
|
||||||
|
asset.accessDetails.addressOrId,
|
||||||
|
tokenInOutMarket,
|
||||||
|
amountsInOutMaxFee
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (values.output === 'exactOut') {
|
||||||
|
const tokenOutMarket: TokenInOutMarket = {
|
||||||
|
tokenIn:
|
||||||
|
values.type === 'sell'
|
||||||
|
? poolInfo.datatokenAddress
|
||||||
|
: poolInfo.baseTokenAddress,
|
||||||
|
tokenOut:
|
||||||
|
values.type === 'sell'
|
||||||
|
? poolInfo.baseTokenAddress
|
||||||
|
: poolInfo.datatokenAddress,
|
||||||
|
marketFeeAddress: appConfig.marketFeeAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
const amountsOutMaxFee: AmountsOutMaxFee = {
|
||||||
|
maxAmountIn: new Decimal(
|
||||||
|
values.type === 'sell' ? values.datatoken : values.baseToken
|
||||||
|
)
|
||||||
|
.mul(
|
||||||
|
new Decimal(1)
|
||||||
|
.plus(new Decimal(values.slippage).div(new Decimal(100)))
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
.toString(),
|
||||||
|
tokenAmountOut:
|
||||||
|
values.type === 'sell' ? values.baseToken : values.datatoken,
|
||||||
|
swapMarketFee: appConfig.consumeMarketPoolSwapFee
|
||||||
|
}
|
||||||
|
tx = await poolInstance.swapExactAmountOut(
|
||||||
|
accountId,
|
||||||
|
asset.accessDetails.addressOrId,
|
||||||
|
tokenOutMarket,
|
||||||
|
amountsOutMaxFee
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
setTxId(tx?.transactionHash)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
LoggerInstance.error(error.message)
|
LoggerInstance.error(error.message)
|
||||||
toast.error(error.message)
|
toast.error(error.message)
|
||||||
@ -112,10 +164,8 @@ export default function FormTrade({
|
|||||||
<Swap
|
<Swap
|
||||||
asset={asset}
|
asset={asset}
|
||||||
balance={balance}
|
balance={balance}
|
||||||
maxDt={maxDt}
|
|
||||||
maxOcean={maxOcean}
|
|
||||||
setCoin={setCoinFrom}
|
setCoin={setCoinFrom}
|
||||||
setMaximumOcean={setMaximumOcean}
|
setMaximumBaseToken={setMaximumBaseToken}
|
||||||
setMaximumDt={setMaximumDt}
|
setMaximumDt={setMaximumDt}
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
@ -154,8 +204,16 @@ export default function FormTrade({
|
|||||||
}
|
}
|
||||||
action={submitForm}
|
action={submitForm}
|
||||||
txId={txId}
|
txId={txId}
|
||||||
tokenAddress={tokenAddress}
|
tokenAddress={
|
||||||
tokenSymbol={tokenSymbol}
|
values.type === 'buy'
|
||||||
|
? poolInfo.baseTokenAddress
|
||||||
|
: poolInfo.datatokenAddress
|
||||||
|
}
|
||||||
|
tokenSymbol={
|
||||||
|
values.type === 'buy'
|
||||||
|
? poolInfo.baseTokenSymbol
|
||||||
|
: poolInfo.datatokenSymbol
|
||||||
|
}
|
||||||
setSubmitting={setSubmitting}
|
setSubmitting={setSubmitting}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -4,73 +4,54 @@ import { useAsset } from '@context/Asset'
|
|||||||
import Token from '../Pool/Token'
|
import Token from '../Pool/Token'
|
||||||
import styles from './Output.module.css'
|
import styles from './Output.module.css'
|
||||||
|
|
||||||
import { isValidNumber } from '@utils/numbers'
|
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
import { FormTradeData } from './_types'
|
import { FormTradeData } from './_types'
|
||||||
|
import { usePool } from '@context/Pool'
|
||||||
|
|
||||||
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
|
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
|
||||||
|
|
||||||
export default function Output({
|
export default function Output({
|
||||||
dtSymbol,
|
poolAddress,
|
||||||
oceanSymbol,
|
lpSwapFee
|
||||||
poolAddress
|
|
||||||
}: {
|
}: {
|
||||||
dtSymbol: string
|
|
||||||
oceanSymbol: string
|
|
||||||
poolAddress: string
|
poolAddress: string
|
||||||
|
lpSwapFee: string
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
const [maxOutput, setMaxOutput] = useState<string>()
|
const { poolInfo } = usePool()
|
||||||
const [swapFee, setSwapFee] = useState<string>()
|
const [outputWithSlippage, setOutputWithSlippage] = useState<string>('0')
|
||||||
const [swapFeeValue, setSwapFeeValue] = useState<string>()
|
|
||||||
// Connect with form
|
// Connect with form
|
||||||
const { values }: FormikContextType<FormTradeData> = useFormikContext()
|
const { values }: FormikContextType<FormTradeData> = useFormikContext()
|
||||||
|
|
||||||
// Get swap fee
|
|
||||||
useEffect(() => {
|
|
||||||
if (!poolAddress || !isAssetNetwork) return
|
|
||||||
|
|
||||||
async function getSwapFee() {
|
|
||||||
// const swapFee = await ocean.pool.getSwapFee(poolAddress)
|
|
||||||
|
|
||||||
// // swapFee is tricky: to get 0.1% you need to convert from 0.001
|
|
||||||
// setSwapFee(
|
|
||||||
// isValidNumber(swapFee) ? new Decimal(swapFee).mul(100).toString() : '0'
|
|
||||||
// )
|
|
||||||
|
|
||||||
const value =
|
|
||||||
values.type === 'buy'
|
|
||||||
? isValidNumber(swapFee) && isValidNumber(values.baseToken)
|
|
||||||
? new Decimal(swapFee).mul(new Decimal(values.baseToken))
|
|
||||||
: 0
|
|
||||||
: isValidNumber(swapFee) && isValidNumber(values.datatoken)
|
|
||||||
? new Decimal(swapFee).mul(new Decimal(values.datatoken))
|
|
||||||
: 0
|
|
||||||
setSwapFeeValue(value.toString())
|
|
||||||
}
|
|
||||||
getSwapFee()
|
|
||||||
}, [poolAddress, values, isAssetNetwork, swapFee])
|
|
||||||
|
|
||||||
// Get output values
|
// Get output values
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!poolAddress || !isAssetNetwork) return
|
if (!poolAddress || !isAssetNetwork) return
|
||||||
|
|
||||||
async function getOutput() {
|
async function getOutput() {
|
||||||
// Minimum received
|
if (!values.baseToken || !values.datatoken || !values.output) return
|
||||||
// TODO: check if this here is redundant cause we call some of that already in Swap.tsx
|
|
||||||
const maxImpact = 1 - Number(values.slippage) / 100
|
|
||||||
const maxPrice =
|
|
||||||
values.type === 'buy'
|
|
||||||
? isValidNumber(values.datatoken) && isValidNumber(maxImpact)
|
|
||||||
? new Decimal(values.datatoken)
|
|
||||||
.mul(new Decimal(maxImpact))
|
|
||||||
.toString()
|
|
||||||
: '0'
|
|
||||||
: isValidNumber(values.baseToken) && isValidNumber(maxImpact)
|
|
||||||
? new Decimal(values.baseToken).mul(new Decimal(maxImpact)).toString()
|
|
||||||
: '0'
|
|
||||||
|
|
||||||
setMaxOutput(maxPrice)
|
const output =
|
||||||
|
values.output === 'exactIn'
|
||||||
|
? new Decimal(
|
||||||
|
values.type === 'sell' ? values.baseToken : values.datatoken
|
||||||
|
)
|
||||||
|
.mul(
|
||||||
|
new Decimal(1)
|
||||||
|
.minus(new Decimal(values.slippage).div(new Decimal(100)))
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
.toString()
|
||||||
|
: new Decimal(
|
||||||
|
values.type === 'sell' ? values.datatoken : values.baseToken
|
||||||
|
)
|
||||||
|
.mul(
|
||||||
|
new Decimal(1)
|
||||||
|
.plus(new Decimal(values.slippage).div(new Decimal(100)))
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
.toString()
|
||||||
|
|
||||||
|
setOutputWithSlippage(output)
|
||||||
}
|
}
|
||||||
getOutput()
|
getOutput()
|
||||||
}, [poolAddress, values, isAssetNetwork])
|
}, [poolAddress, values, isAssetNetwork])
|
||||||
@ -78,19 +59,35 @@ export default function Output({
|
|||||||
return (
|
return (
|
||||||
<div className={styles.output}>
|
<div className={styles.output}>
|
||||||
<div>
|
<div>
|
||||||
<p>Minimum Received</p>
|
<p>
|
||||||
|
{values.output === 'exactIn' ? 'Minimum Received' : 'Maximum Sent'}
|
||||||
|
</p>
|
||||||
<Token
|
<Token
|
||||||
symbol={values.type === 'buy' ? dtSymbol : oceanSymbol}
|
symbol={
|
||||||
balance={maxOutput}
|
values.type === 'buy'
|
||||||
|
? values.output === 'exactIn'
|
||||||
|
? poolInfo.datatokenSymbol
|
||||||
|
: poolInfo.baseTokenSymbol
|
||||||
|
: values.output === 'exactIn'
|
||||||
|
? poolInfo.baseTokenSymbol
|
||||||
|
: poolInfo.datatokenSymbol
|
||||||
|
}
|
||||||
|
balance={outputWithSlippage}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<p>Swap fee</p>
|
<p>Swap fee</p>
|
||||||
<Token
|
<Token
|
||||||
symbol={`${values.type === 'buy' ? oceanSymbol : dtSymbol} ${
|
symbol={`${
|
||||||
swapFee ? `(${swapFee}%)` : ''
|
values.type === 'buy'
|
||||||
|
? poolInfo.baseTokenSymbol
|
||||||
|
: poolInfo.datatokenSymbol
|
||||||
|
} ${
|
||||||
|
poolInfo.liquidityProviderSwapFee
|
||||||
|
? `(${poolInfo.liquidityProviderSwapFee}%)`
|
||||||
|
: ''
|
||||||
}`}
|
}`}
|
||||||
balance={swapFeeValue}
|
balance={lpSwapFee}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,44 +7,54 @@ import { FormikContextType, useFormikContext } from 'formik'
|
|||||||
import Output from './Output'
|
import Output from './Output'
|
||||||
import Slippage from './Slippage'
|
import Slippage from './Slippage'
|
||||||
import PriceImpact from './PriceImpact'
|
import PriceImpact from './PriceImpact'
|
||||||
|
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
|
import { useWeb3 } from '@context/Web3'
|
||||||
import { FormTradeData, TradeItem } from './_types'
|
import { FormTradeData, TradeItem } from './_types'
|
||||||
import { Asset } from '@oceanprotocol/lib'
|
import {
|
||||||
|
calcMaxExactIn,
|
||||||
|
calcMaxExactOut,
|
||||||
|
LoggerInstance,
|
||||||
|
Pool,
|
||||||
|
PoolPriceAndFees
|
||||||
|
} from '@oceanprotocol/lib'
|
||||||
import { AssetExtended } from 'src/@types/AssetExtended'
|
import { AssetExtended } from 'src/@types/AssetExtended'
|
||||||
|
import { usePool } from '@context/Pool'
|
||||||
|
import { useSiteMetadata } from '@hooks/useSiteMetadata'
|
||||||
|
import { MAX_DECIMALS } from '@utils/constants'
|
||||||
|
|
||||||
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
|
// Decimal.set({ toExpNeg: -15, precision: 5, rounding: Decimal.ROUND_DOWN })
|
||||||
|
|
||||||
export default function Swap({
|
export default function Swap({
|
||||||
asset,
|
asset,
|
||||||
maxDt,
|
|
||||||
maxOcean,
|
|
||||||
balance,
|
balance,
|
||||||
setMaximumDt,
|
setMaximumDt,
|
||||||
setMaximumOcean,
|
setMaximumBaseToken,
|
||||||
setCoin
|
setCoin
|
||||||
}: {
|
}: {
|
||||||
asset: AssetExtended
|
asset: AssetExtended
|
||||||
maxDt: string
|
|
||||||
maxOcean: string
|
|
||||||
balance: PoolBalance
|
balance: PoolBalance
|
||||||
setMaximumDt: (value: string) => void
|
setMaximumDt: (value: string) => void
|
||||||
setMaximumOcean: (value: string) => void
|
setMaximumBaseToken: (value: string) => void
|
||||||
setCoin: (value: string) => void
|
setCoin: (value: string) => void
|
||||||
}): ReactElement {
|
}): ReactElement {
|
||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
const [oceanItem, setOceanItem] = useState<TradeItem>({
|
const { web3 } = useWeb3()
|
||||||
|
const { poolInfo, poolData } = usePool()
|
||||||
|
const { appConfig } = useSiteMetadata()
|
||||||
|
|
||||||
|
const [baseTokenItem, setBaseTokenItem] = useState<TradeItem>({
|
||||||
amount: '0',
|
amount: '0',
|
||||||
token: asset.accessDetails.baseToken?.symbol,
|
token: poolInfo?.baseTokenSymbol,
|
||||||
maxAmount: '0'
|
maxAmount: '0',
|
||||||
|
address: poolInfo?.baseTokenAddress
|
||||||
})
|
})
|
||||||
const [dtItem, setDtItem] = useState<TradeItem>({
|
const [dtItem, setDtItem] = useState<TradeItem>({
|
||||||
amount: '0',
|
amount: '0',
|
||||||
token: asset.accessDetails.datatoken.symbol,
|
token: poolInfo?.datatokenSymbol,
|
||||||
maxAmount: '0'
|
maxAmount: '0',
|
||||||
|
address: poolInfo?.datatokenAddress
|
||||||
})
|
})
|
||||||
|
|
||||||
const {
|
const {
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
values,
|
values,
|
||||||
@ -56,148 +66,260 @@ export default function Swap({
|
|||||||
const [spotPrice, setSpotPrice] = useState<string>()
|
const [spotPrice, setSpotPrice] = useState<string>()
|
||||||
const [totalValue, setTotalValue] = useState<string>()
|
const [totalValue, setTotalValue] = useState<string>()
|
||||||
const [tokenAmount, setTokenAmount] = useState<string>()
|
const [tokenAmount, setTokenAmount] = useState<string>()
|
||||||
|
const [lpSwapFee, setLpSwapFee] = useState<string>()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!asset || !balance || !values?.type) return
|
if (!asset || !balance || !values?.type || !web3) return
|
||||||
|
const poolInstance = new Pool(web3)
|
||||||
|
|
||||||
async function calculateMaximum() {
|
async function calculateMaximum() {
|
||||||
|
const maxDtFromPool =
|
||||||
|
values.type === 'buy'
|
||||||
|
? calcMaxExactIn(poolData.datatokenLiquidity)
|
||||||
|
: calcMaxExactOut(poolData.datatokenLiquidity)
|
||||||
|
|
||||||
|
const maxBaseTokenFromPool =
|
||||||
|
values.type === 'buy'
|
||||||
|
? calcMaxExactOut(poolData.baseTokenLiquidity)
|
||||||
|
: calcMaxExactIn(poolData.baseTokenLiquidity)
|
||||||
|
|
||||||
const amountDataToken =
|
const amountDataToken =
|
||||||
values.type === 'buy'
|
values.type === 'buy'
|
||||||
? new Decimal(maxDt)
|
? maxDtFromPool
|
||||||
|
: new Decimal(balance.baseToken).greaterThan(
|
||||||
|
calcMaxExactIn(poolData.datatokenLiquidity)
|
||||||
|
)
|
||||||
|
? calcMaxExactIn(poolData.datatokenLiquidity)
|
||||||
: new Decimal(balance.datatoken)
|
: new Decimal(balance.datatoken)
|
||||||
const amountOcean =
|
|
||||||
|
const amountBaseToken =
|
||||||
values.type === 'buy'
|
values.type === 'buy'
|
||||||
? new Decimal(balance.baseToken)
|
? new Decimal(balance.baseToken).greaterThan(
|
||||||
: new Decimal(maxOcean)
|
calcMaxExactIn(poolData.baseTokenLiquidity)
|
||||||
|
)
|
||||||
|
? calcMaxExactIn(poolData.baseTokenLiquidity)
|
||||||
|
: new Decimal(balance.baseToken)
|
||||||
|
: maxBaseTokenFromPool
|
||||||
|
|
||||||
// const maxBuyOcean = await ocean.pool.getOceanReceived(
|
try {
|
||||||
// price.address,
|
const maxBuyBaseToken: PoolPriceAndFees =
|
||||||
// `${amountDataToken.toString()}`
|
await poolInstance.getAmountOutExactIn(
|
||||||
// )
|
asset.accessDetails.addressOrId,
|
||||||
// const maxBuyDt = await ocean.pool.getDTReceived(
|
poolInfo.datatokenAddress,
|
||||||
// price.address,
|
poolInfo.baseTokenAddress,
|
||||||
// `${amountOcean.toString()}`
|
amountDataToken.toString(),
|
||||||
// )
|
appConfig.consumeMarketPoolSwapFee
|
||||||
|
)
|
||||||
|
|
||||||
// const maximumDt =
|
const maxBuyDt: PoolPriceAndFees =
|
||||||
// values.type === 'buy'
|
await poolInstance.getAmountOutExactIn(
|
||||||
// ? amountDataToken.greaterThan(new Decimal(maxBuyDt))
|
asset.accessDetails?.addressOrId,
|
||||||
// ? maxBuyDt
|
poolInfo.baseTokenAddress,
|
||||||
// : amountDataToken
|
poolInfo.datatokenAddress,
|
||||||
// : amountDataToken.greaterThan(new Decimal(balance.datatoken))
|
amountBaseToken.toString(),
|
||||||
// ? balance.datatoken
|
appConfig.consumeMarketPoolSwapFee
|
||||||
// : amountDataToken
|
)
|
||||||
|
const maximumDt =
|
||||||
|
values.type === 'buy'
|
||||||
|
? amountDataToken.greaterThan(new Decimal(maxBuyDt.tokenAmount))
|
||||||
|
? maxBuyDt.tokenAmount
|
||||||
|
: amountDataToken.toDecimalPlaces(MAX_DECIMALS).toString()
|
||||||
|
: amountDataToken.greaterThan(new Decimal(balance.datatoken))
|
||||||
|
? balance.datatoken
|
||||||
|
: amountDataToken.toDecimalPlaces(MAX_DECIMALS).toString()
|
||||||
|
|
||||||
// const maximumOcean =
|
const maximumBaseToken =
|
||||||
// values.type === 'sell'
|
values.type === 'sell'
|
||||||
// ? amountOcean.greaterThan(new Decimal(maxBuyOcean))
|
? amountBaseToken.greaterThan(
|
||||||
// ? maxBuyOcean
|
new Decimal(maxBuyBaseToken.tokenAmount)
|
||||||
// : amountOcean
|
)
|
||||||
// : amountOcean.greaterThan(new Decimal(balance.ocean))
|
? maxBuyBaseToken.tokenAmount
|
||||||
// ? balance.ocean
|
: amountBaseToken.toDecimalPlaces(MAX_DECIMALS).toString()
|
||||||
// : amountOcean
|
: amountBaseToken.greaterThan(new Decimal(balance.baseToken))
|
||||||
|
? balance.baseToken
|
||||||
|
: amountBaseToken.toDecimalPlaces(MAX_DECIMALS).toString()
|
||||||
|
|
||||||
// setMaximumDt(maximumDt.toString())
|
setMaximumDt(maximumDt)
|
||||||
// setMaximumOcean(maximumOcean.toString())
|
setMaximumBaseToken(maximumBaseToken)
|
||||||
|
|
||||||
// setOceanItem((prevState) => ({
|
setBaseTokenItem((prevState) => ({
|
||||||
// ...prevState,
|
...prevState,
|
||||||
// amount: amountOcean.toString(),
|
amount: amountBaseToken.toDecimalPlaces(MAX_DECIMALS).toString(),
|
||||||
// maxAmount: maximumOcean.toString()
|
maxAmount: maximumBaseToken
|
||||||
// }))
|
}))
|
||||||
|
|
||||||
// setDtItem((prevState) => ({
|
setDtItem((prevState) => ({
|
||||||
// ...prevState,
|
...prevState,
|
||||||
// amount: amountDataToken.toString(),
|
amount: amountDataToken.toDecimalPlaces(MAX_DECIMALS).toString(),
|
||||||
// maxAmount: maximumDt.toString()
|
maxAmount: maximumDt
|
||||||
// }))
|
}))
|
||||||
|
} catch (error) {
|
||||||
|
LoggerInstance.error(error.message)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
calculateMaximum()
|
calculateMaximum()
|
||||||
}, [
|
}, [
|
||||||
asset,
|
poolData,
|
||||||
maxOcean,
|
|
||||||
maxDt,
|
|
||||||
balance,
|
balance,
|
||||||
values?.type,
|
values.type,
|
||||||
setMaximumDt,
|
setMaximumDt,
|
||||||
setMaximumOcean
|
setMaximumBaseToken,
|
||||||
|
asset,
|
||||||
|
web3,
|
||||||
|
dtItem.token,
|
||||||
|
baseTokenItem.token,
|
||||||
|
poolInfo.liquidityProviderSwapFee,
|
||||||
|
poolInfo.datatokenAddress,
|
||||||
|
poolInfo.baseTokenAddress,
|
||||||
|
appConfig.consumeMarketPoolSwapFee
|
||||||
])
|
])
|
||||||
|
|
||||||
const switchTokens = () => {
|
const switchTokens = () => {
|
||||||
setFieldValue('type', values.type === 'buy' ? 'sell' : 'buy')
|
setFieldValue('type', values.type === 'buy' ? 'sell' : 'buy')
|
||||||
setCoin(values.type === 'sell' ? 'OCEAN' : asset.datatokens[0].symbol)
|
setCoin(
|
||||||
|
values.type === 'sell'
|
||||||
|
? poolInfo.baseTokenSymbol
|
||||||
|
: poolInfo.datatokenSymbol
|
||||||
|
)
|
||||||
// don't reset form because we don't want to reset type
|
// don't reset form because we don't want to reset type
|
||||||
setFieldValue('datatoken', 0)
|
setFieldValue('datatoken', 0)
|
||||||
setFieldValue('ocean', 0)
|
setFieldValue('baseToken', 0)
|
||||||
setErrors({})
|
setErrors({})
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleValueChange = async (name: string, value: number) => {
|
const handleValueChange = async (name: string, value: number) => {
|
||||||
const tokenIn = ''
|
try {
|
||||||
const tokenOut = ''
|
let tokenIn = ''
|
||||||
let newValue
|
let tokenOut = ''
|
||||||
|
const poolInstance = new Pool(web3)
|
||||||
|
let newValue: PoolPriceAndFees
|
||||||
|
|
||||||
// if (name === 'ocean') {
|
if (name === 'baseToken') {
|
||||||
// if (values.type === 'sell') {
|
if (values.type === 'sell') {
|
||||||
// newValue = await ocean.pool.getDTNeeded(price.address, value.toString())
|
newValue = await poolInstance.getAmountInExactOut(
|
||||||
|
asset.accessDetails.addressOrId,
|
||||||
|
dtItem.address,
|
||||||
|
baseTokenItem.address,
|
||||||
|
value.toString(),
|
||||||
|
appConfig.consumeMarketPoolSwapFee
|
||||||
|
)
|
||||||
|
|
||||||
// setTotalValue(newValue)
|
setFieldValue('output', 'exactOut')
|
||||||
// setTokenAmount(value.toString())
|
|
||||||
|
|
||||||
// tokenIn = ddo.services[0].datatokenAddress
|
setTotalValue(
|
||||||
// tokenOut = ocean.pool.oceanAddress
|
new Decimal(newValue.tokenAmount)
|
||||||
// } else {
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
// newValue = await ocean.pool.getDTReceived(
|
.toString()
|
||||||
// price.address,
|
)
|
||||||
// value.toString()
|
setLpSwapFee(
|
||||||
// )
|
new Decimal(newValue.liquidityProviderSwapFeeAmount)
|
||||||
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
setTokenAmount(value.toString())
|
||||||
|
|
||||||
// setTotalValue(value.toString())
|
tokenIn = poolInfo.datatokenAddress
|
||||||
// setTokenAmount(newValue)
|
tokenOut = poolInfo.baseTokenAddress
|
||||||
// tokenIn = ocean.pool.oceanAddress
|
} else {
|
||||||
// tokenOut = ddo.services[0].datatokenAddress
|
newValue = await poolInstance.getAmountOutExactIn(
|
||||||
// }
|
asset.accessDetails.addressOrId,
|
||||||
// } else {
|
baseTokenItem.address,
|
||||||
// if (values.type === 'sell') {
|
dtItem.address,
|
||||||
// newValue = await ocean.pool.getOceanReceived(
|
value.toString(),
|
||||||
// price.address,
|
appConfig.consumeMarketPoolSwapFee
|
||||||
// value.toString()
|
)
|
||||||
// )
|
|
||||||
|
|
||||||
// setTotalValue(value.toString())
|
setFieldValue('output', 'exactIn')
|
||||||
// setTokenAmount(newValue)
|
setTotalValue(value.toString())
|
||||||
// tokenIn = ddo.services[0].datatokenAddress
|
setTokenAmount(
|
||||||
// tokenOut = ocean.pool.oceanAddress
|
new Decimal(newValue.tokenAmount)
|
||||||
// } else {
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
// newValue = await ocean.pool.getOceanNeeded(
|
.toString()
|
||||||
// price.address,
|
)
|
||||||
// value.toString()
|
setLpSwapFee(
|
||||||
// )
|
new Decimal(newValue.liquidityProviderSwapFeeAmount)
|
||||||
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
tokenIn = poolInfo.baseTokenAddress
|
||||||
|
tokenOut = poolInfo.datatokenAddress
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (values.type === 'sell') {
|
||||||
|
newValue = await poolInstance.getAmountOutExactIn(
|
||||||
|
asset.accessDetails.addressOrId,
|
||||||
|
dtItem.address,
|
||||||
|
baseTokenItem.address,
|
||||||
|
value.toString(),
|
||||||
|
appConfig.consumeMarketPoolSwapFee
|
||||||
|
)
|
||||||
|
|
||||||
// setTotalValue(newValue)
|
setFieldValue('output', 'exactIn')
|
||||||
// setTokenAmount(value.toString())
|
setTotalValue(value.toString())
|
||||||
// tokenIn = ocean.pool.oceanAddress
|
setTokenAmount(
|
||||||
// tokenOut = ddo.services[0].datatokenAddress
|
new Decimal(newValue.tokenAmount)
|
||||||
// }
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
// }
|
.toString()
|
||||||
|
)
|
||||||
|
setLpSwapFee(
|
||||||
|
new Decimal(newValue.liquidityProviderSwapFeeAmount)
|
||||||
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
tokenIn = poolInfo.datatokenAddress
|
||||||
|
tokenOut = poolInfo.baseTokenAddress
|
||||||
|
} else {
|
||||||
|
newValue = await poolInstance.getAmountInExactOut(
|
||||||
|
asset.accessDetails.addressOrId,
|
||||||
|
baseTokenItem.address,
|
||||||
|
dtItem.address,
|
||||||
|
value.toString(),
|
||||||
|
appConfig.consumeMarketPoolSwapFee
|
||||||
|
)
|
||||||
|
|
||||||
await setFieldValue(name === 'ocean' ? 'datatoken' : 'ocean', newValue)
|
setFieldValue('output', 'exactOut')
|
||||||
|
|
||||||
// const spotPrice = await ocean.pool.getSpotPrice(
|
setTotalValue(
|
||||||
// price.address,
|
new Decimal(newValue.tokenAmount)
|
||||||
// tokenIn,
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
// tokenOut
|
.toString()
|
||||||
// )
|
)
|
||||||
|
setTokenAmount(value.toString())
|
||||||
|
setLpSwapFee(
|
||||||
|
new Decimal(newValue.liquidityProviderSwapFeeAmount)
|
||||||
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
tokenIn = poolInfo.baseTokenAddress
|
||||||
|
tokenOut = poolInfo.datatokenAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// setSpotPrice(spotPrice)
|
await setFieldValue(
|
||||||
validateForm()
|
name === 'baseToken' ? 'datatoken' : 'baseToken',
|
||||||
|
new Decimal(newValue.tokenAmount)
|
||||||
|
.toDecimalPlaces(MAX_DECIMALS)
|
||||||
|
.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
const spotPrice = await poolInstance.getSpotPrice(
|
||||||
|
asset.accessDetails.addressOrId,
|
||||||
|
tokenIn,
|
||||||
|
tokenOut,
|
||||||
|
appConfig.consumeMarketPoolSwapFee
|
||||||
|
)
|
||||||
|
setSpotPrice(spotPrice)
|
||||||
|
validateForm()
|
||||||
|
} catch (ex) {
|
||||||
|
LoggerInstance.error(ex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.swap}>
|
<div className={styles.swap}>
|
||||||
<TradeInput
|
<TradeInput
|
||||||
name={values.type === 'sell' ? 'datatoken' : 'ocean'}
|
name={values.type === 'sell' ? 'datatoken' : 'baseToken'}
|
||||||
item={values.type === 'sell' ? dtItem : oceanItem}
|
item={values.type === 'sell' ? dtItem : baseTokenItem}
|
||||||
disabled={!isAssetNetwork}
|
disabled={!isAssetNetwork}
|
||||||
handleValueChange={handleValueChange}
|
handleValueChange={handleValueChange}
|
||||||
/>
|
/>
|
||||||
@ -212,16 +334,15 @@ export default function Swap({
|
|||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<TradeInput
|
<TradeInput
|
||||||
name={values.type === 'sell' ? 'ocean' : 'datatoken'}
|
name={values.type === 'sell' ? 'baseToken' : 'datatoken'}
|
||||||
item={values.type === 'sell' ? oceanItem : dtItem}
|
item={values.type === 'sell' ? baseTokenItem : dtItem}
|
||||||
disabled={!isAssetNetwork}
|
disabled={!isAssetNetwork}
|
||||||
handleValueChange={handleValueChange}
|
handleValueChange={handleValueChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Output
|
<Output
|
||||||
dtSymbol={dtItem.token}
|
|
||||||
oceanSymbol={oceanItem.token}
|
|
||||||
poolAddress={asset.accessDetails?.addressOrId}
|
poolAddress={asset.accessDetails?.addressOrId}
|
||||||
|
lpSwapFee={lpSwapFee}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<PriceImpact
|
<PriceImpact
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
.tradeInput div[class*='prefix'] {
|
.tradeInput div[class*='prefix'] {
|
||||||
min-width: 6.5rem;
|
min-width: 6.5rem;
|
||||||
width: fit-content;
|
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ export default function TradeInput({
|
|||||||
}: FormikContextType<FormTradeData> = useFormikContext()
|
}: FormikContextType<FormTradeData> = useFormikContext()
|
||||||
|
|
||||||
const isTopField =
|
const isTopField =
|
||||||
(name === 'ocean' && values.type === 'buy') ||
|
(name === 'baseToken' && values.type === 'buy') ||
|
||||||
(name === 'datatoken' && values.type === 'sell')
|
(name === 'datatoken' && values.type === 'sell')
|
||||||
const titleAvailable = isTopField ? `Balance` : `Available from pool`
|
const titleAvailable = isTopField ? `Balance` : `Available from pool`
|
||||||
const titleMaximum = isTopField ? `Maximum to spend` : `Maximum to receive`
|
const titleMaximum = isTopField ? `Maximum to spend` : `Maximum to receive`
|
||||||
@ -54,6 +54,7 @@ export default function TradeInput({
|
|||||||
<Input
|
<Input
|
||||||
type="number"
|
type="number"
|
||||||
max={`${item?.maxAmount}`}
|
max={`${item?.maxAmount}`}
|
||||||
|
min="0"
|
||||||
prefix={item?.token}
|
prefix={item?.token}
|
||||||
placeholder="0"
|
placeholder="0"
|
||||||
field={field}
|
field={field}
|
||||||
@ -68,7 +69,8 @@ export default function TradeInput({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Field>
|
</Field>
|
||||||
{!isTopField && (
|
|
||||||
|
{/* {!isTopField && (
|
||||||
<Button
|
<Button
|
||||||
className={styles.buttonMax}
|
className={styles.buttonMax}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
@ -81,7 +83,7 @@ export default function TradeInput({
|
|||||||
>
|
>
|
||||||
Use Max
|
Use Max
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)} */}
|
||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ export const initialValues: FormTradeData = {
|
|||||||
baseToken: undefined,
|
baseToken: undefined,
|
||||||
datatoken: undefined,
|
datatoken: undefined,
|
||||||
type: 'buy',
|
type: 'buy',
|
||||||
|
output: 'exactIn',
|
||||||
slippage: '5'
|
slippage: '5'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
export interface FormTradeData extends PoolBalance {
|
export interface FormTradeData extends PoolBalance {
|
||||||
// in reference to datatoken, buy = swap from ocean to dt ( buy dt) , sell = swap from dt to ocean (sell dt)
|
// in reference to datatoken, buy = swap from ocean to dt ( buy dt) , sell = swap from dt to ocean (sell dt)
|
||||||
type: 'buy' | 'sell'
|
type: 'buy' | 'sell'
|
||||||
|
// based on what the user inputs, if he fill the top input it is 'exactIn'
|
||||||
|
output: 'exactIn' | 'exactOut'
|
||||||
slippage: string
|
slippage: string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8,4 +10,5 @@ export interface TradeItem {
|
|||||||
amount: string
|
amount: string
|
||||||
token: string
|
token: string
|
||||||
maxAmount: string
|
maxAmount: string
|
||||||
|
address: string
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ import React, { ReactElement, useEffect, useState } from 'react'
|
|||||||
import FormTrade from './FormTrade'
|
import FormTrade from './FormTrade'
|
||||||
import { useAsset } from '@context/Asset'
|
import { useAsset } from '@context/Asset'
|
||||||
import { useWeb3 } from '@context/Web3'
|
import { useWeb3 } from '@context/Web3'
|
||||||
|
import { isValidNumber } from '@utils/numbers'
|
||||||
import Decimal from 'decimal.js'
|
import Decimal from 'decimal.js'
|
||||||
import { Datatoken } from '@oceanprotocol/lib'
|
import { Datatoken, LoggerInstance, Pool } from '@oceanprotocol/lib'
|
||||||
|
import { usePool } from '@context/Pool'
|
||||||
|
|
||||||
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
|
Decimal.set({ toExpNeg: -18, precision: 18, rounding: 1 })
|
||||||
|
|
||||||
@ -12,8 +14,7 @@ export default function Trade(): ReactElement {
|
|||||||
const { isAssetNetwork } = useAsset()
|
const { isAssetNetwork } = useAsset()
|
||||||
const [tokenBalance, setTokenBalance] = useState<PoolBalance>()
|
const [tokenBalance, setTokenBalance] = useState<PoolBalance>()
|
||||||
const { asset } = useAsset()
|
const { asset } = useAsset()
|
||||||
const [maxDt, setMaxDt] = useState('0')
|
const { poolInfo } = usePool()
|
||||||
const [maxOcean, setMaxOcean] = useState('0')
|
|
||||||
|
|
||||||
// Get datatoken balance, and combine with OCEAN balance from hooks into one object
|
// Get datatoken balance, and combine with OCEAN balance from hooks into one object
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -23,14 +24,14 @@ export default function Trade(): ReactElement {
|
|||||||
!isAssetNetwork ||
|
!isAssetNetwork ||
|
||||||
!balance?.ocean ||
|
!balance?.ocean ||
|
||||||
!accountId ||
|
!accountId ||
|
||||||
!asset?.services[0].datatokenAddress
|
!poolInfo?.datatokenAddress
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
async function getTokenBalance() {
|
async function getTokenBalance() {
|
||||||
const datatokenInstance = new Datatoken(web3)
|
const datatokenInstance = new Datatoken(web3)
|
||||||
const dtBalance = await datatokenInstance.balance(
|
const dtBalance = await datatokenInstance.balance(
|
||||||
asset.services[0].datatokenAddress,
|
poolInfo.datatokenAddress,
|
||||||
accountId
|
accountId
|
||||||
)
|
)
|
||||||
setTokenBalance({
|
setTokenBalance({
|
||||||
@ -39,44 +40,13 @@ export default function Trade(): ReactElement {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
getTokenBalance()
|
getTokenBalance()
|
||||||
}, [web3, balance.ocean, accountId, asset, isAssetNetwork])
|
}, [
|
||||||
|
web3,
|
||||||
|
balance.ocean,
|
||||||
|
accountId,
|
||||||
|
poolInfo?.datatokenAddress,
|
||||||
|
isAssetNetwork
|
||||||
|
])
|
||||||
|
|
||||||
// Get maximum amount for either OCEAN or datatoken
|
return <FormTrade asset={asset} balance={tokenBalance} />
|
||||||
useEffect(() => {
|
|
||||||
if (
|
|
||||||
!isAssetNetwork ||
|
|
||||||
!asset.accessDetails ||
|
|
||||||
asset.accessDetails.price === 0
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
async function getMaximum() {
|
|
||||||
// const maxTokensInPool = await ocean.pool.getDTMaxBuyQuantity(
|
|
||||||
// price.address
|
|
||||||
// )
|
|
||||||
// setMaxDt(
|
|
||||||
// isValidNumber(maxTokensInPool)
|
|
||||||
// ? new Decimal(maxTokensInPool).toString()
|
|
||||||
// : '0'
|
|
||||||
// )
|
|
||||||
// const maxOceanInPool = await ocean.pool.getOceanMaxBuyQuantity(
|
|
||||||
// price.address
|
|
||||||
// )
|
|
||||||
// setMaxOcean(
|
|
||||||
// isValidNumber(maxOceanInPool)
|
|
||||||
// ? new Decimal(maxOceanInPool).toString()
|
|
||||||
// : '0'
|
|
||||||
// )
|
|
||||||
}
|
|
||||||
getMaximum()
|
|
||||||
}, [isAssetNetwork, balance.ocean, asset])
|
|
||||||
|
|
||||||
return (
|
|
||||||
<FormTrade
|
|
||||||
asset={asset}
|
|
||||||
balance={tokenBalance}
|
|
||||||
maxDt={maxDt}
|
|
||||||
maxOcean={maxOcean}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user