vaults: multiple bug fixes (#493)

* vaults: multiple bug fixes

* Update src/components/Account/AccountComposition.tsx

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>

* Update src/components/Account/AccountComposition.tsx

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>

* Update src/components/Portfolio/Account/Summary.tsx

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>

* Update src/components/Account/AccountComposition.tsx

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>

* Update src/components/Portfolio/Account/Summary.tsx

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>

---------

Co-authored-by: Linkie Link <linkielink.dev@gmail.com>
This commit is contained in:
Bob van der Helm 2023-09-20 19:05:17 +02:00 committed by GitHub
parent 5bf46d4da0
commit 653227921a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 59 additions and 16 deletions

View File

@ -134,7 +134,11 @@ function Item(props: ItemProps) {
{props.isPercentage ? (
<FormattedNumber
amount={current.toNumber()}
options={{ suffix: '%', minDecimals: 2, maxDecimals: MAX_AMOUNT_DECIMALS }}
options={{
suffix: '%',
minDecimals: 2,
maxDecimals: current.abs().isLessThan(0.1) ? MAX_AMOUNT_DECIMALS : 2,
}}
className='text-sm'
animate
/>
@ -152,7 +156,11 @@ function Item(props: ItemProps) {
{props.isPercentage ? (
<FormattedNumber
amount={change.toNumber()}
options={{ suffix: '%', minDecimals: 2, maxDecimals: MAX_AMOUNT_DECIMALS }}
options={{
suffix: '%',
minDecimals: 2,
maxDecimals: change.abs().isLessThan(0.1) ? MAX_AMOUNT_DECIMALS : 2,
}}
className={classNames('text-sm', increase ? 'text-profit' : 'text-loss')}
animate
/>

View File

@ -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<number>(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],

View File

@ -159,6 +159,7 @@ export default function VaultModalContent(props: Props) {
{
renderContent: () => (
<VaultBorrowings
account={props.account}
borrowings={borrowCoins}
deposits={deposits}
primaryAsset={props.primaryAsset}

View File

@ -74,7 +74,11 @@ function Content(props: Props) {
<FormattedNumber
className='text-xl'
amount={apr.toNumber()}
options={{ suffix: '%', maxDecimals: MAX_AMOUNT_DECIMALS, minDecimals: 2 }}
options={{
suffix: '%',
maxDecimals: apr.abs().isLessThan(0.1) ? MAX_AMOUNT_DECIMALS : 2,
minDecimals: 2,
}}
/>
),
sub: STATS[3].sub,

View File

@ -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(() => {

View File

@ -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)

View File

@ -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 | undefined>(
account ? cloneAccount(account) : undefined,
)
const [slippage] = useLocalStorage<number>(SLIPPAGE_KEY, DEFAULT_SETTINGS.slippage)
const [addedDeposits, addDeposits] = useState<BNCoin[]>([])
const [removedDeposits, removeDeposits] = useState<BNCoin[]>([])
const [addedDebts, addDebts] = useState<BNCoin[]>([])
@ -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(() => {

View File

@ -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

View File

@ -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) => {