feat: ltv and health factor
This commit is contained in:
parent
d5fab229af
commit
dbf08a5729
|
@ -77,7 +77,7 @@ export const BorrowInput = (props: {
|
|||
|
||||
// TODO: select exsisting obligations by collateral reserve
|
||||
userObligationsByReserve.length > 0
|
||||
? userObligationsByReserve[0].obligation
|
||||
? userObligationsByReserve[0].obligation.account
|
||||
: undefined,
|
||||
|
||||
userObligationsByReserve.length > 0
|
||||
|
|
|
@ -4,7 +4,8 @@ import React, { useCallback } from "react";
|
|||
import { useState } from "react";
|
||||
import { LABELS } from "../../constants";
|
||||
import { ParsedAccount } from "../../contexts/accounts";
|
||||
import { LendingObligation, LendingReserve } from "../../models";
|
||||
import { EnrichedLendingObligation } from "../../hooks";
|
||||
import { LendingReserve } from "../../models";
|
||||
import { BackButton } from "../BackButton";
|
||||
import { CollateralSelector } from "../CollateralSelector";
|
||||
import "./style.less";
|
||||
|
@ -13,7 +14,7 @@ export const LiquidateInput = (props: {
|
|||
className?: string;
|
||||
reserve: ParsedAccount<LendingReserve>;
|
||||
collateralReserve?: ParsedAccount<LendingReserve>;
|
||||
obligation: ParsedAccount<LendingObligation>;
|
||||
obligation: EnrichedLendingObligation;
|
||||
}) => {
|
||||
|
||||
const { reserve, collateralReserve } = props;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React, { useCallback, useState } from "react";
|
||||
import { InputType, useAccountByMint, useSliderInput, useTokenName, useUserBalance } from "../../hooks";
|
||||
import { EnrichedLendingObligation, InputType, useAccountByMint, useSliderInput, useTokenName, useUserBalance } from "../../hooks";
|
||||
import {
|
||||
LendingObligation,
|
||||
LendingReserve,
|
||||
} from "../../models";
|
||||
import { TokenIcon } from "../TokenIcon";
|
||||
|
@ -22,7 +21,7 @@ export const RepayInput = (props: {
|
|||
className?: string;
|
||||
borrowReserve: ParsedAccount<LendingReserve>;
|
||||
collateralReserve?: ParsedAccount<LendingReserve>;
|
||||
obligation: ParsedAccount<LendingObligation>;
|
||||
obligation: EnrichedLendingObligation;
|
||||
}) => {
|
||||
const connection = useConnection();
|
||||
const { wallet } = useWallet();
|
||||
|
@ -82,7 +81,7 @@ export const RepayInput = (props: {
|
|||
await repay(
|
||||
fromAccounts[0],
|
||||
toRepayLamports,
|
||||
obligation,
|
||||
obligation.account,
|
||||
obligationAccount,
|
||||
repayReserve,
|
||||
collateralReserve,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React, { useCallback, useContext, useEffect, useState } from "react";
|
||||
import { MINT_TO_MARKET } from "./../models/marketOverrides";
|
||||
import { STABLE_COINS } from "./../utils/utils";
|
||||
import { fromLamports, STABLE_COINS } from "./../utils/utils";
|
||||
import { useConnectionConfig } from "./connection";
|
||||
import { cache, getMultipleAccounts, ParsedAccount } from "./accounts";
|
||||
import { Market, MARKETS, Orderbook, TOKEN_MINTS } from "@project-serum/serum";
|
||||
|
@ -249,8 +249,14 @@ export const usePrecacheMarket = () => {
|
|||
return context.precacheMarkets;
|
||||
};
|
||||
|
||||
export const simulateMarketOrderFill = (amount: number, reserve: LendingReserve) => {
|
||||
const marketInfo = cache.get(reserve?.dexMarket);
|
||||
export const simulateMarketOrderFill = (amount: number, reserve: LendingReserve, dex: PublicKey) => {
|
||||
const liquidityMint = cache.get(reserve.liquidityMint);
|
||||
const collateralMint = cache.get(reserve.collateralMint);
|
||||
if (!liquidityMint || !collateralMint) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
const marketInfo = cache.get(dex);
|
||||
if (!marketInfo) {
|
||||
return 0.0;
|
||||
}
|
||||
|
@ -287,13 +293,20 @@ export const simulateMarketOrderFill = (amount: number, reserve: LendingReserve)
|
|||
const book = new Orderbook(dexMarket, bookInfo.accountFlags, bookInfo.slab);
|
||||
|
||||
let cost = 0;
|
||||
let remaining = amount;
|
||||
let remaining = fromLamports(amount, liquidityMint.info);
|
||||
|
||||
if (book) {
|
||||
for (const level of book) {
|
||||
let size = remaining > level.size ? level.size : level.size - remaining;
|
||||
cost = cost + level.price * size;
|
||||
remaining = remaining - size;
|
||||
const depth = book.getL2(1000);
|
||||
let price, sizeAtLevel: number;
|
||||
|
||||
const op = book.isBids ?
|
||||
(price: number, size: number) => size / price :
|
||||
(price: number, size: number) => size * price;
|
||||
|
||||
for ([price, sizeAtLevel] of depth) {
|
||||
let filled = remaining > sizeAtLevel ? sizeAtLevel : remaining;
|
||||
cost = cost + op(price, filled);
|
||||
remaining = remaining - filled;
|
||||
|
||||
if (remaining <= 0) {
|
||||
break;
|
||||
|
|
|
@ -10,4 +10,4 @@ export * from "./useUserObligationByReserve";
|
|||
export * from "./useBorrowedAmount";
|
||||
export * from "./useUserDeposits";
|
||||
export * from "./useSliderInput";
|
||||
export * from "./useLiquidableObligations";
|
||||
export * from "./useEnrichedLendingObligations";
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
import { PublicKey } from "@solana/web3.js";
|
||||
import { useMemo } from "react";
|
||||
import { cache, ParsedAccount } from "./../contexts/accounts";
|
||||
import { useLendingObligations } from "./useLendingObligations";
|
||||
import { collateralToLiquidity, LendingObligation, LendingReserve } from "../models/lending";
|
||||
import { useLendingReserves } from "./useLendingReserves";
|
||||
import { fromLamports, wadToLamports } from "../utils/utils";
|
||||
import { MintInfo } from "@solana/spl-token";
|
||||
import { simulateMarketOrderFill } from "../contexts/market";
|
||||
|
||||
interface EnrichedLendingObligationInfo extends LendingObligation {
|
||||
ltv: number;
|
||||
health: number
|
||||
}
|
||||
|
||||
export interface EnrichedLendingObligation {
|
||||
account: ParsedAccount<LendingObligation>;
|
||||
info: EnrichedLendingObligationInfo;
|
||||
}
|
||||
|
||||
export function useEnrichedLendingObligations() {
|
||||
const { obligations } = useLendingObligations();
|
||||
const { reserveAccounts } = useLendingReserves();
|
||||
|
||||
const availableReserves = useMemo(() => {
|
||||
return reserveAccounts.reduce((map, reserve) => {
|
||||
map.set(reserve.pubkey.toBase58(), reserve);
|
||||
return map;
|
||||
}, new Map<string, ParsedAccount<LendingReserve>>())
|
||||
}, [reserveAccounts]);
|
||||
|
||||
// TODO: subscribe to market updates
|
||||
|
||||
const enrichedObligations = useMemo(() => {
|
||||
if (availableReserves.size === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return obligations
|
||||
.map(obligation => (
|
||||
{
|
||||
obligation,
|
||||
reserve: availableReserves.get(obligation.info.borrowReserve.toBase58()) as ParsedAccount<LendingReserve>,
|
||||
collateralReserve: availableReserves.get(obligation.info.collateralReserve.toBase58()) as ParsedAccount<LendingReserve>
|
||||
}
|
||||
))
|
||||
// use obligations with reserves available
|
||||
.filter(item => item.reserve)
|
||||
// use reserves with borrow amount greater than zero
|
||||
.filter(item => wadToLamports(item.obligation.info.borrowAmountWad).toNumber() > 0)
|
||||
.map(item => {
|
||||
const obligation = item.obligation;
|
||||
const reserve = item.reserve.info;
|
||||
const liquidityMint = cache.get(reserve.liquidityMint) as ParsedAccount<MintInfo>;
|
||||
let ltv = 0;
|
||||
|
||||
if(liquidityMint) {
|
||||
const collateral = fromLamports(
|
||||
collateralToLiquidity(obligation.info.depositedCollateral, item.reserve.info),
|
||||
cache.get(item.collateralReserve.info.liquidityMint)?.info);
|
||||
|
||||
const borrowed = wadToLamports(obligation.info.borrowAmountWad).toNumber();
|
||||
|
||||
const borrowedAmount = simulateMarketOrderFill(
|
||||
borrowed,
|
||||
item.reserve.info,
|
||||
item.reserve.info.dexMarketOption ? item.reserve.info.dexMarket : item.collateralReserve.info.dexMarket
|
||||
);
|
||||
|
||||
ltv = 100 * collateral / borrowedAmount;
|
||||
}
|
||||
|
||||
const liquidationThreshold = item.reserve.info.config.liquidationThreshold;
|
||||
const health = ltv / liquidationThreshold
|
||||
return {
|
||||
account: obligation,
|
||||
info: {
|
||||
...obligation.info,
|
||||
ltv,
|
||||
health,
|
||||
}
|
||||
} as EnrichedLendingObligation;
|
||||
})
|
||||
.sort((a, b) => a.info.health - b.info.health);
|
||||
}, [obligations, availableReserves]);
|
||||
|
||||
|
||||
return {
|
||||
obligations: enrichedObligations,
|
||||
};
|
||||
}
|
||||
|
||||
export function useEnrichedLendingObligation(address?: string | PublicKey) {
|
||||
const id = typeof address === "string" ? address : address?.toBase58();
|
||||
const { obligations } = useEnrichedLendingObligations();
|
||||
|
||||
const obligation = useMemo(() => {
|
||||
return obligations.find(ob => ob.account.pubkey.toBase58() === id);
|
||||
}, [obligations, id]);
|
||||
|
||||
return obligation;
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
import { useMemo } from "react";
|
||||
import { useLendingObligations } from "./useLendingObligations";
|
||||
import { collateralToLiquidity, LendingReserve } from "../models/lending";
|
||||
import { useLendingReserves } from "./useLendingReserves";
|
||||
import { ParsedAccount } from "../contexts/accounts";
|
||||
import { wadToLamports } from "../utils/utils";
|
||||
import { simulateMarketOrderFill } from "../contexts/market";
|
||||
|
||||
export const useLiquidableObligations = () => {
|
||||
const { obligations } = useLendingObligations();
|
||||
const { reserveAccounts } = useLendingReserves();
|
||||
|
||||
const availableReserves = useMemo(() => {
|
||||
return reserveAccounts.reduce((map, reserve) => {
|
||||
map.set(reserve.pubkey.toBase58(), reserve);
|
||||
return map;
|
||||
}, new Map<string, ParsedAccount<LendingReserve>>())
|
||||
}, [reserveAccounts])
|
||||
|
||||
const liquidableObligations = useMemo(() => {
|
||||
if (availableReserves.size === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return obligations
|
||||
.map(obligation => (
|
||||
{
|
||||
obligation,
|
||||
reserve: availableReserves.get(obligation.info.borrowReserve.toBase58()) as ParsedAccount<LendingReserve>
|
||||
}
|
||||
))
|
||||
// use obligations with reserves available
|
||||
.filter(item => item.reserve)
|
||||
// use reserves with borrow amount greater than zero
|
||||
.filter(item => wadToLamports(item.obligation.info.borrowAmountWad).toNumber() > 0)
|
||||
.map(item => {
|
||||
const obligation = item.obligation;
|
||||
const reserve = item.reserve.info;
|
||||
const collateralLamports = collateralToLiquidity(obligation.info.depositedCollateral, reserve);
|
||||
const cost = simulateMarketOrderFill(collateralLamports, reserve);
|
||||
|
||||
console.log(cost);
|
||||
|
||||
// TODO: calculate LTV
|
||||
const ltv = 81;
|
||||
const liquidationThreshold = item.reserve.info.config.liquidationThreshold;
|
||||
const health = (ltv - liquidationThreshold) / liquidationThreshold
|
||||
return {
|
||||
obligation: item.obligation,
|
||||
ltv,
|
||||
liquidationThreshold,
|
||||
health
|
||||
}
|
||||
})
|
||||
.filter(item => item.ltv > item.liquidationThreshold)
|
||||
.sort((a, b) => b.health - a.health);
|
||||
}, [obligations, availableReserves]);
|
||||
|
||||
return {
|
||||
liquidableObligations
|
||||
};
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
import { useMemo } from "react";
|
||||
import { useUserAccounts } from "./useUserAccounts";
|
||||
import { useLendingObligations } from "./useLendingObligations";
|
||||
import { useEnrichedLendingObligations } from "./useEnrichedLendingObligations";
|
||||
import { TokenAccount } from "../models";
|
||||
|
||||
export function useUserObligations() {
|
||||
const { userAccounts } = useUserAccounts();
|
||||
const { obligations } = useLendingObligations();
|
||||
const { obligations } = useEnrichedLendingObligations();
|
||||
|
||||
const accountsByMint = useMemo(() => {
|
||||
return userAccounts.reduce((res, acc) => {
|
||||
|
|
|
@ -188,11 +188,13 @@ export const collateralExchangeRate = (reserve?: LendingReserve) => {
|
|||
return (reserve?.collateralMintSupply.toNumber() || 1) / reserveMarketCap(reserve);
|
||||
}
|
||||
|
||||
export const collateralToLiquidity = (collateralAmount: BN, reserve?: LendingReserve) => {
|
||||
return Math.floor(collateralAmount.toNumber() / collateralExchangeRate(reserve));
|
||||
export const collateralToLiquidity = (collateralAmount: BN | number, reserve?: LendingReserve) => {
|
||||
const amount = typeof collateralAmount === 'number' ? collateralAmount : collateralAmount.toNumber();
|
||||
return Math.floor(amount / collateralExchangeRate(reserve));
|
||||
}
|
||||
|
||||
|
||||
export const liquidityToCollateral = (liquidityAmount: BN, reserve?: LendingReserve) => {
|
||||
return Math.floor(liquidityAmount.toNumber() * collateralExchangeRate(reserve));
|
||||
export const liquidityToCollateral = (liquidityAmount: BN | number, reserve?: LendingReserve) => {
|
||||
const amount = typeof liquidityAmount === 'number' ? liquidityAmount : liquidityAmount.toNumber();
|
||||
return Math.floor(amount * collateralExchangeRate(reserve));
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ export function toLamports(
|
|||
typeof account === "number" ? account : account.info.amount?.toNumber();
|
||||
|
||||
const precision = Math.pow(10, mint?.decimals || 0);
|
||||
return amount * precision;
|
||||
return Math.floor(amount * precision);
|
||||
}
|
||||
|
||||
export function wadToLamports(amount?: BN): BN {
|
||||
|
@ -120,12 +120,12 @@ export function fromLamports(
|
|||
return 0;
|
||||
}
|
||||
|
||||
const amount =
|
||||
const amount = Math.floor(
|
||||
typeof account === "number"
|
||||
? account
|
||||
: BN.isBN(account)
|
||||
? account.toNumber()
|
||||
: account.info.amount.toNumber();
|
||||
: account.info.amount.toNumber());
|
||||
|
||||
const precision = Math.pow(10, mint?.decimals || 0);
|
||||
return (amount / precision) * rate;
|
||||
|
|
|
@ -43,6 +43,7 @@ export const DashboardView = () => {
|
|||
<div>{LABELS.TABLE_TITLE_YOUR_LOAN_BALANCE}</div>
|
||||
<div>{LABELS.TABLE_TITLE_COLLATERAL_BALANCE}</div>
|
||||
<div>{LABELS.TABLE_TITLE_APY}</div>
|
||||
<div>{LABELS.TABLE_TITLE_LTV}</div>
|
||||
<div>{LABELS.TABLE_TITLE_ACTION}</div>
|
||||
</div>
|
||||
{userObligations.map((item) => {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import React, { useMemo } from "react";
|
||||
import { useTokenName } from "../../hooks";
|
||||
import { EnrichedLendingObligation, useTokenName } from "../../hooks";
|
||||
import {
|
||||
calculateBorrowAPY,
|
||||
collateralToLiquidity,
|
||||
LendingObligation,
|
||||
LendingReserve,
|
||||
} from "../../models/lending";
|
||||
import { TokenIcon } from "../../components/TokenIcon";
|
||||
|
@ -18,7 +17,7 @@ import { Link } from "react-router-dom";
|
|||
import { cache, ParsedAccount, useMint } from "../../contexts/accounts";
|
||||
|
||||
export const ObligationItem = (props: {
|
||||
obligation: ParsedAccount<LendingObligation>;
|
||||
obligation: EnrichedLendingObligation;
|
||||
}) => {
|
||||
const { obligation } = props;
|
||||
|
||||
|
@ -51,17 +50,14 @@ export const ObligationItem = (props: {
|
|||
return (
|
||||
<Card>
|
||||
<div className="dashboard-item">
|
||||
<span style={{ display: "flex" }}>
|
||||
<div style={{ display: "flex" }}>
|
||||
<span style={{ display: "flex", marginLeft: 5 }}>
|
||||
<div style={{ display: "flex" }} title={`${collateralName}→${borrowName}`}>
|
||||
<TokenIcon
|
||||
mintAddress={collateralReserve?.info.liquidityMint}
|
||||
style={{ marginRight: "-0.5rem" }}
|
||||
/>
|
||||
<TokenIcon mintAddress={borrowReserve?.info.liquidityMint} />
|
||||
</div>
|
||||
{collateralName}
|
||||
/
|
||||
{borrowName}
|
||||
</span>
|
||||
<div>
|
||||
{formatNumber.format(borrowAmount)} {borrowName}
|
||||
|
@ -70,13 +66,14 @@ export const ObligationItem = (props: {
|
|||
{formatNumber.format(collateral)} {collateralName}
|
||||
</div>
|
||||
<div>{formatPct.format(borrowAPY)}</div>
|
||||
<div>{formatPct.format(obligation.info.ltv / 100)}</div>
|
||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||
<Link to={`/borrow/${borrowReserve.pubkey.toBase58()}`}>
|
||||
<Button>
|
||||
<span>Borrow</span>
|
||||
</Button>
|
||||
</Link>
|
||||
<Link to={`/repay/loan/${obligation.pubkey.toBase58()}`}>
|
||||
<Link to={`/repay/loan/${obligation.account.pubkey.toBase58()}`}>
|
||||
<Button>
|
||||
<span>Repay</span>
|
||||
</Button>
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
align-items: center;
|
||||
|
||||
& > div, span {
|
||||
flex: 20%;
|
||||
flex: 15%;
|
||||
height: 22px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
& > :first-child {
|
||||
flex: 120px
|
||||
flex: 50px;
|
||||
}
|
||||
|
||||
& > :last-child {
|
||||
|
@ -22,17 +22,17 @@
|
|||
margin: 0px 30px;
|
||||
|
||||
& > div {
|
||||
flex: 20%;
|
||||
flex: 15%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
& > :first-child {
|
||||
text-align: left;
|
||||
flex: 120px
|
||||
flex: 50px;
|
||||
}
|
||||
|
||||
& > :last-child {
|
||||
flex: 200px
|
||||
flex: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
import React from "react";
|
||||
import { LABELS } from "../../constants";
|
||||
import { LiquidateItem } from "./item";
|
||||
import { useLiquidableObligations } from "./../../hooks";
|
||||
import { useEnrichedLendingObligations } from "./../../hooks";
|
||||
import "./style.less";
|
||||
|
||||
export const LiquidateView = () => {
|
||||
const { liquidableObligations } = useLiquidableObligations();
|
||||
const { obligations } = useEnrichedLendingObligations();
|
||||
|
||||
return (
|
||||
<div className="liquidate-container">
|
||||
{liquidableObligations.length === 0 ? (
|
||||
{obligations.length === 0 ? (
|
||||
<div className="liquidate-info">{LABELS.LIQUIDATE_NO_LOANS}</div>
|
||||
) : (
|
||||
<div className="flexColumn">
|
||||
|
@ -20,8 +20,8 @@ export const LiquidateView = () => {
|
|||
<div>{LABELS.TABLE_TITLE_LTV}</div>
|
||||
<div>{LABELS.TABLE_TITLE_ACTION}</div>
|
||||
</div>
|
||||
{liquidableObligations.map((item) => (
|
||||
<LiquidateItem key={item.obligation.pubkey.toBase58()} obligation={item.obligation} ltv={item.ltv}></LiquidateItem>
|
||||
{obligations.map((item) => (
|
||||
<LiquidateItem key={item.account.pubkey.toBase58()} item={item}></LiquidateItem>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useMemo } from "react";
|
||||
import { cache, ParsedAccount, useMint } from "../../contexts/accounts";
|
||||
import { LendingObligation, LendingReserve, calculateBorrowAPY } from "../../models/lending";
|
||||
import { useTokenName } from "../../hooks";
|
||||
import { LendingReserve, calculateBorrowAPY } from "../../models/lending";
|
||||
import { EnrichedLendingObligation, useTokenName } from "../../hooks";
|
||||
import { Link } from "react-router-dom";
|
||||
import { Button, Card } from "antd";
|
||||
import { TokenIcon } from "../../components/TokenIcon";
|
||||
|
@ -14,25 +14,23 @@ import {
|
|||
import { LABELS } from "../../constants";
|
||||
|
||||
export const LiquidateItem = (props: {
|
||||
obligation: ParsedAccount<LendingObligation>;
|
||||
ltv: number
|
||||
item: EnrichedLendingObligation
|
||||
}) => {
|
||||
|
||||
const { obligation, ltv } = props;
|
||||
let obligation = props.item.info
|
||||
|
||||
const borrowReserve = cache.get(
|
||||
obligation.info.borrowReserve
|
||||
obligation.borrowReserve
|
||||
) as ParsedAccount<LendingReserve>;
|
||||
|
||||
const collateralReserve = cache.get(
|
||||
obligation.info.collateralReserve
|
||||
obligation.collateralReserve
|
||||
) as ParsedAccount<LendingReserve>;
|
||||
|
||||
const tokenName = useTokenName(borrowReserve?.info.liquidityMint);
|
||||
const liquidityMint = useMint(borrowReserve.info.liquidityMint);
|
||||
|
||||
const borrowAmount = fromLamports(
|
||||
wadToLamports(obligation.info.borrowAmountWad),
|
||||
wadToLamports(obligation.borrowAmountWad),
|
||||
liquidityMint
|
||||
);
|
||||
|
||||
|
@ -44,7 +42,7 @@ export const LiquidateItem = (props: {
|
|||
const collateralName = useTokenName(collateralReserve?.info.liquidityMint);
|
||||
|
||||
return (
|
||||
<Link to={`/liquidate/${obligation.pubkey.toBase58()}`}>
|
||||
<Link to={`/liquidate/${props.item.account.pubkey.toBase58()}`}>
|
||||
<Card>
|
||||
<div className="liquidate-item">
|
||||
<span style={{ display: "flex" }}>
|
||||
|
@ -56,7 +54,7 @@ export const LiquidateItem = (props: {
|
|||
<TokenIcon mintAddress={borrowReserve?.info.liquidityMint} />
|
||||
</div>
|
||||
{collateralName}
|
||||
/
|
||||
→
|
||||
{borrowName}
|
||||
</span>
|
||||
<div>
|
||||
|
@ -66,7 +64,7 @@ export const LiquidateItem = (props: {
|
|||
{formatPct.format(borrowAPY)}
|
||||
</div>
|
||||
<div>
|
||||
{formatPct.format(ltv / 100)}
|
||||
{formatPct.format(obligation.ltv / 100)}
|
||||
</div>
|
||||
<div>
|
||||
<Button>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useLendingObligation, useLendingReserve } from "../../hooks";
|
||||
import { useEnrichedLendingObligation, useLendingReserve } from "../../hooks";
|
||||
import {
|
||||
SideReserveOverview,
|
||||
SideReserveOverviewMode,
|
||||
|
@ -13,7 +13,7 @@ import "./style.less";
|
|||
export const LiquidateReserveView = () => {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
|
||||
const obligation = useLendingObligation(id);
|
||||
const obligation = useEnrichedLendingObligation(id);
|
||||
const reserve = useLendingReserve(obligation?.info.borrowReserve);
|
||||
const collateralReserve = useLendingReserve(obligation?.info.collateralReserve);
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { useLendingObligation, useLendingReserve } from "../../hooks";
|
||||
import { useEnrichedLendingObligation, useLendingReserve } from "../../hooks";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import { RepayInput } from "../../components/RepayInput";
|
||||
|
@ -16,7 +16,7 @@ export const RepayReserveView = () => {
|
|||
obligation?: string;
|
||||
}>();
|
||||
|
||||
const lendingObligation = useLendingObligation(obligationId);
|
||||
const lendingObligation = useEnrichedLendingObligation(obligationId);
|
||||
const lendingReserve = useLendingReserve(
|
||||
obligationId ? lendingObligation?.info.borrowReserve : reserveId
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue