From 697e83b7cb2379af23e99e3e5dec5bc7ca4bd512 Mon Sep 17 00:00:00 2001 From: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com> Date: Thu, 29 Jun 2023 12:55:47 +0200 Subject: [PATCH] Mp depostied vaults table (#271) * added correct resolving of account positions * solve rendering bug for lp amount * bugfix: add slippage to minlpamount * fix DisplayCurrency to accept only BNCoin * bugfix: remove prices from store * add basic depostied vaults table * Farm: Added deposited table * finish deposited table, remove featured vaults: --- .../Modals/vault/VaultBorrowings.test.tsx | 7 +- src/api/accounts/getAccount.ts | 13 +-- src/api/vaults/getMinLpToReceive.ts | 10 +- src/api/vaults/getVaults.ts | 7 +- .../Account/AccountBalancesTable.tsx | 17 ++-- src/components/Account/AccountComposition.tsx | 8 +- src/components/Account/AccountStats.tsx | 3 +- src/components/Account/AccountSummary.tsx | 7 +- src/components/Borrow/AssetExpanded.tsx | 4 - src/components/Borrow/Borrowings.tsx | 44 ++++----- src/components/Button/constants.ts | 6 +- src/components/DisplayCurrency.tsx | 5 +- src/components/Earn/vault/AvailableVaults.tsx | 38 ------- src/components/Earn/vault/VaultCard.tsx | 4 +- src/components/Earn/vault/VaultExpanded.tsx | 52 +++++----- src/components/Earn/vault/VaultLogo.tsx | 6 +- src/components/Earn/vault/VaultTable.tsx | 98 +++++++++++++------ src/components/Earn/vault/Vaults.tsx | 78 +++++++++++++++ .../Modals/LendAndReclaim/DetailsHeader.tsx | 16 ++- .../Modals/Vault/VaultBorrowings.tsx | 8 +- .../Modals/Vault/VaultBorrowingsSubTitle.tsx | 2 +- src/components/Modals/Vault/VaultDeposits.tsx | 5 +- .../Modals/Vault/VaultDepositsSubTitle.tsx | 5 +- src/components/Select/Option.tsx | 4 +- src/components/TitleAndSubCell.tsx | 4 +- src/components/Wallet/ConnectedButton.tsx | 2 +- src/hooks/broadcast/useDepositVault.ts | 16 ++- src/hooks/useMinLpToReceive.tsx | 14 --- src/hooks/usePrices.tsx | 2 - src/pages/FarmPage.tsx | 8 +- src/store/slices/broadcast.ts | 16 +-- src/store/slices/currency.ts | 1 - src/types/interfaces/store/currency.d.ts | 1 - src/types/interfaces/vaults.d.ts | 4 +- src/utils/constants.ts | 2 +- src/utils/formatters.ts | 6 +- src/utils/resolvers.ts | 7 +- src/utils/vaults.ts | 12 +-- 38 files changed, 309 insertions(+), 233 deletions(-) delete mode 100644 src/components/Earn/vault/AvailableVaults.tsx create mode 100644 src/components/Earn/vault/Vaults.tsx delete mode 100644 src/hooks/useMinLpToReceive.tsx diff --git a/__tests__/components/Modals/vault/VaultBorrowings.test.tsx b/__tests__/components/Modals/vault/VaultBorrowings.test.tsx index a07944d8..30ba0e90 100644 --- a/__tests__/components/Modals/vault/VaultBorrowings.test.tsx +++ b/__tests__/components/Modals/vault/VaultBorrowings.test.tsx @@ -6,6 +6,7 @@ import useStore from 'store' import DisplayCurrency from 'components/DisplayCurrency' import VaultBorrowings, { VaultBorrowingsProps } from 'components/Modals/Vault/VaultBorrowings' import { TESTNET_VAULTS_META_DATA } from 'constants/vaults' +import { BNCoin } from 'types/classes/BNCoin' jest.mock('hooks/usePrices', () => jest.fn(() => ({ @@ -38,8 +39,8 @@ const mockedVault: Vault = { }, cap: { denom: 'test', - max: 10, - used: 2, + max: BN(10), + used: BN(2), }, } describe('', () => { @@ -80,7 +81,7 @@ describe('', () => { it('should render DisplayCurrency correctly', () => { expect(mockedDisplayCurrency).toHaveBeenCalledTimes(1) expect(mockedDisplayCurrency).toHaveBeenCalledWith( - { coin: { denom: 'uosmo', amount: '0' } }, + { coin: new BNCoin({ denom: 'uosmo', amount: '0' }) }, expect.anything(), ) }) diff --git a/src/api/accounts/getAccount.ts b/src/api/accounts/getAccount.ts index ffb6eb13..b57bcbf2 100644 --- a/src/api/accounts/getAccount.ts +++ b/src/api/accounts/getAccount.ts @@ -1,6 +1,7 @@ import { getCreditManagerQueryClient } from 'api/cosmwasm-client' import { BNCoin } from 'types/classes/BNCoin' import { Positions } from 'types/generated/mars-credit-manager/MarsCreditManager.types' +import { resolvePositionResponse } from 'utils/resolvers' export default async function getAccount(accountId: string): Promise { const creditManagerQueryClient = await getCreditManagerQueryClient() @@ -8,17 +9,7 @@ export default async function getAccount(accountId: string): Promise { const accountPosition: Positions = await creditManagerQueryClient.positions({ accountId }) if (accountPosition) { - const debts = accountPosition.debts.map((debt) => new BNCoin(debt)) - const lends = accountPosition.lends.map((lend) => new BNCoin(lend)) - const deposits = accountPosition.deposits.map((deposit) => new BNCoin(deposit)) - - return { - id: accountPosition.account_id, - debts, - deposits, - lends, - vaults: accountPosition.vaults, - } + return resolvePositionResponse(accountPosition) } return new Promise((_, reject) => reject('No account found')) diff --git a/src/api/vaults/getMinLpToReceive.ts b/src/api/vaults/getMinLpToReceive.ts index 7f4ca035..c5bc083e 100644 --- a/src/api/vaults/getMinLpToReceive.ts +++ b/src/api/vaults/getMinLpToReceive.ts @@ -2,8 +2,12 @@ import { getCreditManagerQueryClient } from 'api/cosmwasm-client' import { ENV } from 'constants/env' import { BN } from 'utils/helpers' -export default async function getVaultConfigs(coins: Coin[], lpDenom: string): Promise { - if (!ENV.ADDRESS_CREDIT_MANAGER) return BN(0) +export default async function getVaultConfigs( + coins: Coin[], + lpDenom: string, + slippage: number, +): Promise { + if (!ENV.ADDRESS_CREDIT_MANAGER) return BN(Infinity) const creditManagerQueryClient = await getCreditManagerQueryClient() try { @@ -13,6 +17,8 @@ export default async function getVaultConfigs(coins: Coin[], lpDenom: string): P lpTokenOut: lpDenom, }), ) + .times(1 - slippage) + .integerValue() } catch (ex) { throw ex } diff --git a/src/api/vaults/getVaults.ts b/src/api/vaults/getVaults.ts index 471a8a7d..4e4814ed 100644 --- a/src/api/vaults/getVaults.ts +++ b/src/api/vaults/getVaults.ts @@ -4,6 +4,7 @@ import { getVaultConfigs } from 'api/vaults/getVaultConfigs' import { getVaultUtilizations } from 'api/vaults/getVaultUtilizations' import { ENV } from 'constants/env' import { TESTNET_VAULTS_META_DATA, VAULTS_META_DATA } from 'constants/vaults' +import { BN } from 'utils/helpers' export default async function getVaults(): Promise { const vaultConfigs = await getVaultConfigs([]) @@ -24,12 +25,12 @@ export default async function getVaults(): Promise { const vault: Vault = { ...vaultMetaData, cap: { - max: Number(vaultConfig.deposit_cap.amount), + max: BN(vaultConfig.deposit_cap.amount), denom: vaultConfig.deposit_cap.denom, - used: Number( + used: BN( vaultUtilizations.find( (vaultUtilization) => vaultUtilization.vault.address === vaultConfig.addr, - ) || 0, + )?.utilization.amount || 0, ), }, apy: apr ? convertAprToApy(apr.apr, 365) : null, diff --git a/src/components/Account/AccountBalancesTable.tsx b/src/components/Account/AccountBalancesTable.tsx index 2512b3dd..0046ffc6 100644 --- a/src/components/Account/AccountBalancesTable.tsx +++ b/src/components/Account/AccountBalancesTable.tsx @@ -17,6 +17,8 @@ import { ASSETS } from 'constants/assets' import useStore from 'store' import { convertToDisplayAmount, demagnify } from 'utils/formatters' import { BN } from 'utils/helpers' +import { BNCoin } from 'types/classes/BNCoin' +import usePrices from 'hooks/usePrices' interface Props { data: Account @@ -24,7 +26,8 @@ interface Props { export const AccountBalancesTable = (props: Props) => { const displayCurrency = useStore((s) => s.displayCurrency) - const prices = useStore((s) => s.prices) + const { data: prices } = usePrices() + const [sorting, setSorting] = React.useState([]) const balanceData = React.useMemo(() => { @@ -41,7 +44,7 @@ export const AccountBalancesTable = (props: Props) => { amount: deposit.amount, size: demagnify(deposit.amount, asset), value: convertToDisplayAmount( - { amount: deposit.amount, denom: deposit.denom }, + new BNCoin({ amount: deposit.amount, denom: deposit.denom }), displayCurrency, prices, ).toString(), @@ -58,7 +61,7 @@ export const AccountBalancesTable = (props: Props) => { amount: lending.amount, size: demagnify(lending.amount, asset), value: convertToDisplayAmount( - { amount: lending.amount, denom: lending.denom }, + new BNCoin({ amount: lending.amount, denom: lending.denom }), displayCurrency, prices, ).toString(), @@ -89,12 +92,8 @@ export const AccountBalancesTable = (props: Props) => { accessorKey: 'value', id: 'value', cell: ({ row }) => { - return ( - - ) + const coin = new BNCoin({ denom: row.original.denom, amount: row.original.amount }) + return }, }, { diff --git a/src/components/Account/AccountComposition.tsx b/src/components/Account/AccountComposition.tsx index dfc5c488..acd9aaa5 100644 --- a/src/components/Account/AccountComposition.tsx +++ b/src/components/Account/AccountComposition.tsx @@ -5,7 +5,9 @@ import DisplayCurrency from 'components/DisplayCurrency' import { FormattedNumber } from 'components/FormattedNumber' import { ArrowRight } from 'components/Icons' import Text from 'components/Text' +import usePrices from 'hooks/usePrices' import useStore from 'store' +import { BNCoin } from 'types/classes/BNCoin' import { calculateAccountApr, calculateAccountBorrowRate, @@ -30,7 +32,7 @@ interface ItemProps { } export default function AccountComposition(props: Props) { - const prices = useStore((s) => s.prices) + const { data: prices } = usePrices() const balance = calculateAccountDeposits(props.account, prices) const balanceChange = props.change ? calculateAccountDeposits(props.change, prices) : BN(0) const debtBalance = calculateAccountDebt(props.account, prices) @@ -96,7 +98,7 @@ function Item(props: ItemProps) { /> ) : ( )} @@ -113,7 +115,7 @@ function Item(props: ItemProps) { /> ) : ( )} diff --git a/src/components/Account/AccountStats.tsx b/src/components/Account/AccountStats.tsx index 94e66558..d5d3031c 100644 --- a/src/components/Account/AccountStats.tsx +++ b/src/components/Account/AccountStats.tsx @@ -3,6 +3,7 @@ import BigNumber from 'bignumber.js' import AccountHealth from 'components/Account/AccountHealth' import DisplayCurrency from 'components/DisplayCurrency' import useStore from 'store' +import { BNCoin } from 'types/classes/BNCoin' interface Props { balance: BigNumber @@ -16,7 +17,7 @@ export default function AccountStats(props: Props) { return (
diff --git a/src/components/Account/AccountSummary.tsx b/src/components/Account/AccountSummary.tsx index 76f6550e..e93c0296 100644 --- a/src/components/Account/AccountSummary.tsx +++ b/src/components/Account/AccountSummary.tsx @@ -7,7 +7,9 @@ import DisplayCurrency from 'components/DisplayCurrency' import { ArrowChartLineUp } from 'components/Icons' import Text from 'components/Text' import useIsOpenArray from 'hooks/useIsOpenArray' +import usePrices from 'hooks/usePrices' import useStore from 'store' +import { BNCoin } from 'types/classes/BNCoin' import { calculateAccountDeposits } from 'utils/accounts' import { BN } from 'utils/helpers' @@ -18,8 +20,7 @@ interface Props { export default function AccountSummary(props: Props) { const [isOpen, toggleOpen] = useIsOpenArray(2, true) - - const prices = useStore((s) => s.prices) + const { data: prices } = usePrices() const baseCurrency = useStore((s) => s.baseCurrency) const accountBalance = props.account ? calculateAccountDeposits(props.account, prices) : BN(0) if (!props.account) return null @@ -29,7 +30,7 @@ export default function AccountSummary(props: Props) { diff --git a/src/components/Borrow/AssetExpanded.tsx b/src/components/Borrow/AssetExpanded.tsx index 3afb6991..49d56a46 100644 --- a/src/components/Borrow/AssetExpanded.tsx +++ b/src/components/Borrow/AssetExpanded.tsx @@ -16,10 +16,6 @@ export default function AssetExpanded(props: AssetRowProps) { const asset = marketAssets.find((asset) => asset.denom === props.row.original.denom) let isActive: boolean = false - if ((props.row.original as BorrowAssetActive)?.debt) { - isActive = true - } - if (!asset) return null function borrowHandler() { diff --git a/src/components/Borrow/Borrowings.tsx b/src/components/Borrow/Borrowings.tsx index 2599a397..ef2f9958 100644 --- a/src/components/Borrow/Borrowings.tsx +++ b/src/components/Borrow/Borrowings.tsx @@ -1,4 +1,4 @@ -import { Suspense } from 'react' +import { Suspense, useMemo } from 'react' import { useParams } from 'react-router-dom' import Card from 'components/Card' @@ -18,28 +18,28 @@ function Content(props: Props) { const marketAssets = getEnabledMarketAssets() - function getBorrowAssets() { - return marketAssets.reduce( - (prev: { available: BorrowAsset[]; active: BorrowAssetActive[] }, curr) => { - const borrow = borrowData.find((borrow) => borrow.denom === curr.denom) - if (borrow) { - const debt = debtData?.find((debt) => debt.denom === curr.denom) - if (debt) { - prev.active.push({ - ...borrow, - debt: debt.amount, - }) - } else { - prev.available.push(borrow) + const { available, active } = useMemo( + () => + marketAssets.reduce( + (prev: { available: BorrowAsset[]; active: BorrowAssetActive[] }, curr) => { + const borrow = borrowData.find((borrow) => borrow.denom === curr.denom) + if (borrow) { + const debt = debtData?.find((debt) => debt.denom === curr.denom) + if (debt) { + prev.active.push({ + ...borrow, + debt: debt.amount, + }) + } else { + prev.available.push(borrow) + } } - } - return prev - }, - { available: [], active: [] }, - ) - } - - const { available, active } = getBorrowAssets() + return prev + }, + { available: [], active: [] }, + ), + [marketAssets, borrowData, debtData], + ) const assets = props.type === 'active' ? active : available diff --git a/src/components/Button/constants.ts b/src/components/Button/constants.ts index 06d738c7..753df760 100644 --- a/src/components/Button/constants.ts +++ b/src/components/Button/constants.ts @@ -43,9 +43,9 @@ export const buttonSizeClasses = { } export const buttonPaddingClasses = { - small: 'px-2.5 py-1.5 min-h-[32px]', - medium: 'px-3 py-2 min-h-[40px]', - large: 'px-3.5 py-2.5 min-h-[56px]', + small: 'px-4 py-1.5 min-h-[32px]', + medium: 'px-4 py-2 min-h-[40px]', + large: 'px-4 py-2.5 min-h-[56px]', } export const buttonVariantClasses = { diff --git a/src/components/DisplayCurrency.tsx b/src/components/DisplayCurrency.tsx index 46bf3674..2d7ba16a 100644 --- a/src/components/DisplayCurrency.tsx +++ b/src/components/DisplayCurrency.tsx @@ -1,17 +1,18 @@ import { FormattedNumber } from 'components/FormattedNumber' +import usePrices from 'hooks/usePrices' import useStore from 'store' import { BNCoin } from 'types/classes/BNCoin' import { convertToDisplayAmount } from 'utils/formatters' interface Props { - coin: BNCoin | Coin + coin: BNCoin className?: string isApproximation?: boolean } export default function DisplayCurrency(props: Props) { const displayCurrency = useStore((s) => s.displayCurrency) - const prices = useStore((s) => s.prices) + const { data: prices } = usePrices() return ( -} - -export default function AvailableVaults() { - return ( - - }> - - - - ) -} - -function Fallback() { - // TODO: Replace with loading state of vaulttable - const vaults = IS_TESTNET ? TESTNET_VAULTS_META_DATA : VAULTS_META_DATA - return ( - <> - {vaults.map((vault) => ( - {vault.name} - ))} - - ) -} diff --git a/src/components/Earn/vault/VaultCard.tsx b/src/components/Earn/vault/VaultCard.tsx index 619eac5e..cfcf0a20 100644 --- a/src/components/Earn/vault/VaultCard.tsx +++ b/src/components/Earn/vault/VaultCard.tsx @@ -58,7 +58,7 @@ export default function VaultCard(props: Props) { /> + row: Row resetExpanded: (defaultState?: boolean | undefined) => void } @@ -19,6 +19,11 @@ export default function VaultExpanded(props: Props) { }) } + let isDeposited: boolean = false + if ((props.row.original as DepositedVault)?.amounts) { + isDeposited = true + } + return ( - - Select bonding period -
- - - + +
+ {isDeposited ? ( + <> + + + + ) : ( + + )}
diff --git a/src/components/Earn/vault/VaultLogo.tsx b/src/components/Earn/vault/VaultLogo.tsx index 6c479a5c..b11c9b66 100644 --- a/src/components/Earn/vault/VaultLogo.tsx +++ b/src/components/Earn/vault/VaultLogo.tsx @@ -1,10 +1,8 @@ -import Image from 'next/image' - import AssetImage from 'components/AssetImage' import { getAssetByDenom } from 'utils/assets' interface Props { - vault: Vault + vault: VaultMetaData } export default function VaultLogo(props: Props) { @@ -19,7 +17,7 @@ export default function VaultLogo(props: Props) {
- +
) diff --git a/src/components/Earn/vault/VaultTable.tsx b/src/components/Earn/vault/VaultTable.tsx index 9f6dcc1e..8a25cdc7 100644 --- a/src/components/Earn/vault/VaultTable.tsx +++ b/src/components/Earn/vault/VaultTable.tsx @@ -3,6 +3,7 @@ import { flexRender, getCoreRowModel, getSortedRowModel, + Row, SortingState, useReactTable, } from '@tanstack/react-table' @@ -18,27 +19,58 @@ import TitleAndSubCell from 'components/TitleAndSubCell' import { VAULT_DEPOSIT_BUFFER } from 'constants/vaults' import { getAssetByDenom } from 'utils/assets' import { convertPercentage, formatPercent, formatValue } from 'utils/formatters' +import DisplayCurrency from 'components/DisplayCurrency' +import useStore from 'store' +import { BNCoin } from 'types/classes/BNCoin' +import Loading from 'components/Loading' type Props = { - data: Vault[] + data: Vault[] | DepositedVault[] + isLoading?: boolean } export const VaultTable = (props: Props) => { - const [sorting, setSorting] = React.useState([]) + const [sorting, setSorting] = React.useState([{ id: 'name', desc: true }]) - const columns = React.useMemo[]>( - () => [ + const baseCurrency = useStore((s) => s.baseCurrency) + + const columns = React.useMemo[]>(() => { + return [ { header: 'Vault', - id: 'address', + accessorKey: 'name', cell: ({ row }) => { - return + return ( +
+ + +
+ ) }, }, + + ...((props.data[0] as DepositedVault)?.values + ? [ + { + header: 'Pos. Value', + cell: ({ row }: { row: Row }) => { + const vault = row.original as DepositedVault + const positionValue = vault.values.primary.plus(vault.values.secondary) + const coin = BNCoin.fromDenomAndBigNumber(baseCurrency.denom, positionValue) + return + }, + }, + ] + : []), { accessorKey: 'apy', header: 'APY', cell: ({ row }) => { + if (row.original.apy === null) return return ( {row.original.apy ? formatPercent(row.original.apy, 2) : '-'} ) @@ -48,29 +80,36 @@ export const VaultTable = (props: Props) => { accessorKey: 'tvl', header: 'TVL', cell: ({ row }) => { - // TODO: Replace with DisplayCurrency - const symbol = getAssetByDenom(row.original.cap.denom)?.symbol ?? '' - return ( - - {formatValue(row.original.cap.used, { abbreviated: true, suffix: ` ${symbol}` })} - - ) + if (props.isLoading) return + const coin = new BNCoin({ + denom: row.original.cap.denom, + amount: row.original.cap.used.toString(), + }) + + return }, }, { accessorKey: 'cap', header: 'Depo. Cap', cell: ({ row }) => { + if (props.isLoading) return + const percent = convertPercentage( - (row.original.cap.used / (row.original.cap.max * VAULT_DEPOSIT_BUFFER)) * 100, + row.original.cap.used + .div(row.original.cap.max.times(VAULT_DEPOSIT_BUFFER)) + .times(100) + .integerValue() + .toNumber(), ) const decimals = getAssetByDenom(row.original.cap.denom)?.decimals ?? 6 - // TODO: Replace with DisplayCurrency return ( ) @@ -80,21 +119,24 @@ export const VaultTable = (props: Props) => { accessorKey: 'details', enableSorting: false, header: 'Details', - cell: ({ row }) => ( -
-
- + cell: ({ row }) => { + if (props.isLoading) return + + return ( +
+
+ +
-
- ), + ) + }, }, - ], - [], - ) + ] + }, [baseCurrency.denom, props.data, props.isLoading]) const table = useReactTable({ data: props.data, - columns, + columns: columns, state: { sorting, }, @@ -122,7 +164,7 @@ export const VaultTable = (props: Props) => {
diff --git a/src/components/Earn/vault/Vaults.tsx b/src/components/Earn/vault/Vaults.tsx new file mode 100644 index 00000000..9d299349 --- /dev/null +++ b/src/components/Earn/vault/Vaults.tsx @@ -0,0 +1,78 @@ +import { Suspense, useMemo } from 'react' +import { useParams } from 'react-router-dom' + +import Card from 'components/Card' +import { VaultTable } from 'components/Earn/vault/VaultTable' +import { IS_TESTNET } from 'constants/env' +import { TESTNET_VAULTS_META_DATA, VAULTS_META_DATA } from 'constants/vaults' +import useVaults from 'hooks/useVaults' +import useDepositedVaults from 'hooks/useDepositedVaults' +import { BN } from 'utils/helpers' + +interface Props { + type: 'available' | 'deposited' +} + +function Content(props: Props) { + const { accountId } = useParams() + const { data: vaults } = useVaults() + const { data: depositedVaults } = useDepositedVaults(accountId || '') + + const vaultsMetaData = IS_TESTNET ? TESTNET_VAULTS_META_DATA : VAULTS_META_DATA + + const { deposited, available } = useMemo(() => { + return vaultsMetaData.reduce( + (prev: { deposited: DepositedVault[]; available: Vault[] }, curr) => { + const vault = vaults.find((vault) => vault.address === curr.address) + const depositedVault = depositedVaults?.find((vault) => vault.address === curr.address) + + if (depositedVault) { + prev.deposited.push(depositedVault) + } else if (vault) { + prev.available.push(vault) + } + + return prev + }, + { deposited: [], available: [] }, + ) + }, [vaults, depositedVaults, vaultsMetaData]) + + const vaultsToDisplay = props.type === 'available' ? available : deposited + + if (!vaultsToDisplay.length) return null + + return +} + +export default function Vaults(props: Props) { + return ( + + : null}> + + + + ) +} + +function Fallback() { + const vaults = IS_TESTNET ? TESTNET_VAULTS_META_DATA : VAULTS_META_DATA + const mockVaults: Vault[] = vaults.map((vault) => ({ + ...vault, + apy: null, + ltv: { + max: 0, + liq: 0, + }, + cap: { + denom: 'denom', + used: BN(0), + max: BN(0), + }, + })) + + return +} diff --git a/src/components/Modals/LendAndReclaim/DetailsHeader.tsx b/src/components/Modals/LendAndReclaim/DetailsHeader.tsx index dd771ce5..ee700da5 100644 --- a/src/components/Modals/LendAndReclaim/DetailsHeader.tsx +++ b/src/components/Modals/LendAndReclaim/DetailsHeader.tsx @@ -3,6 +3,7 @@ import TitleAndSubCell from 'components/TitleAndSubCell' import { FormattedNumber } from 'components/FormattedNumber' import useAssetIncentivesApy from 'hooks/useAssetIncentiveApy' import useCurrentWalletBalance from 'hooks/useCurrentWalletBalance' +import { BNCoin } from 'types/classes/BNCoin' interface Props { data: LendingMarketTableData @@ -36,7 +37,11 @@ function DetailsHeader({ data }: Props) { {accountLentAmount && ( <> } + title={ + + } sub={'Deposited'} />
@@ -44,13 +49,18 @@ function DetailsHeader({ data }: Props) { )} {balanceInWallet && ( <> - } sub={'In Wallet'} /> + } + sub={'In Wallet'} + />
)} + } sub={'Deposit Cap'} /> diff --git a/src/components/Modals/Vault/VaultBorrowings.tsx b/src/components/Modals/Vault/VaultBorrowings.tsx index 64efdb96..c5c068c5 100644 --- a/src/components/Modals/Vault/VaultBorrowings.tsx +++ b/src/components/Modals/Vault/VaultBorrowings.tsx @@ -43,8 +43,8 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) { const { actions: depositActions, fee: depositFee } = useDepositVault({ vault: props.vault, - deposits: props.deposits.filter((borrowing) => borrowing.amount.gt(0)), - borrowings: props.borrowings.filter((borrowing) => borrowing.amount.gt(0)), + deposits: props.deposits, + borrowings: props.borrowings, }) const primaryValue = useMemo( @@ -189,7 +189,9 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) {
{`${props.primaryAsset.symbol}-${props.secondaryAsset.symbol} Position Value`} - +
{props.borrowings.map((coin) => { const asset = getAssetByDenom(coin.denom) diff --git a/src/components/Modals/Vault/VaultBorrowingsSubTitle.tsx b/src/components/Modals/Vault/VaultBorrowingsSubTitle.tsx index ff347dc5..d2e17286 100644 --- a/src/components/Modals/Vault/VaultBorrowingsSubTitle.tsx +++ b/src/components/Modals/Vault/VaultBorrowingsSubTitle.tsx @@ -40,7 +40,7 @@ export default function VaultDepositSubTitle(props: Props) { <> {` = `} )} diff --git a/src/components/Modals/Vault/VaultDeposits.tsx b/src/components/Modals/Vault/VaultDeposits.tsx index 77b097ac..6386cbb4 100644 --- a/src/components/Modals/Vault/VaultDeposits.tsx +++ b/src/components/Modals/Vault/VaultDeposits.tsx @@ -14,6 +14,7 @@ import { getAmount } from 'utils/accounts' import { BN } from 'utils/helpers' import { Gauge } from 'components/Gauge' import useStore from 'store' +import { BNCoin } from 'types/classes/BNCoin' interface Props { primaryAmount: BigNumber @@ -204,7 +205,9 @@ export default function VaultDeposit(props: Props) {
{`${props.primaryAsset.symbol}-${props.secondaryAsset.symbol} Deposit Value`} - +
) diff --git a/src/components/TitleAndSubCell.tsx b/src/components/TitleAndSubCell.tsx index 0ce5d78d..29834a58 100644 --- a/src/components/TitleAndSubCell.tsx +++ b/src/components/TitleAndSubCell.tsx @@ -12,10 +12,10 @@ interface Props { export default function TitleAndSubCell(props: Props) { return (
- + {props.title} - + {props.sub}
diff --git a/src/components/Wallet/ConnectedButton.tsx b/src/components/Wallet/ConnectedButton.tsx index 0ee1c4b4..de234544 100644 --- a/src/components/Wallet/ConnectedButton.tsx +++ b/src/components/Wallet/ConnectedButton.tsx @@ -72,7 +72,7 @@ export default function ConnectedButton() { const assetDenoms = marketAssets.map((asset) => asset.denom) const balances = walletBalances.filter((coin) => assetDenoms.includes(coin.denom)) useStore.setState({ balances }) - }, [walletBalances, baseAsset.denom, baseAsset.decimals, marketAssets]) + }, [walletBalances, baseAsset.denom, baseAsset.decimals, marketAssets, walletAmount]) return (
diff --git a/src/hooks/broadcast/useDepositVault.ts b/src/hooks/broadcast/useDepositVault.ts index 018d1678..9580a24b 100644 --- a/src/hooks/broadcast/useDepositVault.ts +++ b/src/hooks/broadcast/useDepositVault.ts @@ -27,7 +27,13 @@ export default function useDepositVault(props: Props): { actions: Action[]; fee: const debouncedGetMinLpToReceive = useMemo(() => debounce(getMinLpToReceive, 500), []) const { primaryCoin, secondaryCoin, totalValue } = useMemo( - () => getVaultDepositCoinsAndValue(props.vault, props.deposits, props.borrowings, prices), + () => + getVaultDepositCoinsAndValue( + props.vault, + props.deposits.filter((borrowing) => borrowing.amount.gt(0)), + props.borrowings.filter((borrowing) => borrowing.amount.gt(0)), + prices, + ), [props.deposits, props.borrowings, props.vault, prices], ) @@ -41,8 +47,8 @@ export default function useDepositVault(props: Props): { actions: Action[]; fee: () => getVaultSwapActions( props.vault, - props.deposits, - props.borrowings, + props.deposits.filter((borrowing) => borrowing.amount.gt(0)), + props.borrowings.filter((borrowing) => borrowing.amount.gt(0)), prices, slippage, totalValue, @@ -56,9 +62,10 @@ export default function useDepositVault(props: Props): { actions: Action[]; fee: const lpAmount = await debouncedGetMinLpToReceive( [secondaryCoin.toCoin(), primaryCoin.toCoin()], props.vault.denoms.lp, + slippage, ) - if (!lpAmount || lpAmount === minLpToReceive) return + if (!lpAmount || lpAmount.eq(minLpToReceive)) return setMinLpToReceive(lpAmount) }, [ primaryCoin, @@ -66,6 +73,7 @@ export default function useDepositVault(props: Props): { actions: Action[]; fee: props.vault.denoms.lp, debouncedGetMinLpToReceive, minLpToReceive, + slippage, ]) const enterVaultActions: Action[] = useMemo(() => { diff --git a/src/hooks/useMinLpToReceive.tsx b/src/hooks/useMinLpToReceive.tsx deleted file mode 100644 index 05f4cdd3..00000000 --- a/src/hooks/useMinLpToReceive.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import useSWR from 'swr' - -import getMinLpToReceive from 'api/vaults/getMinLpToReceive' -import { BN } from 'utils/helpers' - -export default function useMinLpToReceive(coins: Coin[], lpDenom: string) { - return useSWR( - `minLpToReceive-${JSON.stringify(coins)}`, - () => getMinLpToReceive(coins, lpDenom), - { - fallbackData: BN(0), - }, - ) -} diff --git a/src/hooks/usePrices.tsx b/src/hooks/usePrices.tsx index 0352e5d6..fd3b422c 100644 --- a/src/hooks/usePrices.tsx +++ b/src/hooks/usePrices.tsx @@ -1,12 +1,10 @@ import useSWR from 'swr' import getPrices from 'api/prices/getPrices' -import useStore from 'store' export default function usePrices() { return useSWR('prices', getPrices, { fallbackData: [], refreshInterval: 30000, - onSuccess: (prices) => useStore.setState({ prices }), }) } diff --git a/src/pages/FarmPage.tsx b/src/pages/FarmPage.tsx index 909dc0f2..51bab381 100644 --- a/src/pages/FarmPage.tsx +++ b/src/pages/FarmPage.tsx @@ -1,13 +1,13 @@ -import AvailableVaults from 'components/Earn/vault/AvailableVaults' -import FeaturedVaults from 'components/Earn/vault/FeaturedVaults' import Tab from 'components/Earn/Tab' +import Vaults from 'components/Earn/vault/Vaults' export default function FarmPage() { return ( <> - - + {/* */} + + ) } diff --git a/src/store/slices/broadcast.ts b/src/store/slices/broadcast.ts index f9db9a59..a79a8ddf 100644 --- a/src/store/slices/broadcast.ts +++ b/src/store/slices/broadcast.ts @@ -136,20 +136,8 @@ export default function createBroadcastSlice( }, } const response = await get().executeMsg({ msg, fee: options.fee }) - if (response.result) { - set({ - toast: { - message: `Deposited into vault`, - }, - }) - } else { - set({ - toast: { - message: response.error ?? `Transaction failed: ${response.error}`, - isError: true, - }, - }) - } + + handleResponseMessages(response, `Deposited into vault`) return !!response.result }, withdraw: async (options: { fee: StdFee; accountId: string; coin: Coin }) => { diff --git a/src/store/slices/currency.ts b/src/store/slices/currency.ts index adc30e51..a083c967 100644 --- a/src/store/slices/currency.ts +++ b/src/store/slices/currency.ts @@ -9,6 +9,5 @@ export default function createCurrencySlice( return { baseCurrency: ASSETS[0], displayCurrency: ASSETS.find((asset) => asset.denom === ASSETS[0].denom)!, - prices: [], } } diff --git a/src/types/interfaces/store/currency.d.ts b/src/types/interfaces/store/currency.d.ts index 3bdad516..42a4f260 100644 --- a/src/types/interfaces/store/currency.d.ts +++ b/src/types/interfaces/store/currency.d.ts @@ -1,5 +1,4 @@ interface CurrencySlice { baseCurrency: Asset displayCurrency: Asset - prices: Coin[] } diff --git a/src/types/interfaces/vaults.d.ts b/src/types/interfaces/vaults.d.ts index 098c1e0b..6dc4e884 100644 --- a/src/types/interfaces/vaults.d.ts +++ b/src/types/interfaces/vaults.d.ts @@ -27,8 +27,8 @@ interface VaultInfo { } cap: { denom: string - used: number - max: number + used: BigNumber + max: BigNumber } } diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 493820fa..3819e4cb 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -7,7 +7,7 @@ export const hardcodedFee = { amount: '100000', }, ], - gas: '5000000', + gas: '10000000', } export const SECONDS_IN_A_YEAR = 31540000 diff --git a/src/utils/formatters.ts b/src/utils/formatters.ts index 62818f85..1bf7df5e 100644 --- a/src/utils/formatters.ts +++ b/src/utils/formatters.ts @@ -156,11 +156,7 @@ export function demagnify(amount: number | string | BigNumber, asset: Asset) { return value.isZero() ? 0 : value.shiftedBy(-1 * asset.decimals).toNumber() } -export function convertToDisplayAmount( - coin: BNCoin | Coin, - displayCurrency: Asset, - prices: Coin[], -) { +export function convertToDisplayAmount(coin: BNCoin, displayCurrency: Asset, prices: Coin[]) { const price = prices.find((price) => price.denom === coin.denom) const asset = getEnabledMarketAssets().find((asset) => asset.denom === coin.denom) const displayPrice = prices.find((price) => price.denom === displayCurrency.denom) diff --git a/src/utils/resolvers.ts b/src/utils/resolvers.ts index e2ac99bc..047d724b 100644 --- a/src/utils/resolvers.ts +++ b/src/utils/resolvers.ts @@ -1,3 +1,4 @@ +import { BNCoin } from 'types/classes/BNCoin' import { Positions as CreditManagerPosition } from 'types/generated/mars-credit-manager/MarsCreditManager.types' import { Market as RedBankMarket } from 'types/generated/mars-mock-red-bank/MarsMockRedBank.types' @@ -8,9 +9,9 @@ export function resolvePositionResponses(responses: CreditManagerPosition[]): Ac export function resolvePositionResponse(response: CreditManagerPosition): Account { return { id: response.account_id, - deposits: response.deposits, - debts: response.debts, - lends: response.lends, + debts: response.debts.map((debt) => new BNCoin(debt)), + lends: response.lends.map((lend) => new BNCoin(lend)), + deposits: response.deposits.map((deposit) => new BNCoin(deposit)), vaults: response.vaults, } } diff --git a/src/utils/vaults.ts b/src/utils/vaults.ts index 7cb79352..b958fe35 100644 --- a/src/utils/vaults.ts +++ b/src/utils/vaults.ts @@ -49,14 +49,14 @@ export function getVaultDepositCoinsAndValue( return prev.plus(bnCoin.amount.times(price)) }, BN(0)) - const primaryDepositAmount = getTokenPrice(vault.denoms.primary, prices) - .times(totalValue) - .div(2) + const halfValue = totalValue.div(2) + + const primaryDepositAmount = halfValue + .div(getTokenPrice(vault.denoms.primary, prices)) .integerValue() - const secondaryDepositAmount = getTokenPrice(vault.denoms.secondary, prices) - .times(totalValue) - .div(2) + const secondaryDepositAmount = halfValue + .div(getTokenPrice(vault.denoms.secondary, prices)) .integerValue() return {