Skip to content

Commit

Permalink
Merge pull request #162 from blend-capital/backstop-q4w-exp
Browse files Browse the repository at this point in the history
Backstop q4w exp
  • Loading branch information
mootz12 authored Oct 22, 2024
2 parents 5eea1e0 + f02f165 commit 6eed165
Show file tree
Hide file tree
Showing 23 changed files with 312 additions and 274 deletions.
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "blend-ui",
"version": "1.1.2",
"version": "1.1.3",
"private": true,
"type": "module",
"scripts": {
Expand All @@ -12,7 +12,7 @@
"lint": "next lint"
},
"dependencies": {
"@blend-capital/blend-sdk": "2.0.3",
"@blend-capital/blend-sdk": "2.0.4",
"@creit.tech/stellar-wallets-kit": "1.2.1",
"@emotion/react": "^11.9.3",
"@emotion/styled": "^11.9.3",
Expand Down
29 changes: 5 additions & 24 deletions src/components/backstop/BackstopAPR.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { BackstopPoolEst, FixedMath, PoolEstimate } from '@blend-capital/blend-sdk';
import { HelpOutline } from '@mui/icons-material';
import { Box, Tooltip, Typography } from '@mui/material';
import { Box, Typography } from '@mui/material';
import { useBackstop, useBackstopPool, usePool, usePoolOracle } from '../../hooks/api';
import { getEmissionTextFromValue, toPercentage } from '../../utils/formatter';
import { FlameIcon } from '../common/FlameIcon';
import { PoolComponentProps } from '../common/PoolComponentProps';
import { TooltipText } from '../common/TooltipText';

export const BackstopAPR: React.FC<PoolComponentProps> = ({ poolId, sx, ...props }) => {
const { data: pool } = usePool(poolId);
Expand Down Expand Up @@ -45,28 +45,9 @@ export const BackstopAPR: React.FC<PoolComponentProps> = ({ poolId, sx, ...props
padding: '6px',
}}
>
<Tooltip
title="Estimated APR based on pool interest sharing."
placement="top"
enterTouchDelay={0}
enterDelay={500}
leaveTouchDelay={3000}
>
<Box
sx={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'flex-start',
alignItems: 'flex-end',
...sx,
}}
>
<Typography variant="body2" color={'text.secondary'}>
{'Backstop APR'}
</Typography>
<HelpOutline sx={{ marginLeft: '6px', width: '15px', color: 'text.secondary' }} />
</Box>
</Tooltip>
<TooltipText tooltip="Estimated APR based on pool interest sharing." width="100%">
Backstop APR
</TooltipText>
<Box
sx={{
display: 'flex',
Expand Down
64 changes: 23 additions & 41 deletions src/components/backstop/BackstopPreviewBar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { BackstopPoolEst, BackstopPoolUserEst } from '@blend-capital/blend-sdk';
import { HelpOutline } from '@mui/icons-material';
import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import { Box, Tooltip, useTheme } from '@mui/material';
import { Box, useTheme } from '@mui/material';
import { useSettings, ViewType } from '../../contexts';
import { useBackstop, useBackstopPool, useBackstopPoolUser } from '../../hooks/api';
import { toBalance } from '../../utils/formatter';
Expand Down Expand Up @@ -64,46 +63,29 @@ export const BackstopPreviewBar: React.FC<PoolComponentProps> = ({ poolId }) =>
>
<PoolStatusBox titleColor="inherit" type="large" status="Active" />
</Box>
<Tooltip
title="The amount of capital insuring this pool."
placement="top"
enterTouchDelay={0}
enterDelay={500}
leaveTouchDelay={3000}
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginLeft: 'auto',
marginRight: '23px',
}}
>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
marginLeft: 'auto',
marginRight: '23px',
}}
>
<Box sx={{ display: 'flex', flexDirection: 'row' }}>
<StackedText
title="Total Backstop Size"
titleColor="inherit"
text={`$${toBalance(backstopPoolEst.totalSpotValue)}`}
textColor="inherit"
type="large"
/>
<HelpOutline
sx={{
color: theme.palette.text.secondary,
width: '15px',
marginLeft: '4px',
marginTop: '-4px',
}}
/>
</Box>
<Icon
src={'/icons/dashboard/bkstp_size.svg'}
alt={`backstop size icon`}
sx={{ marginLeft: '12px' }}
/>
</Box>
</Tooltip>
<StackedText
title="Total Backstop Size"
titleColor="inherit"
text={`$${toBalance(backstopPoolEst.totalSpotValue)}`}
textColor="inherit"
type="large"
tooltip="The amount of capital insuring this pool."
/>
<Icon
src={'/icons/dashboard/bkstp_size.svg'}
alt={`backstop size icon`}
sx={{ marginLeft: '12px' }}
/>
</Box>
</Box>
<LinkBox
sx={{ width: viewTypeRegular ? '45%' : '100%', display: 'flex' }}
Expand Down
111 changes: 71 additions & 40 deletions src/components/backstop/BackstopQueueItem.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { PoolBackstopActionArgs, Q4W } from '@blend-capital/blend-sdk';
import { BackstopContract, PoolBackstopActionArgs, Q4W } from '@blend-capital/blend-sdk';
import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline';
import { Box, CircularProgress, Tooltip, Typography } from '@mui/material';
import { ReactNode, useEffect, useState } from 'react';
import { Box, CircularProgress, SxProps, Theme, Tooltip, Typography } from '@mui/material';
import { SorobanRpc } from '@stellar/stellar-sdk';
import { useEffect, useState } from 'react';
import { useSettings, ViewType } from '../../contexts';
import { useWallet } from '../../contexts/wallet';
import { useSimulateOperation } from '../../hooks/api';
import theme from '../../theme';
import { toBalance, toTimeSpan } from '../../utils/formatter';
import { Icon } from '../common/Icon';
Expand All @@ -22,10 +24,27 @@ export const BackstopQueueItem: React.FC<BackstopQueueItemProps> = ({
first,
poolId,
}) => {
const { connected, walletAddress, backstopDequeueWithdrawal, backstopWithdraw } = useWallet();

const { connected, walletAddress, backstopDequeueWithdrawal, backstopWithdraw, restore } =
useWallet();
const { viewType } = useSettings();

const backstop = new BackstopContract(process.env.NEXT_PUBLIC_BACKSTOP ?? '');
const actionArgs: PoolBackstopActionArgs = {
from: walletAddress,
pool_address: poolId,
amount: q4w.amount,
};
// the BackstopQueueMod sets the expiration for unlocked withdrawals to 0
const sim_op =
q4w.exp === BigInt(0) ? backstop.withdraw(actionArgs) : backstop.dequeueWithdrawal(actionArgs);
const {
data: simResult,
isLoading,
refetch: refetchSim,
} = useSimulateOperation(sim_op, q4w.exp === BigInt(0) || first);
const isRestore =
isLoading === false && simResult !== undefined && SorobanRpc.Api.isSimulationRestore(simResult);

const TOTAL_QUEUE_TIME_SECONDS = 21 * 24 * 60 * 60;

const [timeLeft, setTimeLeft] = useState<number>(
Expand All @@ -42,13 +61,8 @@ export const BackstopQueueItem: React.FC<BackstopQueueItemProps> = ({
return () => clearInterval(refreshInterval);
}, [q4w]);

const handleClick = async (amount: bigint) => {
const handleClick = async () => {
if (connected) {
let actionArgs: PoolBackstopActionArgs = {
from: walletAddress,
pool_address: poolId,
amount: BigInt(amount),
};
if (timeLeft > 0) {
await backstopDequeueWithdrawal(actionArgs, false);
} else {
Expand All @@ -57,19 +71,58 @@ export const BackstopQueueItem: React.FC<BackstopQueueItemProps> = ({
}
};

const wrapButtonTooptip = (condition: boolean, children: ReactNode) => {
return condition ? (
const handleRestore = async () => {
if (simResult && SorobanRpc.Api.isSimulationRestore(simResult)) {
await restore(simResult);
refetchSim();
}
};

const queueItemActionButton = (sx: SxProps<Theme>) => {
const needsTooltip = !first || isRestore;
const tooltipMessage = !first
? 'You can only unqueue the oldest withdrawal'
: 'This transaction ran into expired entries which need to be restored before proceeding.';

return needsTooltip ? (
<Tooltip
title="You can only unqueue the oldest withdrawal"
title={tooltipMessage}
placement="top"
enterTouchDelay={0}
enterDelay={500}
leaveTouchDelay={3000}
>
<span>{children}</span>
<Box sx={sx}>
{isRestore ? (
<OpaqueButton
onClick={() => handleRestore()}
palette={theme.palette.warning}
disabled={false}
sx={{ width: '100%' }}
>
Restore
</OpaqueButton>
) : (
<OpaqueButton
onClick={() => handleClick()}
palette={theme.palette.positive}
disabled={!first}
sx={{ width: '100%' }}
>
{timeLeft > 0 ? 'Unqueue' : 'Withdraw'}
</OpaqueButton>
)}
</Box>
</Tooltip>
) : (
children
<OpaqueButton
onClick={() => handleClick()}
palette={theme.palette.positive}
disabled={!first}
sx={sx}
>
{timeLeft > 0 ? 'Unqueue' : 'Withdraw'}
</OpaqueButton>
);
};

Expand Down Expand Up @@ -137,32 +190,10 @@ export const BackstopQueueItem: React.FC<BackstopQueueItemProps> = ({
</Box>
</Box>
{viewType === ViewType.REGULAR &&
wrapButtonTooptip(
!first,
<OpaqueButton
onClick={() => handleClick(q4w.amount)}
palette={theme.palette.positive}
disabled={!first}
sx={{ height: '35px', width: '108px', margin: '12px', padding: '6px' }}
>
{timeLeft > 0 ? 'Unqueue' : 'Withdraw'}
</OpaqueButton>
)}
queueItemActionButton({ height: '35px', width: '108px', margin: '12px' })}
</Row>
{viewType !== ViewType.REGULAR && (
<Row>
{wrapButtonTooptip(
!first,
<OpaqueButton
onClick={() => handleClick(q4w.amount)}
palette={theme.palette.positive}
disabled={!first}
sx={{ height: '35px', width: '100%', margin: '12px', padding: '6px' }}
>
{timeLeft > 0 ? 'Unqueue' : 'Withdraw'}
</OpaqueButton>
)}
</Row>
<Row>{queueItemActionButton({ height: '35px', width: '100%', margin: '12px' })}</Row>
)}
</>
);
Expand Down
39 changes: 11 additions & 28 deletions src/components/borrow/BorrowMarketList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import HelpOutline from '@mui/icons-material/HelpOutline';
import { Box, Tooltip, Typography } from '@mui/material';
import { Box, Typography } from '@mui/material';
import { ViewType, useSettings } from '../../contexts';
import { usePool } from '../../hooks/api';
import { PoolComponentProps } from '../common/PoolComponentProps';
import { Skeleton } from '../common/Skeleton';
import { TooltipText } from '../common/TooltipText';
import { BorrowMarketCard } from './BorrowMarketCard';

export const BorrowMarketList: React.FC<PoolComponentProps> = ({ poolId }) => {
Expand Down Expand Up @@ -50,36 +50,19 @@ export const BorrowMarketList: React.FC<PoolComponentProps> = ({ poolId }) => {
>
Available
</Typography>
<Typography
variant="body2"
color="text.secondary"
align="center"
sx={{ width: headerWidth }}
<TooltipText
tooltip="The interest rate charged for a borrowed position. This rate will fluctuate based on the market conditions and is accrued to the borrowed position."
width={headerWidth}
>
APR
</Typography>
</TooltipText>
{viewType !== ViewType.MOBILE && (
<Tooltip
title="The percent of this asset's value subtracted from your borrow capacity."
placement="top"
enterTouchDelay={0}
enterDelay={500}
leaveTouchDelay={3000}
<TooltipText
tooltip="The percent of this asset's value subtracted from your borrow capacity."
width={headerWidth}
>
<Box sx={{ display: 'flex', flexDirection: 'row', width: headerWidth }}>
<Typography variant="body2" color="text.secondary" align="center">
Liability Factor
</Typography>
<HelpOutline
sx={{
color: 'text.secondary',
width: '15px',
marginTop: '-4px',
marginLeft: '4px',
}}
/>
</Box>
</Tooltip>
Liability Factor
</TooltipText>
)}

<Box sx={{ width: viewType === ViewType.MOBILE ? 'auto' : headerWidth }} />
Expand Down
4 changes: 3 additions & 1 deletion src/components/borrow/BorrowPositionCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ export const BorrowPositionCard: React.FC<BorrowPositionCardProps> = ({

const tableNum = viewType === ViewType.REGULAR ? 5 : 3;
const tableWidth = `${(100 / tableNum).toFixed(2)}%`;
const buttonWidth = `${((100 / tableNum) * 1.5).toFixed(2)}%`;
const buttonWidth = `${((100 / tableNum) * (viewType === ViewType.REGULAR ? 1.5 : 1)).toFixed(
2
)}%`;

const emissionsPerAsset = reserve.emissionsPerYearPerBorrowedAsset();

Expand Down
Loading

1 comment on commit 6eed165

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This commit was deployed on ipfs

Please sign in to comment.