Skip to content

Commit

Permalink
feat: address screening (aave#1017)
Browse files Browse the repository at this point in the history
* feat: adding support for blocking known bad addresses

* fix: use temp url for testing

* feat: added modal for showing blocked account

* chore: i18n

* chore: added some TODOs and comments

* feat: adding env var for screening url

* chore: updated text from legal

chore: i18n

* chore: rename to be consistent with file name

* chore: rename variables to be consistent

* chore: i18n

* chore: cleanup

* fix: block all markets, not just mainnet

* chore: remove testing url from env

* fix: lint

* ci: add screening url to CI build

* fix: added usePolling to handle any api errors and to re-screen address

* chore: updated default env files

* fix: url

* feat: check for blocked address at app level to prevent access to entire app

* fix: lint

* fix: add navbar to address blocked screen

* feat: add disconnect button to address blocked modal

* chore: i18n

* fix: added period

Co-authored-by: Vladimir Yumatov <vladimir@aave.com>
  • Loading branch information
grothem and Vladimir Yumatov committed Aug 12, 2022
1 parent a3c9b33 commit 01a9666
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 28 deletions.
3 changes: 2 additions & 1 deletion .env.development
@@ -1 +1,2 @@
NEXT_PUBLIC_ENV=prod
NEXT_PUBLIC_ENV=prod
NEXT_PUBLIC_SCREENING_URL=https://aave-api-v2.aave.com
3 changes: 2 additions & 1 deletion .env.example
Expand Up @@ -4,4 +4,5 @@ TENDERLY_ACCOUNT=
TENDERLY_PROJECT=
NEXT_PUBLIC_ENV=prod
NEXT_PUBLIC_ENABLE_GOVERNANCE=true
NEXT_PUBLIC_ENABLE_STAKING=true
NEXT_PUBLIC_ENABLE_STAKING=true
NEXT_PUBLIC_SCREENING_URL=https://aave-api-v2.aave.com
1 change: 1 addition & 0 deletions .github/actions/build/action.yml
Expand Up @@ -44,3 +44,4 @@ runs:
NEXT_PUBLIC_ENV: '${{ inputs.NEXT_PUBLIC_ENV }}'
NEXT_PUBLIC_ENABLE_GOVERNANCE: 'true'
NEXT_PUBLIC_ENABLE_STAKING: 'true'
NEXT_PUBLIC_SCREENING_URL: 'https://aave-api-v2.aave.com'
1 change: 1 addition & 0 deletions custom.d.ts
Expand Up @@ -8,5 +8,6 @@ namespace NodeJS {
NEXT_PUBLIC_ENABLE_GOVERNANCE: string;
NEXT_PUBLIC_ENABLE_STAKING: string;
NEXT_PUBLIC_ENV: string;
NEXT_PUBLIC_SCREENING_URL: string;
}
}
53 changes: 28 additions & 25 deletions pages/_app.page.tsx
Expand Up @@ -36,6 +36,7 @@ import { WalletModalContextProvider } from 'src/hooks/useWalletModal';
import { PermissionProvider } from 'src/hooks/usePermissions';
import AaveMetaImage from 'public/aaveMetaLogo.png';
import { FaucetModal } from 'src/components/transactions/Faucet/FaucetModal';
import { AddressBlocked } from 'src/components/AddressBlocked';

// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
Expand Down Expand Up @@ -78,31 +79,33 @@ export default function MyApp(props: MyAppProps) {
<ProtocolDataProvider>
<ConnectionStatusProvider>
<AppGlobalStyles>
<PermissionProvider>
<ModalContextProvider>
<BackgroundDataProvider>
<AppDataProvider>
<TxBuilderProvider>
<WalletModalContextProvider>
<GasStationProvider>
{getLayout(<Component {...pageProps} />)}
<SupplyModal />
<WithdrawModal />
<BorrowModal />
<RepayModal />
<CollateralChangeModal />
<RateSwitchModal />
<ClaimRewardsModal />
<EmodeModal />
<SwapModal />
<FaucetModal />
</GasStationProvider>
</WalletModalContextProvider>
</TxBuilderProvider>
</AppDataProvider>
</BackgroundDataProvider>
</ModalContextProvider>
</PermissionProvider>
<AddressBlocked>
<PermissionProvider>
<ModalContextProvider>
<BackgroundDataProvider>
<AppDataProvider>
<TxBuilderProvider>
<WalletModalContextProvider>
<GasStationProvider>
{getLayout(<Component {...pageProps} />)}
<SupplyModal />
<WithdrawModal />
<BorrowModal />
<RepayModal />
<CollateralChangeModal />
<RateSwitchModal />
<ClaimRewardsModal />
<EmodeModal />
<SwapModal />
<FaucetModal />
</GasStationProvider>
</WalletModalContextProvider>
</TxBuilderProvider>
</AppDataProvider>
</BackgroundDataProvider>
</ModalContextProvider>
</PermissionProvider>
</AddressBlocked>
</AppGlobalStyles>
</ConnectionStatusProvider>
</ProtocolDataProvider>
Expand Down
20 changes: 20 additions & 0 deletions src/components/AddressBlocked.tsx
@@ -0,0 +1,20 @@
import { ReactNode } from 'react';
import { useAddressAllowed } from 'src/hooks/useAddressAllowed';
import { MainLayout } from 'src/layouts/MainLayout';
import { useWeb3Context } from 'src/libs/hooks/useWeb3Context';
import { AddressBlockedModal } from './AddressBlockedModal';

export const AddressBlocked = ({ children }: { children: ReactNode }) => {
const { currentAccount, disconnectWallet } = useWeb3Context();
const { isAllowed } = useAddressAllowed(currentAccount);

if (!isAllowed) {
return (
<MainLayout>
<AddressBlockedModal address={currentAccount} onDisconnectWallet={disconnectWallet} />;
</MainLayout>
);
}

return <>{children}</>;
};
53 changes: 53 additions & 0 deletions src/components/AddressBlockedModal.tsx
@@ -0,0 +1,53 @@
import { ExclamationCircleIcon, LogoutIcon } from '@heroicons/react/outline';
import { Trans } from '@lingui/macro';
import { Box, Button, SvgIcon, Typography } from '@mui/material';
import { BasicModal } from './primitives/BasicModal';
import { Link } from './primitives/Link';

export interface AddressBlockedProps {
address: string;
onDisconnectWallet: () => void;
}

export const AddressBlockedModal = ({ address, onDisconnectWallet }: AddressBlockedProps) => {
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars
const setOpen = (_value: boolean) => {}; // ignore, we want the modal to not be dismissable

return (
<BasicModal open={true} withCloseButton={false} setOpen={setOpen}>
<Box
sx={{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
}}
>
<SvgIcon sx={{ fontSize: '24px', color: 'warning.main', mb: 2 }}>
<ExclamationCircleIcon />
</SvgIcon>
<Typography variant="h2">
<Trans>Blocked Address</Trans>
</Typography>
<Typography variant="helperText" sx={{ my: 4 }}>
{address}
</Typography>
<Typography variant="description" sx={{ textAlign: 'center', mb: 4 }}>
<Trans>
This address is blocked on app.aave.com because it is associated with one or more
</Trans>{' '}
<Link href="https://docs.aave.com/faq/#address-screening" underline="always">
<Trans>blocked activities</Trans>
</Link>
{'.'}
</Typography>
<Button variant="contained" onClick={onDisconnectWallet}>
<SvgIcon fontSize="small" sx={{ mx: 1 }}>
<LogoutIcon />
</SvgIcon>
<Trans>Disconnect Wallet</Trans>
</Button>
</Box>
</BasicModal>
);
};
32 changes: 32 additions & 0 deletions src/hooks/useAddressAllowed.tsx
@@ -0,0 +1,32 @@
import { useState } from 'react';
import { usePolling } from './usePolling';

export interface AddressAllowedResult {
isAllowed: boolean;
}

const TWO_MINUTES = 2 * 60 * 1000;

export const useAddressAllowed = (address: string): AddressAllowedResult => {
const [isAllowed, setIsAllowed] = useState(true);

const screeningUrl = process.env.NEXT_PUBLIC_SCREENING_URL;

const getIsAddressAllowed = async () => {
if (screeningUrl && address) {
try {
const response = await fetch(`${screeningUrl}/addresses/status?address=${address}`);
const data: { addressAllowed: boolean } = await response.json();
setIsAllowed(data.addressAllowed);
} catch (e) {}
} else {
setIsAllowed(true);
}
};

usePolling(getIsAddressAllowed, TWO_MINUTES, false, [address]);

return {
isAllowed,
};
};
2 changes: 1 addition & 1 deletion src/locales/en/messages.js

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions src/locales/en/messages.po
Expand Up @@ -266,6 +266,10 @@ msgstr "Before supplying"
msgid "Before supplying, you need to approve its usage by the Aave protocol. You can learn more in our<0>FAQ</0>"
msgstr "Before supplying, you need to approve its usage by the Aave protocol. You can learn more in our<0>FAQ</0>"

#: src/components/AddressBlockedModal.tsx
msgid "Blocked Address"
msgstr "Blocked Address"

#: pages/index.page.tsx
#: src/components/transactions/Borrow/BorrowModal.tsx
#: src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsListItem.tsx
Expand Down Expand Up @@ -587,6 +591,7 @@ msgstr "Disabling E-Mode"
msgid "Disabling this asset as collateral affects your borrowing power and Health Factor."
msgstr "Disabling this asset as collateral affects your borrowing power and Health Factor."

#: src/components/AddressBlockedModal.tsx
#: src/layouts/WalletWidget.tsx
msgid "Disconnect Wallet"
msgstr "Disconnect Wallet"
Expand Down Expand Up @@ -1561,6 +1566,10 @@ msgstr "There was some error. Please try changing the parameters or <0><1>copy t
msgid "These funds have been borrowed and are not available for withdrawal at this time."
msgstr "These funds have been borrowed and are not available for withdrawal at this time."

#: src/components/AddressBlockedModal.tsx
msgid "This address is blocked on app.aave.com because it is associated with one or more"
msgstr "This address is blocked on app.aave.com because it is associated with one or more"

#: src/components/caps/CapsTooltip.tsx
msgid "This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market."
msgstr "This asset has almost reached its borrow cap. There is only {messageValue} available to be borrowed from this market."
Expand Down Expand Up @@ -1992,6 +2001,10 @@ msgstr "Zero address not valid"
msgid "assets"
msgstr "assets"

#: src/components/AddressBlockedModal.tsx
msgid "blocked activities"
msgstr "blocked activities"

#: src/components/transactions/FlowCommons/GasEstimationError.tsx
msgid "copy the error"
msgstr "copy the error"
Expand Down

0 comments on commit 01a9666

Please sign in to comment.