style: format

This commit is contained in:
bartosz-lipinski 2020-12-16 22:31:26 -06:00
parent 306cff16c7
commit 179e4352bc
26 changed files with 253 additions and 190 deletions

View File

@ -104,7 +104,7 @@ export const repay = async (
authority
)
);
let tx = await sendTransaction(
connection,
wallet,

View File

@ -52,7 +52,7 @@ export const BorrowInput = (props: {
const { userObligationsByReserve } = useUserObligationByReserve(
borrowReserve?.pubkey,
collateralReserve?.pubkey,
collateralReserve?.pubkey
);
const onBorrow = useCallback(() => {

View File

@ -29,7 +29,7 @@ export const CollateralSelector = (props: {
<Select
size="large"
showSearch
style={{ minWidth: 300 , margin: "5px 0px" }}
style={{ minWidth: 300, margin: "5px 0px" }}
placeholder="Collateral"
value={props.collateralReserve}
disabled={props.disabled}

View File

@ -17,7 +17,9 @@ export const DepositInfoLine = (props: {
}) => {
const name = useTokenName(props.reserve.liquidityMint);
const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint);
const { balance: collateralBalance } = useUserCollateralBalance(props.reserve);
const { balance: collateralBalance } = useUserCollateralBalance(
props.reserve
);
return (
<Card

View File

@ -106,9 +106,7 @@ export const DepositInput = (props: {
justifyContent: "space-around",
}}
>
<div className="deposit-input-title">
{LABELS.DEPOSIT_QUESTION}
</div>
<div className="deposit-input-title">{LABELS.DEPOSIT_QUESTION}</div>
<div className="token-input">
<TokenIcon mintAddress={reserve?.liquidityMint} />
<NumericInput

View File

@ -16,7 +16,6 @@ export const LiquidateInput = (props: {
collateralReserve?: ParsedAccount<LendingReserve>;
obligation: EnrichedLendingObligation;
}) => {
const { reserve, collateralReserve } = props;
const [pendingTx, setPendingTx] = useState(false);
@ -34,27 +33,25 @@ export const LiquidateInput = (props: {
};
return (
<Card className={props.className} bodyStyle={bodyStyle} >
<div style={{
display: "flex",
flexDirection: "column",
justifyContent: "space-around",
}}>
<Card className={props.className} bodyStyle={bodyStyle}>
<div
style={{
display: "flex",
flexDirection: "column",
justifyContent: "space-around",
}}
>
<div className="liquidate-input-title">{LABELS.SELECT_COLLATERAL}</div>
<CollateralSelector
reserve={reserve.info}
collateralReserve={collateralReserve?.pubkey.toBase58()}
disabled={true}
/>
<Button
type="primary"
onClick={onLiquidate}
loading={pendingTx}
>
<Button type="primary" onClick={onLiquidate} loading={pendingTx}>
{LABELS.LIQUIDATE_ACTION}
</Button>
<BackButton />
</div>
</Card>
)
}
);
};

View File

@ -1,8 +1,13 @@
import React, { useCallback, useState } from "react";
import { EnrichedLendingObligation, InputType, useAccountByMint, useSliderInput, useTokenName, useUserBalance } from "../../hooks";
import {
LendingReserve,
} from "../../models";
EnrichedLendingObligation,
InputType,
useAccountByMint,
useSliderInput,
useTokenName,
useUserBalance,
} from "../../hooks";
import { LendingReserve } from "../../models";
import { TokenIcon } from "../TokenIcon";
import { Button, Card, Slider } from "antd";
import { ParsedAccount, useMint } from "../../contexts/accounts";
@ -33,11 +38,10 @@ export const RepayInput = (props: {
const liquidityMint = useMint(repayReserve.info.liquidityMint);
const borrowAmountLamports = wadToLamports(obligation.info.borrowAmountWad).toNumber();
const borrowAmount = fromLamports(
borrowAmountLamports,
liquidityMint
);
const borrowAmountLamports = wadToLamports(
obligation.info.borrowAmountWad
).toNumber();
const borrowAmount = fromLamports(borrowAmountLamports, liquidityMint);
const collateralReserve = props.collateralReserve;
const name = useTokenName(repayReserve?.info.liquidityMint);
@ -74,9 +78,12 @@ export const RepayInput = (props: {
(async () => {
try {
const toRepayLamports = type === InputType.Percent
? (pct * borrowAmountLamports) / 100
: Math.ceil(borrowAmountLamports * (parseFloat(value) / borrowAmount));
const toRepayLamports =
type === InputType.Percent
? (pct * borrowAmountLamports) / 100
: Math.ceil(
borrowAmountLamports * (parseFloat(value) / borrowAmount)
);
await repay(
fromAccounts[0],
@ -97,7 +104,6 @@ export const RepayInput = (props: {
type: "error",
description: error.message,
});
} finally {
setPendingTx(false);
}
@ -138,9 +144,7 @@ export const RepayInput = (props: {
justifyContent: "space-around",
}}
>
<div className="repay-input-title">
{LABELS.REPAY_QUESTION}
</div>
<div className="repay-input-title">{LABELS.REPAY_QUESTION}</div>
<div className="token-input">
<TokenIcon mintAddress={repayReserve?.info.liquidityMint} />
<NumericInput
@ -157,11 +161,7 @@ export const RepayInput = (props: {
/>
<div>{name}</div>
</div>
<Slider
marks={marks}
value={pct}
onChange={setPct}
/>
<Slider marks={marks} value={pct} onChange={setPct} />
<div className="repay-input-title">{LABELS.COLLATERAL}</div>
<CollateralSelector
reserve={repayReserve.info}

View File

@ -1,9 +1,6 @@
import React, { useMemo } from "react";
import { LendingReserve } from "../../models/lending";
import {
fromLamports,
wadToLamports,
} from "../../utils/utils";
import { fromLamports, wadToLamports } from "../../utils/utils";
import { useMint } from "../../contexts/accounts";
import { WaterWave } from "./../WaterWave";
@ -23,7 +20,10 @@ export const ReserveUtilizationChart = (props: { reserve: LendingReserve }) => {
[props.reserve, liquidityMint]
);
return <WaterWave
style={{ height: 300 }}
percent={availableLiquidity * 100 / (availableLiquidity + totalBorrows)} />;
return (
<WaterWave
style={{ height: 300 }}
percent={(availableLiquidity * 100) / (availableLiquidity + totalBorrows)}
/>
);
};

View File

@ -24,7 +24,9 @@ export const UserLendingCard = (props: {
const name = useTokenName(reserve?.liquidityMint);
const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint);
const { balance: collateralBalance } = useUserCollateralBalance(props.reserve);
const { balance: collateralBalance } = useUserCollateralBalance(
props.reserve
);
const { borrowed: totalBorrowed } = useBorrowedAmount(address);

View File

@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useRef, useState } from "react";
import "./index.less";
export const WaterWave = (props: any) => {
@ -17,9 +17,9 @@ export const WaterWave = (props: any) => {
useEffect(() => {
resize();
window.addEventListener('resize', resize);
window.addEventListener("resize", resize);
return () => {
window.removeEventListener('resize', resize);
window.removeEventListener("resize", resize);
};
}, [resize]);
@ -31,11 +31,12 @@ export const WaterWave = (props: any) => {
(val) => {
timer = val;
},
color);
color
);
return () => {
cancelAnimationFrame(timer);
}
};
}, [percent, color]);
return (
@ -44,7 +45,7 @@ export const WaterWave = (props: any) => {
ref={root as any}
style={{ transform: `scale(${radio})` }}
>
<div style={{ width: height, height, overflow: 'hidden' }}>
<div style={{ width: height, height, overflow: "hidden" }}>
<canvas
className="waterWaveCanvasWrapper"
ref={node as any}
@ -58,16 +59,20 @@ export const WaterWave = (props: any) => {
</div>
</div>
);
}
};
const renderChart = (canvas: HTMLCanvasElement | undefined, percent: number, setTimer: (timer: number) => void, color = '#1890FF',) => {
const renderChart = (
canvas: HTMLCanvasElement | undefined,
percent: number,
setTimer: (timer: number) => void,
color = "#1890FF"
) => {
const data = percent / 100;
if (!canvas || !data) {
return;
}
const ctx = canvas.getContext('2d');
const ctx = canvas.getContext("2d");
if (!ctx) {
return;
@ -95,7 +100,10 @@ const renderChart = (canvas: HTMLCanvasElement | undefined, percent: number, set
const circleOffset = -(Math.PI / 2);
let circleLock = true;
const cStartPoint = [radius + bR * Math.cos(circleOffset), radius + bR * Math.sin(circleOffset)];
const cStartPoint = [
radius + bR * Math.cos(circleOffset),
radius + bR * Math.sin(circleOffset),
];
ctx.strokeStyle = color;
ctx.moveTo(cStartPoint[0], cStartPoint[1]);
@ -125,19 +133,19 @@ const renderChart = (canvas: HTMLCanvasElement | undefined, percent: number, set
ctx.lineTo(startPoint[0], startPoint[1]);
const gradient = ctx.createLinearGradient(0, 0, 0, canvasHeight);
gradient.addColorStop(0, '#ffffff');
gradient.addColorStop(1, '#1890FF');
gradient.addColorStop(0, "#ffffff");
gradient.addColorStop(1, "#1890FF");
ctx.fillStyle = gradient;
ctx.fill();
ctx.restore();
}
};
const render = () => {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
if (circleLock) {
circleLock = false;
ctx.globalCompositeOperation = 'destination-over';
ctx.globalCompositeOperation = "destination-over";
ctx.beginPath();
ctx.save();
@ -145,7 +153,7 @@ const renderChart = (canvas: HTMLCanvasElement | undefined, percent: number, set
ctx.stroke();
ctx.restore();
ctx.clip();
ctx.fillStyle = '#1890FF';
ctx.fillStyle = "#1890FF";
} else {
if (data >= 0.85) {
if (currRange > range / 4) {
@ -178,7 +186,7 @@ const renderChart = (canvas: HTMLCanvasElement | undefined, percent: number, set
drawSin();
}
setTimer(requestAnimationFrame(render));
}
};
render();
}
};

View File

@ -90,7 +90,7 @@ export function MarketProvider({ children = null as any }) {
allMarkets.filter((a) => cache.get(a) === undefined),
"single"
).then(({ keys, array }) => {
allMarkets.forEach(() => { });
allMarkets.forEach(() => {});
return array.map((item, index) => {
const marketAddress = keys[index];
@ -159,7 +159,7 @@ export function MarketProvider({ children = null as any }) {
const info = marketByMint.get(mintAddress);
const market = cache.get(info?.marketInfo.address.toBase58() || "");
if (!market) {
return () => { };
return () => {};
}
// TODO: get recent volume
@ -249,7 +249,11 @@ export const usePrecacheMarket = () => {
return context.precacheMarkets;
};
export const simulateMarketOrderFill = (amount: number, reserve: LendingReserve, dex: PublicKey) => {
export const simulateMarketOrderFill = (
amount: number,
reserve: LendingReserve,
dex: PublicKey
) => {
const liquidityMint = cache.get(reserve.liquidityMint);
const collateralMint = cache.get(reserve.collateralMint);
if (!liquidityMint || !collateralMint) {
@ -279,9 +283,7 @@ export const simulateMarketOrderFill = (amount: number, reserve: LendingReserve,
decodedMarket.programId
);
const bookAccount = lendingMarket.info.quoteMint.equals(
reserve.liquidityMint
)
const bookAccount = lendingMarket.info.quoteMint.equals(reserve.liquidityMint)
? decodedMarket?.bids
: decodedMarket?.asks;
@ -299,9 +301,9 @@ export const simulateMarketOrderFill = (amount: number, reserve: LendingReserve,
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;
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;
@ -315,7 +317,7 @@ export const simulateMarketOrderFill = (amount: number, reserve: LendingReserve,
}
return cost;
}
};
const getMidPrice = (marketAddress?: string, mintAddress?: string) => {
const SERUM_TOKEN = TOKEN_MINTS.find(

View File

@ -2,7 +2,11 @@ import { PublicKey } from "@solana/web3.js";
import { useCallback, useEffect, useMemo, useState } from "react";
import { cache, ParsedAccount } from "./../contexts/accounts";
import { useLendingObligations } from "./useLendingObligations";
import { collateralToLiquidity, LendingObligation, LendingReserve } from "../models/lending";
import {
collateralToLiquidity,
LendingObligation,
LendingReserve,
} from "../models/lending";
import { useLendingReserves } from "./useLendingReserves";
import { fromLamports, wadToLamports } from "../utils/utils";
import { MintInfo } from "@solana/spl-token";
@ -10,7 +14,7 @@ import { simulateMarketOrderFill, useMarkets } from "../contexts/market";
interface EnrichedLendingObligationInfo extends LendingObligation {
ltv: number;
health: number
health: number;
}
export interface EnrichedLendingObligation {
@ -25,67 +29,86 @@ export function useEnrichedLendingObligations() {
const availableReserves = useMemo(() => {
return reserveAccounts.reduce((map, reserve) => {
map.set(reserve.pubkey.toBase58(), reserve);
map.set(reserve.pubkey.toBase58(), reserve);
return map;
}, new Map<string, ParsedAccount<LendingReserve>>())
}, new Map<string, ParsedAccount<LendingReserve>>());
}, [reserveAccounts]);
const enrichedFactory = useCallback(() => {
if (availableReserves.size === 0) {
return [];
}
return obligations
.map(obligation => (
{
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;
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);
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 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
);
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,
// TODO: add borrow and collateral expressed in lending market quote ccy
ltv = (100 * collateral) / borrowedAmount;
}
} as EnrichedLendingObligation;
})
.sort((a, b) => a.info.health - b.info.health);
const liquidationThreshold =
item.reserve.info.config.liquidationThreshold;
const health = ltv / liquidationThreshold;
return {
account: obligation,
info: {
...obligation.info,
ltv,
health,
// TODO: add borrow and collateral expressed in lending market quote ccy
},
} as EnrichedLendingObligation;
})
.sort((a, b) => a.info.health - b.info.health)
);
}, [obligations, availableReserves]);
const [enriched, setEnriched] = useState<EnrichedLendingObligation[]>(enrichedFactory());
const [enriched, setEnriched] = useState<EnrichedLendingObligation[]>(
enrichedFactory()
);
useEffect(() => {
const dispose = marketEmitter.onMarket(() => {
@ -107,7 +130,7 @@ export function useEnrichedLendingObligation(address?: string | PublicKey) {
const { obligations } = useEnrichedLendingObligations();
const obligation = useMemo(() => {
return obligations.find(ob => ob.account.pubkey.toBase58() === id);
return obligations.find((ob) => ob.account.pubkey.toBase58() === id);
}, [obligations, id]);
return obligation;

View File

@ -32,7 +32,9 @@ export function useLendingObligations() {
export function useLendingObligation(address?: string | PublicKey) {
const id = typeof address === "string" ? address : address?.toBase58();
const [obligationAccount, setObligationAccount] = useState(cache.get(id || "") as ParsedAccount<LendingObligation>);
const [obligationAccount, setObligationAccount] = useState(
cache.get(id || "") as ParsedAccount<LendingObligation>
);
useEffect(() => {
const dispose = cache.emitter.onCache((args) => {

View File

@ -3,15 +3,23 @@ import { useUserObligations } from "./useUserObligations";
import { PublicKey } from "@solana/web3.js";
export function useUserObligationByReserve(
borrowReserve?: string | PublicKey,
collateralReserve?: string | PublicKey) {
borrowReserve?: string | PublicKey,
collateralReserve?: string | PublicKey
) {
const { userObligations } = useUserObligations();
const userObligationsByReserve = useMemo(() => {
const borrowId = typeof borrowReserve === "string" ? borrowReserve : borrowReserve?.toBase58();
const collateralId = typeof collateralReserve === "string" ? collateralReserve : collateralReserve?.toBase58();
const borrowId =
typeof borrowReserve === "string"
? borrowReserve
: borrowReserve?.toBase58();
const collateralId =
typeof collateralReserve === "string"
? collateralReserve
: collateralReserve?.toBase58();
return userObligations.filter(
(item) => item.obligation.info.borrowReserve.toBase58() === borrowId &&
(item) =>
item.obligation.info.borrowReserve.toBase58() === borrowId &&
item.obligation.info.collateralReserve.toBase58() === collateralId
);
}, [borrowReserve, collateralReserve, userObligations]);

View File

@ -41,7 +41,7 @@ export const LendingObligationParser = (
info: AccountInfo<Buffer>
) => {
const buffer = Buffer.from(info.data);
const data = LendingObligationLayout.decode(buffer);
const data = LendingObligationLayout.decode(buffer);
const details = {
pubkey: pubKey,

View File

@ -183,16 +183,29 @@ export const reserveMarketCap = (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 | number, reserve?: LendingReserve) => {
const amount = typeof collateralAmount === 'number' ? collateralAmount : collateralAmount.toNumber();
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 | number, reserve?: LendingReserve) => {
const amount = typeof liquidityAmount === 'number' ? liquidityAmount : liquidityAmount.toNumber();
export const liquidityToCollateral = (
liquidityAmount: BN | number,
reserve?: LendingReserve
) => {
const amount =
typeof liquidityAmount === "number"
? liquidityAmount
: liquidityAmount.toNumber();
return Math.floor(amount * collateralExchangeRate(reserve));
}
};

View File

@ -19,7 +19,7 @@ import {
ReserveView,
WithdrawView,
LiquidateView,
LiquidateReserveView
LiquidateReserveView,
} from "./views";
export function Routes() {

View File

@ -125,7 +125,8 @@ export function fromLamports(
? 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;

View File

@ -17,7 +17,9 @@ export const BorrowItem = (props: {
const price = useMidPriceInUSD(props.reserve.liquidityMint.toBase58()).price;
// TODO: calculate avilable amount... based on total owned collateral across all the reserves
const { balance: collateralBalance } = useUserCollateralBalance(props.reserve);
const { balance: collateralBalance } = useUserCollateralBalance(
props.reserve
);
const apr = calculateBorrowAPY(props.reserve);

View File

@ -40,8 +40,11 @@ export const ObligationItem = (props: {
const borrowAPY = useMemo(() => calculateBorrowAPY(borrowReserve.info), [
borrowReserve,
]);
const collateralLamports = collateralToLiquidity(obligation.info.depositedCollateral, borrowReserve.info);
const collateralLamports = collateralToLiquidity(
obligation.info.depositedCollateral,
borrowReserve.info
);
const collateral = fromLamports(collateralLamports, collateralMint);
const borrowName = useTokenName(borrowReserve?.info.liquidityMint);
@ -51,7 +54,10 @@ export const ObligationItem = (props: {
<Card>
<div className="dashboard-item">
<span style={{ display: "flex", marginLeft: 5 }}>
<div style={{ display: "flex" }} title={`${collateralName}${borrowName}`}>
<div
style={{ display: "flex" }}
title={`${collateralName}${borrowName}`}
>
<TokenIcon
mintAddress={collateralReserve?.info.liquidityMint}
style={{ marginRight: "-0.5rem" }}

View File

@ -18,7 +18,9 @@ export const ReserveItem = (props: {
}) => {
const name = useTokenName(props.reserve.liquidityMint);
const { balance: tokenBalance } = useUserBalance(props.reserve.liquidityMint);
const { balance: collateralBalance } = useUserCollateralBalance(props.reserve);
const { balance: collateralBalance } = useUserCollateralBalance(
props.reserve
);
const apy = calculateDepositAPY(props.reserve);

View File

@ -24,7 +24,6 @@ export const HomeView = () => {
reserveAccounts.forEach((item) => {
const marketCapLamports = reserveMarketCap(item.info);
const localCache = cache;
const liquidityMint = localCache.get(
item.info.liquidityMint.toBase58()
@ -40,9 +39,12 @@ export const HomeView = () => {
totalSize = totalSize + marketCap;
borrowed = borrowed + fromLamports(
wadToLamports(item.info?.borrowedLiquidityWad).toNumber(),
liquidityMint.info);
borrowed =
borrowed +
fromLamports(
wadToLamports(item.info?.borrowedLiquidityWad).toNumber(),
liquidityMint.info
);
});
setTotalMarketSize(totalSize);
@ -64,18 +66,18 @@ export const HomeView = () => {
<div className="flexColumn">
<Row gutter={16} className="home-info-row">
<Col span={12}>
<Card >
<Card>
<Statistic
title="Current market size"
value={totalMarketSize}
precision={2}
valueStyle={{ color: '#3f8600' }}
valueStyle={{ color: "#3f8600" }}
prefix="$"
/>
</Card>
</Col>
<Col span={12}>
<Card >
<Card>
<Statistic
title="Total borrowed"
value={totalBorrowed}
@ -86,7 +88,6 @@ export const HomeView = () => {
</Col>
</Row>
<div className="home-item home-header">
<div>{LABELS.TABLE_TITLE_ASSET}</div>
<div>{LABELS.TABLE_TITLE_MARKET_SIZE}</div>

View File

@ -12,19 +12,22 @@ export const LiquidateView = () => {
{obligations.length === 0 ? (
<div className="liquidate-info">{LABELS.LIQUIDATE_NO_LOANS}</div>
) : (
<div className="flexColumn">
<div className="liquidate-item liquidate-header">
<div>{LABELS.TABLE_TITLE_ASSET}</div>
<div>{LABELS.TABLE_TITLE_LOAN_BALANCE}</div>
<div>{LABELS.TABLE_TITLE_APY}</div>
<div>{LABELS.TABLE_TITLE_LTV}</div>
<div>{LABELS.TABLE_TITLE_ACTION}</div>
</div>
{obligations.map((item) => (
<LiquidateItem key={item.account.pubkey.toBase58()} item={item}></LiquidateItem>
))}
<div className="flexColumn">
<div className="liquidate-item liquidate-header">
<div>{LABELS.TABLE_TITLE_ASSET}</div>
<div>{LABELS.TABLE_TITLE_LOAN_BALANCE}</div>
<div>{LABELS.TABLE_TITLE_APY}</div>
<div>{LABELS.TABLE_TITLE_LTV}</div>
<div>{LABELS.TABLE_TITLE_ACTION}</div>
</div>
)}
{obligations.map((item) => (
<LiquidateItem
key={item.account.pubkey.toBase58()}
item={item}
></LiquidateItem>
))}
</div>
)}
</div>
);
};

View File

@ -13,19 +13,17 @@ import {
} from "../../utils/utils";
import { LABELS } from "../../constants";
export const LiquidateItem = (props: {
item: EnrichedLendingObligation
}) => {
let obligation = props.item.info
export const LiquidateItem = (props: { item: EnrichedLendingObligation }) => {
let obligation = props.item.info;
const borrowReserve = cache.get(
obligation.borrowReserve
) as ParsedAccount<LendingReserve>;
const borrowReserve = cache.get(obligation.borrowReserve) as ParsedAccount<
LendingReserve
>;
const collateralReserve = cache.get(
obligation.collateralReserve
) as ParsedAccount<LendingReserve>;
const tokenName = useTokenName(borrowReserve?.info.liquidityMint);
const liquidityMint = useMint(borrowReserve.info.liquidityMint);
@ -53,19 +51,13 @@ export const LiquidateItem = (props: {
/>
<TokenIcon mintAddress={borrowReserve?.info.liquidityMint} />
</div>
{collateralName}
{borrowName}
{collateralName}{borrowName}
</span>
<div>
{formatNumber.format(borrowAmount)} {tokenName}
</div>
<div>
{formatPct.format(borrowAPY)}
</div>
<div>
{formatPct.format(obligation.ltv / 100)}
</div>
<div>{formatPct.format(borrowAPY)}</div>
<div>{formatPct.format(obligation.ltv / 100)}</div>
<div>
<Button>
<span>{LABELS.LIQUIDATE_ACTION}</span>
@ -75,4 +67,4 @@ export const LiquidateItem = (props: {
</Card>
</Link>
);
};
};

View File

@ -15,7 +15,9 @@ export const LiquidateReserveView = () => {
const obligation = useEnrichedLendingObligation(id);
const reserve = useLendingReserve(obligation?.info.borrowReserve);
const collateralReserve = useLendingReserve(obligation?.info.collateralReserve);
const collateralReserve = useLendingReserve(
obligation?.info.collateralReserve
);
if (!obligation || !reserve) {
return null;
@ -37,5 +39,5 @@ export const LiquidateReserveView = () => {
/>
</div>
</div>
)
}
);
};

View File

@ -21,7 +21,6 @@ export const RepayReserveView = () => {
obligationId ? lendingObligation?.info.borrowReserve : reserveId
);
const repayReserve = useLendingReserve(
obligationId ? lendingObligation?.info.collateralReserve : reserveId
);