From a3fe963a9b43a75b7c74c92a1103d18cc7f674b7 Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Wed, 3 Jan 2024 00:25:33 +0800 Subject: [PATCH 01/11] limit min relay amount for usn token --- components/Modal/Action.tsx | 38 ++++++++++++++++++++++----------- components/Modal/index.tsx | 9 ++++++-- components/Modal/utils.ts | 16 +++++++++++--- store/actions/repay.ts | 10 ++++++--- styles/global.css | 10 +++------ utils/wallet-selector-compat.ts | 6 +++--- 6 files changed, 59 insertions(+), 30 deletions(-) diff --git a/components/Modal/Action.tsx b/components/Modal/Action.tsx index 2e3e2889..e1a75483 100644 --- a/components/Modal/Action.tsx +++ b/components/Modal/Action.tsx @@ -1,8 +1,5 @@ import { useState, useMemo, useEffect } from "react"; -import { Box, Typography, Switch, Tooltip, Alert, useTheme } from "@mui/material"; -import LoadingButton from "@mui/lab/LoadingButton"; - -import { FcInfo } from "@react-icons/all-files/fc/FcInfo"; +import Decimal from "decimal.js"; import { nearTokenId } from "../../utils"; import { toggleUseAsCollateral, hideModal } from "../../redux/appSlice"; import { getModalData } from "./utils"; @@ -18,8 +15,9 @@ import { getSelectedValues, getAssetData } from "../../redux/appSelectors"; import { trackActionButton, trackUseAsCollateral } from "../../utils/telemetry"; import { useDegenMode } from "../../hooks/hooks"; import { SubmitButton, AlertWarning } from "./components"; +import { expandToken } from "../../store"; -export default function Action({ maxBorrowAmount, healthFactor }) { +export default function Action({ maxBorrowAmount, healthFactor, poolAsset }) { const [loading, setLoading] = useState(false); const { amount, useAsCollateral, isMax } = useAppSelector(getSelectedValues); const dispatch = useAppDispatch(); @@ -27,13 +25,14 @@ export default function Action({ maxBorrowAmount, healthFactor }) { const { action = "Deposit", tokenId } = asset; const { isRepayFromDeposits } = useDegenMode(); - const { available, canUseAsCollateral, extraDecimals, collateral, disabled } = getModalData({ - ...asset, - maxBorrowAmount, - healthFactor, - amount, - isRepayFromDeposits, - }); + const { available, canUseAsCollateral, extraDecimals, collateral, disabled, decimals } = + getModalData({ + ...asset, + maxBorrowAmount, + healthFactor, + amount, + isRepayFromDeposits, + }); useEffect(() => { if (!canUseAsCollateral) { @@ -96,11 +95,26 @@ export default function Action({ maxBorrowAmount, healthFactor }) { extraDecimals, }); } else { + let usnMinRepay = "0"; + const isUsn = tokenId === "usn"; + if (isUsn && poolAsset?.supplied?.shares) { + usnMinRepay = new Decimal( + expandToken( + new Decimal(poolAsset?.supplied?.balance) + .div(poolAsset?.supplied?.shares) + .mul(2) + .toFixed(), + decimals, + ), + ).toFixed(0); + } await repay({ tokenId, amount, extraDecimals, isMax, + isUsn, + usnMinRepay, }); } break; diff --git a/components/Modal/index.tsx b/components/Modal/index.tsx index 6a223522..530a836c 100644 --- a/components/Modal/index.tsx +++ b/components/Modal/index.tsx @@ -38,10 +38,10 @@ const Modal = () => { const accountId = useAppSelector(getAccountId); const asset = useAppSelector(getAssetData); const { amount } = useAppSelector(getSelectedValues); + const assets = useAppSelector((state) => state.assets?.data || {}); const dispatch = useAppDispatch(); const { isRepayFromDeposits } = useDegenMode(); const theme = useTheme(); - const { action = "Deposit", tokenId } = asset; const healthFactor = useAppSelector( @@ -78,6 +78,7 @@ const Modal = () => { isRepayFromDeposits, healthFactor, amount, + poolAsset: assets[tokenId], }); const total = (price * +amount).toLocaleString(undefined, USD_FORMAT); @@ -129,7 +130,11 @@ const Modal = () => { )} - + diff --git a/components/Modal/utils.ts b/components/Modal/utils.ts index 7ec6d06f..7b92e41c 100644 --- a/components/Modal/utils.ts +++ b/components/Modal/utils.ts @@ -51,6 +51,8 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => maxWithdrawAmount, isRepayFromDeposits, canUseAsCollateral, + tokenId, + poolAsset, } = asset; const data: any = { apy: borrowApy, @@ -117,7 +119,15 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => data.available = getAvailableWithdrawOrAdjust; data.rates = []; break; - case "Repay": + case "Repay": { + let minRepay = 0; + const isUsn = tokenId === "usn"; + if (isUsn && poolAsset?.supplied?.shares) { + minRepay = new Decimal(poolAsset?.supplied?.balance) + .div(poolAsset?.supplied?.shares) + .mul(2) + .toNumber(); + } data.totalTitle = `Repay Borrow Amount`; data.available = toDecimal( isRepayFromDeposits @@ -126,7 +136,7 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => isWrappedNear ? Number(Math.max(0, available + availableNEAR - NEAR_STORAGE_DEPOSIT)) : available, - borrowed, + isUsn ? Math.max(borrowed, minRepay) : borrowed, ), ); data.alerts = {}; @@ -146,7 +156,7 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => }); } break; - + } default: } if ( diff --git a/store/actions/repay.ts b/store/actions/repay.ts index 5e35b63a..0344d2a5 100644 --- a/store/actions/repay.ts +++ b/store/actions/repay.ts @@ -14,11 +14,15 @@ export async function repay({ amount, extraDecimals, isMax, + usnMinRepay, + isUsn, }: { tokenId: string; amount: string; extraDecimals: number; isMax: boolean; + usnMinRepay: string; + isUsn: boolean; }) { const { account, logicContract } = await getBurrow(); const tokenContract = await getTokenContract(tokenId); @@ -32,8 +36,9 @@ export async function repay({ ); const extraDecimalMultiplier = expandTokenDecimal(1, extraDecimals); - - const tokenBorrowedBalance = borrowedBalance.divToInt(extraDecimalMultiplier); + const tokenBorrowedBalance = isUsn + ? Decimal.max(borrowedBalance.divToInt(extraDecimalMultiplier), usnMinRepay) + : borrowedBalance.divToInt(extraDecimalMultiplier); const tokenBalance = new Decimal(await getBalance(tokenId, account.accountId)); const accountBalance = decimalMax( @@ -43,7 +48,6 @@ export async function repay({ const maxAvailableBalance = isNEAR ? tokenBalance.add(accountBalance) : tokenBalance; const maxAmount = decimalMin(tokenBorrowedBalance, maxAvailableBalance); - const expandedAmountToken = isMax ? maxAmount : decimalMin(maxAmount, expandTokenDecimal(amount, decimals)); diff --git a/styles/global.css b/styles/global.css index 37b604cd..ce64f80e 100644 --- a/styles/global.css +++ b/styles/global.css @@ -22,7 +22,7 @@ body { color: #fff; } -#__next{ +#__next { background: #14162b; height: 100%; } @@ -740,11 +740,7 @@ options-list::-webkit-scrollbar { .nws-form-control .account br { display: none; } -.nws-modal-wrapper - .nws-modal - .choose-ledger-account-form-wrapper - .nws-form-control - .account { +.nws-modal-wrapper .nws-modal .choose-ledger-account-form-wrapper .nws-form-control .account { display: flex; align-items: center; gap: 4px; @@ -755,7 +751,7 @@ options-list::-webkit-scrollbar { .choose-ledger-account-form-wrapper .nws-form-control .account - input[type='checkbox'] { + input[type="checkbox"] { transform: scale(1.2); } .nws-modal-wrapper .nws-modal .overview-wrapper .account { diff --git a/utils/wallet-selector-compat.ts b/utils/wallet-selector-compat.ts index ec9d56f6..dd9ef8ba 100644 --- a/utils/wallet-selector-compat.ts +++ b/utils/wallet-selector-compat.ts @@ -97,10 +97,10 @@ export const getWalletSelector = async ({ onAccountChange }: GetWalletSelectorAr debug: !!isTestnet, optimizeWalletOrder: false, }); - - const subscription = selector.store.observable + const { observable }: { observable: any } = selector.store; + const subscription = observable .pipe( - map((s) => s.accounts), + map((s: any) => s.accounts), distinctUntilChanged(), ) .subscribe((nextAccounts) => { From 1cc636509df5fd4dcf08a00510e9479d8922661d Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Wed, 3 Jan 2024 09:11:07 +0800 Subject: [PATCH 02/11] handle usn decimals --- components/Modal/Action.tsx | 22 +++++++++++++--------- components/Modal/utils.ts | 21 ++++++++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/components/Modal/Action.tsx b/components/Modal/Action.tsx index e1a75483..786966d7 100644 --- a/components/Modal/Action.tsx +++ b/components/Modal/Action.tsx @@ -98,15 +98,19 @@ export default function Action({ maxBorrowAmount, healthFactor, poolAsset }) { let usnMinRepay = "0"; const isUsn = tokenId === "usn"; if (isUsn && poolAsset?.supplied?.shares) { - usnMinRepay = new Decimal( - expandToken( - new Decimal(poolAsset?.supplied?.balance) - .div(poolAsset?.supplied?.shares) - .mul(2) - .toFixed(), - decimals, - ), - ).toFixed(0); + // usnMinRepay = new Decimal( + // expandToken( + // new Decimal(poolAsset?.supplied?.balance) + // .div(poolAsset?.supplied?.shares) + // .mul(2) + // .toFixed(0, 2), + // decimals, + // ), + // ).toFixed(0); + usnMinRepay = new Decimal(poolAsset?.supplied?.balance) + .div(poolAsset?.supplied?.shares) + .mul(2) + .toFixed(0, 2); } await repay({ tokenId, diff --git a/components/Modal/utils.ts b/components/Modal/utils.ts index 7b92e41c..7b722ae6 100644 --- a/components/Modal/utils.ts +++ b/components/Modal/utils.ts @@ -2,7 +2,7 @@ import Decimal from "decimal.js"; import { USD_FORMAT, TOKEN_FORMAT, PERCENT_DIGITS, NEAR_STORAGE_DEPOSIT } from "../../store"; import type { UIAsset } from "../../interfaces"; import { formatWithCommas_number, toDecimal } from "../../utils/uiNumber"; -import { expandToken } from "../../store/helper"; +import { expandToken, shrinkToken } from "../../store/helper"; import { decimalMax } from "../../utils"; interface Alert { @@ -120,13 +120,20 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => data.rates = []; break; case "Repay": { - let minRepay = 0; + let minRepay = "0"; const isUsn = tokenId === "usn"; if (isUsn && poolAsset?.supplied?.shares) { - minRepay = new Decimal(poolAsset?.supplied?.balance) - .div(poolAsset?.supplied?.shares) - .mul(2) - .toNumber(); + // minRepay = new Decimal(poolAsset?.supplied?.balance) + // .div(poolAsset?.supplied?.shares) + // .mul(2) + // .toNumber(); + minRepay = shrinkToken( + new Decimal(poolAsset?.supplied?.balance) + .div(poolAsset?.supplied?.shares) + .mul(2) + .toFixed(0, 2), + 18, + ); } data.totalTitle = `Repay Borrow Amount`; data.available = toDecimal( @@ -136,7 +143,7 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => isWrappedNear ? Number(Math.max(0, available + availableNEAR - NEAR_STORAGE_DEPOSIT)) : available, - isUsn ? Math.max(borrowed, minRepay) : borrowed, + isUsn ? Math.max(borrowed, +minRepay) : borrowed, ), ); data.alerts = {}; From 18a9f235fb18541e31218e05225b21d15dedb14e Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Fri, 5 Jan 2024 16:12:32 +0800 Subject: [PATCH 03/11] hide lp asset --- store/assets.ts | 3 ++- utils/config.ts | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/store/assets.ts b/store/assets.ts index c0e9bdab..641d83bb 100644 --- a/store/assets.ts +++ b/store/assets.ts @@ -3,6 +3,7 @@ import Decimal from "decimal.js"; import { IAssetEntry, IAssetDetailed, AssetEntry, ViewMethodsLogic } from "../interfaces"; import { getBurrow } from "../utils"; import { DEFAULT_PRECISION } from "./constants"; +import { hiddenAssets } from "../utils/config"; Decimal.set({ precision: DEFAULT_PRECISION }); @@ -33,5 +34,5 @@ export const getAssetDetailed = async (token_id: string): Promise => { const assets: IAssetEntry[] = await getAssets(); const detailedAssets = await Promise.all(assets.map((asset) => getAssetDetailed(asset.token_id))); - return detailedAssets; + return detailedAssets.filter((asset) => !hiddenAssets.includes(asset.token_id)); }; diff --git a/utils/config.ts b/utils/config.ts index d936653e..6067b914 100644 --- a/utils/config.ts +++ b/utils/config.ts @@ -3,7 +3,7 @@ import { ConnectConfig } from "near-api-js"; export const LOGIC_CONTRACT_NAME = process.env.NEXT_PUBLIC_CONTRACT_NAME as string; export const DUST_THRESHOLD = 0.001; -export const hiddenAssets = ["meta-token.near", "usn"]; +export const hiddenAssets = ["meta-token.near", "usn", "shadow_ref_v1-711", "shadow_ref_v1-269"]; export const defaultNetwork = (process.env.NEXT_PUBLIC_DEFAULT_NETWORK || process.env.NODE_ENV || From 409abfd9a485d06498b9cd12721c80bb7850e861 Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Fri, 12 Jan 2024 16:31:51 +0800 Subject: [PATCH 04/11] repay more for all asset --- components/Modal/Action.tsx | 28 +++++++++------------------- components/Modal/utils.ts | 16 +++++++--------- redux/utils.ts | 2 -- store/actions/repay.ts | 14 +++++++------- utils/index.ts | 1 - 5 files changed, 23 insertions(+), 38 deletions(-) diff --git a/components/Modal/Action.tsx b/components/Modal/Action.tsx index 786966d7..03ad2e70 100644 --- a/components/Modal/Action.tsx +++ b/components/Modal/Action.tsx @@ -52,6 +52,13 @@ export default function Action({ maxBorrowAmount, healthFactor, poolAsset }) { sliderValue: Math.round((+amount * 100) / available) || 0, isRepayFromDeposits, }); + let minRepay = "0"; + if (poolAsset?.supplied?.shares) { + minRepay = new Decimal(poolAsset?.supplied?.balance) + .div(poolAsset?.supplied?.shares) + .mul(2) + .toFixed(0, 2); + } switch (action) { case "Supply": if (tokenId === nearTokenId) { @@ -95,30 +102,13 @@ export default function Action({ maxBorrowAmount, healthFactor, poolAsset }) { extraDecimals, }); } else { - let usnMinRepay = "0"; - const isUsn = tokenId === "usn"; - if (isUsn && poolAsset?.supplied?.shares) { - // usnMinRepay = new Decimal( - // expandToken( - // new Decimal(poolAsset?.supplied?.balance) - // .div(poolAsset?.supplied?.shares) - // .mul(2) - // .toFixed(0, 2), - // decimals, - // ), - // ).toFixed(0); - usnMinRepay = new Decimal(poolAsset?.supplied?.balance) - .div(poolAsset?.supplied?.shares) - .mul(2) - .toFixed(0, 2); - } + // TODO await repay({ tokenId, amount, extraDecimals, isMax, - isUsn, - usnMinRepay, + minRepay, }); } break; diff --git a/components/Modal/utils.ts b/components/Modal/utils.ts index 7b722ae6..229494f8 100644 --- a/components/Modal/utils.ts +++ b/components/Modal/utils.ts @@ -53,6 +53,8 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => canUseAsCollateral, tokenId, poolAsset, + decimals, + extraDecimals, } = asset; const data: any = { apy: borrowApy, @@ -120,30 +122,26 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => data.rates = []; break; case "Repay": { + // TODO let minRepay = "0"; - const isUsn = tokenId === "usn"; - if (isUsn && poolAsset?.supplied?.shares) { - // minRepay = new Decimal(poolAsset?.supplied?.balance) - // .div(poolAsset?.supplied?.shares) - // .mul(2) - // .toNumber(); + if (poolAsset?.supplied?.shares) { minRepay = shrinkToken( new Decimal(poolAsset?.supplied?.balance) .div(poolAsset?.supplied?.shares) .mul(2) .toFixed(0, 2), - 18, + extraDecimals + decimals, ); } data.totalTitle = `Repay Borrow Amount`; data.available = toDecimal( isRepayFromDeposits - ? Math.min(maxWithdrawAmount, borrowed) + ? Math.min(maxWithdrawAmount, Math.max(borrowed, +minRepay)) : Math.min( isWrappedNear ? Number(Math.max(0, available + availableNEAR - NEAR_STORAGE_DEPOSIT)) : available, - isUsn ? Math.max(borrowed, +minRepay) : borrowed, + Math.max(borrowed, +minRepay), ), ); data.alerts = {}; diff --git a/redux/utils.ts b/redux/utils.ts index 9f1ce7b4..9996987c 100644 --- a/redux/utils.ts +++ b/redux/utils.ts @@ -69,7 +69,6 @@ export const transformAsset = ( shrinkToken(totalBorrowedD, asset.metadata.decimals + asset.config.extra_decimals), ); - // TODO: refactor: remove temp vars using ramda const temp1 = new Decimal(asset.supplied.balance) .plus(new Decimal(asset.reserved)) .plus(asset.prot_fee) @@ -91,7 +90,6 @@ export const transformAsset = ( extraDecimals: 0, }; - // TODO: refactor this without conditional if (account.accountId) { const decimals = asset.metadata.decimals + asset.config.extra_decimals; diff --git a/store/actions/repay.ts b/store/actions/repay.ts index 0344d2a5..5d362411 100644 --- a/store/actions/repay.ts +++ b/store/actions/repay.ts @@ -14,15 +14,13 @@ export async function repay({ amount, extraDecimals, isMax, - usnMinRepay, - isUsn, + minRepay, }: { tokenId: string; amount: string; extraDecimals: number; isMax: boolean; - usnMinRepay: string; - isUsn: boolean; + minRepay: string; }) { const { account, logicContract } = await getBurrow(); const tokenContract = await getTokenContract(tokenId); @@ -36,9 +34,11 @@ export async function repay({ ); const extraDecimalMultiplier = expandTokenDecimal(1, extraDecimals); - const tokenBorrowedBalance = isUsn - ? Decimal.max(borrowedBalance.divToInt(extraDecimalMultiplier), usnMinRepay) - : borrowedBalance.divToInt(extraDecimalMultiplier); + // TODO + const tokenBorrowedBalance = Decimal.max( + borrowedBalance.divToInt(extraDecimalMultiplier), + minRepay, + ); const tokenBalance = new Decimal(await getBalance(tokenId, account.accountId)); const accountBalance = decimalMax( diff --git a/utils/index.ts b/utils/index.ts index d6613300..aa1795ab 100644 --- a/utils/index.ts +++ b/utils/index.ts @@ -112,7 +112,6 @@ export const getBurrow = async ({ } }; - /// TODO is this deprecated??? const call = async ( contract: Contract, methodName: string, From 62657de5e676e79c90e2faa6afe1f276d510a006 Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Fri, 12 Jan 2024 17:32:23 +0800 Subject: [PATCH 05/11] add action tip link --- components/Modal/components.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/components/Modal/components.tsx b/components/Modal/components.tsx index 8b9bc9b4..6f09efea 100644 --- a/components/Modal/components.tsx +++ b/components/Modal/components.tsx @@ -75,11 +75,24 @@ export const TokenInfo = ({ apy, asset, onClose }) => { const page = ["Withdraw", "Adjust", "Supply"].includes(action) ? "deposit" : "borrow"; const isRepay = action === "Repay"; const { degenMode, isRepayFromDeposits, setRepayFromDeposits } = useDegenMode(); + const actionDoc = { + Supply: "https://docs.burrow.finance/product-docs/using-burrow/supplying", + Withdraw: "https://docs.burrow.finance/product-docs/using-burrow/supplying", + Adjust: "https://docs.burrow.finance/product-docs/using-burrow/supplying", + Borrow: "https://docs.burrow.finance/product-docs/using-burrow/borrowing", + Repay: "https://docs.burrow.finance/product-docs/using-burrow/borrowing", + }; return (
-
+
{actionMapTitle[action]} {symbol} + { + window.open(actionDoc[action]); + }} + />
From a49a48804078e8d2c888ec6f4ed7f7dc58ee1a07 Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Fri, 12 Jan 2024 17:38:26 +0800 Subject: [PATCH 06/11] update icon --- components/Modal/components.tsx | 6 +++--- components/Modal/svg.tsx | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/components/Modal/components.tsx b/components/Modal/components.tsx index 6f09efea..cd43c576 100644 --- a/components/Modal/components.tsx +++ b/components/Modal/components.tsx @@ -13,7 +13,7 @@ import { toggleUseAsCollateral, hideModal, showModal } from "../../redux/appSlic import { isInvalid, formatWithCommas_usd } from "../../utils/uiNumber"; import { YellowSolidSubmitButton, RedSolidSubmitButton } from "./button"; import { getCollateralAmount } from "../../redux/selectors/getCollateralAmount"; -import { TipIcon, CloseIcon, WarnIcon } from "./svg"; +import { TipIcon, CloseIcon, WarnIcon, JumpTipIcon } from "./svg"; import ReactToolTip from "../ToolTip"; export const USNInfo = () => ( @@ -85,9 +85,9 @@ export const TokenInfo = ({ apy, asset, onClose }) => { return (
-
+
{actionMapTitle[action]} {symbol} - { window.open(actionDoc[action]); diff --git a/components/Modal/svg.tsx b/components/Modal/svg.tsx index d0c8a50a..f5e71b59 100644 --- a/components/Modal/svg.tsx +++ b/components/Modal/svg.tsx @@ -66,3 +66,21 @@ export function WarnIcon(props) { ); } +export function JumpTipIcon(props) { + return ( + + + + + ); +} From d4eac5e205b5712306ab363d8050330ca0e8cf22 Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Sat, 13 Jan 2024 14:03:24 +0800 Subject: [PATCH 07/11] update get price logic --- redux/assetsSlice.ts | 3 +-- store/assets.ts | 4 ++-- utils/config.ts | 3 ++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/redux/assetsSlice.ts b/redux/assetsSlice.ts index e5db5ec4..5734383b 100644 --- a/redux/assetsSlice.ts +++ b/redux/assetsSlice.ts @@ -42,8 +42,7 @@ export const assetSlice = createSlice({ builder.addCase(fetchRefPrices.fulfilled, (state, action) => { missingPriceTokens.forEach((missingToken) => { const missingTokenId = missingToken[defaultNetwork]; - - if (missingTokenId && state.data[missingTokenId]) { + if (missingTokenId && state.data[missingTokenId] && !state.data[missingTokenId]["price"]) { state.data[missingTokenId]["price"] = { decimals: action.payload[missingToken.mainnet].decimal, usd: Number(action.payload[missingToken.mainnet].price), diff --git a/store/assets.ts b/store/assets.ts index 641d83bb..f5692141 100644 --- a/store/assets.ts +++ b/store/assets.ts @@ -3,7 +3,7 @@ import Decimal from "decimal.js"; import { IAssetEntry, IAssetDetailed, AssetEntry, ViewMethodsLogic } from "../interfaces"; import { getBurrow } from "../utils"; import { DEFAULT_PRECISION } from "./constants"; -import { hiddenAssets } from "../utils/config"; +import { lpTokenPrefix } from "../utils/config"; Decimal.set({ precision: DEFAULT_PRECISION }); @@ -34,5 +34,5 @@ export const getAssetDetailed = async (token_id: string): Promise => { const assets: IAssetEntry[] = await getAssets(); const detailedAssets = await Promise.all(assets.map((asset) => getAssetDetailed(asset.token_id))); - return detailedAssets.filter((asset) => !hiddenAssets.includes(asset.token_id)); + return detailedAssets.filter((asset) => !asset.token_id.includes(lpTokenPrefix)); }; diff --git a/utils/config.ts b/utils/config.ts index 6067b914..0e898489 100644 --- a/utils/config.ts +++ b/utils/config.ts @@ -3,7 +3,8 @@ import { ConnectConfig } from "near-api-js"; export const LOGIC_CONTRACT_NAME = process.env.NEXT_PUBLIC_CONTRACT_NAME as string; export const DUST_THRESHOLD = 0.001; -export const hiddenAssets = ["meta-token.near", "usn", "shadow_ref_v1-711", "shadow_ref_v1-269"]; +export const hiddenAssets = ["meta-token.near", "usn"]; +export const lpTokenPrefix = "shadow_ref_v1"; export const defaultNetwork = (process.env.NEXT_PUBLIC_DEFAULT_NETWORK || process.env.NODE_ENV || From 127f3a8d3f56026cf587f0f6c3cbbf1d513ff59e Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Sat, 13 Jan 2024 20:10:10 +0800 Subject: [PATCH 08/11] update repay logic --- components/Modal/Action.tsx | 35 +++++++++++++++++++++--------- components/Modal/utils.ts | 16 ++++++++++++-- store/actions/repay.ts | 4 +++- store/actions/repayFromDeposits.ts | 6 ++++- 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/components/Modal/Action.tsx b/components/Modal/Action.tsx index 03ad2e70..1ce0484f 100644 --- a/components/Modal/Action.tsx +++ b/components/Modal/Action.tsx @@ -22,7 +22,7 @@ export default function Action({ maxBorrowAmount, healthFactor, poolAsset }) { const { amount, useAsCollateral, isMax } = useAppSelector(getSelectedValues); const dispatch = useAppDispatch(); const asset = useAppSelector(getAssetData); - const { action = "Deposit", tokenId } = asset; + const { action = "Deposit", tokenId, borrowApy, price, borrowed } = asset; const { isRepayFromDeposits } = useDegenMode(); const { available, canUseAsCollateral, extraDecimals, collateral, disabled, decimals } = @@ -52,13 +52,6 @@ export default function Action({ maxBorrowAmount, healthFactor, poolAsset }) { sliderValue: Math.round((+amount * 100) / available) || 0, isRepayFromDeposits, }); - let minRepay = "0"; - if (poolAsset?.supplied?.shares) { - minRepay = new Decimal(poolAsset?.supplied?.balance) - .div(poolAsset?.supplied?.shares) - .mul(2) - .toFixed(0, 2); - } switch (action) { case "Supply": if (tokenId === nearTokenId) { @@ -94,24 +87,46 @@ export default function Action({ maxBorrowAmount, healthFactor, poolAsset }) { isMax, }); break; - case "Repay": + case "Repay": { + // TODO + let minRepay = "0"; + let interestChargedIn1min = "0"; + if (borrowApy && price && borrowed) { + interestChargedIn1min = expandToken( + new Decimal(borrowApy) + .div(365 * 24 * 60) + .div(100) + .mul(borrowed) + .toFixed(), + decimals, + 0, + ); + } + if (poolAsset?.supplied?.shares) { + minRepay = new Decimal(poolAsset?.supplied?.balance) + .div(poolAsset?.supplied?.shares) + .mul(2) + .toFixed(0, 2); + } if (isRepayFromDeposits) { await repayFromDeposits({ tokenId, amount, extraDecimals, + isMax, }); } else { - // TODO await repay({ tokenId, amount, extraDecimals, isMax, minRepay, + interestChargedIn1min, }); } break; + } default: break; } diff --git a/components/Modal/utils.ts b/components/Modal/utils.ts index 229494f8..dc521cd4 100644 --- a/components/Modal/utils.ts +++ b/components/Modal/utils.ts @@ -133,15 +133,27 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => extraDecimals + decimals, ); } + let interestChargedIn1min = "0"; + if (borrowApy && price && borrowed) { + interestChargedIn1min = new Decimal(borrowApy) + .div(365 * 24 * 60) + .div(100) + .mul(borrowed) + .toFixed(); + } + const repayAmount = Decimal.max( + new Decimal(borrowed).plus(interestChargedIn1min), + minRepay, + ).toNumber(); data.totalTitle = `Repay Borrow Amount`; data.available = toDecimal( isRepayFromDeposits - ? Math.min(maxWithdrawAmount, Math.max(borrowed, +minRepay)) + ? Math.min(maxWithdrawAmount, repayAmount) : Math.min( isWrappedNear ? Number(Math.max(0, available + availableNEAR - NEAR_STORAGE_DEPOSIT)) : available, - Math.max(borrowed, +minRepay), + repayAmount, ), ); data.alerts = {}; diff --git a/store/actions/repay.ts b/store/actions/repay.ts index 5d362411..d5e55e6a 100644 --- a/store/actions/repay.ts +++ b/store/actions/repay.ts @@ -15,12 +15,14 @@ export async function repay({ extraDecimals, isMax, minRepay, + interestChargedIn1min, }: { tokenId: string; amount: string; extraDecimals: number; isMax: boolean; minRepay: string; + interestChargedIn1min: string; }) { const { account, logicContract } = await getBurrow(); const tokenContract = await getTokenContract(tokenId); @@ -36,7 +38,7 @@ export async function repay({ const extraDecimalMultiplier = expandTokenDecimal(1, extraDecimals); // TODO const tokenBorrowedBalance = Decimal.max( - borrowedBalance.divToInt(extraDecimalMultiplier), + borrowedBalance.divToInt(extraDecimalMultiplier).plus(interestChargedIn1min), minRepay, ); diff --git a/store/actions/repayFromDeposits.ts b/store/actions/repayFromDeposits.ts index 5d370b53..95639eda 100644 --- a/store/actions/repayFromDeposits.ts +++ b/store/actions/repayFromDeposits.ts @@ -12,10 +12,12 @@ export async function repayFromDeposits({ tokenId, amount, extraDecimals, + isMax, }: { tokenId: string; amount: string; extraDecimals: number; + isMax: boolean; }) { const { logicContract, oracleContract } = await getBurrow(); const { decimals } = (await getMetadata(tokenId))!; @@ -56,7 +58,9 @@ export async function repayFromDeposits({ { Repay: { token_id: tokenId, - amount: expandedAmount.mul(extraDecimalMultiplier).toFixed(0), + amount: isMax + ? undefined + : expandedAmount.mul(extraDecimalMultiplier).toFixed(0), }, }, ], From b54822ae72b0aa78b4b75235d961a2313b559417 Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Sat, 13 Jan 2024 20:31:03 +0800 Subject: [PATCH 09/11] update icon color --- components/Modal/components.tsx | 2 +- components/Modal/svg.tsx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/Modal/components.tsx b/components/Modal/components.tsx index cd43c576..cf3dd508 100644 --- a/components/Modal/components.tsx +++ b/components/Modal/components.tsx @@ -88,7 +88,7 @@ export const TokenInfo = ({ apy, asset, onClose }) => {
{actionMapTitle[action]} {symbol} { window.open(actionDoc[action]); }} diff --git a/components/Modal/svg.tsx b/components/Modal/svg.tsx index f5e71b59..478c2141 100644 --- a/components/Modal/svg.tsx +++ b/components/Modal/svg.tsx @@ -78,9 +78,9 @@ export function JumpTipIcon(props) { > - + ); } From 140040fcd18e638f610b9cfced3ef1dec7bc1013 Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Sat, 13 Jan 2024 23:07:50 +0800 Subject: [PATCH 10/11] update repay health factor logic --- redux/selectors/recomputeHealthFactorRepayFromDeposits.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/redux/selectors/recomputeHealthFactorRepayFromDeposits.ts b/redux/selectors/recomputeHealthFactorRepayFromDeposits.ts index ac92e9de..5c21ffc5 100644 --- a/redux/selectors/recomputeHealthFactorRepayFromDeposits.ts +++ b/redux/selectors/recomputeHealthFactorRepayFromDeposits.ts @@ -48,7 +48,11 @@ export const recomputeHealthFactorRepayFromDeposits = (tokenId: string, amount: } } - const adjustedCollateralSum = getAdjustedSum("collateral", account.portfolio, assets.data); + const adjustedCollateralSum = getAdjustedSum( + "collateral", + clonedAccount.portfolio, + assets.data, + ); const adjustedBorrowedSum = getAdjustedSum("borrowed", clonedAccount.portfolio, assets.data); const healthFactor = adjustedCollateralSum.div(adjustedBorrowedSum).mul(100).toNumber(); From c12d1231bfbdd22618fe8752d1c4c8abc2896a9d Mon Sep 17 00:00:00 2001 From: "nature.xie" Date: Sun, 14 Jan 2024 23:38:41 +0800 Subject: [PATCH 11/11] min repay decimal handle --- components/Modal/Action.tsx | 3 +++ components/Modal/utils.ts | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/components/Modal/Action.tsx b/components/Modal/Action.tsx index 1ce0484f..b647d32c 100644 --- a/components/Modal/Action.tsx +++ b/components/Modal/Action.tsx @@ -101,6 +101,9 @@ export default function Action({ maxBorrowAmount, healthFactor, poolAsset }) { decimals, 0, ); + if (+interestChargedIn1min === 0) { + interestChargedIn1min = "1"; + } } if (poolAsset?.supplied?.shares) { minRepay = new Decimal(poolAsset?.supplied?.balance) diff --git a/components/Modal/utils.ts b/components/Modal/utils.ts index dc521cd4..9cf001fb 100644 --- a/components/Modal/utils.ts +++ b/components/Modal/utils.ts @@ -130,7 +130,7 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => .div(poolAsset?.supplied?.shares) .mul(2) .toFixed(0, 2), - extraDecimals + decimals, + decimals, ); } let interestChargedIn1min = "0"; @@ -139,7 +139,7 @@ export const getModalData = (asset): UIAsset & Props & { disabled: boolean } => .div(365 * 24 * 60) .div(100) .mul(borrowed) - .toFixed(); + .toFixed(decimals, 2); } const repayAmount = Decimal.max( new Decimal(borrowed).plus(interestChargedIn1min),