From 3401c49233b1e37b198bd9d63cd73be7a09b0583 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Tue, 9 May 2023 19:48:21 -0700 Subject: [PATCH 01/36] fix: handle vr vaults in vault selector --- src/components/views/Borrow.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index ffb024da2..77c7ad575 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -57,6 +57,7 @@ import useAccountPlus from '../../hooks/useAccountPlus'; import VariableRate from '../selectors/VariableRate'; import useBasesVR from '../../hooks/views/useBasesVR'; import useAssetPair from '../../hooks/viewHelperHooks/useAssetPair/useAssetPair'; +import useVaultsVR from '../../hooks/entities/useVaultsVR'; const Borrow = () => { const mobile: boolean = useContext(ResponsiveContext) === 'small'; @@ -103,6 +104,7 @@ const Borrow = () => { const { apr } = useApr(borrowInput, ActionType.BORROW, selectedSeries); const { data: assetPair } = useAssetPair(selectedBase?.id, selectedIlk?.id); const { data: basesVR } = useBasesVR(); + const { data: vaultsVR } = useVaultsVR(); const { collateralizationPercent, @@ -263,18 +265,18 @@ const Borrow = () => { /* CHECK the list of current vaults which match the current series/ilk selection */ // TODO look at moving this to helper hook? useEffect(() => { - if (selectedBase && selectedSeries && selectedIlk) { - const arr: IVault[] = Array.from(vaultMap?.values()!) as IVault[]; - const _matchingVaults = arr.filter( - (v: IVault) => + if (selectedBase && selectedIlk) { + const vaults = [...(selectedVR ? (vaultsVR || []).values() : (vaultMap || []).values())]; + const matchingVaults = vaults.filter( + (v) => v.ilkId === selectedIlk.proxyId && v.baseId === selectedBase.proxyId && - v.seriesId === selectedSeries.id && + v.seriesId === selectedSeries?.id && v.isActive ); - setMatchingVaults(_matchingVaults); + setMatchingVaults(matchingVaults); } - }, [vaultMap, selectedBase, selectedIlk, selectedSeries]); + }, [vaultMap, selectedBase, selectedIlk, selectedSeries, vaultsVR, selectedVR]); /* handle selected vault */ useEffect(() => { From 13535ef0bc515236db456035a34cecc6614eeffa Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 02:35:22 -0700 Subject: [PATCH 02/36] chore: remove unnecessary types --- .../viewHelperHooks/useCollateralHelpers.ts | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/hooks/viewHelperHooks/useCollateralHelpers.ts b/src/hooks/viewHelperHooks/useCollateralHelpers.ts index 40490f743..3e04eb35c 100644 --- a/src/hooks/viewHelperHooks/useCollateralHelpers.ts +++ b/src/hooks/viewHelperHooks/useCollateralHelpers.ts @@ -7,13 +7,12 @@ import { calculateMinCollateral, decimalNToDecimal18, } from '@yield-protocol/ui-math'; - import { UserContext } from '../../contexts/UserContext'; import { IAssetPair, IVault } from '../../types'; import { cleanValue } from '../../utils/appUtils'; import { ZERO_BN } from '../../utils/constants'; import useTimeTillMaturity from '../useTimeTillMaturity'; -import { Address, useAccount, useBalance } from 'wagmi'; +import { Address, useBalance } from 'wagmi'; import { WETH } from '../../config/assets'; import useAccountPlus from '../useAccountPlus'; import { parseUnits } from 'ethers/lib/utils.js'; @@ -44,31 +43,31 @@ export const useCollateralHelpers = ( }); /* LOCAL STATE */ - const [collateralizationRatio, setCollateralizationRatio] = useState(); - const [collateralizationPercent, setCollateralizationPercent] = useState(); + const [collateralizationRatio, setCollateralizationRatio] = useState(); + const [collateralizationPercent, setCollateralizationPercent] = useState(); const [undercollateralized, setUndercollateralized] = useState(true); const [unhealthyCollatRatio, setUnhealthyCollatRatio] = useState(false); const [oraclePrice, setOraclePrice] = useState(ethers.constants.Zero); - const [liquidationPrice_, setLiquidationPrice_] = useState(); + const [liquidationPrice_, setLiquidationPrice_] = useState(); const [minCollateral, setMinCollateral] = useState(); - const [minCollateral_, setMinCollateral_] = useState(); + const [minCollateral_, setMinCollateral_] = useState(); - const [minCollatRatio, setMinCollatRatio] = useState(); - const [minCollatRatioPct, setMinCollatRatioPct] = useState(); - const [minSafeCollatRatio, setMinSafeCollatRatio] = useState(); - const [minSafeCollatRatioPct, setMinSafeCollatRatioPct] = useState(); - const [minSafeCollateral, setMinSafeCollateral] = useState(); - const [maxRemovableCollateral, setMaxRemovableCollateral] = useState(); - const [maxCollateral, setMaxCollateral] = useState(); + const [minCollatRatio, setMinCollatRatio] = useState(); + const [minCollatRatioPct, setMinCollatRatioPct] = useState(); + const [minSafeCollatRatio, setMinSafeCollatRatio] = useState(); + const [minSafeCollatRatioPct, setMinSafeCollatRatioPct] = useState(); + const [minSafeCollateral, setMinSafeCollateral] = useState(); + const [maxRemovableCollateral, setMaxRemovableCollateral] = useState(); + const [maxCollateral, setMaxCollateral] = useState(); const [totalDebt, setTotalDebt] = useState(); - const [totalDebt_, setTotalDebt_] = useState(); + const [totalDebt_, setTotalDebt_] = useState(); const [totalCollateral, setTotalCollateral] = useState(); - const [totalCollateral_, setTotalCollateral_] = useState(); + const [totalCollateral_, setTotalCollateral_] = useState(); /* update the prices/limits if anything changes with the asset pair */ useEffect(() => { From ab95b38f8a9ed96ba50b7768a15eefefc88b2214 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 02:36:28 -0700 Subject: [PATCH 03/36] fix: deps --- src/hooks/viewHelperHooks/useCollateralHelpers.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hooks/viewHelperHooks/useCollateralHelpers.ts b/src/hooks/viewHelperHooks/useCollateralHelpers.ts index 3e04eb35c..558705805 100644 --- a/src/hooks/viewHelperHooks/useCollateralHelpers.ts +++ b/src/hooks/viewHelperHooks/useCollateralHelpers.ts @@ -214,6 +214,8 @@ export const useCollateralHelpers = ( minSafeCollatRatio, _selectedSeries, getTimeTillMaturity, + selectedBase?.decimals, + selectedVR, ]); /* Monitor for undercollaterization/ danger-collateralisation, and set flags if reqd. */ From 70957c930fd95c4c00aadf1454057aeff2c55590 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 02:51:17 -0700 Subject: [PATCH 04/36] fix: max collat button handle for vr --- src/components/views/Borrow.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index 77c7ad575..a0353f0e3 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -473,7 +473,8 @@ const Borrow = () => { maxCollateral && handleMaxAction(ActionCodes.ADD_COLLATERAL)} disabled={ - !selectedSeries || collatInput === maxCollateral || selectedSeries.seriesIsMature + ((!selectedSeries || selectedSeries.seriesIsMature) && !selectedVR) || + collatInput === maxCollateral } clearAction={() => setCollatInput('')} showingMax={!!collatInput && collatInput === maxCollateral} From 55f4786397d56cf908a5c8e1995e2fa279795496 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 03:01:52 -0700 Subject: [PATCH 05/36] fix: clean the input --- src/hooks/useApr.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hooks/useApr.ts b/src/hooks/useApr.ts index 343aa2e4c..0de033737 100644 --- a/src/hooks/useApr.ts +++ b/src/hooks/useApr.ts @@ -75,7 +75,8 @@ export const useApr = (input: string | undefined, actionType: ActionType, series _apr ? setApr(cleanValue(_apr, 2)) : setApr(_selectedSeries.apr); } else if (selectedBase) { /* logic for VR */ - const baseAmount = ethers.utils.parseUnits(_input || _fallbackInput, selectedBase.decimals); + const cleanedInput = cleanValue(_input || _fallbackInput, selectedBase.decimals); + const baseAmount = ethers.utils.parseUnits(cleanedInput, selectedBase.decimals); const now = Date.now() + 20000; // trying to call interest rate oracle @@ -87,7 +88,7 @@ export const useApr = (input: string | undefined, actionType: ActionType, series const interestRateOracleAddr = await VRCauldron.rateOracles(selectedBase.id); const interestRateOracle = VRInterestRateOracle__factory.connect(interestRateOracleAddr, provider); const joinAddress = selectedBase.joinAddressVR; - console.log('INTEREST RATE ORACLE', interestRateOracleAddr, interestRateOracle); + // console.log('INTEREST RATE ORACLE', interestRateOracleAddr, interestRateOracle); let rate: any = ethers.constants.Zero; // TODO - fix this type @@ -103,7 +104,7 @@ export const useApr = (input: string | undefined, actionType: ActionType, series ); } - console.log('rate in useAPR', rate); + // console.log('rate in useAPR', rate); return rate; } catch (e) { From 281cbda28019f0497a364e3841c8501030ff383e Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 03:02:05 -0700 Subject: [PATCH 06/36] fix: update deps --- src/hooks/useInputValidation.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/hooks/useInputValidation.ts b/src/hooks/useInputValidation.ts index f1d442156..d71626772 100644 --- a/src/hooks/useInputValidation.ts +++ b/src/hooks/useInputValidation.ts @@ -13,8 +13,6 @@ export const useInputValidation = ( limits: (number | string | undefined)[], vault?: IVault | undefined ) => { - console.log('useInputValidation params', input, actionCode, series, limits, vault); - /* STATE FROM CONTEXT */ const { userState } = useContext(UserContext); const { assetMap, selectedSeries, selectedBase, selectedVR } = userState; @@ -110,7 +108,7 @@ export const useInputValidation = ( break; } } else setInputError(null); - }, [actionCode, activeAccount, input, limits, _selectedBase?.symbol, _selectedSeries]); + }, [actionCode, activeAccount, input, limits, _selectedBase?.symbol, _selectedSeries, protocolLimited, selectedVR]); return { inputError, From 91810d67e87cc99d77bdfad5f393f69aa91a0280 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 03:02:18 -0700 Subject: [PATCH 07/36] chore: remove unused --- .../viewHelperHooks/useBorrowHelpers/useBorrowHelpersVR.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/hooks/viewHelperHooks/useBorrowHelpers/useBorrowHelpersVR.ts b/src/hooks/viewHelperHooks/useBorrowHelpers/useBorrowHelpersVR.ts index 51b532524..236c0a1a6 100644 --- a/src/hooks/viewHelperHooks/useBorrowHelpers/useBorrowHelpersVR.ts +++ b/src/hooks/viewHelperHooks/useBorrowHelpers/useBorrowHelpersVR.ts @@ -20,10 +20,6 @@ export const useBorrowHelpersVR = ( assetPairInfo: IAssetPair | null | undefined ) => { /* STATE FROM CONTEXT */ - const { - settingsState: { diagnostics }, - } = useContext(SettingsContext); - const { userState: { assetMap, selectedBase }, } = useContext(UserContext); @@ -39,7 +35,6 @@ export const useBorrowHelpersVR = ( }); /* LOCAL STATE */ - const [debtAfterRepay, setDebtAfterRepay] = useState(); const [debtInBase, setDebtInBase] = useState(); From a5afe4af5776e817869b745b2b21589dc9b9585b Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 03:05:40 -0700 Subject: [PATCH 08/36] feat: use gradient for vr vault --- src/components/PositionAvatar.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/PositionAvatar.tsx b/src/components/PositionAvatar.tsx index 7782a72e6..5dc3ca58d 100644 --- a/src/components/PositionAvatar.tsx +++ b/src/components/PositionAvatar.tsx @@ -58,7 +58,15 @@ function PositionAvatar({ return ( From 38f90d687a7116d7a259611d9c09b6aa92a031c6 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 03:08:00 -0700 Subject: [PATCH 09/36] feat: use variable language for vr borrow --- src/components/views/Borrow.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index a0353f0e3..0ea7e3554 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -561,7 +561,11 @@ const Borrow = () => { /> )} - } value={`${apr}%`} /> + } + value={`${apr}%`} + /> Date: Wed, 10 May 2023 03:14:02 -0700 Subject: [PATCH 10/36] fix: match tx codes --- src/components/views/Borrow.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index 0ea7e3554..f0e74ccd9 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -147,7 +147,10 @@ const Borrow = () => { ]); /* TX info (for disabling buttons) */ - const { txProcess: borrowProcess, resetProcess } = useProcess(ActionCodes.BORROW, selectedSeries?.id!); + const { txProcess: borrowProcess, resetProcess } = useProcess( + ActionCodes.BORROW, + selectedVR ? 'VR' : selectedSeries?.id! + ); /** LOCAL ACTION FNS */ const handleBorrow = () => { From 17daba504944b844c836562f27a7561fd1b8ba08 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 04:14:18 -0700 Subject: [PATCH 11/36] feat: update vaults --- src/hooks/actionHooks/useBorrow/useBorrowVR.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hooks/actionHooks/useBorrow/useBorrowVR.ts b/src/hooks/actionHooks/useBorrow/useBorrowVR.ts index e339f2041..097859db1 100644 --- a/src/hooks/actionHooks/useBorrow/useBorrowVR.ts +++ b/src/hooks/actionHooks/useBorrow/useBorrowVR.ts @@ -14,10 +14,12 @@ import useAccountPlus from '../../useAccountPlus'; import { ContractNames } from '../../../config/contracts'; import useAssetPair from '../../viewHelperHooks/useAssetPair/useAssetPair'; import { useSWRConfig } from 'swr'; +import useVaultsVR from '../../entities/useVaultsVR'; export const useBorrowVR = () => { const { mutate } = useSWRConfig(); const { genKey: genAssetPairKey } = useAssetPair(); + const { key: vaultsKey } = useVaultsVR(); const { userState, userActions } = useContext(UserContext); const { selectedBase, selectedIlk, assetMap } = userState; const { updateAssets } = userActions; @@ -134,8 +136,9 @@ export const useBorrowVR = () => { if (selectedIlk?.proxyId !== WETH) refetchIlkBal(); updateAssets([base, ilkToUse, selectedIlk!]); mutate(genAssetPairKey(selectedBase!.id, selectedIlk!.id)); + mutate(vaultsKey); - // TODO update all vaults + // TODO update borrow history }; return borrowVR; From 7ba927077641c57cbb76b2621dc88de375f3a9ee Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 04:28:30 -0700 Subject: [PATCH 12/36] chore: remove unused --- src/components/positionItems/VaultItem.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/positionItems/VaultItem.tsx b/src/components/positionItems/VaultItem.tsx index 5788b8f38..d3dfcbb5d 100644 --- a/src/components/positionItems/VaultItem.tsx +++ b/src/components/positionItems/VaultItem.tsx @@ -37,7 +37,6 @@ function VaultItem({ vault, index, condensed }: { vault: IVault; index: number; const vaultBase = assetMap?.get(vault.baseId); const vaultIlk = assetMap?.get(vault.ilkId); const vaultIsVR = !vault?.seriesId; - const { isLoading: vaultsLoadingVR } = useVaultsVR(); const { data: assetPair } = useAssetPair(vaultBase?.id, vaultIlk?.id); From 79767dbaaf3f814fb8136053d96469d47a980aa7 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 04:29:07 -0700 Subject: [PATCH 13/36] fix: getting vault after borrow --- src/components/views/Borrow.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index f0e74ccd9..cfe81418e 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -604,10 +604,10 @@ const Borrow = () => { View Vault: {vaultToUse && !vaultsLoading && ( - + v.id === vaultToUse.id)!} condensed index={1} /> )} {!vaultToUse && newVaultId && ( - + )} )} From c1d2cc31de7ab4c7900d247c2b2ae8c82c3a3e2e Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 04:44:37 -0700 Subject: [PATCH 14/36] feat: handle erc1155 allowance to output bignumber --- src/contexts/ChainContext.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/contexts/ChainContext.tsx b/src/contexts/ChainContext.tsx index 3df1dc91d..c74d01326 100644 --- a/src/contexts/ChainContext.tsx +++ b/src/contexts/ChainContext.tsx @@ -1,5 +1,5 @@ import React, { createContext, Dispatch, ReactNode, useCallback, useEffect, useReducer, useContext } from 'react'; -import { BigNumber, Contract } from 'ethers'; +import { BigNumber, Contract, ethers } from 'ethers'; import { format } from 'date-fns'; import { useCachedState } from '../hooks/generalHooks'; @@ -25,6 +25,7 @@ import { Pool__factory } from '../contracts'; import { useProvider } from 'wagmi'; import { SettingsContext } from './SettingsContext'; +import { MAX_256, ZERO_BN } from '@yield-protocol/ui-math'; const initState: IChainContextState = { /* flags */ @@ -117,7 +118,10 @@ const ChainProvider = ({ children }: { children: ReactNode }) => { case TokenType.ERC1155_: assetContract = contractTypes.ERC1155__factory.connect(asset.address, provider); - getAllowance = async (acc: string, spender: string) => assetContract.isApprovedForAll(acc, spender); + getAllowance = async (acc: string, spender: string) => + (await (assetContract as contractTypes.ERC1155).isApprovedForAll(acc, spender)) + ? ethers.constants.MaxUint256 + : ethers.constants.Zero; setAllowance = async (spender: string) => { console.log(spender); console.log(asset.address); From 45bc70fef446179625ac7682c82ae1f9d01f5c4e Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 04:51:00 -0700 Subject: [PATCH 15/36] fix: handling eth borrowing and using as collat --- .../actionHooks/useBorrow/useBorrowVR.ts | 65 ++++++++----------- 1 file changed, 27 insertions(+), 38 deletions(-) diff --git a/src/hooks/actionHooks/useBorrow/useBorrowVR.ts b/src/hooks/actionHooks/useBorrow/useBorrowVR.ts index 097859db1..270c6ac9d 100644 --- a/src/hooks/actionHooks/useBorrow/useBorrowVR.ts +++ b/src/hooks/actionHooks/useBorrow/useBorrowVR.ts @@ -39,7 +39,7 @@ export const useBorrowVR = () => { }); const borrowVR = async (vault: IVault | undefined, input: string | undefined, collInput: string | undefined) => { - if (!contracts) return; + if (!contracts || !account || !selectedBase || !assetMap || !selectedIlk) return; /* generate the reproducible txCode for tx tracking and tracing */ const txCode = getTxCode(ActionCodes.BORROW, 'VR'); @@ -50,45 +50,31 @@ export const useBorrowVR = () => { const ladleAddress = contracts.get(ContractNames.VR_LADLE)?.address; /* Set the series and ilk based on the vault that has been selected or if it's a new vault, get from the globally selected SeriesId */ - const base = assetMap?.get(selectedBase!.id)!; + const base = assetMap.get(selectedBase.id); - const ilkToUse = vault ? assetMap?.get(vault.ilkId)! : assetMap?.get(selectedIlk?.proxyId!)!; // note: we use the wrapped version if required + if (!base) return console.error('base not found'); - /* is ETH used as collateral */ - const isEthCollateral = ETH_BASED_ASSETS.includes(selectedIlk?.proxyId!); - /* is ETH being Borrowed */ - const isEthBase = ETH_BASED_ASSETS.includes(selectedBase!.id); + const ilkToUse = vault ? assetMap.get(vault.ilkId)! : assetMap.get(selectedIlk.proxyId); // note: we use the wrapped version if required - /* parse inputs (clean down to base/ilk decimals so that there is never an underlow) */ + if (!ilkToUse) return console.error('ilk not found'); + if (!ilkToUse.joinAddressVR) return console.error('ilkToUse.joinAddressVR not found'); + + /* is ETH used as collateral */ + const isEthCollateral = ETH_BASED_ASSETS.includes(selectedIlk.proxyId); + + /* is ETH being borrowed */ + const isEthBase = ETH_BASED_ASSETS.includes(selectedBase.id); + + /* parse inputs (clean down to base/ilk decimals so that there is never an underlow) */ const cleanInput = cleanValue(input, base.decimals); const _input = input ? ethers.utils.parseUnits(cleanInput, base.decimals) : ethers.constants.Zero; const cleanCollInput = cleanValue(collInput, ilkToUse.decimals); const _collInput = collInput ? ethers.utils.parseUnits(cleanCollInput, ilkToUse.decimals) : ethers.constants.Zero; - /* if approveMAx, check if signature is required : note: getAllowance may return FALSE if ERC1155 */ - const _allowance = await ilkToUse.getAllowance(account!, ilkToUse.joinAddressVR!); - - const alreadyApproved = ethers.BigNumber.isBigNumber(_allowance) ? _allowance.gte(_collInput) : _allowance; + /* check if signature is required */ + const _allowance = await ilkToUse.getAllowance(account, ilkToUse.joinAddressVR!); + const alreadyApproved = _allowance.gte(_collInput); - /* handle ETH deposit as Collateral, if required (only if collateral used is ETH-based ), else send ZERO_BN */ - const addEthCallData = isEthCollateral - ? [ - { - operation: LadleActions.Fn.WRAP_ETHER, - args: [selectedBase?.joinAddressVR] as LadleActions.Args.WRAP_ETHER, - overrides: { value: _input }, - }, - ] - : []; - - // TODO update for vr - // const removeEthCallData = removeEth(isEthBase ? ONE_BN : ZERO_BN); // (exit_ether sweeps all the eth out the ladle, so exact amount is not importnat -> just greater than zero) - - /* handle wrapping of collateral if required */ - // TODO figure out vr wrapping methodology - // const wrapAssetCallData = await wrapAsset(_collInput, selectedIlk!, txCode); // note: selected ilk used here, not wrapped version - - /* Gather all the required signatures - sign() processes them and returns them as ICallData types */ const permitCallData = await sign( [ { @@ -112,8 +98,8 @@ export const useBorrowVR = () => { /* Include all the signatures gathered, if required */ ...permitCallData, - /* add in the ETH deposit if required */ - ...addEthCallData, + /* add in the ETH collateral deposit if required */ + ...(isEthCollateral ? addEth(_collInput, ilkToUse.joinAddressVR) : []), /* If vault is null, build a new vault, else ignore */ { @@ -124,18 +110,21 @@ export const useBorrowVR = () => { { operation: LadleActions.Fn.POUR, - args: [vaultId, ladleAddress, _collInput, _input] as LadleActions.Args.POUR, + args: [vaultId, isEthBase ? ladleAddress : account, _collInput, _input] as LadleActions.Args.POUR, ignoreIf: false, }, + + /* remove eth if being borrowed */ + ...(isEthBase ? removeEth(_input, account) : []), ]; /* finally, handle the transaction */ await transact(calls, txCode, true); - if (selectedBase?.id !== WETH) refetchBaseBal(); - if (selectedIlk?.proxyId !== WETH) refetchIlkBal(); - updateAssets([base, ilkToUse, selectedIlk!]); - mutate(genAssetPairKey(selectedBase!.id, selectedIlk!.id)); + if (selectedBase.id !== WETH) refetchBaseBal(); + if (selectedIlk.proxyId !== WETH) refetchIlkBal(); + updateAssets([base, ilkToUse, selectedIlk]); + mutate(genAssetPairKey(selectedBase.id, selectedIlk.id)); mutate(vaultsKey); // TODO update borrow history From 5f7d27633cb901cb9b69a49f2264fbab5e61ebf7 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 05:04:06 -0700 Subject: [PATCH 16/36] fix: better check --- src/components/views/Borrow.tsx | 25 +++++-------------------- 1 file changed, 5 insertions(+), 20 deletions(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index cfe81418e..f0f378071 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -1,6 +1,5 @@ import React, { useCallback, useContext, useEffect, useState } from 'react'; import { Box, CheckBox, Keyboard, ResponsiveContext, Text, TextInput } from 'grommet'; - import { FiClock, FiPocket, FiPercent, FiTrendingUp } from 'react-icons/fi'; import SeriesSelector from '../selectors/SeriesSelector'; @@ -9,7 +8,6 @@ import AssetSelector from '../selectors/AssetSelector'; import InputWrap from '../wraps/InputWrap'; import ActionButtonWrap from '../wraps/ActionButtonWrap'; import SectionWrap from '../wraps/SectionWrap'; - import MaxButton from '../buttons/MaxButton'; import { UserContext } from '../../contexts/UserContext'; @@ -18,7 +16,6 @@ import PanelWrap from '../wraps/PanelWrap'; import CenterPanelWrap from '../wraps/CenterPanelWrap'; import VaultSelector from '../selectors/VaultPositionSelector'; import ActiveTransaction from '../ActiveTransaction'; - import { cleanValue, getVaultIdFromReceipt, nFormatter } from '../../utils/appUtils'; import YieldInfo from '../FooterInfo'; @@ -41,19 +38,16 @@ import { useBorrowHelpersVR } from '../../hooks/viewHelperHooks/useBorrowHelpers import InputInfoWrap from '../wraps/InputInfoWrap'; import ColorText from '../texts/ColorText'; import { useProcess } from '../../hooks/useProcess'; - import DummyVaultItem from '../positionItems/DummyVaultItem'; import SeriesOrStrategySelectorModal from '../selectors/SeriesOrStrategySelectorModal'; import Navigation from '../Navigation'; import VaultItem from '../positionItems/VaultItem'; import Line from '../elements/Line'; -import { useAccount, useNetwork } from 'wagmi'; import { GA_Event, GA_Properties, GA_View } from '../../types/analytics'; import useAnalytics from '../../hooks/useAnalytics'; import { WETH } from '../../config/assets'; import useContracts from '../../hooks/useContracts'; import useAccountPlus from '../../hooks/useAccountPlus'; - import VariableRate from '../selectors/VariableRate'; import useBasesVR from '../../hooks/views/useBasesVR'; import useAssetPair from '../../hooks/viewHelperHooks/useAssetPair/useAssetPair'; @@ -66,17 +60,8 @@ const Borrow = () => { /* STATE FROM CONTEXT */ const { userState, userActions } = useContext(UserContext); - const { - assetMap, - vaultMap, - vaultsLoading, - seriesMap, - selectedSeries, - selectedIlk, - selectedBase, - selectedVault, - selectedVR, - } = userState; + const { assetMap, vaultMap, vaultsLoading, selectedSeries, selectedIlk, selectedBase, selectedVault, selectedVR } = + userState; const { setSelectedIlk } = userActions; const { address: activeAccount } = useAccountPlus(); @@ -547,12 +532,12 @@ const Borrow = () => { icon={} value={`${cleanValue(borrowInput, selectedBase?.digitFormat!)} ${selectedBase?.displaySymbol}`} /> - {!selectedVR && ( + {selectedSeries && (
} - value={`${selectedSeries?.displayName}`} + value={`${selectedSeries.displayName}`} /> { borrowProcess?.stage === ProcessStage.PROCESS_COMPLETE && borrowProcess?.tx.status === TxState.SUCCESSFUL && ( - View Vault: + View Vault: {vaultToUse && !vaultsLoading && ( v.id === vaultToUse.id)!} condensed index={1} /> )} From 085adb71f341acc2f7a26dc3bdd93d5479b3268f Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 05:10:57 -0700 Subject: [PATCH 17/36] fix: make sure there is assetPairInfo --- .../viewHelperHooks/useBorrowHelpers/useBorrowHelpersFR.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hooks/viewHelperHooks/useBorrowHelpers/useBorrowHelpersFR.ts b/src/hooks/viewHelperHooks/useBorrowHelpers/useBorrowHelpersFR.ts index f61b406dc..3b5b87542 100644 --- a/src/hooks/viewHelperHooks/useBorrowHelpers/useBorrowHelpersFR.ts +++ b/src/hooks/viewHelperHooks/useBorrowHelpers/useBorrowHelpersFR.ts @@ -139,7 +139,7 @@ export const useBorrowHelpersFR = ( /* SET MAX ROLL and ROLLABLE including Check if the rollToSeries have sufficient base value AND won't be undercollaterallised */ useEffect(() => { - if (futureSeries && vault && vault.accruedArt && vault.seriesId) { + if (futureSeries && vault && vault.accruedArt && vault.seriesId && assetPairInfo) { const _maxFyTokenIn = maxFyTokenIn( futureSeries.sharesReserves, futureSeries.fyTokenReserves, @@ -164,9 +164,9 @@ export const useBorrowHelpersFR = ( ); const _minCollat = calculateMinCollateral( - assetPairInfo?.pairPrice!, + assetPairInfo.pairPrice, newDebt, - assetPairInfo?.minRatio.toString()!, + assetPairInfo.minRatio.toString(), undefined ); From 4fa976f940480b056cf5039ebfb5b2fddcec0a95 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 05:21:24 -0700 Subject: [PATCH 18/36] fix: stricter vr logic --- src/components/views/Borrow.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index f0f378071..7bd17fe3d 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -108,13 +108,13 @@ const Borrow = () => { maxDebt_: maxDebtFR_, borrowPossible: borrowPossibleFR, borrowEstimate_, - } = useBorrowHelpersFR(borrowInput, collatInput, vaultToUse, assetPair, selectedSeries); + } = useBorrowHelpersFR(borrowInput, collatInput, selectedSeries ? vaultToUse : undefined, assetPair, selectedSeries); const { minDebt_: minDebtVR_, maxDebt_: maxDebtVR_, borrowPossible: borrowPossibleVR, - } = useBorrowHelpersVR(borrowInput, vaultToUse, assetPair); + } = useBorrowHelpersVR(borrowInput, selectedVR ? vaultToUse : undefined, assetPair); const minDebt_ = selectedVR ? minDebtVR_ : minDebtFR_; const maxDebt_ = selectedVR ? maxDebtVR_ : maxDebtFR_; @@ -259,7 +259,7 @@ const Borrow = () => { (v) => v.ilkId === selectedIlk.proxyId && v.baseId === selectedBase.proxyId && - v.seriesId === selectedSeries?.id && + (selectedVR ? true : v.seriesId === selectedSeries?.id) && v.isActive ); setMatchingVaults(matchingVaults); @@ -588,9 +588,7 @@ const Borrow = () => { borrowProcess?.tx.status === TxState.SUCCESSFUL && ( View Vault: - {vaultToUse && !vaultsLoading && ( - v.id === vaultToUse.id)!} condensed index={1} /> - )} + {vaultToUse && } {!vaultToUse && newVaultId && ( )} From cdf7aeb6c2e9be8c0ec5c69e4430bb83f2cd22c0 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 05:38:54 -0700 Subject: [PATCH 19/36] fix: explicitly set selected series to null on selecting vr --- src/components/selectors/VariableRate.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/selectors/VariableRate.tsx b/src/components/selectors/VariableRate.tsx index 3f0710a21..c2806dec3 100644 --- a/src/components/selectors/VariableRate.tsx +++ b/src/components/selectors/VariableRate.tsx @@ -75,7 +75,7 @@ const VariableRate = () => { const { userState: { selectedVR }, - userActions: { setSelectedVR }, + userActions: { setSelectedVR, setSelectedSeries }, } = useContext(UserContext); return ( @@ -84,7 +84,10 @@ const VariableRate = () => { round="large" background={selectedVR ? 'purple' : '#00000007'} elevation="xsmall" - onClick={() => setSelectedVR(true)} + onClick={() => { + setSelectedVR(true); + setSelectedSeries(null); + }} className="VR-container" > From e3ce209a8a877f74770f1d83140cf76dbd799f87 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 05:44:08 -0700 Subject: [PATCH 20/36] fix: deps --- src/components/selectors/SeriesSelector.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/selectors/SeriesSelector.tsx b/src/components/selectors/SeriesSelector.tsx index 8701160fb..0c0ab4f79 100644 --- a/src/components/selectors/SeriesSelector.tsx +++ b/src/components/selectors/SeriesSelector.tsx @@ -197,6 +197,7 @@ function SeriesSelector({ selectSeriesLocally, inputValue, actionType, cardLayou selectedSeries, actionType, selectedVault, + options, ]); const handleSelect = (_series: ISeries) => { From b94b4529c9bba6b7aacccb3c18fceb6d6ae933f3 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 05:44:36 -0700 Subject: [PATCH 21/36] chore: remove unused --- src/components/selectors/SeriesSelector.tsx | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/components/selectors/SeriesSelector.tsx b/src/components/selectors/SeriesSelector.tsx index 0c0ab4f79..72e695d77 100644 --- a/src/components/selectors/SeriesSelector.tsx +++ b/src/components/selectors/SeriesSelector.tsx @@ -164,11 +164,6 @@ function SeriesSelector({ selectSeriesLocally, inputValue, actionType, cardLayou /* Keeping options/selection fresh and valid: */ useEffect(() => { - console.log('seriesSelector useEffect', selectedSeries, options); - // if (selectedVR && selectedSeries === null) { - // setOptions(options); - // return; - // } const opts = Array.from(seriesMap?.values()!); /* filter out options based on base Id ( or proxyId ) and if mature */ From 5cd4aabe7c029a6d9a8e3354a629f3c6a4d522da Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 05:57:14 -0700 Subject: [PATCH 22/36] fix: deps --- src/components/selectors/SeriesSelector.tsx | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/selectors/SeriesSelector.tsx b/src/components/selectors/SeriesSelector.tsx index 72e695d77..deaed91fa 100644 --- a/src/components/selectors/SeriesSelector.tsx +++ b/src/components/selectors/SeriesSelector.tsx @@ -184,15 +184,12 @@ function SeriesSelector({ selectSeriesLocally, inputValue, actionType, cardLayou setOptions(filteredOpts.sort((a, b) => a.maturity - b.maturity)); }, [ - seriesMap, - selectedBase, selectSeriesLocally, - _selectedSeries, - userActions, - selectedSeries, - actionType, - selectedVault, - options, + selectedBase?.proxyId, + selectedSeries?.baseId, + selectedSeries?.id, + selectedSeries?.maturity, + seriesMap, ]); const handleSelect = (_series: ISeries) => { From 2bd4512802a36e1aae7e30a5c347c4f068938279 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 06:04:45 -0700 Subject: [PATCH 23/36] fix: handling selected vaults between fr and vr --- src/components/views/Borrow.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index 7bd17fe3d..59892c7f8 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -273,11 +273,19 @@ const Borrow = () => { } if (selectedVault) { - return setVaultToUse(selectedVault); + // if using an already selected vault with series + if (selectedSeries && selectedVault.seriesId === selectedSeries.id) { + return setVaultToUse(selectedVault); + } + + // if using an already selected vr vault + if (selectedVR && selectedVault.baseId === selectedBase?.id) { + return setVaultToUse(selectedVault); + } } setVaultToUse(undefined); - }, [matchingVaults, selectedVault]); + }, [matchingVaults, selectedBase?.id, selectedSeries, selectedVR, selectedVault]); useEffect(() => { if ( From 3add074a6204692f8fb58fa386669b1d5a39c5d5 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 06:09:43 -0700 Subject: [PATCH 24/36] fix: set selected vr when vaults is vr --- src/components/views/VaultPosition.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/components/views/VaultPosition.tsx b/src/components/views/VaultPosition.tsx index 572672ea7..d0d82fced 100644 --- a/src/components/views/VaultPosition.tsx +++ b/src/components/views/VaultPosition.tsx @@ -61,9 +61,10 @@ const VaultPosition = () => { /* STATE FROM CONTEXT */ const { userState, userActions } = useContext(UserContext); - const { assetMap, seriesMap, vaultMap, vaultsLoading } = userState; + const { assetMap, seriesMap, vaultMap, vaultsLoading: vaultsLoadingFR, selectedVR } = userState; const { setSelectedBase, setSelectedIlk, setSelectedSeries, setSelectedVault, setSelectedVR } = userActions; - const { data: vaultsVR } = useVaultsVR(); + const { data: vaultsVR, isLoading: vaultsLoadingVR } = useVaultsVR(); + const vaultsLoading = selectedVR ? vaultsLoadingVR : vaultsLoadingFR; const { address: account } = useAccountPlus(); @@ -400,6 +401,11 @@ const VaultPosition = () => { rollProcess?.stage === ProcessStage.PROCESS_COMPLETE_TIMEOUT && resetInputs(ActionCodes.ROLL_DEBT); }, [addCollateralProcess, removeCollateralProcess, repayProcess, resetInputs, rollProcess]); + // update selectedVR when vault is VR + useEffect(() => { + vaultIsVR && setSelectedVR(true); + }, [setSelectedVR, vaultIsVR]); + return ( <> {_selectedVault && ( From 1c418f2612fb6d551244d14254a8e808ddec0276 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 06:26:27 -0700 Subject: [PATCH 25/36] fix: handle new vr vault --- src/components/positionItems/DummyVaultItem.tsx | 8 +++----- src/components/views/Borrow.tsx | 10 ++++++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/components/positionItems/DummyVaultItem.tsx b/src/components/positionItems/DummyVaultItem.tsx index 4a43bc8fb..1b360e37c 100644 --- a/src/components/positionItems/DummyVaultItem.tsx +++ b/src/components/positionItems/DummyVaultItem.tsx @@ -1,8 +1,6 @@ import { useRouter } from 'next/router'; - import { Box, Text } from 'grommet'; import { ActionType, ISeries } from '../../types'; - import PositionAvatar from '../PositionAvatar'; import ItemWrap from '../wraps/ItemWrap'; import { abbreviateHash } from '../../utils/appUtils'; @@ -13,7 +11,7 @@ function DummyVaultItem({ index = 0, condensed, }: { - series: ISeries; + series: ISeries | undefined; vaultId: string; index?: number; condensed?: boolean; @@ -28,7 +26,7 @@ function DummyVaultItem({ return ( handleSelect(vaultId)} index={index}> - + - {series.displayName} + {series?.displayName} diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index 59892c7f8..73fadda43 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -52,6 +52,8 @@ import VariableRate from '../selectors/VariableRate'; import useBasesVR from '../../hooks/views/useBasesVR'; import useAssetPair from '../../hooks/viewHelperHooks/useAssetPair/useAssetPair'; import useVaultsVR from '../../hooks/entities/useVaultsVR'; +import { ContractNames } from '../../config/contracts'; +import { Cauldron, VRCauldron } from '../../contracts'; const Borrow = () => { const mobile: boolean = useContext(ResponsiveContext) === 'small'; @@ -82,6 +84,7 @@ const Borrow = () => { const [matchingVaults, setMatchingVaults] = useState([]); const [vaultToUse, setVaultToUse] = useState(undefined); const [newVaultId, setNewVaultId] = useState(undefined); + console.log('🦄 ~ file: Borrow.tsx:85 ~ Borrow ~ newVaultId:', newVaultId); const [currentGaugeColor, setCurrentGaugeColor] = useState('#EF4444'); const borrow = useBorrow(); @@ -293,10 +296,13 @@ const Borrow = () => { borrowProcess?.tx.status === TxState.SUCCESSFUL && !vaultToUse ) { - setNewVaultId(getVaultIdFromReceipt(borrowProcess?.tx?.receipt, contracts)!); + const cauldron = contracts?.get(selectedVR ? ContractNames.VR_CAULDRON : ContractNames.CAULDRON) as + | VRCauldron + | Cauldron; + setNewVaultId(getVaultIdFromReceipt(borrowProcess?.tx?.receipt, cauldron!)); } borrowProcess?.stage === ProcessStage.PROCESS_COMPLETE_TIMEOUT && resetInputs(); - }, [borrowProcess, contracts, resetInputs, vaultToUse]); + }, [borrowProcess, contracts, resetInputs, selectedVR, vaultToUse]); return ( setCollatInput('')} onEnter={() => console.log('ENTER smashed')} target="document"> From 2adc596c291e0f4aa4b9da53e00dd2ce92434f47 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 06:26:42 -0700 Subject: [PATCH 26/36] fix: get vault id from receipt for both vr and fr --- src/utils/appUtils.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/utils/appUtils.ts b/src/utils/appUtils.ts index 3a0e029da..3d90fee7d 100644 --- a/src/utils/appUtils.ts +++ b/src/utils/appUtils.ts @@ -4,6 +4,7 @@ import { uniqueNamesGenerator, Config, adjectives, animals } from 'unique-names- import { ContractMap, ContractNames } from '../config/contracts'; import { ActionCodes, ISeries } from '../types'; +import { Cauldron, VRCauldron } from '../contracts'; export const copyToClipboard = (str: string) => { const el = document.createElement('textarea'); @@ -223,11 +224,8 @@ export const getPositionPath = ( } }; -export const getVaultIdFromReceipt = (receipt: ContractReceipt | undefined, contractMap: ContractMap | undefined) => { - if (!receipt || !contractMap) return ''; - - const cauldron = contractMap.get(ContractNames.CAULDRON); - if (!cauldron) return ''; +export const getVaultIdFromReceipt = (receipt: ContractReceipt | undefined, cauldron: Cauldron | VRCauldron) => { + if (!receipt) return ''; const cauldronAddr = cauldron.address; const vaultIdHex = receipt.events?.filter((e) => e.address === cauldronAddr)[0]?.topics[1]!; From 197027ef562407213e9f45ba3538c105d695d6a1 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 07:20:00 -0700 Subject: [PATCH 27/36] chore: clean --- src/components/positionItems/VaultItem.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/positionItems/VaultItem.tsx b/src/components/positionItems/VaultItem.tsx index d3dfcbb5d..0e0e6670c 100644 --- a/src/components/positionItems/VaultItem.tsx +++ b/src/components/positionItems/VaultItem.tsx @@ -14,7 +14,6 @@ import { cleanValue } from '../../utils/appUtils'; import { GA_Event, GA_Properties } from '../../types/analytics'; import useAnalytics from '../../hooks/useAnalytics'; import useAssetPair from '../../hooks/viewHelperHooks/useAssetPair/useAssetPair'; -import useVaultsVR from '../../hooks/entities/useVaultsVR'; function VaultItem({ vault, index, condensed }: { vault: IVault; index: number; condensed?: boolean }) { const router = useRouter(); @@ -36,7 +35,7 @@ function VaultItem({ vault, index, condensed }: { vault: IVault; index: number; const vaultBase = assetMap?.get(vault.baseId); const vaultIlk = assetMap?.get(vault.ilkId); - const vaultIsVR = !vault?.seriesId; + const vaultIsVR = !vault.seriesId; const { data: assetPair } = useAssetPair(vaultBase?.id, vaultIlk?.id); From 33fe18fe3647a984c3b95edeef4a0ab5e4ce3f48 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 07:20:20 -0700 Subject: [PATCH 28/36] fix: make sure there is a selected vault --- src/components/views/VaultPosition.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/VaultPosition.tsx b/src/components/views/VaultPosition.tsx index d0d82fced..79439493c 100644 --- a/src/components/views/VaultPosition.tsx +++ b/src/components/views/VaultPosition.tsx @@ -252,7 +252,7 @@ const VaultPosition = () => { const handleRepay = () => { if (repayDisabled) return; setRepayDisabled(true); - repay(_selectedVault!, repayInput?.toString(), reclaimCollateral); + if (_selectedVault) repay(_selectedVault, repayInput, reclaimCollateral); logAnalyticsEvent(GA_Event.transaction_initiated, { view: GA_View.BORROW, From e172ecc49be62f2d363fb2e42e5a89406a44f251 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 07:20:34 -0700 Subject: [PATCH 29/36] feat: add repay vr args type --- src/types/operations.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/operations.ts b/src/types/operations.ts index 8caf16a6e..86a3517bb 100644 --- a/src/types/operations.ts +++ b/src/types/operations.ts @@ -50,6 +50,7 @@ export namespace LadleActions { export type SERVE = [vaultId: string, to: string, ink: BigNumberish, base: BigNumberish, max: BigNumberish]; export type CLOSE = [vaultId: string, to: string, ink: BigNumberish, art: BigNumberish]; export type REPAY = [vaultId: string, to: string, ink: BigNumberish, min: BigNumberish]; + export type REPAY_VR = [vaultId: string, inkTo: string, refundTo: string, ink: BigNumberish]; export type REPAY_VAULT = [vaultId: string, to: string, ink: BigNumberish, max: BigNumberish]; export type REPAY_LADLE = [vaultId: string]; export type RETRIEVE = [assetAddress: string, to: string]; From d606280824f09e9af5a1e2486b71eba36296d06a Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 07:20:48 -0700 Subject: [PATCH 30/36] fix: handle repaying vr --- .../useRepayDebt/useRepayDebtVR.ts | 123 +++++------------- 1 file changed, 34 insertions(+), 89 deletions(-) diff --git a/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts b/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts index f7f755e80..6a2c48b31 100644 --- a/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts +++ b/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts @@ -1,7 +1,6 @@ import { ethers } from 'ethers'; import { useContext } from 'react'; import { calculateSlippage, MAX_256 } from '@yield-protocol/ui-math'; - import { UserContext } from '../../../contexts/UserContext'; import { ICallData, IVault, ActionCodes, LadleActions, IAsset, RoutedActions } from '../../../types'; import { cleanValue, getTxCode } from '../../../utils/appUtils'; @@ -17,7 +16,8 @@ import useContracts from '../../useContracts'; import useChainId from '../../useChainId'; import useAccountPlus from '../../useAccountPlus'; import { ContractNames } from '../../../config/contracts'; -import useAllowAction from '../../useAllowAction'; +import { mutate } from 'swr'; +import useVaultsVR from '../../entities/useVaultsVR'; export const useRepayDebtVR = () => { const { @@ -40,8 +40,8 @@ export const useRepayDebtVR = () => { token: selectedBase?.id === WETH ? undefined : (selectedBase?.address as Address), }); + const { key: vaultsKey } = useVaultsVR(); const { addEth, removeEth } = useAddRemoveEth(); - const { unwrapAsset } = useWrapUnwrapAsset(); const { sign, transact } = useChain(); const chainId = useChainId(); @@ -51,80 +51,44 @@ export const useRepayDebtVR = () => { * @param input * @param reclaimCollateral */ - const repayVariableRate = async (vault: IVault, input: string | undefined, reclaimCollateral: boolean) => { - if (!contracts) return; + const repay = async (vault: IVault, input: string | undefined, reclaimCollateral: boolean) => { + if (!contracts || !input || !assetMap || !account) return; const txCode = getTxCode(ActionCodes.REPAY, vault.id); const ladleAddress = contracts.get(ContractNames.VR_LADLE)?.address; + if (!ladleAddress) return console.error('Ladle address not found'); - const vrCauldronAddress = contracts.get(ContractNames.VR_CAULDRON)?.address; - // const series: ISeries = seriesMap?.get(vault.seriesId)!; - const base: IAsset = assetMap?.get(vault.baseId)!; - const ilk: IAsset = assetMap?.get(vault.ilkId)!; + const base = assetMap.get(vault.baseId); + const ilk = assetMap.get(vault.ilkId); - // if (!isActionAllowed(ActionCodes.REPAY)) return; // return if action is not allowed + if (!base || !ilk) return console.error('Base or ilk not found'); const isEthCollateral = ETH_BASED_ASSETS.includes(vault.ilkId); - const isEthBase = ETH_BASED_ASSETS.includes(base.id); - - /* is convex-type collateral */ - const isConvexCollateral = CONVEX_BASED_ASSETS.includes(ilk.proxyId); - const convexJoinContract = ConvexJoin__factory.connect(ilk.joinAddress, provider); + const isEthBase = ETH_BASED_ASSETS.includes(vault.baseId); /* Parse inputs */ const cleanInput = cleanValue(input, base.decimals); - const _input = input ? ethers.utils.parseUnits(cleanInput, base.decimals) : ethers.constants.Zero; - - /* - we won't be able to do the below maxSharesIn calculation for VR because - theres no series. Will need to follow up on what to do here - jacob b - - can call Cauldron.balances here to get the debt - call when selects user vault - also worth it to try - and calcultate in the UI - */ - - /* Check if the trade of that size is possible */ - // assuming all trades are possible for now, but will need to revisit - jacob b - const tradeIsNotPossible = false; - - diagnostics && tradeIsNotPossible ? console.log('Trade is not possible:') : console.log('Trade is possible:'); - diagnostics && tradeIsNotPossible && console.log('Trade input', _input.toString()); - - const _inputAsFyTokenWithSlippage = calculateSlippage( - // remove fyToken references - jacob b - _input, - slippageTolerance.toString(), - true // minimize - ); + const _input = ethers.utils.parseUnits(cleanInput, base.decimals); /* Check if input is more than the debt */ - const inputGreaterThanEqualDebt: boolean = ethers.BigNumber.from(_input).gte(vault.accruedArt); + const inputGreaterThanEqualDebt = _input.gte(vault.accruedArt); /* If requested, and all debt will be repaid, automatically remove collateral */ const _collateralToRemove = reclaimCollateral && inputGreaterThanEqualDebt ? vault.ink.mul(-1) : ethers.constants.Zero; - /* Cap the amount to transfer: check that if input is greater than debt, used after maturity only repay the max debt (or accrued debt) */ + /* Cap the amount of debt to repay at total debt */ const _inputCappedAtArt = vault.art.gt(ZERO_BN) && vault.art.lte(_input) ? vault.art : _input; - /* Set the amount to transfer ( + 0.1% after maturity ) */ - /* assuming mature here as well - is this right? - jacob b */ - const amountToTransfer = _input.mul(10001).div(10000); - - /* In low liq situations/or mature, send repay funds to join not pool */ - /* I believe we transfer our repayment directly to the ladle, could be wrong here - jacob b */ - // maybe the cauldron directly? - jacob b - const transferToAddress = vrCauldronAddress; + /* Set the amount of base to transfer for repay with slight buffer */ + const amountToTransfer = _inputCappedAtArt.mul(10001).div(10000); /* Check if already approved */ - const alreadyApproved = (await base.getAllowance(account!, ladleAddress!)).gte(amountToTransfer); - - // const wrapAssetCallData : ICallData[] = await wrapAsset(ilk, account!); - const unwrapAssetCallData: ICallData[] = reclaimCollateral ? await unwrapAsset(ilk, account!) : []; + const alreadyApproved = (await base.getAllowance(account, ladleAddress)).gte(amountToTransfer); const approveAmount = base.id === USDT && chainId !== 42161 ? MAX_256 : amountToTransfer.mul(110).div(100); + const permitCallData: ICallData[] = await sign( [ { @@ -137,64 +101,45 @@ export const useRepayDebtVR = () => { txCode ); - /* Remove ETH collateral. (exit_ether sweeps all the eth out of the ladle, so exact amount is not importnat -> just greater than zero) */ - const removeEthCallData = isEthCollateral ? removeEth(ONE_BN) : []; + const removeEthCallData = isEthCollateral ? removeEth(ONE_BN, ladleAddress) : []; - /* Address to send the funds to either ladle (if eth is used as collateral) or account */ - // TODO - Need to test with this after we get a VR fork with WETH module - jacob b - const reclaimToAddress = () => { - if (isEthCollateral) return ladleAddress; - if (unwrapAssetCallData.length && ilk.unwrapHandlerAddresses?.has(chain?.id!)) - return ilk.unwrapHandlerAddresses?.get(chain?.id!); // if there is somethign to unwrap - return account; - }; + /* Address to send the collateral to either ladle (if eth is used as collateral) or account */ + const reclaimCollatToAddress = isEthCollateral ? ladleAddress : account; const calls: ICallData[] = [ ...permitCallData, - - /* Reqd. when we have a wrappedBase */ - // ...wrapAssetCallData - - /* If ethBase, Send ETH to either base join or pool */ - ...addEth(isEthBase ? amountToTransfer : ZERO_BN, transferToAddress), // destination = either join or series depending if tradeable - ...addEth(isEthBase ? amountToTransfer : ZERO_BN), // no destination defined after maturity , input +1% will will go to weth join - - /* Else, Send Token to either join or pool via a ladle.transfer() */ + ...(isEthBase ? addEth(amountToTransfer, ladleAddress) : []), { operation: LadleActions.Fn.TRANSFER, - args: [base.address, transferToAddress, amountToTransfer] as LadleActions.Args.TRANSFER, + args: [base.address, ladleAddress, amountToTransfer] as LadleActions.Args.TRANSFER, ignoreIf: isEthBase, }, - /* convex-type collateral; ensure checkpoint before giving collateral back to account */ - { - operation: LadleActions.Fn.ROUTE, - args: [vault.owner] as RoutedActions.Args.CHECKPOINT, - fnName: RoutedActions.Fn.CHECKPOINT, - targetContract: convexJoinContract, // use the convex join contract to checkpoint - ignoreIf: !isConvexCollateral || _collateralToRemove.eq(ethers.constants.Zero), - }, - - /* BEFORE MATURITY - !series.seriesIsMature */ { operation: LadleActions.Fn.REPAY, - args: [vault.id, account, ladleAddress, _inputAsFyTokenWithSlippage] as LadleActions.Args.REPAY, - ignoreIf: inputGreaterThanEqualDebt || tradeIsNotPossible, + args: [ + vault.id, + reclaimCollatToAddress, + reclaimCollatToAddress, + _collateralToRemove, + ] as LadleActions.Args.REPAY_VR, + ignoreIf: false, }, ...removeEthCallData, - ...unwrapAssetCallData, ]; + await transact(calls, txCode); if (selectedBase?.proxyId !== WETH) refetchBaseBal(); if (selectedIlk?.proxyId !== WETH) refetchIlkBal(); - updateVaults([vault]); updateAssets([base, ilk, userState.selectedIlk!]); - // updateSeries([series]); + mutate(vaultsKey); + + // TODO update vault history }; - return repayVariableRate; + return repay; }; From f02e7fa14ccad69f1fe8aee6f2ca2d16f4df9345 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 07:41:17 -0700 Subject: [PATCH 31/36] chore: remove log --- src/components/views/Borrow.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/Borrow.tsx b/src/components/views/Borrow.tsx index 73fadda43..8e96f4196 100644 --- a/src/components/views/Borrow.tsx +++ b/src/components/views/Borrow.tsx @@ -84,7 +84,6 @@ const Borrow = () => { const [matchingVaults, setMatchingVaults] = useState([]); const [vaultToUse, setVaultToUse] = useState(undefined); const [newVaultId, setNewVaultId] = useState(undefined); - console.log('🦄 ~ file: Borrow.tsx:85 ~ Borrow ~ newVaultId:', newVaultId); const [currentGaugeColor, setCurrentGaugeColor] = useState('#EF4444'); const borrow = useBorrow(); From 8716bade5e6dd153f3c683e5620ffc344c3879ec Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 07:51:53 -0700 Subject: [PATCH 32/36] chore: clean --- .../actionHooks/useRepayDebt/useRepayDebtVR.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts b/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts index 6a2c48b31..fafc50339 100644 --- a/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts +++ b/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts @@ -87,32 +87,32 @@ export const useRepayDebtVR = () => { /* Check if already approved */ const alreadyApproved = (await base.getAllowance(account, ladleAddress)).gte(amountToTransfer); - const approveAmount = base.id === USDT && chainId !== 42161 ? MAX_256 : amountToTransfer.mul(110).div(100); + const approveAmount = base.id === USDT && chainId !== 42161 ? MAX_256 : amountToTransfer; - const permitCallData: ICallData[] = await sign( + const permitCallData = await sign( [ { target: base, spender: 'LADLE', - amount: approveAmount, // generous approval permits on repayment we can refine at a later stage - ignoreIf: alreadyApproved === true, + amount: approveAmount, + ignoreIf: alreadyApproved, }, ], txCode ); - const removeEthCallData = isEthCollateral ? removeEth(ONE_BN, ladleAddress) : []; + const removeEthCallData = isEthCollateral ? removeEth(ONE_BN, account) : []; - /* Address to send the collateral to either ladle (if eth is used as collateral) or account */ + /* Address to send the collateral to: either ladle (if eth is used as collateral) or account */ const reclaimCollatToAddress = isEthCollateral ? ladleAddress : account; const calls: ICallData[] = [ ...permitCallData, - ...(isEthBase ? addEth(amountToTransfer, ladleAddress) : []), + ...(isEthBase ? addEth(amountToTransfer, base.joinAddressVR) : []), { operation: LadleActions.Fn.TRANSFER, - args: [base.address, ladleAddress, amountToTransfer] as LadleActions.Args.TRANSFER, + args: [base.address, base.joinAddressVR, amountToTransfer] as LadleActions.Args.TRANSFER, ignoreIf: isEthBase, }, From f1212bcc6f44b8a1cfaaa9a0e895ed993eaa7c37 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 07:53:07 -0700 Subject: [PATCH 33/36] fix: update loading --- src/hooks/entities/useVaultsVR.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/entities/useVaultsVR.ts b/src/hooks/entities/useVaultsVR.ts index cb534b94f..934a688f8 100644 --- a/src/hooks/entities/useVaultsVR.ts +++ b/src/hooks/entities/useVaultsVR.ts @@ -134,13 +134,13 @@ const useVaultsVR = () => { [account, forkStartBlock, useForkedEnv, assetRootMap, forkUrl] ); - const { data, error, isLoading } = useSWR(key, getVaults, { + const { data, error, isLoading, isValidating } = useSWR(key, getVaults, { revalidateOnFocus: false, revalidateIfStale: false, shouldRetryOnError: false, }); - return { data, error, isLoading, key }; + return { data, error, isLoading: isLoading || isValidating, key }; }; export default useVaultsVR; From 7d5f8a0a4762a7cf8c7c12a155b415e3a4f2e1d9 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Wed, 10 May 2023 07:56:39 -0700 Subject: [PATCH 34/36] fix: handle load --- src/components/positionItems/VaultItem.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/positionItems/VaultItem.tsx b/src/components/positionItems/VaultItem.tsx index 0e0e6670c..e08b31386 100644 --- a/src/components/positionItems/VaultItem.tsx +++ b/src/components/positionItems/VaultItem.tsx @@ -14,6 +14,7 @@ import { cleanValue } from '../../utils/appUtils'; import { GA_Event, GA_Properties } from '../../types/analytics'; import useAnalytics from '../../hooks/useAnalytics'; import useAssetPair from '../../hooks/viewHelperHooks/useAssetPair/useAssetPair'; +import useVaultsVR from '../../hooks/entities/useVaultsVR'; function VaultItem({ vault, index, condensed }: { vault: IVault; index: number; condensed?: boolean }) { const router = useRouter(); @@ -33,6 +34,7 @@ function VaultItem({ vault, index, condensed }: { vault: IVault; index: number; } as GA_Properties.position_opened); }; + const { isLoading: vaultsLoadingVR } = useVaultsVR(); const vaultBase = assetMap?.get(vault.baseId); const vaultIlk = assetMap?.get(vault.ilkId); const vaultIsVR = !vault.seriesId; @@ -82,7 +84,7 @@ function VaultItem({ vault, index, condensed }: { vault: IVault; index: number; )} {vaultIsVR && ( - {!debtInBase_ ? : cleanValue(debtInBase_, 2)} + {!debtInBase_ || vaultsLoadingVR ? : cleanValue(debtInBase_, 2)} )} From 4a5fc2b2fc3f04f8174fcc6256d3df0001217bd5 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Thu, 11 May 2023 01:37:38 -0700 Subject: [PATCH 35/36] fix: disable if loading --- src/components/views/VaultPosition.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/VaultPosition.tsx b/src/components/views/VaultPosition.tsx index 79439493c..82e055694 100644 --- a/src/components/views/VaultPosition.tsx +++ b/src/components/views/VaultPosition.tsx @@ -341,8 +341,8 @@ const VaultPosition = () => { /* ACTION DISABLING LOGIC */ useEffect(() => { /* if ANY of the following conditions are met: block action */ - !repayInput || repayError || !_selectedVault ? setRepayDisabled(true) : setRepayDisabled(false); - !rollToSeries || rollError || !_selectedVault ? setRollDisabled(true) : setRollDisabled(false); + !repayInput || repayError || !_selectedVault || vaultsLoading ? setRepayDisabled(true) : setRepayDisabled(false); + !rollToSeries || rollError || !_selectedVault || vaultsLoading ? setRollDisabled(true) : setRollDisabled(false); !addCollatInput || addCollatError || !_selectedVault ? setAddCollateralDisabled(true) : setAddCollateralDisabled(false); @@ -359,6 +359,7 @@ const VaultPosition = () => { removeCollatError, rollError, _selectedVault, + vaultsLoading, ]); /* EXTRA INITIATIONS */ From df2e2a8e9e744ea6bd90ee25b06be1eeab2c4b16 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Thu, 11 May 2023 01:37:52 -0700 Subject: [PATCH 36/36] feat: handle repaying less than all debt --- .../actionHooks/useRepayDebt/useRepayDebtVR.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts b/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts index fafc50339..9f98350a3 100644 --- a/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts +++ b/src/hooks/actionHooks/useRepayDebt/useRepayDebtVR.ts @@ -116,6 +116,19 @@ export const useRepayDebtVR = () => { ignoreIf: isEthBase, }, + /* repay less than all debt */ + { + operation: LadleActions.Fn.POUR, + args: [ + vault.id, + reclaimCollatToAddress, + _collateralToRemove, + _inputCappedAtArt.mul(-1), + ] as LadleActions.Args.POUR, + ignoreIf: inputGreaterThanEqualDebt, + }, + + /* repay all debt */ { operation: LadleActions.Fn.REPAY, args: [ @@ -124,7 +137,7 @@ export const useRepayDebtVR = () => { reclaimCollatToAddress, _collateralToRemove, ] as LadleActions.Args.REPAY_VR, - ignoreIf: false, + ignoreIf: !inputGreaterThanEqualDebt, }, ...removeEthCallData,