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

Feat/implement zk ignite program #6

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions public/icons/other/zksync-ignite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions src/components/incentives/IncentivesButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { DotsHorizontalIcon } from '@heroicons/react/solid';
import { Box, SvgIcon, Typography } from '@mui/material';
import { useState } from 'react';
import { useMeritIncentives } from 'src/hooks/useMeritIncentives';
import { useZkSyncIgniteIncentives } from 'src/hooks/useZkSyncIgniteIncentives';
import { useRootStore } from 'src/store/root';
import { DASHBOARD } from 'src/utils/mixPanelEvents';

Expand All @@ -13,6 +14,7 @@ import { FormattedNumber } from '../primitives/FormattedNumber';
import { TokenIcon } from '../primitives/TokenIcon';
import { getSymbolMap, IncentivesTooltipContent } from './IncentivesTooltipContent';
import { MeritIncentivesTooltipContent } from './MeritIncentivesTooltipContent';
import { ZkSyncIgniteIncentivesTooltipContent } from './ZkSyncIgniteIncentivesTooltipContent';

interface IncentivesButtonProps {
symbol: string;
Expand Down Expand Up @@ -61,6 +63,31 @@ export const MeritIncentivesButton = (params: {
);
};

export const ZkIgniteIncentivesButton = (params: { asset?: string }) => {
const [open, setOpen] = useState(false);
const { data: zkSyncIgniteIncentives } = useZkSyncIgniteIncentives(params);

if (!zkSyncIgniteIncentives) {
return null;
}

return (
<ContentWithTooltip
tooltipContent={
<ZkSyncIgniteIncentivesTooltipContent zkSyncIgniteIncentives={zkSyncIgniteIncentives} />
}
withoutHover
setOpen={setOpen}
open={open}
>
<Content
incentives={[zkSyncIgniteIncentives]}
incentivesNetAPR={+zkSyncIgniteIncentives.incentiveAPR}
/>
</ContentWithTooltip>
);
};

export const IncentivesButton = ({ incentives, symbol, displayBlank }: IncentivesButtonProps) => {
const [open, setOpen] = useState(false);

Expand Down
36 changes: 32 additions & 4 deletions src/components/incentives/IncentivesCard.tsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,45 @@
import { ProtocolAction } from '@aave/contract-helpers';
import { ReserveIncentiveResponse } from '@aave/math-utils/dist/esm/formatters/incentive/calculate-reserve-incentives';
import { Box } from '@mui/material';
import { Box, useMediaQuery } from '@mui/material';
import { ReactNode } from 'react';
import { CustomMarket } from 'src/ui-config/marketsConfig';

import { FormattedNumber } from '../primitives/FormattedNumber';
import { NoData } from '../primitives/NoData';
import { IncentivesButton } from './IncentivesButton';
import {
IncentivesButton,
MeritIncentivesButton,
ZkIgniteIncentivesButton,
} from './IncentivesButton';

interface IncentivesCardProps {
symbol: string;
value: string | number;
incentives?: ReserveIncentiveResponse[];
address?: string;
variant?: 'main14' | 'main16' | 'secondary14';
symbolsVariant?: 'secondary14' | 'secondary16';
align?: 'center' | 'flex-end';
color?: string;
tooltip?: ReactNode;
market: string;
protocolAction?: ProtocolAction;
}

export const IncentivesCard = ({
symbol,
value,
incentives,
address,
variant = 'secondary14',
symbolsVariant,
align,
color,
tooltip,
market,
protocolAction,
}: IncentivesCardProps) => {
const isTableChangedToCards = useMediaQuery('(max-width:1125px)');
return (
<Box
sx={{
Expand All @@ -53,8 +66,23 @@ export const IncentivesCard = ({
) : (
<NoData variant={variant} color={color || 'text.secondary'} />
)}

<IncentivesButton incentives={incentives} symbol={symbol} />
<Box
sx={
isTableChangedToCards
? { display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: '4px' }
: {
display: 'flex',
justifyContent: 'center',
gap: '4px',
flexWrap: 'wrap',
flex: '0 0 50%', // 2 items per row
}
}
>
<IncentivesButton incentives={incentives} symbol={symbol} />
<MeritIncentivesButton symbol={symbol} market={market} protocolAction={protocolAction} />
{market === CustomMarket.proto_zksync_v3 && <ZkIgniteIncentivesButton asset={address} />}
</Box>
</Box>
);
};
105 changes: 105 additions & 0 deletions src/components/incentives/ZkSyncIgniteIncentivesTooltipContent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { Trans } from '@lingui/macro';
import { Box, Typography } from '@mui/material';
import { ExtendedReserveIncentiveResponse } from 'src/hooks/useMeritIncentives';

import { FormattedNumber } from '../primitives/FormattedNumber';
import { Link } from '../primitives/Link';
import { Row } from '../primitives/Row';
import { TokenIcon } from '../primitives/TokenIcon';
import { getSymbolMap } from './IncentivesTooltipContent';

export const ZkSyncIgniteIncentivesTooltipContent = ({
zkSyncIgniteIncentives,
}: {
zkSyncIgniteIncentives: ExtendedReserveIncentiveResponse;
}) => {
const typographyVariant = 'secondary12';

const zkSyncIgniteIncentivesFormatted = getSymbolMap(zkSyncIgniteIncentives);

return (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'start',
flexDirection: 'column',
}}
>
<img src={`/icons/other/zksync-ignite.svg`} width="100px" height="40px" alt="" />

<Typography variant="caption" color="text.primary" mb={3}>
<Trans>Eligible for the ZKSync Ignite program.</Trans>
</Typography>

<Typography variant="caption" color="text.secondary" mb={3}>
<Trans>
This is a program initiated and implemented by the decentralised ZKSync community. Aave
Labs does not guarantee the program and accepts no liability.
</Trans>{' '}
<Link
href={'https://zksyncignite.xyz/'}
sx={{ textDecoration: 'underline' }}
variant="caption"
color="text.secondary"
>
Learn more
</Link>
</Typography>

<Typography variant="caption" color="text.secondary" mb={3}>
<Trans>ZKSync Ignite Program rewards are claimed through the</Trans>{' '}
<Link
href="https://app.zksyncignite.xyz/"
sx={{ textDecoration: 'underline' }}
variant="caption"
color="text.secondary"
>
official app
</Link>
{'.'}
</Typography>
{zkSyncIgniteIncentives.customMessage ? (
<Typography variant="caption" color="text.strong" mb={3}>
<Trans>{zkSyncIgniteIncentives.customMessage}</Trans>
</Typography>
) : null}

<Box sx={{ width: '100%' }}>
<Row
height={32}
caption={
<Box
sx={{
display: 'flex',
alignItems: 'center',
mb: 0,
}}
>
<TokenIcon
aToken={zkSyncIgniteIncentivesFormatted.aToken}
symbol={zkSyncIgniteIncentivesFormatted.tokenIconSymbol}
sx={{ fontSize: '20px', mr: 1 }}
/>
<Typography variant={typographyVariant}>
{zkSyncIgniteIncentivesFormatted.symbol}
</Typography>
</Box>
}
width="100%"
>
<Box sx={{ display: 'inline-flex', alignItems: 'center' }}>
<FormattedNumber
value={+zkSyncIgniteIncentivesFormatted.incentiveAPR}
percent
variant={typographyVariant}
/>
<Typography variant={typographyVariant} sx={{ ml: 1 }}>
<Trans>APR</Trans>
</Typography>
</Box>
</Row>
</Box>
</Box>
);
};
103 changes: 103 additions & 0 deletions src/hooks/useZkSyncIgniteIncentives.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { ReserveIncentiveResponse } from '@aave/math-utils/dist/esm/formatters/incentive/calculate-reserve-incentives';
import { AaveV3ZkSync } from '@bgd-labs/aave-address-book';
import { useQuery } from '@tanstack/react-query';
import { Address } from 'viem';

enum Action {
LEND = 'LEND',
BORROW = 'BORROW',
}

enum Status {
LIVE = 'LIVE',
PAST = 'PAST',
UPCOMING = 'UPCOMING',
}

type MerklOpportunity = {
chainId: number;
type: string;
identifier: Address;
name: string;
status: Status;
action: Action;
tvl: number;
apr: number;
dailyRewards: number;
tags: [];
id: string;
tokens: [
{
id: string;
name: string;
chainId: number;
address: Address;
decimals: number;
icon: string;
verified: boolean;
isTest: boolean;
price: number;
symbol: string;
}
];
};

export type ExtendedReserveIncentiveResponse = ReserveIncentiveResponse & {
customMessage: string;
customForumLink: string;
};

const url =
'https://api.merkl.xyz/v4/opportunities?items=50&test=true&tags=zksync&mainProtocolId=aave'; // Merkl API for ZK Ignite opportunities

const rewardToken = AaveV3ZkSync.ASSETS.ZK.UNDERLYING;
const rewardTokenSymbol = 'ZK';

export const useZkSyncIgniteIncentives = ({ asset }: { asset?: string }) => {
return useQuery({
queryFn: async () => {
const response = await fetch(url);
const merklOpportunities: MerklOpportunity[] = await response.json();

console.log('MerklOpportunities', merklOpportunities);

return merklOpportunities;
},
queryKey: ['zkIgniteIncentives'],
staleTime: 1000 * 60 * 5,
select: (merklOpportunities) => {
console.log(merklOpportunities.map((opportunity) => opportunity.identifier));
console.log('asset', asset);

const opportunities = merklOpportunities.filter(
(opportunitiy) => opportunitiy.identifier.toLowerCase() === asset?.toLowerCase()
);

console.log('opportunities', opportunities);

if (opportunities.length === 0) {
return null;
}

const opportunity = opportunities[0];

if (opportunity.status !== Status.LIVE) {
return null;
}

const apr = opportunity.apr / 100;

console.log({
incentiveAPR: apr.toString(),
rewardTokenAddress: rewardToken,
rewardTokenSymbol: rewardTokenSymbol,
});

return {
incentiveAPR: apr.toString(),
rewardTokenAddress: rewardToken,
rewardTokenSymbol: rewardTokenSymbol,
} as ExtendedReserveIncentiveResponse;
},
});
};
2 changes: 1 addition & 1 deletion src/locales/el/messages.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/locales/en/messages.js

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/locales/en/messages.po
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ msgstr "APY, borrow rate"
#: src/components/incentives/IncentivesTooltipContent.tsx
#: src/components/incentives/IncentivesTooltipContent.tsx
#: src/components/incentives/MeritIncentivesTooltipContent.tsx
#: src/components/incentives/ZkSyncIgniteIncentivesTooltipContent.tsx
msgid "APR"
msgstr "APR"

Expand Down Expand Up @@ -955,6 +956,10 @@ msgstr "{tooltipText}"
msgid "Rewards can be claimed through"
msgstr "Rewards can be claimed through"

#: src/components/incentives/ZkSyncIgniteIncentivesTooltipContent.tsx
msgid "This is a program initiated and implemented by the decentralised ZKSync community. Aave Labs does not guarantee the program and accepts no liability."
msgstr "This is a program initiated and implemented by the decentralised ZKSync community. Aave Labs does not guarantee the program and accepts no liability."

#: src/components/incentives/MeritIncentivesTooltipContent.tsx
msgid "This is a program initiated and implemented by the decentralised Aave community. Aave Labs does not guarantee the program and accepts no liability."
msgstr "This is a program initiated and implemented by the decentralised Aave community. Aave Labs does not guarantee the program and accepts no liability."
Expand Down Expand Up @@ -1015,6 +1020,7 @@ msgid "Liquidation at"
msgstr "Liquidation at"

#: src/components/incentives/MeritIncentivesTooltipContent.tsx
#: src/components/incentives/ZkSyncIgniteIncentivesTooltipContent.tsx
#: src/components/MarketSwitcher.tsx
#: src/components/transactions/DelegationTxsWrapper.tsx
#: src/components/transactions/DelegationTxsWrapper.tsx
Expand Down Expand Up @@ -1923,6 +1929,10 @@ msgstr "Eligible for the Merit program."
msgid "Cooldown period warning"
msgstr "Cooldown period warning"

#: src/components/incentives/ZkSyncIgniteIncentivesTooltipContent.tsx
msgid "ZKSync Ignite Program rewards are claimed through the"
msgstr "ZKSync Ignite Program rewards are claimed through the"

#: src/components/transactions/Emode/EmodeModalContent.tsx
#: src/modules/bridge/BridgeWrapper.tsx
#: src/modules/dashboard/lists/BorrowAssetsList/BorrowAssetsList.tsx
Expand Down Expand Up @@ -2746,6 +2756,10 @@ msgstr "All borrow positions outside of this category must be closed to enable t
msgid "Available to supply"
msgstr "Available to supply"

#: src/components/incentives/ZkSyncIgniteIncentivesTooltipContent.tsx
msgid "Eligible for the ZKSync Ignite program."
msgstr "Eligible for the ZKSync Ignite program."

#: src/components/transactions/Warnings/MarketWarning.tsx
msgid "Per the community, the {market} has been frozen."
msgstr "Per the community, the {market} has been frozen."
Expand Down
2 changes: 1 addition & 1 deletion src/locales/es/messages.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/locales/fr/messages.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const BorrowAssetsListItem = ({
totalBorrows,
variableBorrowRate,
vIncentivesData,
variableDebtTokenAddress,
underlyingAsset,
isFreezed,
}: DashboardReserve) => {
Expand Down Expand Up @@ -70,6 +71,7 @@ export const BorrowAssetsListItem = ({
value={Number(variableBorrowRate)}
market={currentMarket}
protocolAction={ProtocolAction.borrow}
address={variableDebtTokenAddress}
incentives={vIncentivesData}
symbol={symbol}
/>
Expand Down
Loading
Loading