Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhanced feature controls #1208

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions src/components/RestrictedAccess.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { FiAlertOctagon } from 'react-icons/fi';
import { Box, Text } from 'grommet';
import styled, { CSSProperties } from 'styled-components';
import { useContext } from 'react';
import { SettingsContext } from '../contexts/SettingsContext';

interface BlurredBoxProps {
darkMode: boolean;
style?: CSSProperties;
}

const BlurredBox = styled(Box)<BlurredBoxProps>`
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: ${(props) => (props.darkMode ? 'rgba(0, 0, 0, 0.8)' : 'rgba(0, 0, 0, 0.5)')};
backdrop-filter: blur(${(props) => (props.darkMode ? '0.08rem' : '0.1rem')});
z-index: 100;
border: ${(props) => (props.darkMode ? '3px solid white' : '3px solid black')};
border-radius: 2px;
`;

export const RestrictedAccess = () => {
const {
settingsState: { darkMode },
} = useContext(SettingsContext);

return (
<BlurredBox darkMode={darkMode} id="restricted" height="100%" style={{ position: 'absolute' }}>
{/* // <BlurredBox darkMode={darkMode} id="restricted"> */}
<Box height="100%" align="center" justify="center">
<Box align="center">
<FiAlertOctagon size="2em" color={darkMode ? 'white' : 'black'} />
<Text margin="medium" color={darkMode ? 'white' : 'black'}>
Functionality restricted
</Text>
</Box>
</Box>
</BlurredBox>
);
};
7 changes: 7 additions & 0 deletions src/components/views/Borrow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SectionWrap from '../wraps/SectionWrap';
import MaxButton from '../buttons/MaxButton';

import { UserContext } from '../../contexts/UserContext';
import { SettingsContext } from '../../contexts/SettingsContext';
import { ActionCodes, ActionType, IVault, ProcessStage, TxState } from '../../types';
import PanelWrap from '../wraps/PanelWrap';
import CenterPanelWrap from '../wraps/CenterPanelWrap';
Expand Down Expand Up @@ -52,6 +53,7 @@ import useAnalytics from '../../hooks/useAnalytics';
import { WETH } from '../../config/assets';
import useContracts from '../../hooks/useContracts';
import useAccountPlus from '../../hooks/useAccountPlus';
import { RestrictedAccess } from '../RestrictedAccess';

const Borrow = () => {
const mobile: boolean = useContext<any>(ResponsiveContext) === 'small';
Expand All @@ -64,6 +66,9 @@ const Borrow = () => {
userState;
const { setSelectedIlk } = userActions;

const { settingsState } = useContext(SettingsContext);
const { featureControls } = settingsState;

const { address: activeAccount } = useAccountPlus();
const contracts = useContracts();

Expand Down Expand Up @@ -284,6 +289,8 @@ const Borrow = () => {
)}

<CenterPanelWrap series={selectedSeries || undefined}>
{!featureControls.borrowingEnabled && <RestrictedAccess />}

<Box id="topsection">
{stepPosition === 0 && ( // INITIAL STEP
<Box height="100%" pad={mobile ? 'medium' : { top: 'large', horizontal: 'large' }} gap="large">
Expand Down
7 changes: 7 additions & 0 deletions src/components/views/Lend.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { cleanValue, nFormatter } from '../../utils/appUtils';
import SectionWrap from '../wraps/SectionWrap';

import { UserContext } from '../../contexts/UserContext';
import { SettingsContext } from '../../contexts/SettingsContext';
import { ActionCodes, ActionType, ProcessStage, TxState } from '../../types';
import MaxButton from '../buttons/MaxButton';
import PanelWrap from '../wraps/PanelWrap';
Expand Down Expand Up @@ -45,6 +46,7 @@ import { GA_Event, GA_Properties, GA_View } from '../../types/analytics';
import useAnalytics from '../../hooks/useAnalytics';
import { WETH } from '../../config/assets';
import useAccountPlus from '../../hooks/useAccountPlus';
import { RestrictedAccess } from '../RestrictedAccess';

const Lend = () => {
const mobile: boolean = useContext<any>(ResponsiveContext) === 'small';
Expand All @@ -53,6 +55,9 @@ const Lend = () => {
const { userState } = useContext(UserContext);
const { selectedSeries, selectedBase, seriesMap } = userState;

const { settingsState } = useContext(SettingsContext);
const { featureControls } = settingsState;

const { address: activeAccount } = useAccountPlus();

/* LOCAL STATE */
Expand Down Expand Up @@ -130,6 +135,8 @@ const Lend = () => {
)}

<CenterPanelWrap series={selectedSeries}>
{!featureControls.lendingEnabled && <RestrictedAccess />}

<Box id="topsection">
{stepPosition === 0 && (
<>
Expand Down
11 changes: 10 additions & 1 deletion src/components/views/LendPosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { abbreviateHash, cleanValue, nFormatter } from '../../utils/appUtils';
import SectionWrap from '../wraps/SectionWrap';

import { UserContext } from '../../contexts/UserContext';
import { SettingsContext } from '../../contexts/SettingsContext';
import { ActionCodes, ActionType, ISeries, ProcessStage } from '../../types';
import MaxButton from '../buttons/MaxButton';
import InfoBite from '../InfoBite';
Expand All @@ -31,6 +32,7 @@ import ExitButton from '../buttons/ExitButton';
import Logo from '../logos/Logo';
import { GA_Event, GA_Properties, GA_View } from '../../types/analytics';
import useAnalytics from '../../hooks/useAnalytics';
import { RestrictedAccess } from '../RestrictedAccess';

const LendPosition = () => {
const mobile: boolean = useContext<any>(ResponsiveContext) === 'small';
Expand All @@ -44,6 +46,9 @@ const LendPosition = () => {
} = useContext(UserContext);
const { selectedSeries, seriesMap, assetMap, seriesLoading } = userState;

const { settingsState } = useContext(SettingsContext);
const { featureControls } = settingsState;

const selectedBase = assetMap?.get(selectedSeries?.baseId!);

/* LOCAL STATE */
Expand Down Expand Up @@ -258,7 +263,11 @@ const LendPosition = () => {
</SectionWrap>
</Box>

<Box height={{ min: '300px' }}>
<Box
height={{ min: '300px' }}
style={!featureControls.lendPositionActionsEnabled ? { position: 'relative' } : {}}
>
{!featureControls.lendPositionActionsEnabled && <RestrictedAccess />}
<SectionWrap title="Position Actions" icon={<FiTool />}>
<Box elevation="xsmall" round background={mobile ? 'hoverBackground' : 'hoverBackground'}>
<Select
Expand Down
7 changes: 7 additions & 0 deletions src/components/views/Pool.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import InfoBite from '../InfoBite';
import ActionButtonGroup from '../wraps/ActionButtonWrap';
import SectionWrap from '../wraps/SectionWrap';
import { UserContext } from '../../contexts/UserContext';
import { SettingsContext } from '../../contexts/SettingsContext';
import { ActionCodes, AddLiquidityType, ProcessStage, TxState } from '../../types';
import MaxButton from '../buttons/MaxButton';
import PanelWrap from '../wraps/PanelWrap';
Expand All @@ -30,6 +31,7 @@ import ColorText from '../texts/ColorText';
import { usePoolHelpers } from '../../hooks/viewHelperHooks/usePoolHelpers';
import { useProcess } from '../../hooks/useProcess';
import StrategyItem from '../positionItems/StrategyItem';
import { RestrictedAccess } from '../RestrictedAccess';

import Navigation from '../Navigation';
import Line from '../elements/Line';
Expand All @@ -48,6 +50,9 @@ function Pool() {
const { userState } = useContext(UserContext);
const { selectedBase, selectedStrategy, strategyMap } = userState;

const { settingsState } = useContext(SettingsContext);
const { featureControls } = settingsState;

const { address: activeAccount } = useAccountPlus();

/* LOCAL STATE */
Expand Down Expand Up @@ -144,6 +149,8 @@ function Pool() {
)}

<CenterPanelWrap series={selectedStrategy?.currentSeries}>
{!featureControls.poolEnabled && <RestrictedAccess />}

<Box id="topsection">
{stepPosition === 0 && (
<Box fill gap="large" height="100%" pad={mobile ? 'medium' : { top: 'large', horizontal: 'large' }}>
Expand Down
12 changes: 11 additions & 1 deletion src/components/views/PoolPosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { abbreviateHash, cleanValue, formatStrategyName, getTxCode, nFormatter }
import SectionWrap from '../wraps/SectionWrap';

import { UserContext } from '../../contexts/UserContext';
import { SettingsContext } from '../../contexts/SettingsContext';
import { ActionCodes, ActionType, ProcessStage } from '../../types';
import MaxButton from '../buttons/MaxButton';
import InfoBite from '../InfoBite';
Expand Down Expand Up @@ -37,6 +38,7 @@ import GeneralButton from '../buttons/GeneralButton';
import { MdShortcut } from 'react-icons/md';
import { ZERO_BN } from '@yield-protocol/ui-math';
import useAccountPlus from '../../hooks/useAccountPlus';
import { RestrictedAccess } from '../RestrictedAccess';

const PoolPosition = () => {
const mobile: boolean = useContext<any>(ResponsiveContext) === 'small';
Expand All @@ -50,6 +52,9 @@ const PoolPosition = () => {
} = useContext(UserContext);
const { selectedStrategy, strategyMap, assetMap, seriesLoading } = userState;

const { settingsState } = useContext(SettingsContext);
const { featureControls } = settingsState;

const { address: activeAccount } = useAccountPlus();

const _selectedStrategy = selectedStrategy || strategyMap?.get((idFromUrl as string).toLowerCase());
Expand Down Expand Up @@ -300,7 +305,12 @@ const PoolPosition = () => {
</SectionWrap>
</Box>

<Box height={{ min: '300px' }}>
<Box
height={{ min: '300px' }}
style={!featureControls.vaultActionsEnabled ? { position: 'relative' } : {}}
>
{!featureControls.poolPositionActionsEnabled && <RestrictedAccess />}

<SectionWrap title="Position Actions">
<Box elevation="xsmall" round background={mobile ? 'hoverBackground' : 'hoverBackground'}>
<Select
Expand Down
12 changes: 11 additions & 1 deletion src/components/views/VaultPosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { GiMedalSkull } from 'react-icons/gi';

import { abbreviateHash, cleanValue, getTxCode, nFormatter } from '../../utils/appUtils';
import { UserContext } from '../../contexts/UserContext';
import { SettingsContext } from '../../contexts/SettingsContext';
import InputWrap from '../wraps/InputWrap';
import InfoBite from '../InfoBite';
import { ActionCodes, ActionType, ISeries, ProcessStage } from '../../types';
Expand Down Expand Up @@ -47,6 +48,8 @@ import { WETH } from '../../config/assets';
import { Address } from '@wagmi/core';
import useAccountPlus from '../../hooks/useAccountPlus';

import { RestrictedAccess } from '../RestrictedAccess';

const VaultPosition = () => {
const mobile: boolean = useContext<any>(ResponsiveContext) === 'small';
const prevLoc = useCachedState('lastVisit', '')[0].slice(1).split('/')[0];
Expand All @@ -59,6 +62,9 @@ const VaultPosition = () => {
const { assetMap, seriesMap, vaultMap, vaultsLoading } = userState;
const { setSelectedBase, setSelectedIlk, setSelectedSeries, setSelectedVault } = userActions;

const { settingsState } = useContext(SettingsContext);
const { featureControls } = settingsState;

const { address: account } = useAccountPlus();

const _selectedVault = vaultMap?.get(idFromUrl as string);
Expand Down Expand Up @@ -486,7 +492,11 @@ const VaultPosition = () => {
)}
</Box>

<Box height={{ min: '300px' }}>
<Box
height={{ min: '300px' }}
style={!featureControls.vaultActionsEnabled ? { position: 'relative' } : {}}
>
{!featureControls.vaultActionsEnabled && <RestrictedAccess />}
<SectionWrap title="Vault Actions">
<Box elevation="xsmall" round background={mobile ? 'hoverBackground' : 'hoverBackground'}>
<Select
Expand Down
16 changes: 12 additions & 4 deletions src/contexts/SettingsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,25 @@ const initState: ISettingsContextState = {

/* Show diagnostic messages in the console */
diagnostics: false,

/* use a forked network */
useForkedEnv: false,
useForkedEnv: true,
forkEnvUrl:
process.env.REACT_APP_DEFAULT_FORK_RPC_URL || process.env.REACT_APP_LOCALHOST_RPC_URL || 'http://127.0.0.1:8545',

/* Mock a particular user */
useMockedUser: false,
mockUserAddress: undefined,

/* Protocol Features Enable/Disable */
featureControls: {
borrowingEnabled: true,
lendingEnabled: true,
poolEnabled: true,
vaultActionsEnabled: true,
lendPositionActionsEnabled: true,
poolPositionActionsEnabled: true,
},
};

const initActions: ISettingsContextActions = {
Expand All @@ -69,7 +79,6 @@ const SettingsContext = createContext<{
});

function settingsReducer(state: ISettingsContextState, action: SettingsContextAction): ISettingsContextState {

/* Helper: if different from existing , update the state and cache */
const cacheAndUpdate = (_action: SettingsContextAction) => {
if (state[action.type] === _action.payload) {
Expand All @@ -82,7 +91,6 @@ function settingsReducer(state: ISettingsContextState, action: SettingsContextAc
}

const SettingsProvider = ({ children }: { children: ReactNode }) => {

/* LOCAL STATE */
const [settingsState, updateState] = useReducer(settingsReducer, initState);

Expand Down
15 changes: 13 additions & 2 deletions src/contexts/types/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,19 @@ export interface ISettingsContext {
}

export interface ISettingsContextActions {
updateSetting: (setting: Settings, value: string | number | boolean | undefined ) => void;
updateSetting: (setting: Settings, value: string | number | boolean | undefined) => void;
}
export type SettingsContextAction = { type: Settings; payload: string | number | boolean | undefined };

export interface FeatureControls {
borrowingEnabled: boolean;
lendingEnabled: boolean;
poolEnabled: boolean;
vaultActionsEnabled: boolean;
lendPositionActionsEnabled: boolean;
poolPositionActionsEnabled: boolean;
}

export interface ISettingsContextState {
/* User Settings ( getting from the cache first ) */
slippageTolerance: number;
Expand Down Expand Up @@ -64,6 +73,8 @@ export interface ISettingsContextState {
forkEnvUrl: string;

useMockedUser: boolean;
mockUserAddress: `0x${string}`| undefined;
mockUserAddress: `0x${string}` | undefined;

/* Feature Controls */
featureControls: FeatureControls;
}
18 changes: 14 additions & 4 deletions src/hooks/useAllowAction.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { useContext } from 'react';
import { toast } from 'react-toastify';
import { UserContext } from '../contexts/UserContext';
import { SettingsContext } from '../contexts/SettingsContext';
import { ActionCodes, ISeries } from '../types';
import { actionControlMapping } from '../utils/appUtils';

/**
* This function/hook is used to determine if a user is allowed to perform an action on a particular series.
Expand All @@ -11,16 +13,24 @@ import { ActionCodes, ISeries } from '../types';
*/
const useAllowAction = () => {
const { userState } = useContext(UserContext);
const { settingsState } = useContext(SettingsContext);

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}
else {
toast.warn(`Action temporarily not allowed on this series.`);
return false;
const actionAllowedBySeries =
seriesToUse.allowActions.includes('allow_all') || seriesToUse.allowActions.includes(action);
const actionAllowedByFeature = settingsState.featureControls[actionControlMapping[action]];

if (actionAllowedBySeries && actionAllowedByFeature) {
return true;
}

// Show the proper warning message based on the condition that was not met
toast.warn(
actionAllowedBySeries ? `Action temporarily restricted.` : `Action temporarily not allowed on this series.`
);
}
return false; // deny action by default if conditions are not met
};
Expand Down
Loading