From 653227921a7ed7b31a852e07eaa6b602c616034f Mon Sep 17 00:00:00 2001 From: Bob van der Helm <34470358+bobthebuidlr@users.noreply.github.com> Date: Wed, 20 Sep 2023 19:05:17 +0200 Subject: [PATCH] vaults: multiple bug fixes (#493) * vaults: multiple bug fixes * Update src/components/Account/AccountComposition.tsx Co-authored-by: Linkie Link * Update src/components/Account/AccountComposition.tsx Co-authored-by: Linkie Link * Update src/components/Portfolio/Account/Summary.tsx Co-authored-by: Linkie Link * Update src/components/Account/AccountComposition.tsx Co-authored-by: Linkie Link * Update src/components/Portfolio/Account/Summary.tsx Co-authored-by: Linkie Link --------- Co-authored-by: Linkie Link --- src/components/Account/AccountComposition.tsx | 12 ++++++++-- .../Modals/Vault/VaultBorrowings.tsx | 22 +++++++++++++++++-- .../Modals/Vault/VaultModalContent.tsx | 1 + src/components/Portfolio/Account/Summary.tsx | 6 ++++- src/hooks/broadcast/useDepositVault.ts | 4 ++-- src/hooks/useHealthComputer.tsx | 2 +- src/hooks/useUpdatedAccount/index.ts | 10 +++++++-- src/utils/constants.ts | 4 ++-- src/utils/vaults.ts | 14 ++++++++---- 9 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/components/Account/AccountComposition.tsx b/src/components/Account/AccountComposition.tsx index fa21b068..e24b6522 100644 --- a/src/components/Account/AccountComposition.tsx +++ b/src/components/Account/AccountComposition.tsx @@ -134,7 +134,11 @@ function Item(props: ItemProps) { {props.isPercentage ? ( @@ -152,7 +156,11 @@ function Item(props: ItemProps) { {props.isPercentage ? ( diff --git a/src/components/Modals/Vault/VaultBorrowings.tsx b/src/components/Modals/Vault/VaultBorrowings.tsx index 9b3bf393..24ada740 100644 --- a/src/components/Modals/Vault/VaultBorrowings.tsx +++ b/src/components/Modals/Vault/VaultBorrowings.tsx @@ -23,6 +23,7 @@ import { formatPercent } from 'utils/formatters' import { getValueFromBNCoins, mergeBNCoinArrays } from 'utils/helpers' export interface VaultBorrowingsProps { + account: Account borrowings: BNCoin[] deposits: BNCoin[] primaryAsset: Asset @@ -41,7 +42,7 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) { const vaultModal = useStore((s) => s.vaultModal) const depositIntoVault = useStore((s) => s.depositIntoVault) const updatedAccount = useStore((s) => s.updatedAccount) - const { computeMaxBorrowAmount } = useHealthComputer(updatedAccount) + const { computeMaxBorrowAmount } = useHealthComputer(props.account) const [percentage, setPercentage] = useState(0) const calculateSliderPercentage = (maxBorrowAmounts: BNCoin[], borrowings: BNCoin[]) => { @@ -54,7 +55,7 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) { return 0 } - const maxBorrowAmounts: BNCoin[] = useMemo(() => { + const maxBorrowAmountsRaw: BNCoin[] = useMemo(() => { return props.borrowings.map((borrowing) => { const maxAmount = computeMaxBorrowAmount(borrowing.denom, { vault: { address: props.vault.address }, @@ -66,6 +67,23 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) { }) }, [props.borrowings, computeMaxBorrowAmount, props.vault.address]) + const maxBorrowAmounts = useMemo(() => { + const borrowPowerLeft = props.borrowings.reduce((capLeft, borrowing) => { + const maxAmount = maxBorrowAmountsRaw.find((amount) => amount.denom === borrowing.denom) + + if (!maxAmount) return capLeft + capLeft -= borrowing.amount.dividedBy(maxAmount.amount).toNumber() + return capLeft + }, 1) + + return maxBorrowAmountsRaw.map((maxAmount) => { + return new BNCoin({ + denom: maxAmount.denom, + amount: maxAmount.amount.times(borrowPowerLeft).integerValue().toString(), + }) + }) + }, [maxBorrowAmountsRaw, props.borrowings]) + const totalValue = useMemo( () => getValueFromBNCoins(mergeBNCoinArrays(props.deposits, props.borrowings), prices), [props.borrowings, props.deposits, prices], diff --git a/src/components/Modals/Vault/VaultModalContent.tsx b/src/components/Modals/Vault/VaultModalContent.tsx index 60482286..e70f84c4 100644 --- a/src/components/Modals/Vault/VaultModalContent.tsx +++ b/src/components/Modals/Vault/VaultModalContent.tsx @@ -159,6 +159,7 @@ export default function VaultModalContent(props: Props) { { renderContent: () => ( ), sub: STATS[3].sub, diff --git a/src/hooks/broadcast/useDepositVault.ts b/src/hooks/broadcast/useDepositVault.ts index d406786c..360748be 100644 --- a/src/hooks/broadcast/useDepositVault.ts +++ b/src/hooks/broadcast/useDepositVault.ts @@ -61,8 +61,8 @@ export default function useDepositVault(props: Props): { }, [borrowings]) const swapActions: Action[] = useMemo( - () => getVaultSwapActions(props.vault, deposits, borrowings, prices, slippage, totalValue), - [totalValue, prices, props.vault, deposits, borrowings, slippage], + () => getVaultSwapActions(props.vault, deposits, reclaims, borrowings, prices, slippage), + [props.vault, deposits, reclaims, borrowings, prices, slippage], ) const enterVaultActions: Action[] = useMemo(() => { diff --git a/src/hooks/useHealthComputer.tsx b/src/hooks/useHealthComputer.tsx index 63aaa447..4c7e6571 100644 --- a/src/hooks/useHealthComputer.tsx +++ b/src/hooks/useHealthComputer.tsx @@ -147,7 +147,7 @@ export default function useHealthComputer(account?: Account) { if (!healthComputer) return BN_ZERO try { return BN(max_borrow_estimate_js(healthComputer, denom, target)) - .multipliedBy(1 - LTV_BUFFER) + .multipliedBy(LTV_BUFFER) .integerValue() } catch (err) { console.error(err) diff --git a/src/hooks/useUpdatedAccount/index.ts b/src/hooks/useUpdatedAccount/index.ts index 0b5a22ef..1468b0d5 100644 --- a/src/hooks/useUpdatedAccount/index.ts +++ b/src/hooks/useUpdatedAccount/index.ts @@ -15,6 +15,10 @@ import { cloneAccount } from 'utils/accounts' import { byDenom } from 'utils/array' import { getValueFromBNCoins } from 'utils/helpers' +import { DEFAULT_SETTINGS } from '../../constants/defaultSettings' +import { SLIPPAGE_KEY } from '../../constants/localStore' +import useLocalStorage from '../useLocalStorage' + export interface VaultValue { address: string value: BigNumber @@ -26,6 +30,7 @@ export function useUpdatedAccount(account?: Account) { const [updatedAccount, setUpdatedAccount] = useState( account ? cloneAccount(account) : undefined, ) + const [slippage] = useLocalStorage(SLIPPAGE_KEY, DEFAULT_SETTINGS.slippage) const [addedDeposits, addDeposits] = useState([]) const [removedDeposits, removeDeposits] = useState([]) const [addedDebts, addDebts] = useState([]) @@ -164,10 +169,11 @@ export function useUpdatedAccount(account?: Account) { removeLends(totalLends) addDebts(borrowCoins) - const value = getValueFromBNCoins([...coins, ...borrowCoins], prices) + // Value has to be adjusted for slippage + const value = getValueFromBNCoins([...coins, ...borrowCoins], prices).times(1 - slippage) addVaultValues([{ address, value }]) }, - [account, prices], + [account, prices, slippage], ) useEffect(() => { diff --git a/src/utils/constants.ts b/src/utils/constants.ts index dc5add87..8fe9fe8e 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -10,7 +10,7 @@ export const defaultFee: StdFee = { export const SECONDS_IN_A_YEAR = 31540000 -export const LTV_BUFFER = 0.01 +export const LTV_BUFFER = 0.99 export const DEPOSIT_CAP_BUFFER = 0.999 -export const VAULT_DEPOSIT_BUFFER = 0.9999 +export const VAULT_DEPOSIT_BUFFER = 0.999 diff --git a/src/utils/vaults.ts b/src/utils/vaults.ts index d7d31d34..cc7b69ba 100644 --- a/src/utils/vaults.ts +++ b/src/utils/vaults.ts @@ -5,6 +5,7 @@ import { TESTNET_VAULTS_META_DATA, VAULTS_META_DATA } from 'constants/vaults' import { BNCoin } from 'types/classes/BNCoin' import { Action, Uint128 } from 'types/generated/mars-credit-manager/MarsCreditManager.types' import { getAssetByDenom } from 'utils/assets' +import { VAULT_DEPOSIT_BUFFER } from 'utils/constants' import { getCoinAmount, getCoinValue } from 'utils/formatters' import { getValueFromBNCoins, mergeBNCoinArrays } from 'utils/helpers' import { getTokenPrice } from 'utils/tokens' @@ -39,14 +40,17 @@ export function getVaultDepositCoinsAndValue( const primaryAsset = getAssetByDenom(vault.denoms.primary) ?? ASSETS[0] const secondaryAsset = getAssetByDenom(vault.denoms.secondary) ?? ASSETS[0] + // The buffer is needed as sometimes the pools are a bit skew, or because of other inaccuracies in the messages const primaryDepositAmount = halfValue .dividedBy(getTokenPrice(primaryAsset.denom, prices)) .shiftedBy(primaryAsset.decimals) + .times(VAULT_DEPOSIT_BUFFER) .integerValue() const secondaryDepositAmount = halfValue .dividedBy(getTokenPrice(secondaryAsset.denom, prices)) .shiftedBy(secondaryAsset.decimals) + .times(VAULT_DEPOSIT_BUFFER) .integerValue() return { @@ -65,16 +69,18 @@ export function getVaultDepositCoinsAndValue( export function getVaultSwapActions( vault: Vault, deposits: BNCoin[], + reclaims: BNCoin[], borrowings: BNCoin[], prices: BNCoin[], slippage: number, - totalValue: BigNumber, ): Action[] { const swapActions: Action[] = [] - const coins = [...deposits, ...borrowings] + const coins = [...deposits, ...borrowings, ...reclaims] - let primaryLeftoverValue = totalValue.dividedBy(2) - let secondaryLeftoverValue = totalValue.dividedBy(2) + const value = getValueFromBNCoins(coins, prices) + + let primaryLeftoverValue = value.dividedBy(2) + let secondaryLeftoverValue = value.dividedBy(2) const [primaryCoins, secondaryCoins, otherCoins] = coins.reduce( (prev, bnCoin) => {