From 06b81a7a5e4e38610ec1b2dad8897a329ba98305 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 14 Mar 2023 14:45:03 +0000 Subject: [PATCH 01/23] update actions to included check --- src/config/series.ts | 5 ++- src/contexts/ChainContext.tsx | 2 ++ src/hooks/actionHooks/useAddCollateral.ts | 4 +++ src/hooks/actionHooks/useAddLiquidity.ts | 4 +++ src/hooks/actionHooks/useBorrow.ts | 5 +++ src/hooks/actionHooks/useClaimRewards.ts | 6 ++++ src/hooks/actionHooks/useClosePosition.ts | 3 ++ src/hooks/actionHooks/useLend.ts | 4 +++ src/hooks/actionHooks/useRemoveCollateral.ts | 4 +++ src/hooks/actionHooks/useRemoveLiquidity.ts | 4 +++ src/hooks/actionHooks/useRepayDebt.ts | 16 +++++++-- src/hooks/actionHooks/useRollDebt.ts | 4 +++ src/hooks/actionHooks/useRollPosition.ts | 3 ++ src/hooks/useAllowAction.ts | 34 ++++++++++++++++++++ src/hooks/useChain.ts | 2 +- src/types/index.ts | 2 ++ 16 files changed, 97 insertions(+), 5 deletions(-) create mode 100644 src/hooks/useAllowAction.ts diff --git a/src/config/series.ts b/src/config/series.ts index efbaa8ae5..ca581007a 100644 --- a/src/config/series.ts +++ b/src/config/series.ts @@ -1,5 +1,6 @@ import { BaseProvider } from '@ethersproject/providers'; import { Cauldron__factory, FYToken__factory, Pool__factory } from '../contracts'; +import { ActionCodes } from '../types'; const commonProperties = { version: '1', poolVersion: '1', decimals: 18 }; @@ -22,8 +23,10 @@ export interface ISeriesStatic { ts: string; g1: string; g2: string; -} + allowActions?: (ActionCodes |'allow_none'|'allow_all')[]; +} + const USDC_2112 = '0x303230340000'; const USDC_2203 = '0x303230350000'; const USDC_2206 = '0x303230360000'; diff --git a/src/contexts/ChainContext.tsx b/src/contexts/ChainContext.tsx index 7d01505a7..98b1a637e 100644 --- a/src/contexts/ChainContext.tsx +++ b/src/contexts/ChainContext.tsx @@ -239,6 +239,8 @@ const ChainProvider = ({ children }: { children: ReactNode }) => { oppEndColor, seriesMark: , + + allowActions: series.allowActions || ['allow_all'], // default to allow all actions }; }, [provider] diff --git a/src/hooks/actionHooks/useAddCollateral.ts b/src/hooks/actionHooks/useAddCollateral.ts index 1c31fff59..3423ab4d7 100644 --- a/src/hooks/actionHooks/useAddCollateral.ts +++ b/src/hooks/actionHooks/useAddCollateral.ts @@ -17,6 +17,7 @@ import { Address, useBalance } from 'wagmi'; import useContracts from '../useContracts'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; export const useAddCollateral = () => { const { userState, userActions } = useContext(UserContext); @@ -33,6 +34,8 @@ export const useAddCollateral = () => { const { wrapAsset } = useWrapUnwrapAsset(); const { addEth } = useAddRemoveEth(); + const {isActionAllowed} = useAllowAction(); + const { refetch: refetchBaseBal } = useBalance({ address: account, token: selectedBase?.address as Address, @@ -44,6 +47,7 @@ export const useAddCollateral = () => { const addCollateral = async (vault: IVault | undefined, input: string) => { if (!contracts) return; + if (!isActionAllowed(ActionCodes.ADD_COLLATERAL)) return; // return if action is not allowed /* use the vault id provided OR 0 if new/ not provided */ const vaultId = vault?.id || BLANK_VAULT; diff --git a/src/hooks/actionHooks/useAddLiquidity.ts b/src/hooks/actionHooks/useAddLiquidity.ts index 2ee0d7c93..11cf260be 100644 --- a/src/hooks/actionHooks/useAddLiquidity.ts +++ b/src/hooks/actionHooks/useAddLiquidity.ts @@ -30,6 +30,7 @@ import useContracts from '../useContracts'; import useChainId from '../useChainId'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; export const useAddLiquidity = () => { const { @@ -49,6 +50,8 @@ export const useAddLiquidity = () => { historyActions: { updateStrategyHistory }, } = useContext(HistoryContext); + const {isActionAllowed} = useAllowAction(); + const { addEth } = useAddRemoveEth(); const { getTimeTillMaturity } = useTimeTillMaturity(); const { refetch: refetchBaseBal } = useBalance({ @@ -67,6 +70,7 @@ export const useAddLiquidity = () => { matchingVault: IVault | undefined = undefined ) => { if (!contracts) return; + if (!isActionAllowed(ActionCodes.ADD_LIQUIDITY)) return; // return if action is not allowed const txCode = getTxCode(ActionCodes.ADD_LIQUIDITY, strategy.id); diff --git a/src/hooks/actionHooks/useBorrow.ts b/src/hooks/actionHooks/useBorrow.ts index c08e6a5b2..a9104bce1 100644 --- a/src/hooks/actionHooks/useBorrow.ts +++ b/src/hooks/actionHooks/useBorrow.ts @@ -20,6 +20,7 @@ import { Address, useBalance } from 'wagmi'; import useContracts from '../useContracts'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; export const useBorrow = () => { const { @@ -47,8 +48,12 @@ export const useBorrow = () => { const { sign, transact } = useChain(); const { getTimeTillMaturity } = useTimeTillMaturity(); + const {isActionAllowed} = useAllowAction(); + const borrow = async (vault: IVault | undefined, input: string | undefined, collInput: string | undefined) => { if (!contracts) return; + if (!isActionAllowed(ActionCodes.BORROW)) return; // return if action is not allowed + /* generate the reproducible txCode for tx tracking and tracing */ const txCode = getTxCode(ActionCodes.BORROW, selectedSeries?.id!); diff --git a/src/hooks/actionHooks/useClaimRewards.ts b/src/hooks/actionHooks/useClaimRewards.ts index 66e51eafd..5911c0b8d 100644 --- a/src/hooks/actionHooks/useClaimRewards.ts +++ b/src/hooks/actionHooks/useClaimRewards.ts @@ -6,11 +6,13 @@ import { ActionCodes, IAsset, IStrategy} from '../../types'; import { useSigner, useAccount } from 'wagmi'; import useAccountPlus from '../useAccountPlus'; +import useAllowAction from '../useAllowAction'; const useClaimRewards = (strategy: IStrategy | undefined) => { const { data: signer, isError, isLoading } = useSigner(); const { address:account } = useAccountPlus(); + const {isActionAllowed} = useAllowAction(); const { userState, userActions } = useContext(UserContext); const { assetMap } = userState; @@ -25,9 +27,13 @@ const useClaimRewards = (strategy: IStrategy | undefined) => { const [rewardsToken, setRewardsToken] = useState(); const claimRewards = async () => { + if (!account) throw new Error('no account detected when claiming rewards'); if (!signer) throw new Error('no signer detected when claiming rewards'); if (!strategy) throw new Error('no strategy detected when claiming rewards'); + + if (!isActionAllowed(ActionCodes.CLAIM_REWARDS)) return; // return if action is not allowed + const claim = async () => await strategy.strategyContract.connect(signer).claim(account); diff --git a/src/hooks/actionHooks/useClosePosition.ts b/src/hooks/actionHooks/useClosePosition.ts index b06527bc8..6afd29ef7 100644 --- a/src/hooks/actionHooks/useClosePosition.ts +++ b/src/hooks/actionHooks/useClosePosition.ts @@ -17,6 +17,7 @@ import { Address, useBalance } from 'wagmi'; import useContracts from '../useContracts'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; /* Lend Actions Hook */ export const useClosePosition = () => { @@ -44,6 +45,7 @@ export const useClosePosition = () => { const { sign, transact } = useChain(); const { removeEth } = useAddRemoveEth(); const { getTimeTillMaturity } = useTimeTillMaturity(); + const { isActionAllowed } = useAllowAction(); const closePosition = async ( input: string | undefined, @@ -51,6 +53,7 @@ export const useClosePosition = () => { getValuesFromNetwork: boolean = true // get market values by network call or offline calc (default: NETWORK) ) => { if (!contracts) return; + if (!isActionAllowed(ActionCodes.CLOSE_POSITION)) return; // return if action is not allowed const txCode = getTxCode(ActionCodes.CLOSE_POSITION, series.id); const base = assetMap?.get(series.baseId)!; diff --git a/src/hooks/actionHooks/useLend.ts b/src/hooks/actionHooks/useLend.ts index eff91a4a7..18aaf4c24 100644 --- a/src/hooks/actionHooks/useLend.ts +++ b/src/hooks/actionHooks/useLend.ts @@ -16,6 +16,7 @@ import useContracts from '../useContracts'; import useChainId from '../useChainId'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; /* Lend Actions Hook */ export const useLend = () => { @@ -28,6 +29,7 @@ export const useLend = () => { const { updateSeries, updateAssets } = userActions; const { address: account } = useAccountPlus(); const chainId = useChainId(); + const { isActionAllowed } = useAllowAction(); const { refetch: refetchFyTokenBal } = useBalance({ address: account, token: selectedSeries?.address as Address }); const { refetch: refetchBaseBal } = useBalance({ @@ -46,6 +48,8 @@ export const useLend = () => { const lend = async (input: string | undefined, series: ISeries) => { if (!contracts) return; + if (!isActionAllowed(ActionCodes.LEND)) return; // return if action is not allowed + /* generate the reproducible txCode for tx tracking and tracing */ const txCode = getTxCode(ActionCodes.LEND, series.id); diff --git a/src/hooks/actionHooks/useRemoveCollateral.ts b/src/hooks/actionHooks/useRemoveCollateral.ts index dba8c7893..5b61bebab 100644 --- a/src/hooks/actionHooks/useRemoveCollateral.ts +++ b/src/hooks/actionHooks/useRemoveCollateral.ts @@ -14,6 +14,7 @@ import { Address, useBalance, useNetwork, useProvider } from 'wagmi'; import useContracts from '../useContracts'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; export const useRemoveCollateral = () => { const { userState, userActions } = useContext(UserContext); @@ -35,9 +36,12 @@ export const useRemoveCollateral = () => { const { transact } = useChain(); const { removeEth } = useAddRemoveEth(); const { unwrapAsset } = useWrapUnwrapAsset(); + const { isActionAllowed } = useAllowAction(); const removeCollateral = async (vault: IVault, input: string, unwrapOnRemove: boolean = true) => { if (!contracts) return; + if (!isActionAllowed(ActionCodes.REMOVE_COLLATERAL)) return; // return if action is not allowed + /* generate the txCode for tx tracking and tracing */ const txCode = getTxCode(ActionCodes.REMOVE_COLLATERAL, vault.id); diff --git a/src/hooks/actionHooks/useRemoveLiquidity.ts b/src/hooks/actionHooks/useRemoveLiquidity.ts index 4d88ce7cc..cc262cc7b 100644 --- a/src/hooks/actionHooks/useRemoveLiquidity.ts +++ b/src/hooks/actionHooks/useRemoveLiquidity.ts @@ -28,6 +28,7 @@ import { Strategy__factory } from '../../contracts'; import { StrategyType } from '../../config/strategies'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; /* +---------+ DEFUNCT PATH @@ -67,6 +68,7 @@ export const useRemoveLiquidity = () => { const { sign, transact } = useChain(); const { removeEth } = useAddRemoveEth(); const { getTimeTillMaturity } = useTimeTillMaturity(); + const { isActionAllowed } = useAllowAction(); const contracts = useContracts(); const { refetch: refetchBaseBal } = useBalance({ @@ -88,6 +90,8 @@ export const useRemoveLiquidity = () => { const removeLiquidity = async (input: string, series: ISeries, matchingVault: IVault | undefined) => { if (!contracts) return; + if (!isActionAllowed(ActionCodes.REMOVE_LIQUIDITY)) return; // return if action is not allowed + /* generate the reproducible txCode for tx tracking and tracing */ const txCode = getTxCode(ActionCodes.REMOVE_LIQUIDITY, series.id); diff --git a/src/hooks/actionHooks/useRepayDebt.ts b/src/hooks/actionHooks/useRepayDebt.ts index 15d9724d4..892c07f7d 100644 --- a/src/hooks/actionHooks/useRepayDebt.ts +++ b/src/hooks/actionHooks/useRepayDebt.ts @@ -18,6 +18,7 @@ import useContracts from '../useContracts'; import useChainId from '../useChainId'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; export const useRepayDebt = () => { const { @@ -46,6 +47,8 @@ export const useRepayDebt = () => { const { getTimeTillMaturity, isMature } = useTimeTillMaturity(); const chainId = useChainId(); + const {isActionAllowed} = useAllowAction(); + /** * REPAY FN * @param vault @@ -53,8 +56,9 @@ export const useRepayDebt = () => { * @param reclaimCollateral */ const repay = async (vault: IVault, input: string | undefined, reclaimCollateral: boolean) => { + if (!contracts) return; - + const txCode = getTxCode(ActionCodes.REPAY, vault.id); const ladleAddress = contracts.get(ContractNames.LADLE)?.address; @@ -62,6 +66,8 @@ export const useRepayDebt = () => { const base: IAsset = assetMap?.get(vault.baseId)!; const ilk: IAsset = assetMap?.get(vault.ilkId)!; + if (!isActionAllowed(ActionCodes.REPAY, series )) return; // return if action is not allowed + const isEthCollateral = ETH_BASED_ASSETS.includes(vault.ilkId); const isEthBase = ETH_BASED_ASSETS.includes(series.baseId); @@ -123,7 +129,7 @@ export const useRepayDebt = () => { /* Set the amount to transfer ( + 0.1% after maturity ) */ const amountToTransfer = series.seriesIsMature ? _input.mul(10001).div(10000) : _input; // After maturity + 0.1% for increases during tx time - /* In low liq situations/or mature, send repay funds to join not pool */ + /* In low liq situations/or mature, send repay funds to join not pool */ const transferToAddress = tradeIsNotPossible || series.seriesIsMature ? base.joinAddress : series.poolAddress; /* Check if already approved */ @@ -174,7 +180,6 @@ export const useRepayDebt = () => { ignoreIf: isEthBase, }, - /* BEFORE MATURITY - !series.seriesIsMature */ /* convex-type collateral; ensure checkpoint before giving collateral back to account */ { operation: LadleActions.Fn.ROUTE, @@ -184,6 +189,7 @@ export const useRepayDebt = () => { ignoreIf: !isConvexCollateral || _collateralToRemove.eq(ethers.constants.Zero), }, + /* BEFORE MATURITY - !series.seriesIsMature */ { operation: LadleActions.Fn.REPAY, args: [vault.id, account, ethers.constants.Zero, _inputAsFyTokenWithSlippage] as LadleActions.Args.REPAY, @@ -211,12 +217,16 @@ export const useRepayDebt = () => { args: [vault.id, reclaimToAddress(), _collateralToRemove, _inputCappedAtArt.mul(-1)] as LadleActions.Args.CLOSE, ignoreIf: !series.seriesIsMature, }, + ...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]); diff --git a/src/hooks/actionHooks/useRollDebt.ts b/src/hooks/actionHooks/useRollDebt.ts index a0ddec0e6..5724b2e0f 100644 --- a/src/hooks/actionHooks/useRollDebt.ts +++ b/src/hooks/actionHooks/useRollDebt.ts @@ -4,6 +4,7 @@ import { UserContext } from '../../contexts/UserContext'; import { ICallData, IVault, ISeries, ActionCodes, LadleActions, IHistoryContext } from '../../types'; import { getTxCode } from '../../utils/appUtils'; import { MAX_128, ZERO_BN } from '../../utils/constants'; +import useAllowAction from '../useAllowAction'; import { useChain } from '../useChain'; /* Generic hook for chain transactions */ @@ -17,6 +18,7 @@ export const useRollDebt = () => { } = useContext(HistoryContext) as IHistoryContext; const { transact } = useChain(); + const { isActionAllowed } = useAllowAction(); const rollDebt = async (vault: IVault, toSeries: ISeries) => { const txCode = getTxCode(ActionCodes.ROLL_DEBT, vault.id); @@ -24,6 +26,8 @@ export const useRollDebt = () => { const hasDebt = vault.accruedArt.gt(ZERO_BN); const fromSeries = seriesMap?.get(vault.seriesId); + if (!isActionAllowed(ActionCodes.ROLL_DEBT)) return; // return if action is not allowed + const calls: ICallData[] = [ { // ladle.rollAction(vaultId: string, newSeriesId: string, max: BigNumberish) diff --git a/src/hooks/actionHooks/useRollPosition.ts b/src/hooks/actionHooks/useRollPosition.ts index e3e977c8a..fcfc6cf81 100644 --- a/src/hooks/actionHooks/useRollPosition.ts +++ b/src/hooks/actionHooks/useRollPosition.ts @@ -14,6 +14,7 @@ import { useRouter } from 'next/router'; import useContracts from '../useContracts'; import useAccountPlus from '../useAccountPlus'; import { ContractNames } from '../../config/contracts'; +import useAllowAction from '../useAllowAction'; /* Roll Lend Position Action Hook */ export const useRollPosition = () => { @@ -35,6 +36,7 @@ export const useRollPosition = () => { const { sign, transact } = useChain(); const { getTimeTillMaturity } = useTimeTillMaturity(); + const { isActionAllowed } = useAllowAction(); /** * Transfer fyToken to the "from" pool to sell for base, then send base to "to" pool and sell base for fyToken @@ -44,6 +46,7 @@ export const useRollPosition = () => { */ const rollPosition = async (input: string | undefined, fromSeries: ISeries, toSeries: ISeries) => { if (!contracts) return; + if (!isActionAllowed(ActionCodes.ROLL_POSITION)) return; // return if action is not allowed /* generate the reproducible txCode for tx tracking and tracing */ const txCode = getTxCode(ActionCodes.ROLL_POSITION, fromSeries.id); diff --git a/src/hooks/useAllowAction.ts b/src/hooks/useAllowAction.ts new file mode 100644 index 000000000..5681df5a2 --- /dev/null +++ b/src/hooks/useAllowAction.ts @@ -0,0 +1,34 @@ +import { useContext } from 'react'; +import { toast } from 'react-toastify'; +import { useNetwork } from 'wagmi'; +import { UserContext } from '../contexts/UserContext'; +import { ActionCodes, ISeries } from '../types'; +import useChainId from './useChainId'; + +/** + * This function/hook is used to determine if a user is allowed to perform an action on a particular series. + * @param series + * @param action + * @returns boolean + */ +const useAllowAction = () => { + + const { userState } = useContext(UserContext); + + const isActionAllowed = (action: ActionCodes, series?: ISeries): boolean => { + const seriesToUse = series || userState.selectedSeries; + + if (seriesToUse) { + if (seriesToUse.allowActions.includes('allow_all') || seriesToUse.allowActions.includes(action)) return true; + if (!seriesToUse.allowActions.includes(action) || seriesToUse.allowActions.includes('allow_none')) { + toast.warn(`Action not allowed on this series.`); + return false; + } + } + return false; // deny action by default if conditions are not met + }; + + return { isActionAllowed }; +}; + +export default useAllowAction; diff --git a/src/hooks/useChain.ts b/src/hooks/useChain.ts index 4683cfa81..8e53292db 100644 --- a/src/hooks/useChain.ts +++ b/src/hooks/useChain.ts @@ -49,7 +49,7 @@ export const useChain = () => { */ const transact = async (calls: ICallData[], txCode: string): Promise => { if (!contracts) return; - + /* Set the router contract instance, ladle by default */ const _contract: Contract = contracts.get(ContractNames.LADLE)?.connect(signer!) as Ladle; diff --git a/src/types/index.ts b/src/types/index.ts index c9b5467ee..baed47107 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -111,6 +111,8 @@ export interface ISeriesRoot extends ISignable { oppEndColor: string; seriesMark: ReactNode; + + allowActions: (ActionCodes | 'allow_all' | 'allow_none')[]; } export enum TokenType { From 482c311d5aca99d144f6a727427704f3cf544648 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Wed, 15 Mar 2023 11:06:08 +0000 Subject: [PATCH 02/23] isolate euler pool --- src/config/series.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/config/series.ts b/src/config/series.ts index ca581007a..808dde9cf 100644 --- a/src/config/series.ts +++ b/src/config/series.ts @@ -232,6 +232,7 @@ SERIES.set( ts: '12989823246', g1: '16602069666338596454', g2: '20496382304121724017', + allowActions: [ActionCodes.REPAY], }, ], [ @@ -400,6 +401,7 @@ SERIES.set( ts: '23381681843', g1: '16602069666338596454', g2: '20496382304121724017', + allowActions: [ActionCodes.REPAY], }, ], [ @@ -484,6 +486,7 @@ SERIES.set( ts: '10628037201', g1: '16602069666338596454', g2: '20496382304121724017', + allowActions: [ActionCodes.REPAY], }, ], [ @@ -567,6 +570,7 @@ SERIES.set( ts: '23381681843', g1: '16602069666338596454', g2: '20496382304121724017', + allowActions: [ActionCodes.REPAY], }, ], @@ -588,6 +592,7 @@ SERIES.set( ts: '12989823246', g1: '16602069666338596454', g2: '20496382304121724017', + allowActions: [ActionCodes.REPAY], }, ], @@ -609,6 +614,7 @@ SERIES.set( ts: '10628037201', g1: '16602069666338596454', g2: '20496382304121724017', + allowActions: [ActionCodes.REPAY], }, ], From 10918e5ad53e6b102e828fe998b43e4718547c88 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Wed, 15 Mar 2023 11:06:49 +0000 Subject: [PATCH 03/23] catch series errors --- src/contexts/UserContext.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 3b6ada6c6..0cb5c0f02 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -305,13 +305,17 @@ const UserProvider = ({ children }: { children: ReactNode }) => { /* Add in the dynamic series data of the series in the list */ _publicData = await Promise.all( seriesList.map(async (series): Promise => { + /* Get all the data simultanenously in a promise.all */ const [baseReserves, fyTokenReserves, totalSupply, fyTokenRealReserves] = await Promise.all([ series.poolContract.getBaseBalance(), series.poolContract.getFYTokenBalance(), series.poolContract.totalSupply(), series.fyTokenContract.balanceOf(series.poolAddress), - ]); + ]).catch((e) => { + console.log('Series Error: ', series.id); + return [ZERO_BN, ZERO_BN, ZERO_BN, ZERO_BN]; + }); // catch error and return 0 values if error with series let sharesReserves: BigNumber; let c: BigNumber | undefined; @@ -319,6 +323,8 @@ const UserProvider = ({ children }: { children: ReactNode }) => { let currentSharePrice: BigNumber; let sharesAddress: string; + + try { [sharesReserves, c, mu, currentSharePrice, sharesAddress] = await Promise.all([ series.poolContract.getSharesBalance(), From ad7b1c3192536a33c5b6539430aeca9c3c3bef10 Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Fri, 17 Mar 2023 11:50:26 -0700 Subject: [PATCH 04/23] chore: format --- src/config/series.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/config/series.ts b/src/config/series.ts index 808dde9cf..c79e9c8c6 100644 --- a/src/config/series.ts +++ b/src/config/series.ts @@ -24,9 +24,9 @@ export interface ISeriesStatic { g1: string; g2: string; - allowActions?: (ActionCodes |'allow_none'|'allow_all')[]; + allowActions?: (ActionCodes | 'allow_none' | 'allow_all')[]; } - + const USDC_2112 = '0x303230340000'; const USDC_2203 = '0x303230350000'; const USDC_2206 = '0x303230360000'; From 82e332662fecadbda28c557c8b8ed9df0e8066bc Mon Sep 17 00:00:00 2001 From: marcomariscal Date: Fri, 17 Mar 2023 12:09:16 -0700 Subject: [PATCH 05/23] chore: remove unused imports --- src/hooks/useAllowAction.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hooks/useAllowAction.ts b/src/hooks/useAllowAction.ts index 5681df5a2..cb346ecf9 100644 --- a/src/hooks/useAllowAction.ts +++ b/src/hooks/useAllowAction.ts @@ -1,9 +1,7 @@ import { useContext } from 'react'; import { toast } from 'react-toastify'; -import { useNetwork } from 'wagmi'; import { UserContext } from '../contexts/UserContext'; import { ActionCodes, ISeries } from '../types'; -import useChainId from './useChainId'; /** * This function/hook is used to determine if a user is allowed to perform an action on a particular series. @@ -12,7 +10,6 @@ import useChainId from './useChainId'; * @returns boolean */ const useAllowAction = () => { - const { userState } = useContext(UserContext); const isActionAllowed = (action: ActionCodes, series?: ISeries): boolean => { From b3e4ebf369a8162d548a5015ae363757539b667c Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 09:18:01 +0000 Subject: [PATCH 06/23] remove initSeries from useStrategyReturns --- src/contexts/UserContext.tsx | 5 ++++- src/hooks/useStrategyReturns.ts | 28 ---------------------------- 2 files changed, 4 insertions(+), 29 deletions(-) diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index a23a4c325..100b64417 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -426,7 +426,10 @@ const UserProvider = ({ children }: { children: ReactNode }) => { const [poolTokens, fyTokenBalance] = await Promise.all([ series.poolContract.balanceOf(account), series.fyTokenContract.balanceOf(account), - ]); + ]).catch((e) => { + console.log('Error etting user balances: ', series.id); + return [ ZERO_BN, ZERO_BN ]; + }); // catch error and return 0 values if error with series const poolPercent = mulDecimal(divDecimal(poolTokens, series.totalSupply), '100'); return { diff --git a/src/hooks/useStrategyReturns.ts b/src/hooks/useStrategyReturns.ts index ca6cf2fec..6fc7d586d 100644 --- a/src/hooks/useStrategyReturns.ts +++ b/src/hooks/useStrategyReturns.ts @@ -105,15 +105,6 @@ const useStrategyReturns = ( const { getTimeTillMaturity } = useTimeTillMaturity(); - const [initSeries, setInitSeries] = useState<{ - sharesReserves: BigNumber; - fyTokenReserves: BigNumber; - totalSupply: BigNumber; - ts: BigNumber; - g2: BigNumber; - c: BigNumber; - }>(); - const [returns, setLpReturns] = useState(); const NOW = useMemo(() => Math.round(new Date().getTime() / 1000), []); @@ -293,25 +284,6 @@ const useStrategyReturns = ( return cleanValue(apy, digits); }; - // get the init series data to use the invariant function - useEffect(() => { - (async () => { - if (!series) return; - const { poolContract, currentInvariant, initInvariant } = series; - if (!currentInvariant || !initInvariant) { - const [sharesReserves, fyTokenReserves, totalSupply, ts, g2, c] = await Promise.all([ - poolContract.getSharesBalance(), - poolContract.getFYTokenBalance(), - poolContract.totalSupply(), - poolContract.ts(), - poolContract.g2(), - poolContract.getC(), - ]); - setInitSeries({ sharesReserves, fyTokenReserves, totalSupply, ts, g2, c }); - } - })(); - }, [series]); - const calcStrategyReturns = (strategy: IStrategy | null, input: string) => { if (!strategy) return; From 7ea56ffa8f7748455bb2032f2af823d18bc79ec5 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 10:44:28 +0000 Subject: [PATCH 07/23] remove account import --- src/components/views/Pool.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/Pool.tsx b/src/components/views/Pool.tsx index fca02e7d0..f0f4e1c10 100644 --- a/src/components/views/Pool.tsx +++ b/src/components/views/Pool.tsx @@ -33,7 +33,6 @@ import StrategyItem from '../positionItems/StrategyItem'; import Navigation from '../Navigation'; import Line from '../elements/Line'; -import { useAccount } from 'wagmi'; import useStrategyReturns from '../../hooks/useStrategyReturns'; import { GA_Event, GA_View, GA_Properties } from '../../types/analytics'; import useAnalytics from '../../hooks/useAnalytics'; From b1d70701424413f14993e221ee0285a9834c5ed3 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 10:45:04 +0000 Subject: [PATCH 08/23] defaultProvider to use Correct Key --- src/hooks/useDefaultProvider.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useDefaultProvider.ts b/src/hooks/useDefaultProvider.ts index 0d13ba3dd..558b50c10 100644 --- a/src/hooks/useDefaultProvider.ts +++ b/src/hooks/useDefaultProvider.ts @@ -5,8 +5,8 @@ import useChainId from './useChainId'; // default provider always uses the non-fork provider and the non-fork chainId const useDefaultProvider = () => { const chainId = useChainId(); - - return useMemo(() => new AlchemyProvider(chainId, process.env.ALCHEMY_ARBITRUM_KEY!), [chainId]); + const key = chainId > 1 ? process.env.ALCHEMY_ARBITRUM_KEY! : process.env.ALCHEMY_MAINNET_KEY!; + return useMemo(() => new AlchemyProvider(chainId, key), [chainId, key]); }; export default useDefaultProvider; From aff3e763d7db471595667dbf8c9655494aa2bef4 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 10:48:00 +0000 Subject: [PATCH 09/23] remove commented code --- src/hooks/useChain.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hooks/useChain.ts b/src/hooks/useChain.ts index 11c78f115..6f9624db7 100644 --- a/src/hooks/useChain.ts +++ b/src/hooks/useChain.ts @@ -87,10 +87,6 @@ export const useChain = () => { return _contract.interface.encodeFunctionData(call.operation as string, call.args); }); - // const calldata = wrapEtherModule.interface.encodeFunctionData('wrap', [other, WAD]) - // await ladle.ladle.moduleCall(wrapEtherModule.address, calldata, { value: WAD }) - // expect(await weth.balanceOf(other)).to.equal(WAD) - /* calculate the value sent */ const batchValue = _getCallValue(_calls); From 1f394e688e1d47f553c31c81045f12f069589840 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 11:16:24 +0000 Subject: [PATCH 10/23] make provider in chainContext chainaware --- src/contexts/ChainContext.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/contexts/ChainContext.tsx b/src/contexts/ChainContext.tsx index 98b1a637e..3df1dc91d 100644 --- a/src/contexts/ChainContext.tsx +++ b/src/contexts/ChainContext.tsx @@ -90,11 +90,11 @@ const ChainProvider = ({ children }: { children: ReactNode }) => { } = useContext(SettingsContext); /* HOOKS */ - const provider = useProvider({ - chainId: 42161, - }); const chainId = useChainId(); const contracts = useContracts(); + const provider = useProvider({ + chainId: chainId, + }); /* CACHED VARIABLES */ const [lastAppVersion, setLastAppVersion] = useCachedState('lastAppVersion', ''); From f902273f723357e5d7697062e4599c9835be1105 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 11:17:09 +0000 Subject: [PATCH 11/23] use the correct key with defaultChainId --- src/contexts/WagmiContext.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/contexts/WagmiContext.tsx b/src/contexts/WagmiContext.tsx index caa12f1c8..9e0abda06 100644 --- a/src/contexts/WagmiContext.tsx +++ b/src/contexts/WagmiContext.tsx @@ -31,15 +31,17 @@ import { useCachedState } from '../hooks/generalHooks'; import { Settings } from './types/settings'; const WagmiContext = ({ children }: { children: ReactNode }) => { + const colorTheme = useColorScheme(); + const [useForkedEnv] = useCachedState(Settings.USE_FORKED_ENV, false); const [forkEnvUrl] = useCachedState(Settings.FORK_ENV_URL, process.env.REACT_APP_DEFAULT_FORK_RPC_URL); - const colorTheme = useColorScheme(); + const defaultChainId = parseInt(process.env.REACT_APP_DEFAULT_CHAINID!) const chainConfig = useMemo( () => useForkedEnv ? jsonRpcProvider({ rpc: () => ({ http: forkEnvUrl }) }) - : alchemyProvider({ apiKey: process.env.ALCHEMY_ARBITRUM_KEY! }), + : alchemyProvider({ apiKey: defaultChainId === 1 ? process.env.ALCHEMY_MAINNET_KEY! : process.env.ALCHEMY_ARBITRUM_KEY! }), [forkEnvUrl, useForkedEnv] ); From 08239e0ed8c5e84e41397b0ef9df748d3234a856 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 11:24:31 +0000 Subject: [PATCH 12/23] WIP: userContext adjust --- src/contexts/UserContext.tsx | 38 ++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 100b64417..aa91cb0b7 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -132,7 +132,6 @@ const UserProvider = ({ children }: { children: ReactNode }) => { /* LOCAL STATE */ const [userState, updateState] = useReducer(userReducer, initState); - const [vaultFromUrl, setVaultFromUrl] = useState(null); /* HOOKS */ const chainId = useChainId(); @@ -303,8 +302,7 @@ const UserProvider = ({ children }: { children: ReactNode }) => { /* Add in the dynamic series data of the series in the list */ _publicData = await Promise.all( - seriesList.map(async (series): Promise => { - + seriesList.map(async (series): Promise => { /* Get all the data simultanenously in a promise.all */ const [baseReserves, fyTokenReserves, totalSupply, fyTokenRealReserves] = await Promise.all([ series.poolContract.getBaseBalance(), @@ -322,8 +320,6 @@ const UserProvider = ({ children }: { children: ReactNode }) => { let currentSharePrice: BigNumber; let sharesAddress: string; - - try { [sharesReserves, c, mu, currentSharePrice, sharesAddress] = await Promise.all([ series.poolContract.getSharesBalance(), @@ -427,8 +423,8 @@ const UserProvider = ({ children }: { children: ReactNode }) => { series.poolContract.balanceOf(account), series.fyTokenContract.balanceOf(account), ]).catch((e) => { - console.log('Error etting user balances: ', series.id); - return [ ZERO_BN, ZERO_BN ]; + console.log('Error getting user balances for series: ', series.id); + return [ZERO_BN, ZERO_BN]; }); // catch error and return 0 values if error with series const poolPercent = mulDecimal(divDecimal(poolTokens, series.totalSupply), '100'); @@ -476,23 +472,23 @@ const UserProvider = ({ children }: { children: ReactNode }) => { _strategy.strategyContract.totalSupply(), _strategy.strategyContract.fyToken(), _strategy.strategyContract.pool(), - ]); + ]).catch((e: any) => { + console.log('Error getting strategy data: ', _strategy.name); + return [ZERO_BN, undefined, undefined]; + }); // const stratConnected = _strategy.strategyContract.connect(signer); // const accountRewards = // _strategy.rewardsRate?.gt(ZERO_BN) && signer ? await stratConnected.callStatic.claim(account) : ZERO_BN; // console.log(accountRewards.gt(ZERO_BN) ? accountRewards.toString() : 'no rewards'); - // const accountStrategyPercent = mulDecimal( - // divDecimal(accountBalance, _strategy.strategyTotalSupply || '0'), - // '100' - // ); - /* We check if the strategy has been supersecced by a v2 version */ const hasAnUpdatedVersion = _strategy.type === 'V1' && !!_strategy.associatedStrategy; /* Attatch the current series (if any) */ - const currentSeries = _seriesList.find((s: ISeriesRoot) => s.address.toLowerCase() === fyToken.toLowerCase()); + const currentSeries = _seriesList.find((s: ISeriesRoot) => + fyToken ? s.address.toLowerCase() === (fyToken as String).toLowerCase() : undefined + ); if (currentSeries) { const [poolTotalSupply, strategyPoolBalance] = await Promise.all([ @@ -500,7 +496,11 @@ const UserProvider = ({ children }: { children: ReactNode }) => { currentSeries.poolContract.balanceOf( hasAnUpdatedVersion && _strategy.associatedStrategy ? _strategy.associatedStrategy : _strategy.address ), - ]); + ]).catch((e: any) => { + console.log('Error getting current series data: ', _strategy.name); + return [ZERO_BN, ZERO_BN]; + }); + const strategyPoolPercent = mulDecimal(divDecimal(strategyPoolBalance, poolTotalSupply), '100'); /* get rewards data */ @@ -530,17 +530,17 @@ const UserProvider = ({ children }: { children: ReactNode }) => { return { ..._strategy, strategyTotalSupply, - strategyTotalSupply_: ethers.utils.formatUnits(strategyTotalSupply, _strategy.decimals), + strategyTotalSupply_: ethers.utils.formatUnits(strategyTotalSupply || ZERO_BN, _strategy.decimals), poolTotalSupply, poolTotalSupply_: ethers.utils.formatUnits(poolTotalSupply, _strategy.decimals), strategyPoolBalance, strategyPoolBalance_: ethers.utils.formatUnits(strategyPoolBalance, _strategy.decimals), strategyPoolPercent, - currentSeriesAddr: fyToken, + currentSeriesAddr: fyToken as string | undefined, currentSeries, - currentPoolAddr, + currentPoolAddr: currentPoolAddr as string | undefined, active: isActive, rewardsRate, @@ -737,7 +737,7 @@ const UserProvider = ({ children }: { children: ReactNode }) => { /* If the url references a series/vault...set that one as active */ useEffect(() => { const vaultId = pathname.split('/')[2]; - pathname && userState.vaultMap?.has(vaultId) && setVaultFromUrl(vaultId); + pathname && userState.vaultMap?.has(vaultId); }, [pathname, userState.vaultMap]); /** From efe72bcc041b8dafebadf7c5524bb671d2f02994 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 14:30:10 +0000 Subject: [PATCH 13/23] catch error on loading strategy --- src/contexts/UserContext.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index aa91cb0b7..a582a81f9 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -466,6 +466,7 @@ const UserProvider = ({ children }: { children: ReactNode }) => { // let _publicData: IStrategy[] = []; const _publicData = await Promise.all( + strategyList.map(async (_strategy): Promise => { /* Get all the data simultanenously in a promise.all */ const [strategyTotalSupply, fyToken, currentPoolAddr] = await Promise.all([ @@ -565,7 +566,10 @@ const UserProvider = ({ children }: { children: ReactNode }) => { const [accountBalance, accountPoolBalance] = await Promise.all([ _strategy.strategyContract.balanceOf(account), _strategy.currentSeries?.poolContract.balanceOf(account), - ]); + ]).catch((e: any) => { + console.log('Error getting current account balance data: ', _strategy.name); + return [ZERO_BN, ZERO_BN]; + });; // const stratConnected = _strategy.strategyContract.connect(signer!); // const accountRewards = From 9ec9c15cac470c8788045035c91e6594a3e0387e Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 16:03:08 +0000 Subject: [PATCH 14/23] kill switch off --- .env.local | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.env.local b/.env.local index 090adc07c..706fd8ad0 100644 --- a/.env.local +++ b/.env.local @@ -27,6 +27,6 @@ GENERATE_SOURCEMAP=false ALLOWED_SUPPORT_ADDRESSES='0x1Bd3Abb6ef058408734EA01cA81D325039cd7bcA, ' -KILLSWITCH_ACTIVE=true +KILLSWITCH_ACTIVE=false KILLSWITCH_CHAIN=1 KILLSWITCH_TEXT='Due to an Euler Finance security incident, we are suspending UI interaction with the Yield Protocol until we have fully assessed the implications of the breach' From 0d56e65c839947e011ede2519da5e512635f0738 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 17:25:28 +0000 Subject: [PATCH 15/23] useAllowAction if logic --- src/hooks/useAllowAction.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useAllowAction.ts b/src/hooks/useAllowAction.ts index cb346ecf9..115bbacc5 100644 --- a/src/hooks/useAllowAction.ts +++ b/src/hooks/useAllowAction.ts @@ -16,8 +16,8 @@ const useAllowAction = () => { const seriesToUse = series || userState.selectedSeries; if (seriesToUse) { - if (seriesToUse.allowActions.includes('allow_all') || seriesToUse.allowActions.includes(action)) return true; - if (!seriesToUse.allowActions.includes(action) || seriesToUse.allowActions.includes('allow_none')) { + if (seriesToUse.allowActions.includes('allow_all') || seriesToUse.allowActions.includes(action)) {return true} + else { toast.warn(`Action not allowed on this series.`); return false; } From 2637948ad5b35e5185a26ebfebf797c800228f34 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 17:29:50 +0000 Subject: [PATCH 16/23] fix a few of marcos comments --- src/contexts/UserContext.tsx | 10 +++++----- src/hooks/actionHooks/useRollDebt.ts | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index a582a81f9..1f9c66356 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -738,11 +738,11 @@ const UserProvider = ({ children }: { children: ReactNode }) => { } }, [strategyRootMap, userState.seriesMap, chainLoaded, chainId, updateStrategies]); - /* If the url references a series/vault...set that one as active */ - useEffect(() => { - const vaultId = pathname.split('/')[2]; - pathname && userState.vaultMap?.has(vaultId); - }, [pathname, userState.vaultMap]); + // /* If the url references a series/vault...set that one as active */ + // useEffect(() => { + // const vaultId = pathname.split('/')[2]; + // pathname && userState.vaultMap?.has(vaultId); + // }, [pathname, userState.vaultMap]); /** * Explicitly update selected series on series map changes diff --git a/src/hooks/actionHooks/useRollDebt.ts b/src/hooks/actionHooks/useRollDebt.ts index 5724b2e0f..d45ac07a8 100644 --- a/src/hooks/actionHooks/useRollDebt.ts +++ b/src/hooks/actionHooks/useRollDebt.ts @@ -21,13 +21,14 @@ export const useRollDebt = () => { const { isActionAllowed } = useAllowAction(); const rollDebt = async (vault: IVault, toSeries: ISeries) => { + + if (!isActionAllowed(ActionCodes.ROLL_DEBT)) return; // return if action is not allowed + const txCode = getTxCode(ActionCodes.ROLL_DEBT, vault.id); const base = assetMap?.get(vault.baseId); const hasDebt = vault.accruedArt.gt(ZERO_BN); const fromSeries = seriesMap?.get(vault.seriesId); - if (!isActionAllowed(ActionCodes.ROLL_DEBT)) return; // return if action is not allowed - const calls: ICallData[] = [ { // ladle.rollAction(vaultId: string, newSeriesId: string, max: BigNumberish) From d67e8d2993ea879d7d9c221bb4229fc85bb770aa Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 17:40:58 +0000 Subject: [PATCH 17/23] remove sep series for now --- src/config/series.ts | 160 +++++++++++++++++++++---------------------- 1 file changed, 80 insertions(+), 80 deletions(-) diff --git a/src/config/series.ts b/src/config/series.ts index 254f6048f..077cb65be 100644 --- a/src/config/series.ts +++ b/src/config/series.ts @@ -625,26 +625,26 @@ SERIES.set( }, ], - [ - DAI_2309, - { - id: DAI_2309, - baseId: '0x303100000000', - maturity: 1695999600, - name: 'FYDAI2309', - symbol: 'FYDAI2309', - address: '0x5e0f24ec7b948e8e589ec66c858a72a1c1b88217', - decimals: 18, - version: '1', - poolAddress: '0x8808510d380b6f96dd2e2d9980d370b098840916', - poolName: 'FYDAI2309 LP', - poolSymbol: 'FYDAI2309LP', - poolVersion: '1', - ts: '12989823246', - g1: '16602069666338596454', - g2: '20496382304121724017', - }, - ], + // [ + // DAI_2309, + // { + // id: DAI_2309, + // baseId: '0x303100000000', + // maturity: 1695999600, + // name: 'FYDAI2309', + // symbol: 'FYDAI2309', + // address: '0x5e0f24ec7b948e8e589ec66c858a72a1c1b88217', + // decimals: 18, + // version: '1', + // poolAddress: '0x8808510d380b6f96dd2e2d9980d370b098840916', + // poolName: 'FYDAI2309 LP', + // poolSymbol: 'FYDAI2309LP', + // poolVersion: '1', + // ts: '12989823246', + // g1: '16602069666338596454', + // g2: '20496382304121724017', + // }, + // ], [ USDC_2306, @@ -668,26 +668,26 @@ SERIES.set( }, ], - [ - USDC_2309, - { - id: USDC_2309, - baseId: '0x303200000000', - maturity: 1695999600, - name: 'FYUSDC2309', - symbol: 'FYUSDC2309', - address: '0x5eaf4e6160eda8222acf0ebcb52fbadb6b8bb1ad', - decimals: 6, - version: '1', - poolAddress: '0x243118102406ea39e313568ed4c52e3b2c0e9ec1', - poolName: 'FYUSDC2309 LP', - poolSymbol: 'FYUSDC2309LP', - poolVersion: '1', - ts: '10628037201', - g1: '16602069666338596454', - g2: '20496382304121724017', - }, - ], + // [ + // USDC_2309, + // { + // id: USDC_2309, + // baseId: '0x303200000000', + // maturity: 1695999600, + // name: 'FYUSDC2309', + // symbol: 'FYUSDC2309', + // address: '0x5eaf4e6160eda8222acf0ebcb52fbadb6b8bb1ad', + // decimals: 6, + // version: '1', + // poolAddress: '0x243118102406ea39e313568ed4c52e3b2c0e9ec1', + // poolName: 'FYUSDC2309 LP', + // poolSymbol: 'FYUSDC2309LP', + // poolVersion: '1', + // ts: '10628037201', + // g1: '16602069666338596454', + // g2: '20496382304121724017', + // }, + // ], [ FRAX_2306, @@ -709,26 +709,26 @@ SERIES.set( g2: '20496382304121724017', }, ], - [ - FRAX_2309, - { - id: FRAX_2309, - baseId: '0x313800000000', - maturity: 1695999600, - name: 'FYFRAX2309', - symbol: 'FYFRAX2309', - address: '0xeed224d35a39db18e6440d06f5bdb4a9ca94d44d', - decimals: 18, - version: '1', - poolAddress: '0x6d8ff80d3cfc38c376d6e8af9c2c9da88f9661f2', - poolName: 'FYFRAX2309 LP', - poolSymbol: 'FYFRAX2309LP', - poolVersion: '1', - ts: '12989823246', - g1: '16602069666338596454', - g2: '20496382304121724017', - }, - ], + // [ + // FRAX_2309, + // { + // id: FRAX_2309, + // baseId: '0x313800000000', + // maturity: 1695999600, + // name: 'FYFRAX2309', + // symbol: 'FYFRAX2309', + // address: '0xeed224d35a39db18e6440d06f5bdb4a9ca94d44d', + // decimals: 18, + // version: '1', + // poolAddress: '0x6d8ff80d3cfc38c376d6e8af9c2c9da88f9661f2', + // poolName: 'FYFRAX2309 LP', + // poolSymbol: 'FYFRAX2309LP', + // poolVersion: '1', + // ts: '12989823246', + // g1: '16602069666338596454', + // g2: '20496382304121724017', + // }, + // ], [ USDT_2306, { @@ -769,26 +769,26 @@ SERIES.set( g2: '20496382304121724017', }, ], - [ - USDT_2309, - { - id: USDT_2309, - baseId: '0x30a000000000', - maturity: 1695999600, - name: 'FYUSDT2309', - symbol: 'FYUSDT2309', - address: '0xa85f51b398cbb01dede20062ef06a2fa6f536bfc', - decimals: 6, - version: '1', - poolAddress: '0x98a0883856fc11e6131eaa25211a4d7474a5fd98', - poolName: 'FYUSDT2309 LP', - poolSymbol: 'FYUSDT2309LP', - poolVersion: '1', - ts: '16701201316', - g1: '16602069666338596454', - g2: '20496382304121724017', - }, - ], + // [ + // USDT_2309, + // { + // id: USDT_2309, + // baseId: '0x30a000000000', + // maturity: 1695999600, + // name: 'FYUSDT2309', + // symbol: 'FYUSDT2309', + // address: '0xa85f51b398cbb01dede20062ef06a2fa6f536bfc', + // decimals: 6, + // version: '1', + // poolAddress: '0x98a0883856fc11e6131eaa25211a4d7474a5fd98', + // poolName: 'FYUSDT2309 LP', + // poolSymbol: 'FYUSDT2309LP', + // poolVersion: '1', + // ts: '16701201316', + // g1: '16602069666338596454', + // g2: '20496382304121724017', + // }, + // ], ]) ); From 53cc4cc712fd660a7fa7ee3f940eedafc06f28ae Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 17:42:18 +0000 Subject: [PATCH 18/23] also remove WETH 2309 --- src/config/series.ts | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/config/series.ts b/src/config/series.ts index 077cb65be..3525f3db0 100644 --- a/src/config/series.ts +++ b/src/config/series.ts @@ -582,26 +582,26 @@ SERIES.set( }, ], - [ - WETH_2309, - { - id: WETH_2309, - baseId: '0x303000000000', - maturity: 1695999600, - name: 'FYETH2309', - symbol: 'FYETH2309', - address: '0xac981e8d4b0d1e56d5b2d983ba0558d96c63ceaa', - decimals: 18, - version: '1', - poolAddress: '0xc33ec597244008b058ad0811f144e5b2b85bc1e0', - poolName: 'FYETH2309 LP', - poolSymbol: 'FYETH2309LP', - poolVersion: '1', - ts: '23381681843', - g1: '16602069666338596454', - g2: '20496382304121724017', - }, - ], + // [ + // WETH_2309, + // { + // id: WETH_2309, + // baseId: '0x303000000000', + // maturity: 1695999600, + // name: 'FYETH2309', + // symbol: 'FYETH2309', + // address: '0xac981e8d4b0d1e56d5b2d983ba0558d96c63ceaa', + // decimals: 18, + // version: '1', + // poolAddress: '0xc33ec597244008b058ad0811f144e5b2b85bc1e0', + // poolName: 'FYETH2309 LP', + // poolSymbol: 'FYETH2309LP', + // poolVersion: '1', + // ts: '23381681843', + // g1: '16602069666338596454', + // g2: '20496382304121724017', + // }, + // ], [ DAI_2306, From cab3e7aee88d271e0dd8f112ff02a8638120df70 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Mon, 20 Mar 2023 18:35:36 +0000 Subject: [PATCH 19/23] separate out getBaseBalance --- src/contexts/UserContext.tsx | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/contexts/UserContext.tsx b/src/contexts/UserContext.tsx index 1f9c66356..e5959f754 100644 --- a/src/contexts/UserContext.tsx +++ b/src/contexts/UserContext.tsx @@ -302,17 +302,19 @@ const UserProvider = ({ children }: { children: ReactNode }) => { /* Add in the dynamic series data of the series in the list */ _publicData = await Promise.all( - seriesList.map(async (series): Promise => { + seriesList.map(async (series): Promise => { + let baseReserves: BigNumber; + try { + baseReserves = await series.poolContract.getBaseBalance(); + } catch (error) { + baseReserves = ZERO_BN; + } /* Get all the data simultanenously in a promise.all */ - const [baseReserves, fyTokenReserves, totalSupply, fyTokenRealReserves] = await Promise.all([ - series.poolContract.getBaseBalance(), + const [fyTokenReserves, totalSupply, fyTokenRealReserves] = await Promise.all([ series.poolContract.getFYTokenBalance(), series.poolContract.totalSupply(), series.fyTokenContract.balanceOf(series.poolAddress), - ]).catch((e) => { - console.log('Series Error: ', series.id); - return [ZERO_BN, ZERO_BN, ZERO_BN, ZERO_BN]; - }); // catch error and return 0 values if error with series + ]); let sharesReserves: BigNumber; let c: BigNumber | undefined; @@ -466,7 +468,6 @@ const UserProvider = ({ children }: { children: ReactNode }) => { // let _publicData: IStrategy[] = []; const _publicData = await Promise.all( - strategyList.map(async (_strategy): Promise => { /* Get all the data simultanenously in a promise.all */ const [strategyTotalSupply, fyToken, currentPoolAddr] = await Promise.all([ @@ -501,7 +502,7 @@ const UserProvider = ({ children }: { children: ReactNode }) => { console.log('Error getting current series data: ', _strategy.name); return [ZERO_BN, ZERO_BN]; }); - + const strategyPoolPercent = mulDecimal(divDecimal(strategyPoolBalance, poolTotalSupply), '100'); /* get rewards data */ @@ -567,9 +568,9 @@ const UserProvider = ({ children }: { children: ReactNode }) => { _strategy.strategyContract.balanceOf(account), _strategy.currentSeries?.poolContract.balanceOf(account), ]).catch((e: any) => { - console.log('Error getting current account balance data: ', _strategy.name); - return [ZERO_BN, ZERO_BN]; - });; + console.log('Error getting current account balance data: ', _strategy.name); + return [ZERO_BN, ZERO_BN]; + }); // const stratConnected = _strategy.strategyContract.connect(signer!); // const accountRewards = From a38d1bf55cb454b2ef806db5038296943e6a6862 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 21 Mar 2023 16:29:45 +0000 Subject: [PATCH 20/23] show when series actions are restricted --- src/components/selectors/SeriesSelector.tsx | 30 +++++++++++-------- src/components/selectors/StrategySelector.tsx | 19 ++++++++---- src/hooks/useDefaultProvider.ts | 2 +- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/components/selectors/SeriesSelector.tsx b/src/components/selectors/SeriesSelector.tsx index c93d06fe0..669a855ec 100644 --- a/src/components/selectors/SeriesSelector.tsx +++ b/src/components/selectors/SeriesSelector.tsx @@ -1,13 +1,13 @@ import { useContext, useEffect, useState } from 'react'; import { Avatar, Box, Grid, ResponsiveContext, Select, Text } from 'grommet'; -import { FiChevronDown } from 'react-icons/fi'; +import { FiAlertTriangle, FiChevronDown } from 'react-icons/fi'; import { ethers } from 'ethers'; import styled from 'styled-components'; import { maxBaseIn } from '@yield-protocol/ui-math'; -import { ActionType, ISeries } from '../../types'; +import { ActionCodes, ActionType, ISeries } from '../../types'; import { UserContext } from '../../contexts/UserContext'; import { useApr } from '../../hooks/useApr'; import { cleanValue } from '../../utils/appUtils'; @@ -157,9 +157,6 @@ function SeriesSelector({ selectSeriesLocally, inputValue, actionType, cardLayou Mature )} - {_series && actionType !== 'POOL' && ( - - )} ); @@ -293,14 +290,23 @@ function SeriesSelector({ selectSeriesLocally, inputValue, actionType, cardLayou > {series.seriesMark} - - + { + series.allowActions.includes('allow_all') || + (series.allowActions.includes(ActionCodes.BORROW) && actionType === ActionType.BORROW) || + (series.allowActions.includes(ActionCodes.LEND) && actionType === ActionType.LEND) ? ( + + ) : ( + + Restricted + + )} + - - +{returns?.rewardsAPY}% - + + +{returns?.rewardsAPY}% + )} @@ -103,7 +103,14 @@ const StrategySelectItem = ({ boxShadow: `inset 1px 1px 2px ${strategy.currentSeries?.endColor.toString().concat('69')}`, }} > - {(+returns.blendedAPY - +returns.rewardsAPY!).toFixed(1)}% + {strategy.currentSeries?.allowActions.includes('allow_all') || + strategy.currentSeries?.allowActions.includes(ActionCodes.ADD_LIQUIDITY) ? ( + {(+returns.blendedAPY - +returns.rewardsAPY!).toFixed(1)}% + ) : ( + + + + )} )} diff --git a/src/hooks/useDefaultProvider.ts b/src/hooks/useDefaultProvider.ts index 558b50c10..8821d7d66 100644 --- a/src/hooks/useDefaultProvider.ts +++ b/src/hooks/useDefaultProvider.ts @@ -5,7 +5,7 @@ import useChainId from './useChainId'; // default provider always uses the non-fork provider and the non-fork chainId const useDefaultProvider = () => { const chainId = useChainId(); - const key = chainId > 1 ? process.env.ALCHEMY_ARBITRUM_KEY! : process.env.ALCHEMY_MAINNET_KEY!; + const key = chainId === 1 ? process.env.ALCHEMY_MAINNET_KEY! : process.env.ALCHEMY_ARBITRUM_KEY!; return useMemo(() => new AlchemyProvider(chainId, key), [chainId, key]); }; From 60b5d26bd9097ef8ad1d0906b240e1c9009a5057 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 21 Mar 2023 18:12:22 +0000 Subject: [PATCH 21/23] version bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ce4854f3..6dea46327 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "app-v2", - "version": "2.5.12", + "version": "2.5.13", "private": true, "dependencies": { "@ethersproject/providers": "^5.6.8", From a51c11e3a9202b9d40444529fb611407eb1b50e0 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 21 Mar 2023 18:14:25 +0000 Subject: [PATCH 22/23] verbiage notification --- src/hooks/useAllowAction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useAllowAction.ts b/src/hooks/useAllowAction.ts index 115bbacc5..3aaaaf903 100644 --- a/src/hooks/useAllowAction.ts +++ b/src/hooks/useAllowAction.ts @@ -18,7 +18,7 @@ const useAllowAction = () => { if (seriesToUse) { if (seriesToUse.allowActions.includes('allow_all') || seriesToUse.allowActions.includes(action)) {return true} else { - toast.warn(`Action not allowed on this series.`); + toast.warn(`Action temporarily not allowed on this series.`); return false; } } From 6e29301f6ade9938da3d243f36fe85633cc20d51 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 21 Mar 2023 18:44:27 +0000 Subject: [PATCH 23/23] feat/ permananet notification --- src/components/FooterInfo.tsx | 6 +++++ src/components/PublicNotification.tsx | 37 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/components/PublicNotification.tsx diff --git a/src/components/FooterInfo.tsx b/src/components/FooterInfo.tsx index 18640a0b4..1796596fc 100644 --- a/src/components/FooterInfo.tsx +++ b/src/components/FooterInfo.tsx @@ -13,6 +13,7 @@ import { FaDiscord as Discord } from 'react-icons/fa'; import { ChainContext } from '../contexts/ChainContext'; import BoxWrap from './wraps/BoxWrap'; import NetworkSelector from './selectors/NetworkSelector'; +import PublicNotification from './PublicNotification'; const IconSize = '1.15rem'; const IconGap = 'small'; @@ -25,7 +26,11 @@ const FooterInfo = () => { const handleExternal = (destination: string) => {}; return ( + <> + + + App version: v{process.env.REACT_APP_VERSION} @@ -108,6 +113,7 @@ const FooterInfo = () => { + ); }; diff --git a/src/components/PublicNotification.tsx b/src/components/PublicNotification.tsx new file mode 100644 index 000000000..62629bfcc --- /dev/null +++ b/src/components/PublicNotification.tsx @@ -0,0 +1,37 @@ +import { useContext } from 'react'; +import { Box, ResponsiveContext, Text } from 'grommet'; +import { FiAlertCircle, FiAlertTriangle } from 'react-icons/fi'; +import useChainId from '../hooks/useChainId'; + +type PublicNotificationProps = { + children?: any; +}; + +const PublicNotification = ({ children }: PublicNotificationProps) => { + const chainId = useChainId(); + return ( + <> + {chainId === 1 ? ( + + + + + + + Full functionality is temporarily resticted on Ethereum mainnet. + + + + ) : null} + + ); +}; + +export default PublicNotification;