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:
parent
5bf46d4da0
commit
653227921a
@ -134,7 +134,11 @@ function Item(props: ItemProps) {
|
|||||||
{props.isPercentage ? (
|
{props.isPercentage ? (
|
||||||
<FormattedNumber
|
<FormattedNumber
|
||||||
amount={current.toNumber()}
|
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'
|
className='text-sm'
|
||||||
animate
|
animate
|
||||||
/>
|
/>
|
||||||
@ -152,7 +156,11 @@ function Item(props: ItemProps) {
|
|||||||
{props.isPercentage ? (
|
{props.isPercentage ? (
|
||||||
<FormattedNumber
|
<FormattedNumber
|
||||||
amount={change.toNumber()}
|
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')}
|
className={classNames('text-sm', increase ? 'text-profit' : 'text-loss')}
|
||||||
animate
|
animate
|
||||||
/>
|
/>
|
||||||
|
@ -23,6 +23,7 @@ import { formatPercent } from 'utils/formatters'
|
|||||||
import { getValueFromBNCoins, mergeBNCoinArrays } from 'utils/helpers'
|
import { getValueFromBNCoins, mergeBNCoinArrays } from 'utils/helpers'
|
||||||
|
|
||||||
export interface VaultBorrowingsProps {
|
export interface VaultBorrowingsProps {
|
||||||
|
account: Account
|
||||||
borrowings: BNCoin[]
|
borrowings: BNCoin[]
|
||||||
deposits: BNCoin[]
|
deposits: BNCoin[]
|
||||||
primaryAsset: Asset
|
primaryAsset: Asset
|
||||||
@ -41,7 +42,7 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) {
|
|||||||
const vaultModal = useStore((s) => s.vaultModal)
|
const vaultModal = useStore((s) => s.vaultModal)
|
||||||
const depositIntoVault = useStore((s) => s.depositIntoVault)
|
const depositIntoVault = useStore((s) => s.depositIntoVault)
|
||||||
const updatedAccount = useStore((s) => s.updatedAccount)
|
const updatedAccount = useStore((s) => s.updatedAccount)
|
||||||
const { computeMaxBorrowAmount } = useHealthComputer(updatedAccount)
|
const { computeMaxBorrowAmount } = useHealthComputer(props.account)
|
||||||
const [percentage, setPercentage] = useState<number>(0)
|
const [percentage, setPercentage] = useState<number>(0)
|
||||||
|
|
||||||
const calculateSliderPercentage = (maxBorrowAmounts: BNCoin[], borrowings: BNCoin[]) => {
|
const calculateSliderPercentage = (maxBorrowAmounts: BNCoin[], borrowings: BNCoin[]) => {
|
||||||
@ -54,7 +55,7 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const maxBorrowAmounts: BNCoin[] = useMemo(() => {
|
const maxBorrowAmountsRaw: BNCoin[] = useMemo(() => {
|
||||||
return props.borrowings.map((borrowing) => {
|
return props.borrowings.map((borrowing) => {
|
||||||
const maxAmount = computeMaxBorrowAmount(borrowing.denom, {
|
const maxAmount = computeMaxBorrowAmount(borrowing.denom, {
|
||||||
vault: { address: props.vault.address },
|
vault: { address: props.vault.address },
|
||||||
@ -66,6 +67,23 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) {
|
|||||||
})
|
})
|
||||||
}, [props.borrowings, computeMaxBorrowAmount, props.vault.address])
|
}, [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(
|
const totalValue = useMemo(
|
||||||
() => getValueFromBNCoins(mergeBNCoinArrays(props.deposits, props.borrowings), prices),
|
() => getValueFromBNCoins(mergeBNCoinArrays(props.deposits, props.borrowings), prices),
|
||||||
[props.borrowings, props.deposits, prices],
|
[props.borrowings, props.deposits, prices],
|
||||||
|
@ -159,6 +159,7 @@ export default function VaultModalContent(props: Props) {
|
|||||||
{
|
{
|
||||||
renderContent: () => (
|
renderContent: () => (
|
||||||
<VaultBorrowings
|
<VaultBorrowings
|
||||||
|
account={props.account}
|
||||||
borrowings={borrowCoins}
|
borrowings={borrowCoins}
|
||||||
deposits={deposits}
|
deposits={deposits}
|
||||||
primaryAsset={props.primaryAsset}
|
primaryAsset={props.primaryAsset}
|
||||||
|
@ -74,7 +74,11 @@ function Content(props: Props) {
|
|||||||
<FormattedNumber
|
<FormattedNumber
|
||||||
className='text-xl'
|
className='text-xl'
|
||||||
amount={apr.toNumber()}
|
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,
|
sub: STATS[3].sub,
|
||||||
|
@ -61,8 +61,8 @@ export default function useDepositVault(props: Props): {
|
|||||||
}, [borrowings])
|
}, [borrowings])
|
||||||
|
|
||||||
const swapActions: Action[] = useMemo(
|
const swapActions: Action[] = useMemo(
|
||||||
() => getVaultSwapActions(props.vault, deposits, borrowings, prices, slippage, totalValue),
|
() => getVaultSwapActions(props.vault, deposits, reclaims, borrowings, prices, slippage),
|
||||||
[totalValue, prices, props.vault, deposits, borrowings, slippage],
|
[props.vault, deposits, reclaims, borrowings, prices, slippage],
|
||||||
)
|
)
|
||||||
|
|
||||||
const enterVaultActions: Action[] = useMemo(() => {
|
const enterVaultActions: Action[] = useMemo(() => {
|
||||||
|
@ -147,7 +147,7 @@ export default function useHealthComputer(account?: Account) {
|
|||||||
if (!healthComputer) return BN_ZERO
|
if (!healthComputer) return BN_ZERO
|
||||||
try {
|
try {
|
||||||
return BN(max_borrow_estimate_js(healthComputer, denom, target))
|
return BN(max_borrow_estimate_js(healthComputer, denom, target))
|
||||||
.multipliedBy(1 - LTV_BUFFER)
|
.multipliedBy(LTV_BUFFER)
|
||||||
.integerValue()
|
.integerValue()
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
|
@ -15,6 +15,10 @@ import { cloneAccount } from 'utils/accounts'
|
|||||||
import { byDenom } from 'utils/array'
|
import { byDenom } from 'utils/array'
|
||||||
import { getValueFromBNCoins } from 'utils/helpers'
|
import { getValueFromBNCoins } from 'utils/helpers'
|
||||||
|
|
||||||
|
import { DEFAULT_SETTINGS } from '../../constants/defaultSettings'
|
||||||
|
import { SLIPPAGE_KEY } from '../../constants/localStore'
|
||||||
|
import useLocalStorage from '../useLocalStorage'
|
||||||
|
|
||||||
export interface VaultValue {
|
export interface VaultValue {
|
||||||
address: string
|
address: string
|
||||||
value: BigNumber
|
value: BigNumber
|
||||||
@ -26,6 +30,7 @@ export function useUpdatedAccount(account?: Account) {
|
|||||||
const [updatedAccount, setUpdatedAccount] = useState<Account | undefined>(
|
const [updatedAccount, setUpdatedAccount] = useState<Account | undefined>(
|
||||||
account ? cloneAccount(account) : undefined,
|
account ? cloneAccount(account) : undefined,
|
||||||
)
|
)
|
||||||
|
const [slippage] = useLocalStorage<number>(SLIPPAGE_KEY, DEFAULT_SETTINGS.slippage)
|
||||||
const [addedDeposits, addDeposits] = useState<BNCoin[]>([])
|
const [addedDeposits, addDeposits] = useState<BNCoin[]>([])
|
||||||
const [removedDeposits, removeDeposits] = useState<BNCoin[]>([])
|
const [removedDeposits, removeDeposits] = useState<BNCoin[]>([])
|
||||||
const [addedDebts, addDebts] = useState<BNCoin[]>([])
|
const [addedDebts, addDebts] = useState<BNCoin[]>([])
|
||||||
@ -164,10 +169,11 @@ export function useUpdatedAccount(account?: Account) {
|
|||||||
removeLends(totalLends)
|
removeLends(totalLends)
|
||||||
addDebts(borrowCoins)
|
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 }])
|
addVaultValues([{ address, value }])
|
||||||
},
|
},
|
||||||
[account, prices],
|
[account, prices, slippage],
|
||||||
)
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -10,7 +10,7 @@ export const defaultFee: StdFee = {
|
|||||||
|
|
||||||
export const SECONDS_IN_A_YEAR = 31540000
|
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 DEPOSIT_CAP_BUFFER = 0.999
|
||||||
export const VAULT_DEPOSIT_BUFFER = 0.9999
|
export const VAULT_DEPOSIT_BUFFER = 0.999
|
||||||
|
@ -5,6 +5,7 @@ import { TESTNET_VAULTS_META_DATA, VAULTS_META_DATA } from 'constants/vaults'
|
|||||||
import { BNCoin } from 'types/classes/BNCoin'
|
import { BNCoin } from 'types/classes/BNCoin'
|
||||||
import { Action, Uint128 } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
import { Action, Uint128 } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||||
import { getAssetByDenom } from 'utils/assets'
|
import { getAssetByDenom } from 'utils/assets'
|
||||||
|
import { VAULT_DEPOSIT_BUFFER } from 'utils/constants'
|
||||||
import { getCoinAmount, getCoinValue } from 'utils/formatters'
|
import { getCoinAmount, getCoinValue } from 'utils/formatters'
|
||||||
import { getValueFromBNCoins, mergeBNCoinArrays } from 'utils/helpers'
|
import { getValueFromBNCoins, mergeBNCoinArrays } from 'utils/helpers'
|
||||||
import { getTokenPrice } from 'utils/tokens'
|
import { getTokenPrice } from 'utils/tokens'
|
||||||
@ -39,14 +40,17 @@ export function getVaultDepositCoinsAndValue(
|
|||||||
const primaryAsset = getAssetByDenom(vault.denoms.primary) ?? ASSETS[0]
|
const primaryAsset = getAssetByDenom(vault.denoms.primary) ?? ASSETS[0]
|
||||||
const secondaryAsset = getAssetByDenom(vault.denoms.secondary) ?? 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
|
const primaryDepositAmount = halfValue
|
||||||
.dividedBy(getTokenPrice(primaryAsset.denom, prices))
|
.dividedBy(getTokenPrice(primaryAsset.denom, prices))
|
||||||
.shiftedBy(primaryAsset.decimals)
|
.shiftedBy(primaryAsset.decimals)
|
||||||
|
.times(VAULT_DEPOSIT_BUFFER)
|
||||||
.integerValue()
|
.integerValue()
|
||||||
|
|
||||||
const secondaryDepositAmount = halfValue
|
const secondaryDepositAmount = halfValue
|
||||||
.dividedBy(getTokenPrice(secondaryAsset.denom, prices))
|
.dividedBy(getTokenPrice(secondaryAsset.denom, prices))
|
||||||
.shiftedBy(secondaryAsset.decimals)
|
.shiftedBy(secondaryAsset.decimals)
|
||||||
|
.times(VAULT_DEPOSIT_BUFFER)
|
||||||
.integerValue()
|
.integerValue()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -65,16 +69,18 @@ export function getVaultDepositCoinsAndValue(
|
|||||||
export function getVaultSwapActions(
|
export function getVaultSwapActions(
|
||||||
vault: Vault,
|
vault: Vault,
|
||||||
deposits: BNCoin[],
|
deposits: BNCoin[],
|
||||||
|
reclaims: BNCoin[],
|
||||||
borrowings: BNCoin[],
|
borrowings: BNCoin[],
|
||||||
prices: BNCoin[],
|
prices: BNCoin[],
|
||||||
slippage: number,
|
slippage: number,
|
||||||
totalValue: BigNumber,
|
|
||||||
): Action[] {
|
): Action[] {
|
||||||
const swapActions: Action[] = []
|
const swapActions: Action[] = []
|
||||||
const coins = [...deposits, ...borrowings]
|
const coins = [...deposits, ...borrowings, ...reclaims]
|
||||||
|
|
||||||
let primaryLeftoverValue = totalValue.dividedBy(2)
|
const value = getValueFromBNCoins(coins, prices)
|
||||||
let secondaryLeftoverValue = totalValue.dividedBy(2)
|
|
||||||
|
let primaryLeftoverValue = value.dividedBy(2)
|
||||||
|
let secondaryLeftoverValue = value.dividedBy(2)
|
||||||
|
|
||||||
const [primaryCoins, secondaryCoins, otherCoins] = coins.reduce(
|
const [primaryCoins, secondaryCoins, otherCoins] = coins.reduce(
|
||||||
(prev, bnCoin) => {
|
(prev, bnCoin) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user