Skip to content

Commit

Permalink
feat(ui-ux): allow dusd loops in vaults (#4114)
Browse files Browse the repository at this point in the history
* feat(ui-ux): allow dusd loops in vaults

* feat(ui-ux): keep dusd loan requirement of 50% dfi

* chore(translations): update error message texts and add translation placeholder

* feat(ui-ux): allow removal of dfi asset if vault will be left with only dusd

* feat(ui-ux): disable load for non-dusd token when 100% col is dusd

* feat(ui-ux): use symbol instead of displaySymbol

* feat(ui-ux): use symbol instead of displaySymbol

* chore(translations): update translation for required collateral error message

* feat(ui-ux): feature-gate dusd-loop based on wallet-website api flags

* chore(translations): update insufficient dusd error message

* Keep previous error message when dusd loop is disabled

* update docker-compose

* update vault details collateral info message
  • Loading branch information
lykalabrada authored Nov 1, 2023
1 parent 269c2e2 commit 9b52cb0
Show file tree
Hide file tree
Showing 14 changed files with 259 additions and 159 deletions.
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ services:
- "/var/run/docker.sock:/var/run/docker.sock:ro"

defi-blockchain:
image: defi/defichain:HEAD-420563c450
image: defi/defichain:master-11717b5810
ports:
- "19554:19554"
- "19551:19551"
Expand Down Expand Up @@ -59,7 +59,7 @@ services:
-fortcanningepilogueheight=15
-grandcentralheight=16
-grandcentralepilogueheight=17
-nextnetworkupgradeheight=18
-metachainheight=18
environment:
- RUST_LOG=debug

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import { CollateralFactorTag } from "@components/CollateralFactorTag";
import { CollateralItem } from "@screens/AppNavigator/screens/Loans/screens/EditCollateralScreen";
import { VaultStatus } from "@screens/AppNavigator/screens/Loans/VaultStatusTypes";
import { useFeatureFlagContext } from "@contexts/FeatureFlagContext";
import { getCollateralPrice } from "../../hooks/CollateralPrice";

interface CollateralCardProps {
Expand All @@ -45,22 +46,56 @@ export function VaultDetailCollateralsRow({
onAddPress: (collateralItem: CollateralItem) => void;
onRemovePress: (collateralItem: CollateralItem) => void;
}): JSX.Element {
const { isFeatureAvailable } = useFeatureFlagContext();
const [hideDFIStaticCard, setHideDFIStaticCard] = useState<boolean>(false);
const [isAffectedVault, setIsAffectedVault] = useState<boolean>(false); // Affected Vault means having DUSD in both collaterals and loans
const [info, setInfo] = useState<{
displayText: string;
title: string;
message: string;
}>();

useEffect(() => {
if (vault.state !== LoanVaultState.IN_LIQUIDATION) {
setHideDFIStaticCard(
vault.collateralAmounts.some((col) => col.displaySymbol === "DFI")
vault.collateralAmounts.some((col) => col.displaySymbol === "DFI"),
);

setIsAffectedVault(
vault.collateralAmounts.some((col) => col.displaySymbol === "DUSD") &&
vault.loanAmounts.some((loan) => loan.displaySymbol === "DUSD")
vault.loanAmounts.some((loan) => loan.displaySymbol === "DUSD"),
);
}
}, [vault]);

useEffect(() => {
const isLoopDusdAllowed = isFeatureAvailable("loop_dusd");
if (isAffectedVault && isLoopDusdAllowed) {
setInfo({
displayText:
"Maintain either 100% DUSD (recommended) or at least 50% DFI as collateral for DUSD loans",
title: "Why is this so?",
message:
"DUSD loans which contains DUSD as collateral are required to maintain at least 50% of the collateral in the form of DFI.\n\nThis only affects vaults that has DUSD as both collateral and loan.\n\nTake note that DUSD Loop Vault will become a regular Vault if DFI is added as collateral.",
});
} else if (isAffectedVault) {
setInfo({
displayText: "Maintain at least 50% DFI as collateral for DUSD loans",
title: "Why you need 50% DFI",
message:
"DUSD loans which contains DUSD as collateral are required to maintain at least 50% of the collateral in the form of DFI.\n\nThis only affects vaults that has DUSD as both collateral and loan.",
});
} else {
setInfo({
displayText:
"Your loan amount can be maximized by adding DFI/DUSD as collaterals",
title: "DFI/DUSD collaterals",
message:
"Adding in DFI and/or DUSD will boost your borrowing power and help maximize your vault's loan amount.",
});
}
}, [isAffectedVault]);

return (
<View style={tailwind("mx-5 mt-6")}>
<ThemedTextV2
Expand All @@ -85,7 +120,7 @@ export function VaultDetailCollateralsRow({
<CollateralCardDfi
onDFIAdd={() => {
const collateralItem = collateralTokens.find(
(col) => col.token.displaySymbol === "DFI"
(col) => col.token.displaySymbol === "DFI",
);
if (collateralItem !== undefined) {
onAddPress(collateralItem);
Expand All @@ -97,7 +132,7 @@ export function VaultDetailCollateralsRow({
{vault.state !== LoanVaultState.IN_LIQUIDATION &&
vault.collateralAmounts.map((collateral, index) => {
const collateralItem = collateralTokens.find(
(col) => col.token.id === collateral.id
(col) => col.token.id === collateral.id,
);

if (collateralItem !== undefined) {
Expand All @@ -119,27 +154,25 @@ export function VaultDetailCollateralsRow({
}
})}

<InfoText
displayText={translate(
"screens/VaultDetailScreenCollateralSection",
isAffectedVault
? "Maintain at least 50% DFI as collateral for DUSD loans"
: "Your loan amount can be maximized by adding DFI/DUSD as collaterals"
)}
info={{
title: translate(
"screens/VaultDetailScreenCollateralSection",
isAffectedVault ? "Why you need 50% DFI" : "DFI/DUSD collaterals"
),
message: translate(
{info && (
<InfoText
displayText={translate(
"screens/VaultDetailScreenCollateralSection",
isAffectedVault
? "DUSD loans which contains DUSD as collateral are required to maintain at least 50% of the collateral in the form of DFI.\n\nThis only affects vaults that has DUSD as both collateral and loan."
: "Adding in DFI and/or DUSD will boost your borrowing power and help maximize your vault's loan amount."
),
}}
isAffectedVault={isAffectedVault}
/>
info.displayText,
)}
info={{
title: translate(
"screens/VaultDetailScreenCollateralSection",
info.title,
),
message: translate(
"screens/VaultDetailScreenCollateralSection",
info.message,
),
}}
isAffectedVault={isAffectedVault}
/>
)}
</View>
);
}
Expand Down Expand Up @@ -216,7 +249,7 @@ function CollateralCard(props: CollateralCardProps): JSX.Element {
const prices = getCollateralPrice(
props.amount,
props.collateralItem,
props.totalCollateralValue
props.totalCollateralValue,
);

return (
Expand Down Expand Up @@ -254,7 +287,7 @@ function CollateralCard(props: CollateralCardProps): JSX.Element {
<CollateralFactorTag
factor={props.collateralItem.factor}
containerStyle={tailwind(
"h-5 flex flex-row items-center rounded px-2 py-1 ml-1 border-0.5"
"h-5 flex flex-row items-center rounded px-2 py-1 ml-1 border-0.5",
)}
textStyle={tailwind("font-semibold-v2 text-2xs leading-3")}
/>
Expand All @@ -263,7 +296,7 @@ function CollateralCard(props: CollateralCardProps): JSX.Element {
<View style={tailwind("flex flex-row")}>
<ActiveUSDValueV2
price={new BigNumber(props.amount).multipliedBy(
prices.activePrice
prices.activePrice,
)}
testId={`vault_detail_collateral_${props.displaySymbol}_usd`}
/>
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import {
CollateralToken,
LoanToken,
LoanVaultTokenAmount,
} from "@defichain/whale-api-client/dist/api/loan";
import { RootState } from "@store";
import BigNumber from "bignumber.js";
import { useSelector } from "react-redux";
import { useFeatureFlagContext } from "@contexts/FeatureFlagContext";
import { getActivePrice } from "../../Auctions/helpers/ActivePrice";

interface useValidateLoanAndCollateralProps {
collateralAmounts: LoanVaultTokenAmount[];
loanAmounts: LoanVaultTokenAmount[];
collateralValue: BigNumber;
loanValue: BigNumber;
loanToken: LoanToken;
minColRatio: string;
}

/**
* To check if current vault has either at least 50% of DFI or 100% of DUSD as total collateral when taking DUSD loan
*
* Modified formula from [DeFiCh/ain] to include new loan amount to be taken during `Borrow` flow
* Source: https://github.com/DeFiCh/ain/blob/07ba855f73c7fdfb0b2f10fc3b31fe73c17b1630/src/dfi/consensus/txvisitor.cpp#L270
*
* Note: DUSD loops in vaults are now allowed - https://github.com/DeFiCh/ain/pull/1971
*
* @returns
*/
export function useValidateLoanAndCollateral(
props: useValidateLoanAndCollateralProps,
) {
const { isFeatureAvailable } = useFeatureFlagContext();
const collateralTokens: CollateralToken[] = useSelector(
(state: RootState) => state.loans.collateralTokens,
);
const isTakingDUSDLoan = props.loanToken.token.symbol === "DUSD";

const dfiCollateralToken = collateralTokens.find(
(col) => col.token.symbol === "DFI",
);

const dfiActivePrice = getActivePrice(
"DFI",
dfiCollateralToken?.activePrice,
dfiCollateralToken?.factor,
"ACTIVE",
"COLLATERAL",
);

const dfiCollateralValue = new BigNumber(dfiActivePrice).multipliedBy(
props.collateralAmounts.find((col) => col.symbol === "DFI")?.amount ?? 0,
);
const totalRequiredCollateral = new BigNumber(props.loanValue)
.multipliedBy(props.minColRatio)
.dividedBy(100);

const isDFIGreaterThanHalfOfRequiredCollateral =
dfiCollateralValue.isGreaterThanOrEqualTo(
totalRequiredCollateral.dividedBy(2),
);

// check if all collaterals is of DUSD token
const isDUSD100PercentOfCollateral = props.collateralAmounts.every(
(col) => col.symbol === "DUSD",
);

const isNonDUSDLoanAllowed =
!isTakingDUSDLoan && isDFIGreaterThanHalfOfRequiredCollateral;

const isDUSDLoanAllowed =
isTakingDUSDLoan &&
(isDFIGreaterThanHalfOfRequiredCollateral ||
(isFeatureAvailable("loop_dusd") && isDUSD100PercentOfCollateral));

return {
isLoanAllowed: isNonDUSDLoanAllowed || isDUSDLoanAllowed,
};
}
Loading

0 comments on commit 9b52cb0

Please sign in to comment.