mirror of https://github.com/certusone/oyster.git
feat: borrowing power
This commit is contained in:
parent
9805849b85
commit
21051f776a
|
@ -22,7 +22,7 @@ export const CollateralItem = (props: {
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
style={{ display: "flex", alignItems: "center" }}
|
style={{ display: "flex", alignItems: "center" }}
|
||||||
>
|
>
|
||||||
|
@ -32,10 +32,10 @@ export const CollateralItem = (props: {
|
||||||
className="token-balance"
|
className="token-balance"
|
||||||
>
|
>
|
||||||
{" "}
|
{" "}
|
||||||
{userDeposit ? formatAmount(userDeposit.info.amount): '--'}
|
{userDeposit ? formatAmount(userDeposit.info.amount) : '--'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +52,11 @@ export const CollateralSelector = (props: {
|
||||||
const market = cache.get(props.reserve?.lendingMarket) as ParsedAccount<
|
const market = cache.get(props.reserve?.lendingMarket) as ParsedAccount<
|
||||||
LendingMarket
|
LendingMarket
|
||||||
>;
|
>;
|
||||||
const onlyQuoteAllowed = props.reserve?.liquidityMint?.toBase58() !==
|
|
||||||
market?.info?.quoteMint?.toBase58();
|
const quoteMintAddress = market?.info?.quoteMint?.toBase58();
|
||||||
|
|
||||||
|
const onlyQuoteAllowed = props.reserve?.liquidityMint?.toBase58() !==
|
||||||
|
quoteMintAddress;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
export const LABELS = {
|
export const LABELS = {
|
||||||
CONNECT_LABEL: "Connect Wallet",
|
CONNECT_LABEL: "Connect Wallet",
|
||||||
|
BORROWING_POWER_USED: "Borrowing Power Used",
|
||||||
|
BORROWING_POWER_VALUE: "Borrowing Power",
|
||||||
|
BORROWED_VALUE: "You borrowed",
|
||||||
GIVE_SOL: "Give me SOL",
|
GIVE_SOL: "Give me SOL",
|
||||||
LIQUIDATION_INFO: "This view displays all loans that can be liquidated. A liquidation is a process where borrower collateral does not cover value of the loan. It is represented by health factor falling below 1.o. When a loan is liquidated, an liquidator can purchase collateral at a discount by repaing the portio of the loan. ",
|
LIQUIDATION_INFO: "This view displays all loans that can be liquidated. A liquidation is a process where borrower collateral does not cover value of the loan. It is represented by health factor falling below 1.o. When a loan is liquidated, an liquidator can purchase collateral at a discount by repaing the portio of the loan. ",
|
||||||
FAUCET_INFO:
|
FAUCET_INFO:
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { useMidPriceInUSD } from "../contexts/market";
|
||||||
import { useLendingMarket } from "./useLendingMarket";
|
import { useLendingMarket } from "./useLendingMarket";
|
||||||
import { getLendingReserves, useLendingReserve } from "./useLendingReserves";
|
import { getLendingReserves, useLendingReserve } from "./useLendingReserves";
|
||||||
import { useUserDeposits } from "./useUserDeposits";
|
import { useUserDeposits } from "./useUserDeposits";
|
||||||
|
import { useUserObligations } from "./useUserObligations";
|
||||||
|
|
||||||
// TODO: add option to decrease buying power by overcollateralization factor
|
// TODO: add option to decrease buying power by overcollateralization factor
|
||||||
|
|
||||||
|
@ -37,16 +38,24 @@ export function useBorrowingPower(reserveAddress: string | PublicKey, overcollat
|
||||||
|
|
||||||
const price = useMidPriceInUSD(liquidityMintAddress).price;
|
const price = useMidPriceInUSD(liquidityMintAddress).price;
|
||||||
|
|
||||||
|
const { totalInQuote: loansValue } = useUserObligations();
|
||||||
|
|
||||||
|
const totalDeposits = loansValue + totalInQuote;
|
||||||
|
|
||||||
|
const utilization = totalDeposits === 0 ? 0 : loansValue / totalDeposits;
|
||||||
|
|
||||||
// amounts already expressed as quite mint
|
// amounts already expressed as quite mint
|
||||||
if (liquidityMintAddress === market?.info.quoteMint?.toBase58()) {
|
if (liquidityMintAddress === quoteMintAddess) {
|
||||||
return {
|
return {
|
||||||
borrowingPower: totalInQuote,
|
borrowingPower: totalInQuote,
|
||||||
totalInQuote,
|
totalInQuote,
|
||||||
|
utilization,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
borrowingPower: totalInQuote / price,
|
borrowingPower: totalInQuote / price,
|
||||||
totalInQuote,
|
totalInQuote,
|
||||||
|
utilization
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,32 +10,26 @@ import {
|
||||||
} from "../../components/SideReserveOverview";
|
} from "../../components/SideReserveOverview";
|
||||||
import { Card, Col, Row, Statistic } from "antd";
|
import { Card, Col, Row, Statistic } from "antd";
|
||||||
import { BarChartStatistic } from "../../components/BarChartStatistic";
|
import { BarChartStatistic } from "../../components/BarChartStatistic";
|
||||||
import { GUTTER } from "../../constants";
|
import { GUTTER, LABELS } from "../../constants";
|
||||||
|
|
||||||
export const BorrowReserveView = () => {
|
export const BorrowReserveView = () => {
|
||||||
const { id } = useParams<{ id: string }>();
|
const { id } = useParams<{ id: string }>();
|
||||||
const lendingReserve = useLendingReserve(id);
|
const lendingReserve = useLendingReserve(id);
|
||||||
const { userObligations, totalInQuote: loansValue } = useUserObligations();
|
const { userObligations, totalInQuote: loansValue } = useUserObligations();
|
||||||
|
|
||||||
const { totalInQuote: borrowingPower } = useBorrowingPower(id)
|
const { totalInQuote: borrowingPower, utilization } = useBorrowingPower(id)
|
||||||
|
|
||||||
if (!lendingReserve) {
|
if (!lendingReserve) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const numberOfLoans = userObligations
|
|
||||||
.filter(ob =>
|
|
||||||
// ob.obligation.info.borrowReserve.toBase58() === id &&
|
|
||||||
ob.obligation.info.collateralInQuote > 0)
|
|
||||||
.length;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="borrow-reserve">
|
<div className="borrow-reserve">
|
||||||
<Row gutter={GUTTER}>
|
<Row gutter={GUTTER}>
|
||||||
<Col xs={24} xl={5}>
|
<Col xs={24} xl={5}>
|
||||||
<Card>
|
<Card>
|
||||||
<Statistic
|
<Statistic
|
||||||
title="Your loans value"
|
title={LABELS.BORROWED_VALUE}
|
||||||
value={loansValue}
|
value={loansValue}
|
||||||
precision={2}
|
precision={2}
|
||||||
prefix="$"
|
prefix="$"
|
||||||
|
@ -45,16 +39,17 @@ export const BorrowReserveView = () => {
|
||||||
<Col xs={24} xl={5}>
|
<Col xs={24} xl={5}>
|
||||||
<Card>
|
<Card>
|
||||||
<Statistic
|
<Statistic
|
||||||
title="Number of loans"
|
title={LABELS.BORROWING_POWER_USED}
|
||||||
value={numberOfLoans}
|
value={utilization * 100}
|
||||||
precision={0}
|
precision={2}
|
||||||
|
suffix="%"
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} xl={5}>
|
<Col xs={24} xl={5}>
|
||||||
<Card>
|
<Card>
|
||||||
<Statistic
|
<Statistic
|
||||||
title="Borrowing power"
|
title={LABELS.BORROWING_POWER_VALUE}
|
||||||
value={borrowingPower}
|
value={borrowingPower}
|
||||||
valueStyle={{ color: "#3f8600" }}
|
valueStyle={{ color: "#3f8600" }}
|
||||||
precision={2}
|
precision={2}
|
||||||
|
|
Loading…
Reference in New Issue