diff --git a/src/components/Layout/Layout.tsx b/src/components/Layout/Layout.tsx index 78b8d74b..171b24f4 100644 --- a/src/components/Layout/Layout.tsx +++ b/src/components/Layout/Layout.tsx @@ -7,6 +7,7 @@ import React, { useEffect } from 'react' import styled from 'styled-components' import { useWeb3React } from '@web3-react/core' import { useClearPositions } from '@/state/positions/hooks' +import { useClearSwap } from '@/state/swap/hooks' interface PageProps { children: any full?: boolean @@ -17,6 +18,7 @@ const Layout: React.FC = (props) => { const removeItem = useRemoveItem() const clearOptions = useClearOptions() const clearPositions = useClearPositions() + const clearSwap = useClearSwap() const router = useRouter() const { active, account } = useWeb3React() useEffect(() => { @@ -25,6 +27,8 @@ const Layout: React.FC = (props) => { removeItem() clearPositions() clearOptions() + } else { + clearSwap() } }, [props.loading]) diff --git a/src/components/LineItem/LineItem.tsx b/src/components/LineItem/LineItem.tsx index 37faba20..9380d034 100644 --- a/src/components/LineItem/LineItem.tsx +++ b/src/components/LineItem/LineItem.tsx @@ -82,7 +82,11 @@ interface ColorProps { const Color = styled.span` color: ${(props) => - props.color == 'red' ? props.theme.color.red[500] : 'inherit'}; + props.color == 'red' + ? props.theme.color.red[500] + : props.color == 'green' + ? props.theme.color.green[500] + : 'inherit'}; ` const StyledSym = styled.a` diff --git a/src/components/Liquidity/LiquidityHeader/index.tsx b/src/components/Liquidity/LiquidityHeader/index.tsx index 7cb057c2..694e4043 100644 --- a/src/components/Liquidity/LiquidityHeader/index.tsx +++ b/src/components/Liquidity/LiquidityHeader/index.tsx @@ -31,13 +31,13 @@ const LiquidityHeader: React.FC = ({ ) } const Reverse = styled.div` - margin-bottom: -1em; + margin-bottom: -2em; ` const StyledHeader = styled.div` padding-bottom: ${(props) => props.theme.spacing[4]}px; display: block; - margin-left: -15em; + margin-left: -21em; margin-right: 1em; margin-top: -1em; width: 50em; diff --git a/src/components/Liquidity/LiquidityTable.tsx b/src/components/Liquidity/LiquidityTable.tsx index a1a1cbc1..af934302 100644 --- a/src/components/Liquidity/LiquidityTable.tsx +++ b/src/components/Liquidity/LiquidityTable.tsx @@ -1,6 +1,5 @@ import React, { useCallback } from 'react' import styled from 'styled-components' -import Spacer from '@/components/Spacer' // table import Table from '@/components/Table' @@ -12,12 +11,11 @@ import LiquidityTableRow from './LiquidityTable/LiquidityTableRow' import LoadingTable from '@/components/Market/OptionsTable/LoadingTable' import { usePositions } from '@/state/positions/hooks' -import { useItem, useUpdateItem, useRemoveItem } from '@/state/order/hooks' -import { useOptions, useUpdateOptions } from '@/state/options/hooks' -import { formatEther, parseEther } from 'ethers/lib/utils' +import { useUpdateItem } from '@/state/order/hooks' +import { useOptions } from '@/state/options/hooks' +import { formatEther } from 'ethers/lib/utils' import { BigNumber } from 'ethers' import { Operation } from '@primitivefi/sdk' -import { Fraction, TokenAmount } from '@uniswap/sdk' export interface OptionsTableProps { callActive: boolean @@ -29,30 +27,12 @@ const LiquidityTable: React.FC = (props) => { const updateItem = useUpdateItem() const options = useOptions() const type = callActive ? 'calls' : 'puts' - /* const tableColumns: TableColumns = { - key: 'key', - asset: 'tableAssset', - strike: '0.00', - share: '0.00', - asset1: '0.00', - asset2: '0.00', - fees: '0.00', - liquidity: ['0.00', '0.00'], - expiry: 0, - isCall: true, - } */ const formatTableColumns = useCallback( (option: any): TableColumns => { const tableKey: string = option.entity.address /* const tableAssset: string = asset.toUpperCase() */ const tableStrike: string = option.entity.strikePrice.toString() - const tableBid: string = formatEther( - option.market.spotClosePremium.raw.toString() - ).toString() - const tableAsk: string = formatEther( - option.market.spotOpenPremium.raw.toString() - ).toString() const tableReserve0: string = formatEther( option.market.reserveOf(option.entity.underlying).raw.toString() @@ -65,18 +45,6 @@ const LiquidityTable: React.FC = (props) => { const tableReserves: string[] = [tableReserve0, tableReserve1] const tableExpiry: number = option.entity.expiryValue - /* const supply = BigNumber.from(parseEther(lpTotalSupply).toString()) - const tSupply = new TokenAmount( - option.market.liquidityToken, - parseEther(lpTotalSupply).toString() - ) - - supply.gt(0) && lpBalance.gt(0) - ? lpBalance.divide(tSupply.add(lpBalance)) - : new Fraction('0') - - poolShare = poolShare.multiply('100').toSignificant(6) */ - const tableColumns: TableColumns = { key: tableKey, asset: option.entity.underlying.symbol, diff --git a/src/components/Liquidity/LiquidityTable/LiquidityTableHeader/LiquidityTableHeader.tsx b/src/components/Liquidity/LiquidityTable/LiquidityTableHeader/LiquidityTableHeader.tsx index f930d785..633b12fc 100644 --- a/src/components/Liquidity/LiquidityTable/LiquidityTableHeader/LiquidityTableHeader.tsx +++ b/src/components/Liquidity/LiquidityTable/LiquidityTableHeader/LiquidityTableHeader.tsx @@ -17,12 +17,16 @@ export const headers = [ }, { name: 'Pool Size', - tip: 'The amount of underlying tokens in the pool.', + tip: 'The total amount of tokens in the pool.', }, { name: 'Your Share', tip: 'The proportion of ownership of the option pair.', }, + { + name: 'Your Liquidity', + tip: 'Your quantity of tokens in the pool.', + }, { name: 'Market', tip: 'The option market the pool serves.', diff --git a/src/components/Liquidity/LiquidityTable/LiquidityTableRow/LiquidityTableRow.tsx b/src/components/Liquidity/LiquidityTable/LiquidityTableRow/LiquidityTableRow.tsx index b94656f9..116e52e3 100644 --- a/src/components/Liquidity/LiquidityTable/LiquidityTableRow/LiquidityTableRow.tsx +++ b/src/components/Liquidity/LiquidityTable/LiquidityTableRow/LiquidityTableRow.tsx @@ -143,7 +143,6 @@ const LiquidityTableRow: React.FC = ({ updateItem(item, Operation.REMOVE_LIQUIDITY_CLOSE, market) } }, [provide, item, updateItem]) */ - const calculatePoolShare = useCallback(() => { const supply = BigNumber.from(parseEther(lpTotalSupply).toString()) if (typeof market === 'undefined' || market === null || supply.isZero()) @@ -157,7 +156,9 @@ const LiquidityTableRow: React.FC = ({ market.liquidityToken, parseEther(lp).toString() ) - const poolShare = supply.gt(0) ? lpBal.divide(tSupply) : new Fraction('0') + const poolShare = supply.gt(0) + ? lpBal.divide(tSupply).multiply('100') + : new Fraction('0') return poolShare.toSignificant(6) }, [market, lpTotalSupply, lp]) @@ -196,6 +197,41 @@ const LiquidityTableRow: React.FC = ({ return { shortPerLp, underlyingPerLp, totalUnderlyingPerLp } }, [market, lp, lpTotalSupply]) + const calculateTotalLiquidity = useCallback(() => { + if ( + typeof market === 'undefined' || + market === null || + BigNumber.from(parseEther(lpTotalSupply)).isZero() + ) + return { + shortPerLp: '0', + underlyingPerLp: '0', + totalUnderlyingPerLp: '0', + } + + const [ + shortValue, + underlyingValue, + totalUnderlyingValue, + ] = market.getLiquidityValuePerShare( + new TokenAmount( + market.liquidityToken, + parseEther(lpTotalSupply).toString() + ) + ) + const shortPerLp = parseEther(lpTotalSupply) + .mul(shortValue.raw.toString()) + .div(parseEther('1')) + const underlyingPerLp = parseEther(lpTotalSupply) + .mul(underlyingValue.raw.toString()) + .div(parseEther('1')) + const totalUnderlyingPerLp = parseEther(lpTotalSupply) + .mul(totalUnderlyingValue.raw.toString()) + .div(parseEther('1')) + + return { shortPerLp, underlyingPerLp, totalUnderlyingPerLp } + }, [market, lpTotalSupply]) + const handleOnClick = useCallback(() => { //setProvide(true) setToggle(!toggle) @@ -278,10 +314,13 @@ const LiquidityTableRow: React.FC = ({ )} - {parseFloat(liquidity[0]) > 0 ? ( + {!isZero(parseEther(lpTotalSupply)) ? ( - {numeral(liquidity[0]).format('0.00a')} {units} + {numeral( + formatEther(calculateTotalLiquidity().totalUnderlyingPerLp) + ).format('0.00a')}{' '} + {units} ) : ( @@ -290,13 +329,30 @@ const LiquidityTableRow: React.FC = ({ {!isZero(parseEther(lp)) ? ( - {numeral(calculatePoolShare()).format('0.00%')} % + {numeral(calculatePoolShare()).format('0.00')} % ) : ( <>{`-`} )} + {parseFloat( + formatEther(calculateLiquidityValuePerShare().totalUnderlyingPerLp) + ) > 0 ? ( + + + {numeral( + formatEther( + calculateLiquidityValuePerShare().totalUnderlyingPerLp + ) + ).format('0.00a')}{' '} + {units} + + + ) : ( + - + )} + {isCall ? asset : entity.strike.symbol} {expiry ? ( @@ -308,7 +364,7 @@ const LiquidityTableRow: React.FC = ({ )} - {numeral(strike).format(+strike >= 10 ? '0' : '0.00')}{' '} + {numeral(strike).format(+strike >= 10 ? '0a' : '0.00')}{' '} DAI @@ -365,8 +421,12 @@ const LiquidityTableRow: React.FC = ({ diff --git a/src/components/Market/OptionsTable/LoadingTable/LoadingTable.tsx b/src/components/Market/OptionsTable/LoadingTable/LoadingTable.tsx index 6bdb1d3f..13e55c63 100644 --- a/src/components/Market/OptionsTable/LoadingTable/LoadingTable.tsx +++ b/src/components/Market/OptionsTable/LoadingTable/LoadingTable.tsx @@ -11,20 +11,19 @@ const alt = [ }, { name: 'Pool Size', - tip: 'The amount of underlying tokens in the pool.', + tip: 'The total amount of tokens in the pool.', }, { - name: 'Share', + name: 'Your Share', tip: 'The proportion of ownership of the option pair.', }, - { - name: 'Pool Ratio', - tip: 'The ratio of underlying tokens to short option tokens.', + name: 'Your Liquidity', + tip: 'Your quantity of tokens in the pool.', }, { - name: 'Price', - tip: 'The ask price of 1 option token.', + name: 'Market', + tip: 'The option market the pool serves.', }, { name: 'Expiry', tip: 'The maturity date of the option token.' }, { diff --git a/src/components/Market/OptionsTable/OptionsTable.tsx b/src/components/Market/OptionsTable/OptionsTable.tsx index fea336e7..1664380f 100644 --- a/src/components/Market/OptionsTable/OptionsTable.tsx +++ b/src/components/Market/OptionsTable/OptionsTable.tsx @@ -31,6 +31,7 @@ import OptionsTableRow, { TableColumns } from './OptionsTableRow' import OptionsTableHeader from './OptionsTableHeader' import LoadingTable from './LoadingTable' import { useAddNotif } from '@/state/notifs/hooks' +import { TokenAmount } from '@sushiswap/sdk' export type FormattedOption = { breakEven: number @@ -174,6 +175,7 @@ const OptionsTable: React.FC = (props) => { reserves: tableReserves, expiry: tableExpiry, isCall: option.entity.isCall, + market: option.market, } return tableColumns }, diff --git a/src/components/Market/OptionsTable/OptionsTableRow/OptionsTableRow.tsx b/src/components/Market/OptionsTable/OptionsTableRow/OptionsTableRow.tsx index 0118f45e..17b78486 100644 --- a/src/components/Market/OptionsTable/OptionsTableRow/OptionsTableRow.tsx +++ b/src/components/Market/OptionsTable/OptionsTableRow/OptionsTableRow.tsx @@ -17,8 +17,19 @@ import GreeksTableRow, { Greeks } from '../GreeksTableRow' import numeral from 'numeral' import isZero from '@/utils/isZero' -import { parseEther } from 'ethers/lib/utils' +import { parseEther, formatEther } from 'ethers/lib/utils' +import { BigNumber } from 'ethers' import formatExpiry from '@/utils/formatExpiry' +import { TokenAmount } from '@sushiswap/sdk' + +import useTokenTotalSupply from '@/hooks/useTokenTotalSupply' +import { + Option, + UniswapMarket, + SushiSwapMarket, + Operation, + Venue, +} from '@primitivefi/sdk' export interface TableColumns { key: string @@ -30,6 +41,7 @@ export interface TableColumns { reserves: string[] expiry: number isCall: boolean + market: UniswapMarket | SushiSwapMarket } export interface OptionsTableRowProps { @@ -58,6 +70,7 @@ const OptionsTableRow: React.FC = ({ reserves, expiry, isCall, + market, } = columns const handleOnClick = useCallback(() => { if (reserves[0] !== '0.00') { @@ -73,6 +86,42 @@ const OptionsTableRow: React.FC = ({ }) const units = isCall ? asset.toUpperCase() : 'DAI' + const lpTotalSupply = useTokenTotalSupply(market.liquidityToken.address) + + const calculateTotalLiquidity = useCallback(() => { + if ( + typeof market === 'undefined' || + market === null || + BigNumber.from(parseEther(lpTotalSupply)).isZero() + ) + return { + shortPerLp: '0', + underlyingPerLp: '0', + totalUnderlyingPerLp: '0', + } + + const [ + shortValue, + underlyingValue, + totalUnderlyingValue, + ] = market.getLiquidityValuePerShare( + new TokenAmount( + market.liquidityToken, + parseEther(lpTotalSupply).toString() + ) + ) + const shortPerLp = parseEther(lpTotalSupply) + .mul(shortValue.raw.toString()) + .div(parseEther('1')) + const underlyingPerLp = parseEther(lpTotalSupply) + .mul(underlyingValue.raw.toString()) + .div(parseEther('1')) + const totalUnderlyingPerLp = parseEther(lpTotalSupply) + .mul(totalUnderlyingValue.raw.toString()) + .div(parseEther('1')) + + return { shortPerLp, underlyingPerLp, totalUnderlyingPerLp } + }, [market, lpTotalSupply]) return ( @@ -96,7 +145,7 @@ const OptionsTableRow: React.FC = ({ {!isZero(parseEther(bid)) ? ( - {numeral(breakeven).format('0.00')} $ + {numeral(breakeven).format('0.00a')} DAI ) : ( <>{`-`} @@ -110,17 +159,22 @@ const OptionsTableRow: React.FC = ({ ) : ( - {numeral(bid).format('(0.000a)')} $ + {numeral(bid).format('(0.000a)')} DAI )} ) : ( - )} - {parseFloat(reserves[0]) > 0 ? ( + {parseFloat( + formatEther(calculateTotalLiquidity().totalUnderlyingPerLp) + ) > 0 ? ( - {numeral(reserves[0]).format('0.00a')} {units} + {numeral( + formatEther(calculateTotalLiquidity().totalUnderlyingPerLp) + ).format('0.00a')}{' '} + {units} ) : ( diff --git a/src/components/Market/OrderCard/components/AddLiquidity/AddLiquidity.tsx b/src/components/Market/OrderCard/components/AddLiquidity/AddLiquidity.tsx index f7a7fdef..71edb36c 100644 --- a/src/components/Market/OrderCard/components/AddLiquidity/AddLiquidity.tsx +++ b/src/components/Market/OrderCard/components/AddLiquidity/AddLiquidity.tsx @@ -528,7 +528,6 @@ const AddLiquidity: React.FC = () => { ) } - const LiquidityContainer = styled.div` width: 34em; ` diff --git a/src/components/Market/OrderCard/components/ManageOptions/ManageOptions.tsx b/src/components/Market/OrderCard/components/ManageOptions/ManageOptions.tsx index f271b9dd..c67eda47 100644 --- a/src/components/Market/OrderCard/components/ManageOptions/ManageOptions.tsx +++ b/src/components/Market/OrderCard/components/ManageOptions/ManageOptions.tsx @@ -37,7 +37,7 @@ const LPOptions: React.FC<{ balance?: any }> = ({ balance }) => { diff --git a/src/components/Market/OrderCard/components/OrderOptions/OrderOptions.tsx b/src/components/Market/OrderCard/components/OrderOptions/OrderOptions.tsx index 93ec4627..8e6935ff 100644 --- a/src/components/Market/OrderCard/components/OrderOptions/OrderOptions.tsx +++ b/src/components/Market/OrderCard/components/OrderOptions/OrderOptions.tsx @@ -53,7 +53,7 @@ const LPOptions: React.FC<{ balance?: any; open?: boolean }> = ({ { {orderType === Operation.REMOVE_LIQUIDITY_CLOSE ? ( @@ -372,7 +372,7 @@ const RemoveLiquidity: React.FC = () => { {!formatEther( @@ -388,7 +388,7 @@ const RemoveLiquidity: React.FC = () => { parseEther(optionBalance) ) ) - ).format('0.00')}`} + ).format('0.00a')}`} units={`LONG`} />{' '} @@ -398,7 +398,7 @@ const RemoveLiquidity: React.FC = () => { @@ -411,7 +411,7 @@ const RemoveLiquidity: React.FC = () => { formatEther( calculateRemoveOutputs().underlyingValue.raw.toString() ) - ).format('0.00')} + ).format('0.00a')} units={`${entity.underlying.symbol.toUpperCase()}`} /> @@ -419,13 +419,13 @@ const RemoveLiquidity: React.FC = () => { label="To Receive" data={numeral( formatEther(calculateRemoveOutputs().shortValue.raw.toString()) - ).format('0.00')} + ).format('0.00a')} units={`SHORT`} />{' '} )} - + {loading ? (