Skip to content

Commit

Permalink
Merge pull request #1040 from liquity/redemptions-info-bubble
Browse files Browse the repository at this point in the history
feat: give a heads up about redemption risk
  • Loading branch information
danielattilasimon authored Feb 26, 2024
2 parents f79fc03 + 9ec7d77 commit 120d0e6
Show file tree
Hide file tree
Showing 19 changed files with 130 additions and 70 deletions.
10 changes: 2 additions & 8 deletions packages/dev-frontend/src/components/ActionDescription.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { Box, Flex, Text } from "theme-ui";

import { Icon } from "./Icon";

export const ActionDescription: React.FC = ({ children }) => (
<Box
sx={{
Expand All @@ -13,15 +11,11 @@ export const ActionDescription: React.FC = ({ children }) => (
p: 3,

border: 1,
borderRadius: "8px",
borderColor: "accent",
boxShadow: 2,
bg: "rgba(46, 182, 234, 0.05)"
borderColor: "transparent"
}}
>
<Flex sx={{ alignItems: "center" }}>
<Icon name="info-circle" size="lg" />
<Text sx={{ ml: 2 }}>{children}</Text>
<Text>{children}</Text>
</Flex>
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { EventType } from "../../../HorizontalTimeline";
import * as l from "../../lexicon";
import { Cancel } from "./actions/cancel/Cancel";
import { Claim } from "./actions/claim/Claim";
import { Warning } from "../../../Warning";
import { WarningBubble } from "../../../WarningBubble";
import { ReactModal } from "../../../ReactModal";
import { percentify } from "../../utils";
import { Decimal } from "@liquity/lib-base";
Expand Down Expand Up @@ -144,10 +144,14 @@ export const Actioning: React.FC = () => {

<Box mt={3}>
{view === "CLAIMING" && bond.claimNowReturn < 0 && (
<Warning>You are claiming a bond which currently has a negative return</Warning>
<WarningBubble>
You are claiming a bond which currently has a negative return
</WarningBubble>
)}
{view === "CANCELLING" && bond.accrued.gte(bond.breakEvenAccrual) && (
<Warning>Your are cancelling a bond which has accrued a positive return</Warning>
<WarningBubble>
Your are cancelling a bond which has accrued a positive return
</WarningBubble>
)}
</Box>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { Flex, Button, Text, Spinner } from "theme-ui";
import { ActionDescription } from "../../../../../ActionDescription";
import { Flex, Button, Spinner } from "theme-ui";
import { ActionDescription, Amount } from "../../../../../ActionDescription";
import { useBondView } from "../../../../context/BondViewContext";

export const Cancel: React.FC = () => {
Expand All @@ -21,9 +21,8 @@ export const Cancel: React.FC = () => {
return (
<>
<ActionDescription>
You will receive your bonded{" "}
<Text sx={{ fontWeight: "bold" }}>{bond.deposit.prettify(2)} LUSD</Text> back and forgo{" "}
<Text sx={{ fontWeight: "bold" }}>{bond.accrued.shorten()} bLUSD</Text>
You will receive your bonded <Amount>{bond.deposit.prettify(2)} LUSD</Amount> back and forgo{" "}
<Amount>{bond.accrued.shorten()} bLUSD</Amount>
</ActionDescription>

<Flex variant="layout.actions">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from "react";
import { Flex, Button, Text, Spinner } from "theme-ui";
import { ActionDescription } from "../../../../../ActionDescription";
import { Flex, Button, Spinner } from "theme-ui";
import { ActionDescription, Amount } from "../../../../../ActionDescription";
import { useBondView } from "../../../../context/BondViewContext";

export const Claim: React.FC = () => {
Expand All @@ -21,9 +21,8 @@ export const Claim: React.FC = () => {
return (
<>
<ActionDescription>
You will receive <Text sx={{ fontWeight: "bold" }}>{bond.accrued.prettify(2)} bLUSD</Text>{" "}
and forgo your bonded{" "}
<Text sx={{ fontWeight: "bold" }}>{bond.deposit.prettify(2)} LUSD</Text>
You will receive <Amount>{bond.accrued.prettify(2)} bLUSD</Amount> and forgo your bonded{" "}
<Amount>{bond.deposit.prettify(2)} LUSD</Amount>
</ActionDescription>

<Flex variant="layout.actions">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { Record } from "../../Record";
import { InfoIcon } from "../../../InfoIcon";
import { useBondView } from "../../context/BondViewContext";
import { HorizontalTimeline, Label, SubLabel, UNKNOWN_DATE } from "../../../HorizontalTimeline";
import { ActionDescription } from "../../../ActionDescription";
import { ActionDescription, Amount } from "../../../ActionDescription";
import { EXAMPLE_NFT } from "../../context/BondViewProvider";
import * as l from "../../lexicon";
import { useWizard } from "../../../Wizard/Context";
import { Warning } from "../../../Warning";
import { WarningBubble } from "../../../WarningBubble";
import type { CreateBondPayload } from "../../context/transitions";
import {
dateWithoutHours,
Expand All @@ -25,7 +25,6 @@ import {
} from "../../utils";
import { HorizontalSlider } from "../../../HorizontalSlider";
import { ErrorDescription } from "../../../ErrorDescription";
import { Amount } from "../../../ActionDescription";
import { InfiniteEstimate } from "../InfiniteEstimation";
import { LearnMoreLink } from "../../../Tooltip";

Expand Down Expand Up @@ -269,11 +268,11 @@ export const Details: React.FC<DetailsProps> = ({ onBack }) => {
/>

{!protocolInfo.hasMarketPremium && (
<Warning>
<WarningBubble>
When the bLUSD market price is less than 3% above the floor price, it's not profitable to
bond. Buying bLUSD from the market currently generates a higher return than bonding.{" "}
<LearnMoreLink link={l.INFINITE_ESTIMATION.link} />
</Warning>
</WarningBubble>
)}

{!isInfiniteBondApproved && (
Expand All @@ -283,14 +282,16 @@ export const Details: React.FC<DetailsProps> = ({ onBack }) => {
)}

{statuses.APPROVE === "FAILED" && (
<Warning>Failed to approve spend of LUSD. Please try again.</Warning>
<WarningBubble>Failed to approve spend of LUSD. Please try again.</WarningBubble>
)}

{statuses.CREATE === "FAILED" && <Warning>Failed to create bond. Please try again.</Warning>}
{statuses.CREATE === "FAILED" && (
<WarningBubble>Failed to create bond. Please try again.</WarningBubble>
)}

{isInfiniteBondApproved && (
<ActionDescription>
You are bonding <Text sx={{ fontWeight: "bold" }}>{deposit.prettify(2)} LUSD</Text>
You are bonding <Amount>{deposit.prettify(2)} LUSD</Amount>
</ActionDescription>
)}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useBondView } from "../../context/BondViewContext";
import type { BondStatus, Bond as BondType } from "../../context/transitions";
import { Bond } from "./Bond";
import { OptimisticBond } from "./OptimisticBond";
import { ActionDescription } from "../../../ActionDescription";
import { InfoBubble } from "../../../InfoBubble";
import { Box } from "theme-ui";

type BondFilter = "pending" | "claimed" | "cancelled";
Expand Down Expand Up @@ -45,9 +45,9 @@ export const FilteredBondList = () => {

{!showOptimisticBond && filteredBonds.length === 0 && (
<Box mt={2}>
<ActionDescription>
<InfoBubble>
You don't have any {bondFilter !== "all" ? bondFilter : null} bonds
</ActionDescription>
</InfoBubble>
</Box>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Amount } from "../../../ActionDescription";
import { ErrorDescription } from "../../../ErrorDescription";
import { Icon } from "../../../Icon";
import { DisabledEditableAmounts, DisabledEditableRow, EditableRow } from "../../../Trove/Editor";
import { Warning } from "../../../Warning";
import { WarningBubble } from "../../../WarningBubble";
import { useBondView } from "../../context/BondViewContext";
import { ApprovePressedPayload, BLusdAmmTokenIndex } from "../../context/transitions";
import { PoolDetails } from "./PoolDetails";
Expand Down Expand Up @@ -135,10 +135,10 @@ export const WithdrawPane: React.FC = () => {
return (
<>
{stakedLpTokenBalance?.nonZero && (
<Warning>
<WarningBubble>
You {lpTokenBalance?.nonZero && " also "} have {stakedLpTokenBalance.shorten()} staked LP
tokens. Unstake them to withdraw liquidity from them.
</Warning>
</WarningBubble>
)}
<EditableRow
label="Burn LP Tokens"
Expand Down Expand Up @@ -236,4 +236,4 @@ export const WithdrawPane: React.FC = () => {
</Flex>
</>
);
};;
};
27 changes: 27 additions & 0 deletions packages/dev-frontend/src/components/InfoBubble.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Box, Flex, Text } from "theme-ui";

import { Icon } from "./Icon";

export const InfoBubble: React.FC = ({ children }) => (
<Box
sx={{
display: "flex",
flexDirection: "column",
justifyContent: "space-around",

mb: [2, 3],
p: 3,

border: 1,
borderRadius: "8px",
borderColor: "accent",
boxShadow: 2,
bg: "rgba(46, 182, 234, 0.05)"
}}
>
<Flex sx={{ alignItems: "center" }}>
<Icon name="info-circle" size="lg" />
<Text sx={{ ml: 2 }}>{children}</Text>
</Flex>
</Box>
);
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { LiquityStoreUpdate, useLiquityReducer, useLiquitySelector } from "@liqu

import { COIN } from "../../strings";

import { ActionDescription } from "../ActionDescription";
import { InfoBubble } from "../InfoBubble";
import { useMyTransactionState } from "../Transaction";

import { StabilityDepositEditor } from "./StabilityDepositEditor";
Expand Down Expand Up @@ -132,9 +132,9 @@ export const StabilityDepositManager: React.FC = () => {
>
{description ??
(makingNewDeposit ? (
<ActionDescription>Enter the amount of {COIN} you'd like to deposit.</ActionDescription>
<InfoBubble>Enter the amount of {COIN} you'd like to deposit.</InfoBubble>
) : (
<ActionDescription>Adjust the {COIN} amount to deposit or withdraw.</ActionDescription>
<InfoBubble>Adjust the {COIN} amount to deposit or withdraw.</InfoBubble>
))}

<Flex variant="layout.actions">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { StakingEditor } from "./StakingEditor";
import { StakingManagerAction } from "./StakingManagerAction";
import { ActionDescription, Amount } from "../ActionDescription";
import { ErrorDescription } from "../ErrorDescription";
import { InfoBubble } from "../InfoBubble";

const init = ({ lqtyStake }: LiquityStoreState) => ({
originalStake: lqtyStake,
Expand Down Expand Up @@ -143,9 +144,9 @@ export const StakingManager: React.FC = () => {
<StakingEditor title={"Staking"} {...{ originalStake, editedLQTY, dispatch }}>
{description ??
(makingNewStake ? (
<ActionDescription>Enter the amount of {GT} you'd like to stake.</ActionDescription>
<InfoBubble>Enter the amount of {GT} you'd like to stake.</InfoBubble>
) : (
<ActionDescription>Adjust the {GT} amount to stake or withdraw.</ActionDescription>
<InfoBubble>Adjust the {GT} amount to stake or withdraw.</InfoBubble>
))}

<Flex variant="layout.actions">
Expand Down
5 changes: 2 additions & 3 deletions packages/dev-frontend/src/components/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import Tippy from "@tippyjs/react";
import type { TippyProps } from "@tippyjs/react";
import React from "react";
import { Box, Card, Link } from "theme-ui";
import { Icon } from "./Icon";

export type TooltipProps = Pick<TippyProps, "placement"> & {
message: React.ReactNode;
Expand All @@ -11,10 +10,10 @@ export type TooltipProps = Pick<TippyProps, "placement"> & {

export type LearnMoreLinkProps = Pick<TooltipProps, "link">;

export const LearnMoreLink: React.FC<LearnMoreLinkProps> = ({ link }) => {
export const LearnMoreLink: React.FC<LearnMoreLinkProps> = ({ link, children }) => {
return (
<Link href={link} target="_blank">
Learn more <Icon size="xs" name="external-link-alt" />
{children ?? <>Learn more</>}
</Link>
);
};
Expand Down
9 changes: 4 additions & 5 deletions packages/dev-frontend/src/components/Trove/Adjusting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import {
import { useLiquitySelector } from "@liquity/lib-react";

import { useStableTroveChange } from "../../hooks/useStableTroveChange";
import { ActionDescription } from "../ActionDescription";
import { InfoBubble } from "../InfoBubble";
import { useMyTransactionState } from "../Transaction";
import { TroveAction } from "./TroveAction";
import { useTroveView } from "./context/TroveViewContext";
import { COIN } from "../../strings";
import { Icon } from "../Icon";
import { InfoIcon } from "../InfoIcon";
import { LoadingOverlay } from "../LoadingOverlay";
import { CollateralRatio } from "./CollateralRatio";
import { CollateralRatio, CollateralRatioInfoBubble } from "./CollateralRatio";
import { EditableRow, StaticRow } from "./Editor";
import { ExpensiveTroveChangeWarning, GasEstimationState } from "./ExpensiveTroveChangeWarning";
import {
Expand Down Expand Up @@ -253,11 +253,10 @@ export const Adjusting: React.FC = () => {
/>

<CollateralRatio value={collateralRatio} change={collateralRatioChange} />
<CollateralRatioInfoBubble value={collateralRatio} />

{description ?? (
<ActionDescription>
Adjust your Trove by modifying its collateral, debt, or both.
</ActionDescription>
<InfoBubble>Adjust your Trove by modifying its collateral, debt, or both.</InfoBubble>
)}

<ExpensiveTroveChangeWarning
Expand Down
28 changes: 24 additions & 4 deletions packages/dev-frontend/src/components/Trove/CollateralRatio.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import { Icon } from "../Icon";

import { StaticRow } from "./Editor";
import { InfoIcon } from "../InfoIcon";
import { ActionDescription } from "../ActionDescription";
import { InfoBubble } from "../InfoBubble";
import { LearnMoreLink } from "../Tooltip";

type CollateralRatioProps = {
value?: Decimal;
Expand Down Expand Up @@ -60,10 +61,29 @@ export const CollateralRatio: React.FC<CollateralRatioProps> = ({ value, change
}
/>
</Flex>
</>
);
};

type CollateralRatioInfoBubbleProps = {
value?: Decimal;
change?: Difference;
};

export const CollateralRatioInfoBubble: React.FC<CollateralRatioInfoBubbleProps> = ({ value }) => {
return (
<>
{value?.lt(1.5) && (
<ActionDescription>
Keeping your CR above 150% can help avoid liquidation under Recovery Mode.
</ActionDescription>
<InfoBubble>
Keep your collateral ratio above 150% to avoid being{" "}
<LearnMoreLink link="https://docs.liquity.org/faq/stability-pool-and-liquidations#what-are-liquidations">
liquidated
</LearnMoreLink>{" "}
under{" "}
<LearnMoreLink link="https://docs.liquity.org/faq/recovery-mode">
Recovery Mode.
</LearnMoreLink>
</InfoBubble>
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Decimal, TroveChange } from "@liquity/lib-base";
import { PopulatedEthersLiquityTransaction } from "@liquity/lib-ethers";

import { useLiquity } from "../../hooks/LiquityContext";
import { Warning } from "../Warning";
import { WarningBubble } from "../WarningBubble";

export type GasEstimationState =
| { type: "idle" | "inProgress" }
Expand Down Expand Up @@ -70,15 +70,15 @@ export const ExpensiveTroveChangeWarning: React.FC<ExpensiveTroveChangeWarningPa
gasEstimationState.populatedTx.gasHeadroom >= 200000
) {
return troveChange.type === "creation" ? (
<Warning>
<WarningBubble>
The cost of opening a Trove in this collateral ratio range is rather high. To lower it,
choose a slightly different collateral ratio.
</Warning>
</WarningBubble>
) : (
<Warning>
<WarningBubble>
The cost of adjusting a Trove into this collateral ratio range is rather high. To lower it,
choose a slightly different collateral ratio.
</Warning>
</WarningBubble>
);
}

Expand Down
Loading

0 comments on commit 120d0e6

Please sign in to comment.