Skip to content

Commit

Permalink
SOV-3390: reimplement increasing debt without adding collateral (#703)
Browse files Browse the repository at this point in the history
* feat: allow borrowing more money

* fix: review comments

* chore: add changeset

---------

Co-authored-by: soulBit <[email protected]>
  • Loading branch information
creed-victor and soulBit authored Dec 5, 2023
1 parent f9c3795 commit cb660fb
Show file tree
Hide file tree
Showing 9 changed files with 182 additions and 38 deletions.
5 changes: 5 additions & 0 deletions .changeset/gold-turkeys-behave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"frontend": patch
---

SOV-3390: Fixed Rate Borrow - add ability to increase debt without adding collateral
8 changes: 8 additions & 0 deletions apps/frontend/src/app/5_pages/BorrowPage/BorrowPage.utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,11 @@ export const normalizeToken = (token: string): SupportedTokens => {

return SupportedTokens[token] || token;
};

export const normalizeTokenWrapped = (token: string): SupportedTokens => {
if (isBtcBasedAsset(token)) {
return SupportedTokens.wrbtc;
}

return normalizeToken(token);
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ export const INTEREST_DURATION = 3600; // according to the PRD
export const ACTIVE_CLASSNAME = 'bg-gray-70 text-primary-20';

export const DEBT_TABS = [
// {
// tabAction: DebtTabAction.Borrow,
// label: t(translations.fixedInterestPage.adjustLoanDialog.actions.borrow),
// activeClassName: ACTIVE_CLASSNAME,
// },
{
tabAction: DebtTabAction.Borrow,
label: t(translations.fixedInterestPage.adjustLoanDialog.actions.borrow),
activeClassName: ACTIVE_CLASSNAME,
},
{
tabAction: DebtTabAction.Repay,
label: t(translations.fixedInterestPage.adjustLoanDialog.actions.repay),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import { useGetBorrowingAPR } from '../../hooks/useGetBorrowingAPR';
import { useGetMaintenanceStates } from '../../hooks/useGetMaintenanceStates';
import { useGetOriginationFee } from '../../hooks/useGetOriginationFee';
import { CurrentLoanData } from '../CurrentLoanData/CurrentLoanData';
import { useBorrow } from '../NewLoanForm/hooks/useBorrow';
import { useGetMaximumCollateralAmount } from '../NewLoanForm/hooks/useGetMaximumCollateralAmount';
import {
COLLATERAL_TABS,
Expand All @@ -59,6 +60,7 @@ import {
import { Label } from './components/Label';
import { useCloseWithDepositIsTinyPosition } from './hooks/useCloseWithDepositIsTinyPosition';
import { useDepositCollateral } from './hooks/useDepositCollateral';
import { useDrawdown } from './hooks/useDrawdown';
import { useGetInterestRefund } from './hooks/useGetInterestRefund';
import { useGetMaxCollateralWithdrawal } from './hooks/useGetMaxCollateralWithdrawal';
import { useGetMaxRepayAmount } from './hooks/useGetMaxRepayAmount';
Expand All @@ -77,9 +79,9 @@ export const AdjustLoanForm: FC<AdjustLoanFormProps> = ({ loan }) => {
const [collateralAmount, setCollateralAmount, collateralSize] =
useDecimalAmountInput('');

const [debtTab, setDebtTab] = useState(DebtTabAction.Repay);
const [debtTab, setDebtTab] = useState(DebtTabAction.Borrow);
const [collateralTab, setCollateralTab] = useState(
CollateralTabAction.WithdrawCollateral,
CollateralTabAction.AddCollateral,
);

const isCloseTab = useMemo(() => debtTab === DebtTabAction.Close, [debtTab]);
Expand Down Expand Up @@ -392,7 +394,7 @@ export const AdjustLoanForm: FC<AdjustLoanFormProps> = ({ loan }) => {
}, [setCollateralAmount, setDebtAmount]);

const handleRepay = useRepayLoan();
// const handleBorrow = useBorrow();
const handleBorrow = useBorrow();
const handleWithdrawCollateral = useWithdrawCollateral();
const handleDepositCollateral = useDepositCollateral();

Expand All @@ -416,53 +418,60 @@ export const AdjustLoanForm: FC<AdjustLoanFormProps> = ({ loan }) => {
return;
}

if (isBorrowTab) {
if (debtSize.isZero()) {
handleDepositCollateral(collateralAmount, collateralToken, loan.id);
} else {
handleBorrow(
debtToken,
debtAmount,
loan.rolloverDate,
collateralSize.toString(),
collateralToken,
loan.id,
);
}
return;
}

if (isAddCollateralTab) {
handleDepositCollateral(collateralAmount, collateralToken, loan.id);
return;
}

// if (isBorrowTab) {
// if (debtSize.isZero()) {
// handleDepositCollateral(collateralAmount, collateralToken, loan.id);
// } else {
// handleBorrow(
// debtToken,
// debtAmount,
// loan.rolloverDate,
// collateralSize.toString(),
// collateralToken,
// loan.id,
// );
// }
// }

if (isCollateralWithdrawMode) {
handleWithdrawCollateral(collateralAmount, loan.id);
}
}, [
collateralAmount,
collateralSize,
collateralToken,
debtAmount,
debtSize,
debtToken,
handleBorrow,
handleDepositCollateral,
handleRepay,
handleWithdrawCollateral,
isAddCollateralTab,
isBorrowTab,
isCloseTab,
isCollateralWithdrawMode,
isRepayTab,
loan.debt,
loan.debtAsset,
loan.id,
loan.rolloverDate,
]);

const onDebtTabChange = useCallback(
(value: DebtTabAction) => {
switch (value) {
// case DebtTabAction.Borrow:
// setCollateralTab(CollateralTabAction.AddCollateral);
// setDebtTab(value);
// resetCloseDebtTabValues();
// return;
case DebtTabAction.Borrow:
setCollateralTab(CollateralTabAction.AddCollateral);
setDebtTab(value);
resetCloseDebtTabValues();
return;
case DebtTabAction.Repay:
if (isCloseTab) {
setIsTinyPosition(false);
Expand All @@ -487,11 +496,10 @@ export const AdjustLoanForm: FC<AdjustLoanFormProps> = ({ loan }) => {
(value: CollateralTabAction) => {
switch (value) {
case CollateralTabAction.AddCollateral:
// if (!isBorrowTab) {
// setDebtTab(DebtTabAction.Borrow);
// }
if (!isBorrowTab) {
setDebtTab(DebtTabAction.Borrow);
}

setDebtTab(DebtTabAction.None);
setDebtAmount(loan.debt.toString());

setCollateralTab(value);
Expand Down Expand Up @@ -674,6 +682,8 @@ export const AdjustLoanForm: FC<AdjustLoanFormProps> = ({ loan }) => {
[isValidDebtAmount],
);

const { maxBorrow } = useDrawdown(loan, collateralSize, isAddCollateralTab);

return (
<>
<CurrentLoanData
Expand Down Expand Up @@ -712,10 +722,7 @@ export const AdjustLoanForm: FC<AdjustLoanFormProps> = ({ loan }) => {
invalid={!isValidDebtAmount}
placeholder="0"
disabled={
isCloseTab ||
isCollateralWithdrawMode ||
isDebtAmountDisabled ||
isAddCollateralTab
isCloseTab || isCollateralWithdrawMode || isDebtAmountDisabled
}
/>
<AssetRenderer
Expand Down Expand Up @@ -921,7 +928,9 @@ export const AdjustLoanForm: FC<AdjustLoanFormProps> = ({ loan }) => {
className="w-full"
onClick={handleFormSubmit}
dataAttribute="adjust-loan-confirm-button"
disabled={submitButtonDisabled}
disabled={
submitButtonDisabled || (isBorrowTab && debtSize.gt(maxBorrow))
}
/>
</div>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export enum DebtTabAction {
None = -1,
Borrow,
Repay,
Close,
Borrow,
}

export enum CollateralTabAction {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import {
SupportedTokens,
getLoanTokenContract,
getProtocolContract,
getTokenDetails,
} from '@sovryn/contracts';
import { getProvider } from '@sovryn/ethers-provider';
import { Decimal } from '@sovryn/utils';

import { defaultChainId } from '../../../../../config/chains';

import { normalizeTokenWrapped } from '../../BorrowPage.utils';

export const calculateDebtRepaidPercentage = (
totalDebt: string,
debtRepaid: Decimal,
Expand All @@ -13,3 +24,57 @@ export const calculateRepayCollateralWithdrawn = (
Decimal.from(totalCollateral).mul(
calculateDebtRepaidPercentage(totalDebt, debtRepaid),
);

export const getMaxDrawdown = async (
loanToken: SupportedTokens,
collateralToken: SupportedTokens,
loanAmount: Decimal,
collateralAmount: Decimal,
margin: Decimal,
): Promise<Decimal> => {
const [contract, loanAddress, collateralAddress] = await Promise.all([
getProtocolContract('priceFeed', defaultChainId).then(({ contract }) =>
contract(getProvider(defaultChainId)),
),
getTokenDetails(normalizeTokenWrapped(loanToken), defaultChainId).then(
({ address }) => address,
),
getTokenDetails(
normalizeTokenWrapped(collateralToken),
defaultChainId,
).then(({ address }) => address),
]);

const amount = await contract.getMaxDrawdown(
loanAddress,
collateralAddress,
loanAmount.toHexString(),
collateralAmount.toHexString(),
margin.toHexString(),
);
return Decimal.fromBigNumberString(amount);
};

export const getBorrowAmount = async (
loanToken: SupportedTokens,
collateralAmount: Decimal,
collateralToken: SupportedTokens,
durationInSeconds: number,
): Promise<Decimal> => {
const [contract, collateralTokenAddress] = await Promise.all([
getLoanTokenContract(loanToken, defaultChainId).then(({ contract }) =>
contract(getProvider(defaultChainId)),
),
getTokenDetails(collateralToken, defaultChainId).then(
({ address }) => address,
),
]);

const amount = await contract.getBorrowAmountForDeposit(
collateralAmount.toHexString(),
durationInSeconds,
collateralTokenAddress,
);

return Decimal.fromBigNumberString(amount);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { useEffect, useState } from 'react';

import { Decimal } from '@sovryn/utils';

import { decimalic } from '../../../../../../utils/math';
import { LoanItem } from '../../OpenLoansTable/OpenLoansTable.types';
import { getBorrowAmount, getMaxDrawdown } from '../AdjustLoanForm.utils';

export const useDrawdown = (
loan: LoanItem,
collateralSize: Decimal,
isAddCollateralTab: boolean,
) => {
const [drawDown, setDrawDown] = useState(Decimal.ZERO);
const [maxBorrow, setMaxBorrow] = useState(Decimal.ZERO);

useEffect(() => {
getMaxDrawdown(
loan.debtAsset,
loan.collateralAsset,
decimalic(loan.debt),
decimalic(loan.collateral),
loan.startMargin,
).then(setDrawDown);
}, [
loan.collateral,
loan.collateralAsset,
loan.debt,
loan.debtAsset,
loan.startMargin,
]);

useEffect(() => {
getBorrowAmount(
loan.debtAsset,
drawDown.add(collateralSize.mul(isAddCollateralTab ? 1 : -1)),
loan.collateralAsset,
Math.max(Math.floor(loan.rolloverDate - Date.now() / 1000), 0),
// 28 * 86400,
).then(setMaxBorrow);
}, [
collateralSize,
drawDown,
isAddCollateralTab,
loan.collateralAsset,
loan.debtAsset,
loan.rolloverDate,
]);

return { drawDown, maxBorrow };
};
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,6 @@ export type LoanItem = {
rolloverDate: number;
interestOwedPerDay: number;
startMargin: Decimal;
currentMargin: Decimal;
maintenanceMargin: Decimal;
};
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ export const useGetOpenLoans = () => {
item.interestOwedPerDay,
),
startMargin: Decimal.fromBigNumberString(item.startMargin),
currentMargin: Decimal.fromBigNumberString(item.currentMargin),
maintenanceMargin: Decimal.fromBigNumberString(
item.maintenanceMargin,
),
};
})
.filter(Boolean)
Expand Down

0 comments on commit cb660fb

Please sign in to comment.