/ src / modules / reserve-overview / ReserveConfiguration.tsx
ReserveConfiguration.tsx
  1  import { ExternalLinkIcon } from '@heroicons/react/solid';
  2  import { Trans } from '@lingui/macro';
  3  import { Box, Button, Divider, SvgIcon } from '@mui/material';
  4  import { getFrozenProposalLink } from 'src/components/infoTooltips/FrozenTooltip';
  5  import { PausedTooltipText } from 'src/components/infoTooltips/PausedTooltip';
  6  import { FormattedNumber } from 'src/components/primitives/FormattedNumber';
  7  import { Link } from 'src/components/primitives/Link';
  8  import { Warning } from 'src/components/primitives/Warning';
  9  import { AMPLWarning } from 'src/components/Warnings/AMPLWarning';
 10  import { BorrowDisabledWarning } from 'src/components/Warnings/BorrowDisabledWarning';
 11  import {
 12    AssetsBeingOffboarded,
 13    OffboardingWarning,
 14  } from 'src/components/Warnings/OffboardingWarning';
 15  import { ComputedReserveData } from 'src/hooks/app-data-provider/useAppDataProvider';
 16  import { useAssetCaps } from 'src/hooks/useAssetCaps';
 17  import { BROKEN_ASSETS } from 'src/hooks/useReservesHistory';
 18  import { useRootStore } from 'src/store/root';
 19  import { GENERAL } from 'src/utils/mixPanelEvents';
 20  import { useShallow } from 'zustand/shallow';
 21  
 22  import { BorrowInfo } from './BorrowInfo';
 23  import { InterestRateModelGraphContainer } from './graphs/InterestRateModelGraphContainer';
 24  import { ReserveEModePanel } from './ReserveEModePanel';
 25  import { PanelItem, PanelRow, PanelTitle } from './ReservePanels';
 26  import { SupplyInfo } from './SupplyInfo';
 27  
 28  type ReserveConfigurationProps = {
 29    reserve: ComputedReserveData;
 30  };
 31  
 32  export const ReserveConfiguration: React.FC<ReserveConfigurationProps> = ({ reserve }) => {
 33    const [trackEvent, currentNetworkConfig, currentMarketData, currentMarket] = useRootStore(
 34      useShallow((store) => [
 35        store.trackEvent,
 36        store.currentNetworkConfig,
 37        store.currentMarketData,
 38        store.currentMarket,
 39      ])
 40    );
 41    const reserveId =
 42      reserve.underlyingAsset + currentMarketData.addresses.LENDING_POOL_ADDRESS_PROVIDER;
 43    const renderCharts =
 44      !!currentNetworkConfig.ratesHistoryApiUrl &&
 45      !currentMarketData.disableCharts &&
 46      !BROKEN_ASSETS.includes(reserveId);
 47    const { supplyCap, borrowCap, debtCeiling } = useAssetCaps();
 48    const showSupplyCapStatus: boolean = reserve.supplyCap !== '0';
 49    const showBorrowCapStatus: boolean = reserve.borrowCap !== '0';
 50  
 51    const offboardingDiscussion = AssetsBeingOffboarded[currentMarket]?.[reserve.symbol];
 52  
 53    return (
 54      <>
 55        <Box>
 56          {reserve.isFrozen && !offboardingDiscussion ? (
 57            <Warning sx={{ mt: '16px', mb: '40px' }} severity="error">
 58              <Trans>
 59                This asset is frozen due to an Aave community decision.{' '}
 60                <Link
 61                  href={getFrozenProposalLink(reserve.symbol, currentMarket)}
 62                  sx={{ textDecoration: 'underline' }}
 63                >
 64                  <Trans>More details</Trans>
 65                </Link>
 66              </Trans>
 67            </Warning>
 68          ) : offboardingDiscussion ? (
 69            <Warning sx={{ mt: '16px', mb: '40px' }} severity="error">
 70              <OffboardingWarning discussionLink={offboardingDiscussion} />
 71            </Warning>
 72          ) : (
 73            reserve.symbol == 'AMPL' && (
 74              <Warning sx={{ mt: '16px', mb: '40px' }} severity="warning">
 75                <AMPLWarning />
 76              </Warning>
 77            )
 78          )}
 79  
 80          {reserve.isPaused ? (
 81            reserve.symbol === 'MAI' ? (
 82              <Warning sx={{ mt: '16px', mb: '40px' }} severity="error">
 83                <Trans>
 84                  MAI has been paused due to a community decision. Supply, borrows and repays are
 85                  impacted.{' '}
 86                  <Link
 87                    href={
 88                      'https://governance.aave.com/t/arfc-add-mai-to-arbitrum-aave-v3-market/12759/8'
 89                    }
 90                    sx={{ textDecoration: 'underline' }}
 91                  >
 92                    <Trans>More details</Trans>
 93                  </Link>
 94                </Trans>
 95              </Warning>
 96            ) : (
 97              <Warning sx={{ mt: '16px', mb: '40px' }} severity="error">
 98                <PausedTooltipText />
 99              </Warning>
100            )
101          ) : null}
102        </Box>
103  
104        <PanelRow>
105          <PanelTitle>Supply Info</PanelTitle>
106          <SupplyInfo
107            reserve={reserve}
108            currentMarketData={currentMarketData}
109            renderCharts={renderCharts}
110            showSupplyCapStatus={showSupplyCapStatus}
111            supplyCap={supplyCap}
112            debtCeiling={debtCeiling}
113          />
114        </PanelRow>
115  
116        {(reserve.borrowingEnabled || Number(reserve.totalDebt) > 0) && (
117          <>
118            <Divider sx={{ my: { xs: 6, sm: 10 } }} />
119            <PanelRow>
120              <PanelTitle>Borrow info</PanelTitle>
121              <Box sx={{ flexGrow: 1, minWidth: 0, maxWidth: '100%', width: '100%' }}>
122                {!reserve.borrowingEnabled && (
123                  <Warning sx={{ mb: '40px' }} severity="error">
124                    <BorrowDisabledWarning symbol={reserve.symbol} currentMarket={currentMarket} />
125                  </Warning>
126                )}
127                <BorrowInfo
128                  reserve={reserve}
129                  currentMarketData={currentMarketData}
130                  currentNetworkConfig={currentNetworkConfig}
131                  renderCharts={renderCharts}
132                  showBorrowCapStatus={showBorrowCapStatus}
133                  borrowCap={borrowCap}
134                />
135              </Box>
136            </PanelRow>
137          </>
138        )}
139  
140        {reserve.eModes.length > 0 && (
141          <>
142            <Divider sx={{ my: { xs: 6, sm: 10 } }} />
143            <ReserveEModePanel reserve={reserve} />
144          </>
145        )}
146  
147        {(reserve.borrowingEnabled || Number(reserve.totalDebt) > 0) && (
148          <>
149            <Divider sx={{ my: { xs: 6, sm: 10 } }} />
150  
151            <PanelRow>
152              <PanelTitle>Interest rate model</PanelTitle>
153              <Box sx={{ flexGrow: 1, minWidth: 0, maxWidth: '100%', width: '100%' }}>
154                <Box
155                  sx={{
156                    display: 'flex',
157                    alignItems: 'center',
158                    flexWrap: 'wrap',
159                    justifyContent: 'space-between',
160                  }}
161                >
162                  <PanelItem title={<Trans>Utilization Rate</Trans>} className="borderless">
163                    <FormattedNumber
164                      value={reserve.borrowUsageRatio}
165                      percent
166                      variant="main16"
167                      compact
168                    />
169                  </PanelItem>
170                  <Button
171                    onClick={() => {
172                      trackEvent(GENERAL.EXTERNAL_LINK, {
173                        asset: reserve.underlyingAsset,
174                        Link: 'Interest Rate Strategy',
175                        assetName: reserve.name,
176                      });
177                    }}
178                    href={currentNetworkConfig.explorerLinkBuilder({
179                      address: reserve.interestRateStrategyAddress,
180                    })}
181                    endIcon={
182                      <SvgIcon sx={{ width: 14, height: 14 }}>
183                        <ExternalLinkIcon />
184                      </SvgIcon>
185                    }
186                    component={Link}
187                    size="small"
188                    variant="outlined"
189                    sx={{ verticalAlign: 'top' }}
190                  >
191                    <Trans>Interest rate strategy</Trans>
192                  </Button>
193                </Box>
194                <InterestRateModelGraphContainer reserve={reserve} />
195              </Box>
196            </PanelRow>
197          </>
198        )}
199      </>
200    );
201  };