([])
const { data: walletBalances } = useWalletBalances(address)
const baseAsset = getBaseAsset()
const { autoLendEnabledAccountIds, toggleAutoLend } = useAutoLendEnabledAccountIds()
const isAutoLendEnabled = autoLendEnabledAccountIds.includes(accountId ?? '0')
const hasAssetSelected = fundingAssets.length > 0
- const hasFundingAssets = fundingAssets.length > 0 && fundingAssets.every((a) => a.amount !== '0')
+ const hasFundingAssets =
+ fundingAssets.length > 0 && fundingAssets.every((a) => a.toCoin().amount !== '0')
const baseBalance = useMemo(
() => walletBalances.find(byDenom(baseAsset.denom))?.amount ?? '0',
@@ -77,10 +79,9 @@ export default function AccountFund() {
)
return
- const newFundingAssets = selectedDenoms.map((denom) => ({
- denom,
- amount: fundingAssets.find((asset) => asset.denom === denom)?.amount ?? '0',
- }))
+ const newFundingAssets = selectedDenoms.map((denom) =>
+ BNCoin.fromDenomAndBigNumber(denom, BN(fundingAssets.find(byDenom(denom))?.amount ?? '0')),
+ )
setFundingAssets(newFundingAssets)
}, [selectedDenoms, fundingAssets])
@@ -89,7 +90,7 @@ export default function AccountFund() {
(amount: BigNumber, denom: string) => {
const assetToUpdate = fundingAssets.find((asset) => asset.denom === denom)
if (assetToUpdate) {
- assetToUpdate.amount = amount.toString()
+ assetToUpdate.amount = amount
setFundingAssets([...fundingAssets.filter((a) => a.denom !== denom), assetToUpdate])
}
},
diff --git a/src/components/Account/AccountList.tsx b/src/components/Account/AccountList.tsx
index c2a969fe..2f86cf90 100644
--- a/src/components/Account/AccountList.tsx
+++ b/src/components/Account/AccountList.tsx
@@ -14,7 +14,7 @@ import useAutoLendEnabledAccountIds from 'hooks/useAutoLendEnabledAccountIds'
import useCurrentAccount from 'hooks/useCurrentAccount'
import usePrices from 'hooks/usePrices'
import useStore from 'store'
-import { calculateAccountDepositsValue } from 'utils/accounts'
+import { calculateAccountValue } from 'utils/accounts'
import { getPage, getRoute } from 'utils/route'
interface Props {
@@ -54,7 +54,7 @@ export default function AccountList(props: Props) {
return (
{props.accounts.map((account) => {
- const positionBalance = calculateAccountDepositsValue(account, prices)
+ const positionBalance = calculateAccountValue('deposits', account, prices)
const isActive = accountId === account.id
const isAutoLendEnabled = autoLendEnabledAccountIds.includes(account.id)
diff --git a/src/components/Account/AccountStats.tsx b/src/components/Account/AccountStats.tsx
index fe444e29..d02d9346 100644
--- a/src/components/Account/AccountStats.tsx
+++ b/src/components/Account/AccountStats.tsx
@@ -4,7 +4,7 @@ import { ORACLE_DENOM } from 'constants/oracle'
import useHealthComputer from 'hooks/useHealthComputer'
import usePrices from 'hooks/usePrices'
import { BNCoin } from 'types/classes/BNCoin'
-import { calculateAccountDepositsValue } from 'utils/accounts'
+import { calculateAccountValue } from 'utils/accounts'
import { formatHealth } from 'utils/formatters'
import { BN } from 'utils/helpers'
@@ -14,7 +14,7 @@ interface Props {
export default function AccountStats(props: Props) {
const { data: prices } = usePrices()
- const positionBalance = calculateAccountDepositsValue(props.account, prices)
+ const positionBalance = calculateAccountValue('deposits', props.account, prices)
const { health } = useHealthComputer(props.account)
const healthFactor = BN(100).minus(formatHealth(health)).toNumber()
return (
diff --git a/src/components/Account/AccountSummary.tsx b/src/components/Account/AccountSummary.tsx
index 9839a138..7ee8f67a 100644
--- a/src/components/Account/AccountSummary.tsx
+++ b/src/components/Account/AccountSummary.tsx
@@ -13,7 +13,7 @@ import useIsOpenArray from 'hooks/useIsOpenArray'
import useLendingMarketAssetsTableData from 'hooks/useLendingMarketAssetsTableData'
import usePrices from 'hooks/usePrices'
import { BNCoin } from 'types/classes/BNCoin'
-import { calculateAccountDepositsValue } from 'utils/accounts'
+import { calculateAccountValue } from 'utils/accounts'
interface Props {
account?: Account
@@ -24,7 +24,7 @@ export default function AccountSummary(props: Props) {
const [isOpen, toggleOpen] = useIsOpenArray(2, true)
const { data: prices } = usePrices()
const accountBalance = props.account
- ? calculateAccountDepositsValue(props.account, prices)
+ ? calculateAccountValue('deposits', props.account, prices)
: BN_ZERO
const { availableAssets: borrowAvailableAssets, accountBorrowedAssets } =
useBorrowMarketAssetsTableData()
diff --git a/src/components/Modals/AssetAmountSelectActionModal.tsx b/src/components/Modals/AssetAmountSelectActionModal.tsx
index 06ce9b0d..27217f93 100644
--- a/src/components/Modals/AssetAmountSelectActionModal.tsx
+++ b/src/components/Modals/AssetAmountSelectActionModal.tsx
@@ -8,10 +8,10 @@ import Divider from 'components/Divider'
import { ArrowRight } from 'components/Icons'
import Modal from 'components/Modal'
import Text from 'components/Text'
-import TokenInputWithSlider from 'components/TokenInputWithSlider'
+import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider'
+import { BN_ZERO } from 'constants/math'
import { byDenom } from 'utils/array'
import { BN } from 'utils/helpers'
-import { BN_ZERO } from 'constants/math'
interface Props {
asset: Asset
diff --git a/src/components/Modals/AssetsSelect/AssetSelectTable.tsx b/src/components/Modals/AssetsSelect/AssetSelectTable.tsx
index ac004205..3a76bffa 100644
--- a/src/components/Modals/AssetsSelect/AssetSelectTable.tsx
+++ b/src/components/Modals/AssetsSelect/AssetSelectTable.tsx
@@ -24,15 +24,12 @@ interface Props {
export default function AssetSelectTable(props: Props) {
const defaultSelected = useMemo(() => {
const assets = props.assets as BorrowAsset[]
- return assets.reduce(
- (acc, asset, index) => {
- if (props.selectedDenoms?.includes(asset.denom)) {
- acc[index] = true
- }
- return acc
- },
- {} as { [key: number]: boolean },
- )
+ return assets.reduce((acc, asset, index) => {
+ if (props.selectedDenoms?.includes(asset.denom)) {
+ acc[index] = true
+ }
+ return acc
+ }, {} as { [key: number]: boolean })
}, [props.selectedDenoms, props.assets])
const [sorting, setSorting] = useState
([{ id: 'symbol', desc: false }])
const [selected, setSelected] = useState(defaultSelected)
diff --git a/src/components/Modals/BorrowModal.tsx b/src/components/Modals/BorrowModal.tsx
index 9dcf8cc7..bbf67ab5 100644
--- a/src/components/Modals/BorrowModal.tsx
+++ b/src/components/Modals/BorrowModal.tsx
@@ -1,5 +1,5 @@
-import { useEffect, useState } from 'react'
import BigNumber from 'bignumber.js'
+import { useEffect, useState } from 'react'
import AccountSummary from 'components/Account/AccountSummary'
import AssetImage from 'components/AssetImage'
@@ -11,17 +11,17 @@ import Modal from 'components/Modal'
import Switch from 'components/Switch'
import Text from 'components/Text'
import TitleAndSubCell from 'components/TitleAndSubCell'
-import TokenInputWithSlider from 'components/TokenInputWithSlider'
+import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider'
import { ASSETS } from 'constants/assets'
+import { BN_ZERO } from 'constants/math'
import useCurrentAccount from 'hooks/useCurrentAccount'
+import useHealthComputer from 'hooks/useHealthComputer'
import useToggle from 'hooks/useToggle'
import useStore from 'store'
import { BNCoin } from 'types/classes/BNCoin'
import { hardcodedFee } from 'utils/constants'
import { formatPercent, formatValue } from 'utils/formatters'
import { BN } from 'utils/helpers'
-import useHealthComputer from 'hooks/useHealthComputer'
-import { BN_ZERO } from 'constants/math'
function getDebtAmount(modal: BorrowModal | null) {
return BN((modal?.marketData as BorrowMarketTableData)?.debt ?? 0).toString()
diff --git a/src/components/Modals/FundWithdraw/FundAccount.tsx b/src/components/Modals/FundWithdraw/FundAccount.tsx
new file mode 100644
index 00000000..b8d3867c
--- /dev/null
+++ b/src/components/Modals/FundWithdraw/FundAccount.tsx
@@ -0,0 +1,88 @@
+import BigNumber from 'bignumber.js'
+import { useState } from 'react'
+
+import Button from 'components/Button'
+import { ArrowRight } from 'components/Icons'
+import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider'
+import { ASSETS } from 'constants/assets'
+import { BN_ZERO } from 'constants/math'
+import useToggle from 'hooks/useToggle'
+import useStore from 'store'
+import { BNCoin } from 'types/classes/BNCoin'
+import { getAmount } from 'utils/accounts'
+import { byDenom } from 'utils/array'
+import { hardcodedFee } from 'utils/constants'
+
+interface Props {
+ account: Account
+ setChange: (change: AccountChange | undefined) => void
+}
+
+export default function FundAccount(props: Props) {
+ const { account, setChange } = props
+ const deposit = useStore((s) => s.deposit)
+ const balances = useStore((s) => s.balances)
+ const defaultAsset = ASSETS.find(byDenom(balances[0].denom)) ?? ASSETS[0]
+ const [isConfirming, setIsConfirming] = useToggle()
+ const [currentAsset, setCurrentAsset] = useState(defaultAsset)
+ const [amount, setAmount] = useState(BN_ZERO)
+ const depositAmount = BN_ZERO.plus(amount)
+ const max = getAmount(currentAsset.denom, balances ?? [])
+
+ function onChangeAmount(val: BigNumber) {
+ setAmount(val)
+ setChange({
+ deposits: [
+ {
+ amount: depositAmount.toString(),
+ denom: currentAsset.denom,
+ },
+ ],
+ })
+ }
+
+ function resetState() {
+ setCurrentAsset(defaultAsset)
+ setAmount(BN_ZERO)
+ setChange(undefined)
+ }
+
+ async function onConfirm() {
+ setIsConfirming(true)
+ const result = await deposit({
+ fee: hardcodedFee,
+ accountId: account.id,
+ coins: [BNCoin.fromDenomAndBigNumber(currentAsset.denom, amount)],
+ })
+
+ setIsConfirming(false)
+ if (result) {
+ resetState()
+ useStore.setState({ fundAndWithdrawModal: null })
+ }
+ }
+
+ return (
+ <>
+
+ }
+ />
+ >
+ )
+}
diff --git a/src/components/Modals/FundWithdraw/FundAndWithdrawModalContent.tsx b/src/components/Modals/FundWithdraw/FundAndWithdrawModalContent.tsx
index 52c56bea..7dfa6c6c 100644
--- a/src/components/Modals/FundWithdraw/FundAndWithdrawModalContent.tsx
+++ b/src/components/Modals/FundWithdraw/FundAndWithdrawModalContent.tsx
@@ -1,17 +1,9 @@
-import BigNumber from 'bignumber.js'
import { useState } from 'react'
import AccountSummary from 'components/Account/AccountSummary'
-import Button from 'components/Button'
import Card from 'components/Card'
-import Divider from 'components/Divider'
-import { ArrowRight } from 'components/Icons'
-import TokenInputWithSlider from 'components/TokenInputWithSlider'
-import useToggle from 'hooks/useToggle'
-import useStore from 'store'
-import { getAmount } from 'utils/accounts'
-import { hardcodedFee } from 'utils/constants'
-import { BN_ZERO } from 'constants/math'
+import FundAccount from 'components/Modals/FundWithdraw/FundAccount'
+import WithdrawFromAccount from 'components/Modals/FundWithdraw/WithdrawFromAccount'
interface Props {
account: Account
@@ -19,103 +11,22 @@ interface Props {
}
export default function FundWithdrawModalContent(props: Props) {
- const baseCurrency = useStore((s) => s.baseCurrency)
- const withdraw = useStore((s) => s.withdraw)
- const deposit = useStore((s) => s.deposit)
- const balances = useStore((s) => s.balances)
- const [isConfirming, setIsConfirming] = useToggle()
- const [currentAsset, setCurrentAsset] = useState(baseCurrency)
- const [amount, setAmount] = useState(BN_ZERO)
+ const { account, isFunding } = props
const [change, setChange] = useState()
- const max = props.isFunding
- ? getAmount(currentAsset.denom, balances ?? [])
- : props.account
- ? getAmount(currentAsset.denom, props.account.deposits)
- : BN_ZERO
-
- function onChangeAmount(val: BigNumber) {
- setAmount(val)
- setChange({
- deposits: [
- {
- amount: props.isFunding
- ? BN_ZERO.plus(amount).toString()
- : BN_ZERO.minus(amount).toString(),
- denom: currentAsset.denom,
- },
- ],
- })
- }
-
- function resetState() {
- setCurrentAsset(baseCurrency)
- setAmount(BN_ZERO)
- setChange(undefined)
- }
-
- async function onConfirm() {
- setIsConfirming(true)
- let result
- if (props.isFunding) {
- result = await deposit({
- fee: hardcodedFee,
- accountId: props.account.id,
- coins: [
- {
- denom: currentAsset.denom,
- amount: amount.toString(),
- },
- ],
- })
- } else {
- result = await withdraw({
- fee: hardcodedFee,
- accountId: props.account.id,
- coins: [
- {
- denom: currentAsset.denom,
- amount: amount.toString(),
- },
- ],
- })
- }
-
- setIsConfirming(false)
- if (result) {
- resetState()
- useStore.setState({ fundAndWithdrawModal: null })
- }
- }
-
return (
-
-
- }
- />
+ {isFunding ? (
+
+ ) : (
+
+ )}
-
+
)
}
diff --git a/src/components/Modals/FundWithdraw/WithdrawFromAccount.tsx b/src/components/Modals/FundWithdraw/WithdrawFromAccount.tsx
new file mode 100644
index 00000000..42eaa920
--- /dev/null
+++ b/src/components/Modals/FundWithdraw/WithdrawFromAccount.tsx
@@ -0,0 +1,129 @@
+import BigNumber from 'bignumber.js'
+import { useEffect, useState } from 'react'
+
+import Button from 'components/Button'
+import Divider from 'components/Divider'
+import { ArrowRight } from 'components/Icons'
+import Switch from 'components/Switch'
+import Text from 'components/Text'
+import TokenInputWithSlider from 'components/TokenInput/TokenInputWithSlider'
+import { ASSETS } from 'constants/assets'
+import { BN_ZERO } from 'constants/math'
+import useHealthComputer from 'hooks/useHealthComputer'
+import useToggle from 'hooks/useToggle'
+import { useUpdatedAccount } from 'hooks/useUpdatedAccount'
+import useStore from 'store'
+import { BNCoin } from 'types/classes/BNCoin'
+import { byDenom } from 'utils/array'
+import { hardcodedFee } from 'utils/constants'
+
+interface Props {
+ account: Account
+ setChange: (change: AccountChange | undefined) => void
+}
+
+export default function WithdrawFromAccount(props: Props) {
+ const { account, setChange } = props
+ const defaultAsset = ASSETS.find(byDenom(account.deposits[0].denom)) ?? ASSETS[0]
+ const withdraw = useStore((s) => s.withdraw)
+ const [withdrawWithBorrowing, setWithdrawWithBorrowing] = useToggle()
+ const [isConfirming, setIsConfirming] = useToggle()
+ const [currentAsset, setCurrentAsset] = useState(defaultAsset)
+ const [amount, setAmount] = useState(BN_ZERO)
+ const { updatedAccount, removeDepositByDenom } = useUpdatedAccount(account)
+ const { computeMaxWithdrawAmount } = useHealthComputer(account)
+ const { computeMaxBorrowAmount } = useHealthComputer(updatedAccount)
+ const maxWithdrawAmount = computeMaxWithdrawAmount(currentAsset.denom)
+ const maxWithdrawWithBorrowAmount = computeMaxBorrowAmount(currentAsset.denom, 'wallet').plus(
+ maxWithdrawAmount,
+ )
+ const isWithinBalance = amount.isLessThan(maxWithdrawAmount)
+ const depositAmount = BN_ZERO.minus(isWithinBalance ? amount : maxWithdrawAmount)
+ const debtAmount = isWithinBalance ? BN_ZERO : amount.minus(maxWithdrawAmount)
+ const max = withdrawWithBorrowing ? maxWithdrawWithBorrowAmount : maxWithdrawAmount
+
+ function onChangeAmount(val: BigNumber) {
+ setAmount(val)
+ setChange({
+ deposits: [
+ {
+ amount: depositAmount.toString(),
+ denom: currentAsset.denom,
+ },
+ ],
+ debts: [{ amount: debtAmount.toString(), denom: currentAsset.denom }],
+ })
+ }
+
+ function resetState() {
+ setCurrentAsset(defaultAsset)
+ setAmount(BN_ZERO)
+ setChange(undefined)
+ }
+
+ async function onConfirm() {
+ setIsConfirming(true)
+ const result = await withdraw({
+ fee: hardcodedFee,
+ accountId: account.id,
+ coins: [BNCoin.fromDenomAndBigNumber(currentAsset.denom, amount)],
+ borrow: debtAmount.isZero()
+ ? []
+ : [BNCoin.fromDenomAndBigNumber(currentAsset.denom, debtAmount)],
+ })
+
+ setIsConfirming(false)
+ if (result) {
+ resetState()
+ useStore.setState({ fundAndWithdrawModal: null })
+ }
+ }
+
+ useEffect(() => {
+ removeDepositByDenom(currentAsset.denom)
+ }, [currentAsset.denom, removeDepositByDenom])
+
+ return (
+ <>
+
+
1}
+ maxText='Max'
+ disabled={isConfirming}
+ />
+
+
+
+ Withdraw with borrowing
+
+ Borrow assets from your credit account to withdraw to your wallet
+
+
+
+
+
+
+
+ }
+ />
+ >
+ )
+}
diff --git a/src/components/Modals/Vault/VaultBorrowings.tsx b/src/components/Modals/Vault/VaultBorrowings.tsx
index 0a19a020..9781ecb0 100644
--- a/src/components/Modals/Vault/VaultBorrowings.tsx
+++ b/src/components/Modals/Vault/VaultBorrowings.tsx
@@ -157,8 +157,9 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) {
{props.borrowings.map((coin) => {
const asset = getAssetByDenom(coin.denom)
- const maxAmount = maxBorrowAmounts.find((maxAmount) => maxAmount.denom === coin.denom)
- ?.amount
+ const maxAmount = maxBorrowAmounts.find(
+ (maxAmount) => maxAmount.denom === coin.denom,
+ )?.amount
if (!asset || !maxAmount)
return
return (
diff --git a/src/components/Modals/Vault/VaultModalContent.tsx b/src/components/Modals/Vault/VaultModalContent.tsx
index 19e251de..a08e6881 100644
--- a/src/components/Modals/Vault/VaultModalContent.tsx
+++ b/src/components/Modals/Vault/VaultModalContent.tsx
@@ -1,4 +1,3 @@
-import BigNumber from 'bignumber.js'
import { useCallback, useEffect, useState } from 'react'
import Accordion from 'components/Accordion'
@@ -7,10 +6,10 @@ import VaultBorrowings from 'components/Modals/Vault/VaultBorrowings'
import VaultBorrowingsSubTitle from 'components/Modals/Vault/VaultBorrowingsSubTitle'
import VaultDeposit from 'components/Modals/Vault/VaultDeposits'
import VaultDepositSubTitle from 'components/Modals/Vault/VaultDepositsSubTitle'
-import useIsOpenArray from 'hooks/useIsOpenArray'
-import useDepositVault from 'hooks/broadcast/useDepositVault'
-import { useUpdatedAccount } from 'hooks/useUpdatedAccount'
import { BN_ZERO } from 'constants/math'
+import useDepositVault from 'hooks/broadcast/useDepositVault'
+import useIsOpenArray from 'hooks/useIsOpenArray'
+import { useUpdatedAccount } from 'hooks/useUpdatedAccount'
interface Props {
vault: Vault | DepositedVault
diff --git a/src/components/Select/Option.tsx b/src/components/Select/Option.tsx
index 8c1e316f..79f75c8e 100644
--- a/src/components/Select/Option.tsx
+++ b/src/components/Select/Option.tsx
@@ -75,9 +75,10 @@ export default function Option(props: Props) {
{formatValue(5, { maxDecimals: 2, minDecimals: 0, prefix: 'APY ', suffix: '%' })}
-
-
-
+
)
}
diff --git a/src/components/Slider.tsx b/src/components/Slider.tsx
index 07fd9bd7..6420d064 100644
--- a/src/components/Slider.tsx
+++ b/src/components/Slider.tsx
@@ -150,7 +150,7 @@ export default function Slider(props: Props) {
{(showTooltip || isDragging) && (
- {props.value}%
+ {props.value.toFixed(0)}%
)}
diff --git a/src/components/TokenInputWithSlider.tsx b/src/components/TokenInput/TokenInputWithSlider.tsx
similarity index 81%
rename from src/components/TokenInputWithSlider.tsx
rename to src/components/TokenInput/TokenInputWithSlider.tsx
index a713d4ec..16d6820d 100644
--- a/src/components/TokenInputWithSlider.tsx
+++ b/src/components/TokenInput/TokenInputWithSlider.tsx
@@ -1,10 +1,10 @@
import BigNumber from 'bignumber.js'
-import { useState } from 'react'
+import { useEffect, useState } from 'react'
import Slider from 'components/Slider'
import TokenInput from 'components/TokenInput'
-import { BN } from 'utils/helpers'
import { BN_ZERO } from 'constants/math'
+import { BN } from 'utils/helpers'
interface Props {
amount: BigNumber
@@ -44,6 +44,13 @@ export default function TokenInputWithSlider(props: Props) {
props.onChangeAsset(newAsset)
}
+ useEffect(() => {
+ const newAmount = props.amount.isLessThan(props.max) ? props.amount : props.max
+ const newPercentage = newAmount.dividedBy(props.max).multipliedBy(100).toNumber()
+ if (!amount.isEqualTo(newAmount)) setAmount(newAmount)
+ if (percentage !== newPercentage) setPercentage(newPercentage)
+ }, [props.max, props.amount, amount, percentage])
+
return (
{
if (!account?.vaults) return null
- return account.vaults.reduce(
- (prev, curr) => {
- const baseCoinPrice = prices.find((price) => price.denom === curr.denoms.lp)?.amount || 0
- prev[curr.address] = {
- base_coin: {
- amount: '0', // Not used by healthcomputer
- denom: curr.denoms.lp,
- value: curr.amounts.unlocking.times(baseCoinPrice).integerValue().toString(),
- },
- vault_coin: {
- amount: '0', // Not used by healthcomputer
- denom: curr.denoms.vault,
- value: curr.values.primary
- .div(baseCurrencyPrice)
- .plus(curr.values.secondary.div(baseCurrencyPrice))
- .integerValue()
- .toString(),
- },
- }
- return prev
- },
- {} as { [key: string]: VaultPositionValue },
- )
+ return account.vaults.reduce((prev, curr) => {
+ const baseCoinPrice = prices.find((price) => price.denom === curr.denoms.lp)?.amount || 0
+ prev[curr.address] = {
+ base_coin: {
+ amount: '0', // Not used by healthcomputer
+ denom: curr.denoms.lp,
+ value: curr.amounts.unlocking.times(baseCoinPrice).integerValue().toString(),
+ },
+ vault_coin: {
+ amount: '0', // Not used by healthcomputer
+ denom: curr.denoms.vault,
+ value: curr.values.primary
+ .div(baseCurrencyPrice)
+ .plus(curr.values.secondary.div(baseCurrencyPrice))
+ .integerValue()
+ .toString(),
+ },
+ }
+ return prev
+ }, {} as { [key: string]: VaultPositionValue })
}, [account?.vaults, prices, baseCurrencyPrice])
const priceData = useMemo(() => {
const baseCurrencyPrice =
prices.find((price) => price.denom === baseCurrency.denom)?.amount || 0
- return prices.reduce(
- (prev, curr) => {
- prev[curr.denom] = curr.amount.div(baseCurrencyPrice).decimalPlaces(18).toString()
- return prev
- },
- {} as { [key: string]: string },
- )
+ return prices.reduce((prev, curr) => {
+ prev[curr.denom] = curr.amount.div(baseCurrencyPrice).decimalPlaces(18).toString()
+ return prev
+ }, {} as { [key: string]: string })
}, [prices, baseCurrency.denom])
const denomsData = useMemo(
() =>
- assetParams.reduce(
- (prev, curr) => {
- const params: AssetParamsBaseForAddr = {
- ...curr,
- // The following overrides are required as testnet is 'broken' and new contracts are not updated yet
- // These overrides are not used by the healthcomputer internally, so they're not important anyways.
- protocol_liquidation_fee: '1',
- liquidation_bonus: {
- max_lb: '1',
- min_lb: '1',
- slope: '1',
- starting_lb: '1',
- },
- }
- prev[params.denom] = params
+ assetParams.reduce((prev, curr) => {
+ const params: AssetParamsBaseForAddr = {
+ ...curr,
+ // The following overrides are required as testnet is 'broken' and new contracts are not updated yet
+ // These overrides are not used by the healthcomputer internally, so they're not important anyways.
+ protocol_liquidation_fee: '1',
+ liquidation_bonus: {
+ max_lb: '1',
+ min_lb: '1',
+ slope: '1',
+ starting_lb: '1',
+ },
+ }
+ prev[params.denom] = params
- return prev
- },
- {} as { [key: string]: AssetParamsBaseForAddr },
- ),
+ return prev
+ }, {} as { [key: string]: AssetParamsBaseForAddr }),
[assetParams],
)
@@ -112,13 +103,10 @@ export default function useHealthComputer(account?: Account) {
const vaultPositionDenoms = positions.vaults.map((vault) => vault.vault.address)
return vaultConfigs
.filter((config) => vaultPositionDenoms.includes(config.addr))
- .reduce(
- (prev, curr) => {
- prev[curr.addr] = curr
- return prev
- },
- {} as { [key: string]: VaultConfigBaseForString },
- )
+ .reduce((prev, curr) => {
+ prev[curr.addr] = curr
+ return prev
+ }, {} as { [key: string]: VaultConfigBaseForString })
}, [vaultConfigs, positions])
const healthComputer: HealthComputer | null = useMemo(() => {
diff --git a/src/hooks/useUpdatedAccount/index.ts b/src/hooks/useUpdatedAccount/index.ts
index fa50d7b5..34be021d 100644
--- a/src/hooks/useUpdatedAccount/index.ts
+++ b/src/hooks/useUpdatedAccount/index.ts
@@ -1,7 +1,7 @@
-import { useEffect, useState } from 'react'
+import { useCallback, useEffect, useState } from 'react'
-import { BNCoin } from 'types/classes/BNCoin'
import { addCoins, addValueToVaults, removeCoins } from 'hooks/useUpdatedAccount/functions'
+import { BNCoin } from 'types/classes/BNCoin'
import { cloneAccount } from 'utils/accounts'
export interface VaultValue {
@@ -17,6 +17,16 @@ export function useUpdatedAccount(account: Account) {
const [removedDebt, removeDebt] = useState([])
const [addedVaultValues, addVaultValues] = useState([])
+ const removeDepositByDenom = useCallback(
+ (denom: string) => {
+ const deposit = account.deposits.find((deposit) => deposit.denom === denom)
+ if (deposit) {
+ removeDeposits([...removedDeposits, deposit])
+ }
+ },
+ [account, removedDeposits],
+ )
+
useEffect(() => {
async function updateAccount() {
const accountCopy = cloneAccount(account)
@@ -35,6 +45,7 @@ export function useUpdatedAccount(account: Account) {
updatedAccount,
addDeposits,
removeDeposits,
+ removeDepositByDenom,
addDebt,
removeDebt,
addVaultValues,
diff --git a/src/store/slices/broadcast.ts b/src/store/slices/broadcast.ts
index 34102f42..619b9cf8 100644
--- a/src/store/slices/broadcast.ts
+++ b/src/store/slices/broadcast.ts
@@ -147,24 +147,26 @@ export default function createBroadcastSlice(
return !!response.result
},
- deposit: async (options: { fee: StdFee; accountId: string; coins: Coin[] }) => {
+ deposit: async (options: { fee: StdFee; accountId: string; coins: BNCoin[] }) => {
const msg: CreditManagerExecuteMsg = {
update_credit_account: {
account_id: options.accountId,
actions: options.coins.map((coin) => ({
- deposit: coin,
+ deposit: coin.toCoin(),
})),
},
}
+ const funds = options.coins.map((coin) => coin.toCoin())
+
const response = await get().executeMsg({
- messages: [
- generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, options.coins),
- ],
+ messages: [generateExecutionMessage(get().address, ENV.ADDRESS_CREDIT_MANAGER, msg, funds)],
fee: options.fee,
})
- const depositString = options.coins.map((coin) => formatAmountWithSymbol(coin)).join('and ')
+ const depositString = options.coins
+ .map((coin) => formatAmountWithSymbol(coin.toCoin()))
+ .join('and ')
handleResponseMessages(response, `Deposited ${depositString} to Account ${options.accountId}`)
return !!response.result
},
@@ -247,13 +249,23 @@ export default function createBroadcastSlice(
handleResponseMessages(response, `Deposited into vault`)
return !!response.result
},
- withdraw: async (options: { fee: StdFee; accountId: string; coins: Coin[] }) => {
+ withdraw: async (options: {
+ fee: StdFee
+ accountId: string
+ coins: BNCoin[]
+ borrow: BNCoin[]
+ }) => {
+ const withdrawActions = options.coins.map((coin) => ({
+ withdraw: coin.toCoin(),
+ }))
+ const borrowActions = options.borrow.map((coin) => ({
+ borrow: coin.toCoin(),
+ }))
+
const msg: CreditManagerExecuteMsg = {
update_credit_account: {
account_id: options.accountId,
- actions: options.coins.map((coin) => ({
- withdraw: coin,
- })),
+ actions: [...borrowActions, ...withdrawActions],
},
}
@@ -262,7 +274,9 @@ export default function createBroadcastSlice(
fee: options.fee,
})
- const withdrawString = options.coins.map((coin) => formatAmountWithSymbol(coin)).join('and ')
+ const withdrawString = options.coins
+ .map((coin) => formatAmountWithSymbol(coin.toCoin()))
+ .join('and ')
handleResponseMessages(
response,
`Withdrew ${withdrawString} from Account ${options.accountId}`,
diff --git a/src/styles/globals.css b/src/styles/globals.css
index 3e611736..a6115bb5 100644
--- a/src/styles/globals.css
+++ b/src/styles/globals.css
@@ -4,8 +4,7 @@
@font-face {
font-family: Inter;
- src:
- url('../fonts/Inter-ExtraLight.woff2') format('woff2'),
+ src: url('../fonts/Inter-ExtraLight.woff2') format('woff2'),
url('../fonts/Inter-ExtraLight.woff') format('woff');
font-weight: 300;
font-style: normal;
@@ -14,8 +13,7 @@
@font-face {
font-family: Inter;
- src:
- url('../fonts/Inter-Regular.woff2') format('woff2'),
+ src: url('../fonts/Inter-Regular.woff2') format('woff2'),
url('../fonts/Inter-Regular.woff') format('woff');
font-weight: 400;
font-style: normal;
@@ -24,8 +22,7 @@
@font-face {
font-family: Inter;
- src:
- url('../fonts/Inter-SemiBold.woff2') format('woff2'),
+ src: url('../fonts/Inter-SemiBold.woff2') format('woff2'),
url('../fonts/Inter-SemiBold.woff') format('woff');
font-weight: 600;
font-style: normal;
diff --git a/src/types/interfaces/store/broadcast.d.ts b/src/types/interfaces/store/broadcast.d.ts
index fc719240..e952ec31 100644
--- a/src/types/interfaces/store/broadcast.d.ts
+++ b/src/types/interfaces/store/broadcast.d.ts
@@ -16,7 +16,7 @@ interface BroadcastSlice {
}) => Promise
createAccount: (options: { fee: StdFee }) => Promise
deleteAccount: (options: { fee: StdFee; accountId: string; lends: BNCoin[] }) => Promise
- deposit: (options: { fee: StdFee; accountId: string; coins: Coin[] }) => Promise
+ deposit: (options: { fee: StdFee; accountId: string; coins: BNCoin[] }) => Promise
unlock: (options: {
fee: StdFee
accountId: string
@@ -33,7 +33,12 @@ interface BroadcastSlice {
accountId: string
actions: Action[]
}) => Promise
- withdraw: (options: { fee: StdFee; accountId: string; coins: Coin[] }) => Promise
+ withdraw: (options: {
+ fee: StdFee
+ accountId: string
+ coins: BNCoin[]
+ borrow: BNCoin[]
+ }) => Promise
lend: (options: {
fee: StdFee
accountId: string
diff --git a/src/utils/accounts.ts b/src/utils/accounts.ts
index 47e5df0f..a0fe4b18 100644
--- a/src/utils/accounts.ts
+++ b/src/utils/accounts.ts
@@ -13,39 +13,34 @@ export const calculateAccountBalanceValue = (
account: Account | AccountChange,
prices: BNCoin[],
): BigNumber => {
- const totalDepositValue = calculateAccountDepositsValue(account, prices)
- const totalDebtValue = calculateAccountDebtValue(account, prices)
+ const depositsValue = calculateAccountValue('deposits', account, prices)
+ const lendsValue = calculateAccountValue('lends', account, prices)
+ const debtsValue = calculateAccountValue('debts', account, prices)
- return totalDepositValue.minus(totalDebtValue)
+ return depositsValue.plus(lendsValue).minus(debtsValue)
}
-export const calculateAccountDepositsValue = (
+export const getAccountPositionValues = (account: Account | AccountChange, prices: BNCoin[]) => {
+ const deposits = calculateAccountValue('deposits', account, prices)
+ const lends = calculateAccountValue('lends', account, prices)
+ const debts = calculateAccountValue('debts', account, prices)
+
+ return [deposits, lends, debts]
+}
+
+export const calculateAccountValue = (
+ type: 'deposits' | 'lends' | 'debts',
account: Account | AccountChange,
prices: BNCoin[],
): BigNumber => {
- if (!account.deposits) return BN_ZERO
- return account.deposits.reduce((acc, deposit) => {
- const asset = getAssetByDenom(deposit.denom)
+ if (!account[type]) return BN_ZERO
+ return account[type]?.reduce((acc, position) => {
+ const asset = getAssetByDenom(position.denom)
if (!asset) return acc
- const price = prices.find((price) => price.denom === deposit.denom)?.amount ?? 0
- const amount = BN(deposit.amount).shiftedBy(-asset.decimals)
- const depositValue = amount.multipliedBy(price)
- return acc.plus(depositValue)
- }, BN_ZERO)
-}
-
-export const calculateAccountDebtValue = (
- account: Account | AccountChange,
- prices: BNCoin[],
-): BigNumber => {
- if (!account.debts) return BN_ZERO
- return account.debts.reduce((acc, debt) => {
- const asset = getAssetByDenom(debt.denom)
- if (!asset) return acc
- const price = prices.find((price) => price.denom === debt.denom)?.amount ?? 0
- const debtAmount = BN(debt.amount).shiftedBy(-asset.decimals)
- const debtValue = debtAmount.multipliedBy(price)
- return acc.plus(debtValue)
+ const price = prices.find((price) => price.denom === position.denom)?.amount ?? 0
+ const amount = BN(position.amount).shiftedBy(-asset.decimals)
+ const positionValue = amount.multipliedBy(price)
+ return acc.plus(positionValue)
}, BN_ZERO)
}
@@ -105,7 +100,7 @@ export function convertAccountToPositions(account: Account): Positions {
],
},
},
- }) as VaultPosition,
+ } as VaultPosition),
),
}
}