[vault modal] add borrow max calcs (#337)
* [vault modal] add borrow max calcs * fixed test
This commit is contained in:
parent
1a55d8bd39
commit
103c8bed9a
@ -27,6 +27,8 @@ jest.mock('hooks/broadcast/useDepositVault', () => jest.fn(() => ({ actions: []
|
||||
|
||||
jest.mock('components/DisplayCurrency')
|
||||
|
||||
jest.mock('hooks/useHealthComputer', () => jest.fn(() => ({ computeMaxBorrowAmount: () => {} })))
|
||||
|
||||
const mockedDisplayCurrency = jest
|
||||
.mocked(DisplayCurrency)
|
||||
.mockImplementation(() => <div>Display currency</div>)
|
||||
|
@ -24,12 +24,15 @@ 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<SortingState>([{ id: 'symbol', desc: false }])
|
||||
const [selected, setSelected] = useState<RowSelectionState>(defaultSelected)
|
||||
|
@ -16,6 +16,7 @@ import { BNCoin } from 'types/classes/BNCoin'
|
||||
import { Action } from 'types/generated/mars-credit-manager/MarsCreditManager.types'
|
||||
import { findCoinByDenom, getAssetByDenom } from 'utils/assets'
|
||||
import { formatPercent } from 'utils/formatters'
|
||||
import useHealthComputer from 'hooks/useHealthComputer'
|
||||
|
||||
export interface VaultBorrowingsProps {
|
||||
updatedAccount: Account
|
||||
@ -36,7 +37,19 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) {
|
||||
const vaultModal = useStore((s) => s.vaultModal)
|
||||
const depositIntoVault = useStore((s) => s.depositIntoVault)
|
||||
const [isConfirming, setIsConfirming] = useState(false)
|
||||
const maxBorrowAmounts: BNCoin[] = []
|
||||
const { computeMaxBorrowAmount } = useHealthComputer(props.updatedAccount)
|
||||
|
||||
const maxBorrowAmounts: BNCoin[] = useMemo(() => {
|
||||
return props.borrowings.map((borrowing) => {
|
||||
const maxAmount = computeMaxBorrowAmount(borrowing.denom, {
|
||||
vault: { address: props.vault.address },
|
||||
})
|
||||
return new BNCoin({
|
||||
denom: borrowing.denom,
|
||||
amount: maxAmount.toString(),
|
||||
})
|
||||
})
|
||||
}, [props.borrowings, computeMaxBorrowAmount, props.vault.address])
|
||||
|
||||
const borrowingValue = useMemo(() => {
|
||||
return props.borrowings.reduce((prev, curr) => {
|
||||
@ -144,9 +157,8 @@ export default function VaultBorrowings(props: VaultBorrowingsProps) {
|
||||
<div className='flex flex-1 flex-col gap-4 p-4'>
|
||||
{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 <React.Fragment key={`input-${coin.denom}`}></React.Fragment>
|
||||
return (
|
||||
|
@ -43,57 +43,66 @@ export default function useHealthComputer(account?: Account) {
|
||||
|
||||
const vaultPositionValues = useMemo(() => {
|
||||
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],
|
||||
)
|
||||
|
||||
@ -103,10 +112,13 @@ 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(() => {
|
||||
|
@ -4,7 +4,8 @@
|
||||
|
||||
@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;
|
||||
@ -13,7 +14,8 @@
|
||||
|
||||
@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;
|
||||
@ -22,7 +24,8 @@
|
||||
|
||||
@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;
|
||||
|
@ -105,7 +105,7 @@ export function convertAccountToPositions(account: Account): Positions {
|
||||
],
|
||||
},
|
||||
},
|
||||
} as VaultPosition),
|
||||
}) as VaultPosition,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user