mirror of https://github.com/certusone/oyster.git
Merge branch 'main' into main
This commit is contained in:
commit
c57082969a
|
@ -34,16 +34,16 @@ export const BorrowInput = (props: {
|
||||||
|
|
||||||
const borrowReserve = props.reserve;
|
const borrowReserve = props.reserve;
|
||||||
|
|
||||||
const [collateralReserveMint, setCollateralReserveMint] = useState<string>();
|
const [collateralReserveKey, setCollateralReserveKey] = useState<string>();
|
||||||
|
|
||||||
const collateralReserve = useMemo(() => {
|
const collateralReserve = useMemo(() => {
|
||||||
const id: string =
|
const id: string =
|
||||||
cache
|
cache
|
||||||
.byParser(LendingReserveParser)
|
.byParser(LendingReserveParser)
|
||||||
.find((acc) => acc === collateralReserveMint) || "";
|
.find((acc) => acc === collateralReserveKey) || "";
|
||||||
|
|
||||||
return cache.get(id) as ParsedAccount<LendingReserve>;
|
return cache.get(id) as ParsedAccount<LendingReserve>;
|
||||||
}, [collateralReserveMint]);
|
}, [collateralReserveKey]);
|
||||||
|
|
||||||
const name = useTokenName(borrowReserve?.info.liquidityMint);
|
const name = useTokenName(borrowReserve?.info.liquidityMint);
|
||||||
const { accounts: fromAccounts } = useUserBalance(
|
const { accounts: fromAccounts } = useUserBalance(
|
||||||
|
@ -51,7 +51,8 @@ export const BorrowInput = (props: {
|
||||||
);
|
);
|
||||||
|
|
||||||
const { userObligationsByReserve } = useUserObligationByReserve(
|
const { userObligationsByReserve } = useUserObligationByReserve(
|
||||||
borrowReserve.pubkey
|
borrowReserve?.pubkey,
|
||||||
|
collateralReserve?.pubkey,
|
||||||
);
|
);
|
||||||
|
|
||||||
const onBorrow = useCallback(() => {
|
const onBorrow = useCallback(() => {
|
||||||
|
@ -74,6 +75,7 @@ export const BorrowInput = (props: {
|
||||||
borrowReserve,
|
borrowReserve,
|
||||||
collateralReserve,
|
collateralReserve,
|
||||||
|
|
||||||
|
// TODO: select exsisting obligations by collateral reserve
|
||||||
userObligationsByReserve.length > 0
|
userObligationsByReserve.length > 0
|
||||||
? userObligationsByReserve[0].obligation
|
? userObligationsByReserve[0].obligation
|
||||||
: undefined,
|
: undefined,
|
||||||
|
@ -126,8 +128,8 @@ export const BorrowInput = (props: {
|
||||||
<div className="borrow-input-title">{LABELS.SELECT_COLLATERAL}</div>
|
<div className="borrow-input-title">{LABELS.SELECT_COLLATERAL}</div>
|
||||||
<CollateralSelector
|
<CollateralSelector
|
||||||
reserve={borrowReserve.info}
|
reserve={borrowReserve.info}
|
||||||
mint={collateralReserveMint}
|
collateralReserve={collateralReserveKey}
|
||||||
onMintChange={setCollateralReserveMint}
|
onCollateralReserve={setCollateralReserveKey}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="borrow-input-title">{LABELS.BORROW_QUESTION}</div>
|
<div className="borrow-input-title">{LABELS.BORROW_QUESTION}</div>
|
||||||
|
|
|
@ -11,8 +11,9 @@ const { Option } = Select;
|
||||||
|
|
||||||
export const CollateralSelector = (props: {
|
export const CollateralSelector = (props: {
|
||||||
reserve: LendingReserve;
|
reserve: LendingReserve;
|
||||||
mint?: string;
|
collateralReserve?: string;
|
||||||
onMintChange: (id: string) => void;
|
disabled?: boolean;
|
||||||
|
onCollateralReserve?: (id: string) => void;
|
||||||
}) => {
|
}) => {
|
||||||
const { reserveAccounts } = useLendingReserves();
|
const { reserveAccounts } = useLendingReserves();
|
||||||
const { tokenMap } = useConnectionConfig();
|
const { tokenMap } = useConnectionConfig();
|
||||||
|
@ -20,8 +21,8 @@ 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.equals(
|
const onlyQuoteAllowed = !props.reserve?.liquidityMint?.equals(
|
||||||
market.info.quoteMint
|
market?.info?.quoteMint
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -30,10 +31,12 @@ export const CollateralSelector = (props: {
|
||||||
showSearch
|
showSearch
|
||||||
style={{ minWidth: 300 , margin: "5px 0px" }}
|
style={{ minWidth: 300 , margin: "5px 0px" }}
|
||||||
placeholder="Collateral"
|
placeholder="Collateral"
|
||||||
value={props.mint}
|
value={props.collateralReserve}
|
||||||
|
disabled={props.disabled}
|
||||||
|
defaultValue={props.collateralReserve}
|
||||||
onChange={(item) => {
|
onChange={(item) => {
|
||||||
if (props.onMintChange) {
|
if (props.onCollateralReserve) {
|
||||||
props.onMintChange(item);
|
props.onCollateralReserve(item);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
filterOption={(input, option) =>
|
filterOption={(input, option) =>
|
||||||
|
|
|
@ -21,7 +21,8 @@ import { notify } from "../../utils/notifications";
|
||||||
|
|
||||||
export const RepayInput = (props: {
|
export const RepayInput = (props: {
|
||||||
className?: string;
|
className?: string;
|
||||||
reserve: ParsedAccount<LendingReserve>;
|
borrowReserve: ParsedAccount<LendingReserve>;
|
||||||
|
collateralReserve?: ParsedAccount<LendingReserve>;
|
||||||
obligation: ParsedAccount<LendingObligation>;
|
obligation: ParsedAccount<LendingObligation>;
|
||||||
}) => {
|
}) => {
|
||||||
const connection = useConnection();
|
const connection = useConnection();
|
||||||
|
@ -29,7 +30,7 @@ export const RepayInput = (props: {
|
||||||
const [pendingTx, setPendingTx] = useState(false);
|
const [pendingTx, setPendingTx] = useState(false);
|
||||||
const [showConfirmation, setShowConfirmation] = useState(false);
|
const [showConfirmation, setShowConfirmation] = useState(false);
|
||||||
|
|
||||||
const repayReserve = props.reserve;
|
const repayReserve = props.borrowReserve;
|
||||||
const obligation = props.obligation;
|
const obligation = props.obligation;
|
||||||
|
|
||||||
const liquidityMint = useMint(repayReserve.info.liquidityMint);
|
const liquidityMint = useMint(repayReserve.info.liquidityMint);
|
||||||
|
@ -39,17 +40,7 @@ export const RepayInput = (props: {
|
||||||
borrowAmountLamports,
|
borrowAmountLamports,
|
||||||
liquidityMint
|
liquidityMint
|
||||||
);
|
);
|
||||||
|
const collateralReserve = props.collateralReserve;
|
||||||
const [collateralReserveMint, setCollateralReserveMint] = useState<string>();
|
|
||||||
|
|
||||||
const collateralReserve = useMemo(() => {
|
|
||||||
const id: string =
|
|
||||||
cache
|
|
||||||
.byParser(LendingReserveParser)
|
|
||||||
.find((acc) => acc === collateralReserveMint) || "";
|
|
||||||
|
|
||||||
return cache.get(id) as ParsedAccount<LendingReserve>;
|
|
||||||
}, [collateralReserveMint]);
|
|
||||||
|
|
||||||
const name = useTokenName(repayReserve?.info.liquidityMint);
|
const name = useTokenName(repayReserve?.info.liquidityMint);
|
||||||
const { accounts: fromAccounts } = useUserBalance(
|
const { accounts: fromAccounts } = useUserBalance(
|
||||||
|
@ -173,11 +164,11 @@ export const RepayInput = (props: {
|
||||||
value={pct}
|
value={pct}
|
||||||
onChange={setPct}
|
onChange={setPct}
|
||||||
/>
|
/>
|
||||||
<div className="repay-input-title">{LABELS.SELECT_COLLATERAL}</div>
|
<div className="repay-input-title">{LABELS.COLLATERAL}</div>
|
||||||
<CollateralSelector
|
<CollateralSelector
|
||||||
reserve={repayReserve.info}
|
reserve={repayReserve.info}
|
||||||
mint={collateralReserveMint}
|
collateralReserve={collateralReserve?.pubkey.toBase58()}
|
||||||
onMintChange={setCollateralReserveMint}
|
disabled={true}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|
|
@ -24,6 +24,7 @@ export const LABELS = {
|
||||||
WALLET_TOOLTIP: "Wallet public key",
|
WALLET_TOOLTIP: "Wallet public key",
|
||||||
SETTINGS_TOOLTIP: "Settings",
|
SETTINGS_TOOLTIP: "Settings",
|
||||||
SELECT_COLLATERAL: "Select collateral",
|
SELECT_COLLATERAL: "Select collateral",
|
||||||
|
COLLATERAL: "Collateral",
|
||||||
BORROW_QUESTION: "How much would you like to borrow?",
|
BORROW_QUESTION: "How much would you like to borrow?",
|
||||||
BORROW_ACTION: "Borrow",
|
BORROW_ACTION: "Borrow",
|
||||||
LIQUIDATE_ACTION: "Liquidate",
|
LIQUIDATE_ACTION: "Liquidate",
|
||||||
|
@ -31,6 +32,7 @@ export const LABELS = {
|
||||||
TABLE_TITLE_ASSET: "Asset",
|
TABLE_TITLE_ASSET: "Asset",
|
||||||
TABLE_TITLE_YOUR_LOAN_BALANCE: "Your loan balance",
|
TABLE_TITLE_YOUR_LOAN_BALANCE: "Your loan balance",
|
||||||
TABLE_TITLE_LOAN_BALANCE: "Loan balance",
|
TABLE_TITLE_LOAN_BALANCE: "Loan balance",
|
||||||
|
TABLE_TITLE_COLLATERAL_BALANCE: "Collateral",
|
||||||
TABLE_TITLE_DEPOSIT_BALANCE: "Your deposit balance",
|
TABLE_TITLE_DEPOSIT_BALANCE: "Your deposit balance",
|
||||||
TABLE_TITLE_APY: "APY",
|
TABLE_TITLE_APY: "APY",
|
||||||
TABLE_TITLE_LTV: "LTV",
|
TABLE_TITLE_LTV: "LTV",
|
||||||
|
|
|
@ -9,6 +9,7 @@ import { useMemo } from "react";
|
||||||
import { EventEmitter } from "./../utils/eventEmitter";
|
import { EventEmitter } from "./../utils/eventEmitter";
|
||||||
|
|
||||||
import { DexMarketParser } from "./../models/dex";
|
import { DexMarketParser } from "./../models/dex";
|
||||||
|
import { LendingReserve } from "../models";
|
||||||
|
|
||||||
export interface MarketsContextState {
|
export interface MarketsContextState {
|
||||||
midPriceInUSD: (mint: string) => number;
|
midPriceInUSD: (mint: string) => number;
|
||||||
|
@ -248,6 +249,55 @@ export const usePrecacheMarket = () => {
|
||||||
return context.precacheMarkets;
|
return context.precacheMarkets;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const simulateMarketOrderFill = (amount: number, reserve: LendingReserve) => {
|
||||||
|
const marketInfo = cache.get(reserve?.dexMarket);
|
||||||
|
if (!marketInfo) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
const decodedMarket = marketInfo.info;
|
||||||
|
|
||||||
|
const baseMintDecimals =
|
||||||
|
cache.get(decodedMarket.baseMint)?.info.decimals || 0;
|
||||||
|
const quoteMintDecimals =
|
||||||
|
cache.get(decodedMarket.quoteMint)?.info.decimals || 0;
|
||||||
|
|
||||||
|
const market = new Market(
|
||||||
|
decodedMarket,
|
||||||
|
baseMintDecimals,
|
||||||
|
quoteMintDecimals,
|
||||||
|
undefined,
|
||||||
|
decodedMarket.programId
|
||||||
|
);
|
||||||
|
|
||||||
|
const bids = cache.get(decodedMarket.bids)?.info;
|
||||||
|
const asks = cache.get(decodedMarket.asks)?.info;
|
||||||
|
|
||||||
|
if (bids && asks) {
|
||||||
|
const bidsBook = new Orderbook(market, bids.accountFlags, bids.slab);
|
||||||
|
const asksBook = new Orderbook(market, asks.accountFlags, asks.slab);
|
||||||
|
|
||||||
|
// TODO: pick side
|
||||||
|
let book = bidsBook;
|
||||||
|
|
||||||
|
let cost = 0;
|
||||||
|
let remaining = amount;
|
||||||
|
|
||||||
|
for (const level of book) {
|
||||||
|
let size = remaining > level.size ? level.size : level.size - remaining;
|
||||||
|
cost = cost + level.price * size;
|
||||||
|
remaining = remaining - size;
|
||||||
|
|
||||||
|
if(remaining <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const getMidPrice = (marketAddress?: string, mintAddress?: string) => {
|
const getMidPrice = (marketAddress?: string, mintAddress?: string) => {
|
||||||
const SERUM_TOKEN = TOKEN_MINTS.find(
|
const SERUM_TOKEN = TOKEN_MINTS.find(
|
||||||
(a) => a.address.toBase58() === mintAddress
|
(a) => a.address.toBase58() === mintAddress
|
||||||
|
|
|
@ -2,15 +2,19 @@ import { useMemo } from "react";
|
||||||
import { useUserObligations } from "./useUserObligations";
|
import { useUserObligations } from "./useUserObligations";
|
||||||
import { PublicKey } from "@solana/web3.js";
|
import { PublicKey } from "@solana/web3.js";
|
||||||
|
|
||||||
export function useUserObligationByReserve(reserve?: string | PublicKey) {
|
export function useUserObligationByReserve(
|
||||||
|
borrowReserve?: string | PublicKey,
|
||||||
|
collateralReserve?: string | PublicKey) {
|
||||||
const { userObligations } = useUserObligations();
|
const { userObligations } = useUserObligations();
|
||||||
|
|
||||||
const userObligationsByReserve = useMemo(() => {
|
const userObligationsByReserve = useMemo(() => {
|
||||||
const id = typeof reserve === "string" ? reserve : reserve?.toBase58();
|
const borrowId = typeof borrowReserve === "string" ? borrowReserve : borrowReserve?.toBase58();
|
||||||
|
const collateralId = typeof collateralReserve === "string" ? collateralReserve : collateralReserve?.toBase58();
|
||||||
return userObligations.filter(
|
return userObligations.filter(
|
||||||
(item) => item.obligation.info.borrowReserve.toBase58() === id
|
(item) => item.obligation.info.borrowReserve.toBase58() === borrowId &&
|
||||||
|
item.obligation.info.collateralReserve.toBase58() === collateralId
|
||||||
);
|
);
|
||||||
}, [reserve, userObligations]);
|
}, [borrowReserve, collateralReserve, userObligations]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
userObligationsByReserve,
|
userObligationsByReserve,
|
||||||
|
|
|
@ -47,7 +47,7 @@ export const liquidateInstruction = (
|
||||||
dataLayout.encode(
|
dataLayout.encode(
|
||||||
{
|
{
|
||||||
instruction: LendingInstruction.LiquidateObligation,
|
instruction: LendingInstruction.LiquidateObligation,
|
||||||
collateralAmount: new BN(liquidityAmount),
|
liquidityAmount: new BN(liquidityAmount),
|
||||||
},
|
},
|
||||||
data
|
data
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,9 +8,9 @@ export const LendingObligationLayout: typeof BufferLayout.Structure = BufferLayo
|
||||||
/// Slot when obligation was updated. Used for calculating interest.
|
/// Slot when obligation was updated. Used for calculating interest.
|
||||||
Layout.uint64("lastUpdateSlot"),
|
Layout.uint64("lastUpdateSlot"),
|
||||||
/// Amount of collateral tokens deposited for this obligation
|
/// Amount of collateral tokens deposited for this obligation
|
||||||
Layout.uint64("collateralAmount"),
|
Layout.uint64("depositedCollateral"),
|
||||||
/// Reserve which collateral tokens were deposited into
|
/// Reserve which collateral tokens were deposited into
|
||||||
Layout.publicKey("collateralSupply"),
|
Layout.publicKey("collateralReserve"),
|
||||||
/// Borrow rate used for calculating interest.
|
/// Borrow rate used for calculating interest.
|
||||||
Layout.uint128("cumulativeBorrowRateWad"),
|
Layout.uint128("cumulativeBorrowRateWad"),
|
||||||
/// Amount of tokens borrowed for this obligation plus interest
|
/// Amount of tokens borrowed for this obligation plus interest
|
||||||
|
@ -28,8 +28,8 @@ export const isLendingObligation = (info: AccountInfo<Buffer>) => {
|
||||||
|
|
||||||
export interface LendingObligation {
|
export interface LendingObligation {
|
||||||
lastUpdateSlot: BN;
|
lastUpdateSlot: BN;
|
||||||
collateralAmount: BN;
|
depositedCollateral: BN;
|
||||||
collateralSupply: PublicKey;
|
collateralReserve: PublicKey;
|
||||||
cumulativeBorrowRateWad: BN; // decimals
|
cumulativeBorrowRateWad: BN; // decimals
|
||||||
borrowAmountWad: BN; // decimals
|
borrowAmountWad: BN; // decimals
|
||||||
borrowReserve: PublicKey;
|
borrowReserve: PublicKey;
|
||||||
|
|
|
@ -187,3 +187,12 @@ export const reserveMarketCap = (reserve?: LendingReserve) => {
|
||||||
export const collateralExchangeRate = (reserve?: LendingReserve) => {
|
export const collateralExchangeRate = (reserve?: LendingReserve) => {
|
||||||
return (reserve?.collateralMintSupply.toNumber() || 1) / reserveMarketCap(reserve);
|
return (reserve?.collateralMintSupply.toNumber() || 1) / reserveMarketCap(reserve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const collateralToLiquidity = (collateralAmount: BN, reserve?: LendingReserve) => {
|
||||||
|
return Math.floor(collateralAmount.toNumber() / collateralExchangeRate(reserve));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const liquidityToCollateral = (liquidityAmount: BN, reserve?: LendingReserve) => {
|
||||||
|
return Math.floor(liquidityAmount.toNumber() * collateralExchangeRate(reserve));
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ export const DashboardView = () => {
|
||||||
<div className="dashboard-item dashboard-header">
|
<div className="dashboard-item dashboard-header">
|
||||||
<div>{LABELS.TABLE_TITLE_ASSET}</div>
|
<div>{LABELS.TABLE_TITLE_ASSET}</div>
|
||||||
<div>{LABELS.TABLE_TITLE_YOUR_LOAN_BALANCE}</div>
|
<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_APY}</div>
|
||||||
<div>{LABELS.TABLE_TITLE_ACTION}</div>
|
<div>{LABELS.TABLE_TITLE_ACTION}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { useUserCollateralBalance, useTokenName } from "../../hooks";
|
||||||
import {
|
import {
|
||||||
calculateBorrowAPY,
|
calculateBorrowAPY,
|
||||||
collateralExchangeRate,
|
collateralExchangeRate,
|
||||||
|
collateralToLiquidity,
|
||||||
LendingObligation,
|
LendingObligation,
|
||||||
LendingReserve,
|
LendingReserve,
|
||||||
reserveMarketCap,
|
reserveMarketCap,
|
||||||
|
@ -17,6 +18,7 @@ import {
|
||||||
import { Button, Card } from "antd";
|
import { Button, Card } from "antd";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { cache, ParsedAccount, useMint } from "../../contexts/accounts";
|
import { cache, ParsedAccount, useMint } from "../../contexts/accounts";
|
||||||
|
import { simulateMarketOrderFill } from "../../contexts/market";
|
||||||
|
|
||||||
export const ObligationItem = (props: {
|
export const ObligationItem = (props: {
|
||||||
obligation: ParsedAccount<LendingObligation>;
|
obligation: ParsedAccount<LendingObligation>;
|
||||||
|
@ -27,10 +29,12 @@ export const ObligationItem = (props: {
|
||||||
obligation.info.borrowReserve
|
obligation.info.borrowReserve
|
||||||
) as ParsedAccount<LendingReserve>;
|
) as ParsedAccount<LendingReserve>;
|
||||||
|
|
||||||
const name = useTokenName(borrowReserve?.info.liquidityMint);
|
const collateralReserve = cache.get(
|
||||||
|
obligation.info.collateralReserve
|
||||||
|
) as ParsedAccount<LendingReserve>;
|
||||||
|
|
||||||
const liquidityMint = useMint(borrowReserve.info.liquidityMint);
|
const liquidityMint = useMint(borrowReserve.info.liquidityMint);
|
||||||
const collateralMint = useMint(borrowReserve.info.collateralMint);
|
const collateralMint = useMint(collateralReserve.info.liquidityMint);
|
||||||
|
|
||||||
const borrowAmount = fromLamports(
|
const borrowAmount = fromLamports(
|
||||||
wadToLamports(obligation.info.borrowAmountWad),
|
wadToLamports(obligation.info.borrowAmountWad),
|
||||||
|
@ -40,21 +44,49 @@ export const ObligationItem = (props: {
|
||||||
const borrowAPY = useMemo(() => calculateBorrowAPY(borrowReserve.info), [
|
const borrowAPY = useMemo(() => calculateBorrowAPY(borrowReserve.info), [
|
||||||
borrowReserve,
|
borrowReserve,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const collateralLamports = collateralToLiquidity(obligation.info.depositedCollateral, borrowReserve.info);
|
||||||
|
const collateral = fromLamports(collateralLamports, collateralMint);
|
||||||
|
|
||||||
|
const borrowName = useTokenName(borrowReserve?.info.liquidityMint);
|
||||||
|
const collateralName = useTokenName(collateralReserve?.info.liquidityMint);
|
||||||
|
|
||||||
|
|
||||||
const rate = collateralExchangeRate(borrowReserve.info) ;
|
const cost = simulateMarketOrderFill(collateralLamports, borrowReserve.info);
|
||||||
|
console.log(cost);
|
||||||
|
|
||||||
console.log(`collateral ${fromLamports(obligation.info.collateralAmount.toNumber() / rate, collateralMint)}`);
|
// TODO: health factor
|
||||||
|
// let borrow_amount_as_collateral = withdraw_reserve_rates.liquidity_to_collateral(
|
||||||
|
// simulate_market_order_fill(
|
||||||
|
// obligation.borrowed_liquidity_wads,
|
||||||
|
// memory,
|
||||||
|
// dex_market_order_book_side_info,
|
||||||
|
// dex_market_info,
|
||||||
|
// &repay_reserve,
|
||||||
|
// )?
|
||||||
|
// .round_u64(),
|
||||||
|
// );
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Card>
|
<Card>
|
||||||
<div className="dashboard-item">
|
<div className="dashboard-item">
|
||||||
<span style={{ display: "flex" }}>
|
<span style={{ display: "flex" }}>
|
||||||
<TokenIcon mintAddress={borrowReserve?.info.liquidityMint} />
|
<div style={{ display: "flex" }}>
|
||||||
{name}
|
<TokenIcon
|
||||||
|
mintAddress={collateralReserve?.info.liquidityMint}
|
||||||
|
style={{ marginRight: "-0.5rem" }}
|
||||||
|
/>
|
||||||
|
<TokenIcon mintAddress={borrowReserve?.info.liquidityMint} />
|
||||||
|
</div>
|
||||||
|
{collateralName}
|
||||||
|
/
|
||||||
|
{borrowName}
|
||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
{formatNumber.format(borrowAmount)} {name}
|
{formatNumber.format(borrowAmount)} {borrowName}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
{formatNumber.format(collateral)} {collateralName}
|
||||||
</div>
|
</div>
|
||||||
<div>{formatPct.format(borrowAPY)}</div>
|
<div>{formatPct.format(borrowAPY)}</div>
|
||||||
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
<div style={{ display: "flex", justifyContent: "flex-end" }}>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
& > :first-child {
|
& > :first-child {
|
||||||
flex: 80px
|
flex: 120px
|
||||||
}
|
}
|
||||||
|
|
||||||
& > :last-child {
|
& > :last-child {
|
||||||
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
& > :first-child {
|
& > :first-child {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
flex: 80px
|
flex: 120px
|
||||||
}
|
}
|
||||||
|
|
||||||
& > :last-child {
|
& > :last-child {
|
||||||
|
|
|
@ -20,6 +20,12 @@ export const RepayReserveView = () => {
|
||||||
const lendingReserve = useLendingReserve(
|
const lendingReserve = useLendingReserve(
|
||||||
obligationId ? lendingObligation?.info.borrowReserve : reserveId
|
obligationId ? lendingObligation?.info.borrowReserve : reserveId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
const repayReserve = useLendingReserve(
|
||||||
|
obligationId ? lendingObligation?.info.collateralReserve : reserveId
|
||||||
|
);
|
||||||
|
|
||||||
const reserve = lendingReserve?.info;
|
const reserve = lendingReserve?.info;
|
||||||
|
|
||||||
if (!reserve || !lendingReserve || !lendingObligation) {
|
if (!reserve || !lendingReserve || !lendingObligation) {
|
||||||
|
@ -31,7 +37,8 @@ export const RepayReserveView = () => {
|
||||||
<div className="repay-reserve-container">
|
<div className="repay-reserve-container">
|
||||||
<RepayInput
|
<RepayInput
|
||||||
className="repay-reserve-item repay-reserve-item-left"
|
className="repay-reserve-item repay-reserve-item-left"
|
||||||
reserve={lendingReserve}
|
borrowReserve={lendingReserve}
|
||||||
|
collateralReserve={repayReserve}
|
||||||
obligation={lendingObligation}
|
obligation={lendingObligation}
|
||||||
/>
|
/>
|
||||||
<SideReserveOverview
|
<SideReserveOverview
|
||||||
|
|
Loading…
Reference in New Issue