Skip to content

Commit

Permalink
Bug: max withdraw, Optimize STRKFarm APYs loading (#149)
Browse files Browse the repository at this point in the history
* feat: harvest time ui

* feat: display API data

* fix: imports

* fix: lint

* fix: remove mock contract

* fix: remove mock contract

* fix: change query

* Add tx history (#78)

* Add GraphQL tx history (#77)

* feat: use STRKFarm Graphql API to show tx history

* add console.log statements for debugging

* modify graphql query

* fix: fix apollo client

* refac: modify graphgl query

* feat: implement function to get tx history using graphql

* feat: show tx history in Strategy page

* fix: fix linting issue

* feat: implement function to get strategy address

---------

Co-authored-by: Mystic <[email protected]>
Co-authored-by: Gift-Naomi <[email protected]>

* fix tx toast update delay, add earnings info, cleaned tx component

---------

Co-authored-by: Mystic <[email protected]>
Co-authored-by: Gift-Naomi <[email protected]>

* add cache to /stats

* Update og_nft_eligible_users.json

* use u256 max for max withdraw

* use u256 max for max withdraw

* use u256 max for max withdraw [bug fix]

* optimization: load strkfarm apy from api

* optimization: load strkfarm apy from api [2]

---------

Co-authored-by: Iwueseiter <[email protected]>
Co-authored-by: Mystic <[email protected]>
Co-authored-by: Gift-Naomi <[email protected]>
  • Loading branch information
4 people authored Sep 30, 2024
1 parent 3fb9205 commit b28ac58
Show file tree
Hide file tree
Showing 15 changed files with 293 additions and 66 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
"@nikolovlazar/chakra-ui-prose": "1.2.1",
"@prisma/client": "5.18.0",
"@starknet-react/chains": "0.1.7",
"@apollo/client": "^3.11.8",
"graphql": "^16.9.0",
"@starknet-react/core": "2.8.0",
"@tanstack/query-core": "5.28.0",
"@types/mixpanel-browser": "2.49.0",
Expand Down
18 changes: 15 additions & 3 deletions public/og_nft_eligible_users.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[
"0x52a2dffcfa271420af69ae50b13345ccaa38fc04b09f350f33c8d0e3850a232",
"0x5b55db55f5884856860e63f3595b2ec6b2c9555f3f507b4ca728d8e427b7864",
"0x5095078578a59f8a9c17df97188db1b59574c6d4836dd3e705fe8537624228a",
"0x18489438975ee3c6bc18add415d7889a9630547398f26bb5dee27481216a67d",
Expand All @@ -19,6 +20,7 @@
"0x7a900c5b496d15bbb1c3c69d090e890a4b19dbceabee72232d4f2bec67ff4c",
"0x7f5d5b58f2a1c504f6a8d0e47269c903485582308b6f3415c27a561e0d1a6fa",
"0x17603b7963b1e2357a57e3c16f83abacef6bd8cf59e5394c34ae72ce566da2",
"0x27391b415a803a1aa7fffbed7db19336cf4b7f9bb1d3468986eef9a26341356",
"0x4bbdde9359d8bc7e513f510f9080306dbf267acb41228a4706d1b55f2fd065d",
"0x4015548595f22ccf56f6f42ada31a5d8eb7cb307c4e9e550b578d44fa25bcc",
"0x50393e851e40de930abcd9569d9df55883b9f2836d4bae724f126d2258cd292",
Expand All @@ -27,16 +29,26 @@
"0x14f59c23735b4aaaf6b6c0df567cacff9adc27f50dcb8b5270cf1237605c263",
"0x6733e297fe300f78f48c7106ad550626377aa732cef360867218c08a536ea5e",
"0x1ca34f742a91a588a3e770c8c8c8618a0713d7f64fda7935d42dcfcf4adffa0",
"0x571d4b6f5a34d7a43517d2eca4166804f753a643ec28bec0f51143bef50a9a6",
"0x6a98eef8b1ce965ec9f6daf4c896f5c21217f2365652c30d462b13a1858ed7c",
"0x5105649f42252f79109356e1c8765b7dcdb9bf4a6a68534e7fc962421c7efd2",
"0x36177b6741a43c219602ce857c18e445920d5a6ea5f4ee3a0240e8ae319bbf5",
"0x679316db27cdb5d579d0508859ce450db3c2a2483e3628f7c1fc80b52e87634",
"0x7463d3ebcd4c6de2035cca849814bbba4dd7820dac25e074e78087903d1b585",
"0x47ccae4b7dccabd0689624812f7deeb3ed283dc3349b826974ff88107d71f4c",
"0x9fb60ac230ceeda227d28f138e327d2509d01531d20d9c8b2c4a7bf65afd8c",
"0x1f13873d0e2ff24321ca91d0530f093c25dc7b52d9316df8c2ec1a17fbfb5c1",
"0x7342070d73d4ceef7e7c84420acb3026720e88fef10302fc11fd25a7ee0b715",
"0x2b27457428b94b38ccad5339ebc17a211b7c482c008ac8ad22e01b30e923628",
"0x67b72d3df972e5816b07ad4794af8e85c968409554281880149e96f09df1d56",
"0x1eb945a1b881a2d8f8d8ea5eada7ec42c999ab5e5ed225af7b62f00865bafbd",
"0x73298a2ca8b06596d7bc85311c1c9d06458664a02a341655dee4e663600ac53",
"0x297268ffc3c342f9c7fa3df6a5a6ef63ef5a5232ceaaf67168df686283effca",
"0x16d730875c5dd15f3c1086523683bf5463fc11572405c8bee6e1ec65bead84e",
"0x5c755ba1828c70314349ec4c4ddaf310e648d5773f9bb6c4eb6ce2369288569"
"0x4d1b676e430b55175ce9ecbe073486a15411a8605c99aff8a14804fd4088da5",
"0x147b941bec50a2b497eb1bd966cf36e33ad3da7e508ebd5ea994978fa5be5a6",
"0x5a39462a82784de9f0f30c356f3fd5dfe71c7fa510bf22e8893cec254f59fc2",
"0x7364ce0a8aab411beddf7780f222b3508af4daf5c542bb258e9fe55ae5846ba",
"0x3d87ee70baf292cdc23c654153cfd711ff580a076d1dccc0dfd9d3eb62df311",
"0x63d87659aeb300ce268e872fd16d3d2ad5821444c438fae86f2b1fc39d26c17",
"0x6afcff37fe09b4d92f834475c70452c91ede180ddd387ec09191333f1f908a",
"0x6857c54d51eb6410f3a4974fc7f89b7735f4b135c587d62ca8bb725b7848bb9"
]
6 changes: 4 additions & 2 deletions src/app/api/stats/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getStrategies } from '@/store/strategies.atoms';
import { NextResponse } from 'next/server';

export const revalidate = 60;
export const revalidate = 1800;

export async function GET(_req: Request) {
const strategies = getStrategies();
Expand All @@ -28,7 +28,9 @@ export async function GET(_req: Request) {

const result = await Promise.all(values);

return NextResponse.json({
const response = NextResponse.json({
tvl: result.reduce((a, b) => a + b, 0),
});

return response;
}
16 changes: 13 additions & 3 deletions src/app/api/strategies/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ZkLendAtoms from '@/store/zklend.store';
import { PoolInfo } from '@/store/pools';
import NostraLendingAtoms from '@/store/nostralending.store';
import { RpcProvider } from 'starknet';
import { getStrategies } from '@/store/strategies.atoms';
import { getLiveStatusNumber, getStrategies } from '@/store/strategies.atoms';
import { MY_STORE } from '@/store';
import MyNumber from '@/utils/MyNumber';
import { IStrategy, NFTInfo, TokenInfo } from '@/strategies/IStrategy';
Expand Down Expand Up @@ -42,15 +42,25 @@ async function getStrategyInfo(strategy: IStrategy) {
id: strategy.id,
apy: strategy.netYield,
depositToken: strategy
.depositMethods(MyNumber.fromZero(), '', provider)
.depositMethods({
amount: MyNumber.fromZero(),
address: '',
provider,
isMax: false,
})
.map((t) => t.tokenInfo.token),
leverage: strategy.leverage,
contract: strategy.holdingTokens.map((t) => ({
name: t.name,
address: (<any>t).token ? (<TokenInfo>t).token : (<NFTInfo>t).address,
})),
tvlUsd: tvl.usdValue || 0,
status: strategy.liveStatus,
status: {
number: getLiveStatusNumber(strategy.liveStatus),
value: strategy.liveStatus,
},
riskFactor: strategy.riskFactor,
logo: strategy.holdingTokens[0].logo,
};
}

Expand Down
5 changes: 5 additions & 0 deletions src/app/strategy/[strategyId]/_components/Strategy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,11 @@ const Strategy = ({ params }: StrategyParams) => {
</Text>
</Box>
))}
{strategy.actions.length == 0 && (
<Center width={'100%'} padding={'10px'}>
<Spinner size={'xs'} color="white" />
</Center>
)}
</Card>
<Grid width={'100%'} templateColumns="repeat(5, 1fr)" gap={2}>
<GridItem colSpan={colSpan1} bg="highlight">
Expand Down
34 changes: 22 additions & 12 deletions src/components/Deposit.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { DUMMY_BAL_ATOM } from '@/store/balance.atoms';
import { StrategyInfo } from '@/store/strategies.atoms';
import { StrategyTxProps } from '@/store/transactions.atom';
import { IStrategyActionHook, TokenInfo } from '@/strategies/IStrategy';
import {
DepositActionInputs,
IStrategyActionHook,
TokenInfo,
} from '@/strategies/IStrategy';
import { MyMenuItemProps, MyMenuListProps } from '@/utils';
import MyNumber from '@/utils/MyNumber';
import { ChevronDownIcon } from '@chakra-ui/icons';
Expand Down Expand Up @@ -31,7 +35,6 @@ import { useAccount, useProvider } from '@starknet-react/core';
import { useAtomValue } from 'jotai';
import mixpanel from 'mixpanel-browser';
import { useEffect, useMemo, useState } from 'react';
import { ProviderInterface } from 'starknet';
import LoadingWrap from './LoadingWrap';
import TxButton from './TxButton';

Expand All @@ -40,11 +43,7 @@ interface DepositProps {
// ? If you want to add more button text, you can add here
// ? @dev ensure below actionType is updated accordingly
buttonText: 'Deposit' | 'Redeem';
callsInfo: (
amount: MyNumber,
address: string,
provider: ProviderInterface,
) => IStrategyActionHook[];
callsInfo: (inputs: DepositActionInputs) => IStrategyActionHook[];
}

export default function Deposit(props: DepositProps) {
Expand All @@ -57,8 +56,12 @@ export default function Deposit(props: DepositProps) {

// This is the selected market token
const [selectedMarket, setSelectedMarket] = useState(
props.callsInfo(MyNumber.fromZero(), address || '0x0', provider)[0]
.tokenInfo,
props.callsInfo({
amount: MyNumber.fromZero(),
address: address || '0x0',
provider,
isMax: isMaxClicked,
})[0].tokenInfo,
);

// This is processed amount stored in MyNumber format and meant for sending tx
Expand All @@ -69,11 +72,13 @@ export default function Deposit(props: DepositProps) {
// This is used to store the raw amount entered by the user
const [rawAmount, setRawAmount] = useState('');

const isDeposit = useMemo(() => props.buttonText === 'Deposit', [props]);

// use to maintain tx history and show toasts
const txInfo: StrategyTxProps = useMemo(() => {
return {
strategyId: props.strategy.id,
actionType: props.buttonText === 'Deposit' ? 'deposit' : 'withdraw',
actionType: isDeposit ? 'deposit' : 'withdraw',
amount,
tokenAddr: selectedMarket.token,
};
Expand All @@ -88,11 +93,16 @@ export default function Deposit(props: DepositProps) {

// constructs tx calls
const { calls, actions } = useMemo(() => {
const actions = props.callsInfo(amount, address || '0x0', provider);
const actions = props.callsInfo({
amount,
address: address || '0x0',
provider,
isMax: isMaxClicked,
});
const hook = actions.find((a) => a.tokenInfo.name === selectedMarket.name);
if (!hook) return { calls: [], actions };
return { calls: hook.calls, actions };
}, [selectedMarket, amount, address, provider]);
}, [selectedMarket, amount, address, provider, isMaxClicked]);

const balData = useAtomValue(
actions.find((a) => a.tokenInfo.name === selectedMarket.name)
Expand Down
29 changes: 27 additions & 2 deletions src/components/HarvestTime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useMemo } from 'react';
import {
Box,
Flex,
Spinner,
Stat,
StatLabel,
StatNumber,
Expand All @@ -15,6 +16,9 @@ import { HarvestTimeAtom } from '@/store/harvest.atom';
import { useAtomValue } from 'jotai';
import { formatTimediff, getDisplayCurrencyAmount, timeAgo } from '@/utils';
import { isMobile } from 'react-device-detect';
import STRKFarmAtoms, {
STRKFarmStrategyAPIResult,
} from '@/store/strkfarm.atoms';

interface HarvestTimeProps {
strategy: StrategyInfo;
Expand Down Expand Up @@ -70,6 +74,24 @@ const HarvestTime: React.FC<HarvestTimeProps> = ({ strategy, balData }) => {
return formatTimediff(nextHarvest);
}, [data?.timestamp, lastHarvest]);

const strategiesInfo = useAtomValue(STRKFarmAtoms.baseAPRs!);

const strategyInfo = useMemo(() => {
if (!strategiesInfo || !strategiesInfo.data) return null;

const strategiesList: STRKFarmStrategyAPIResult[] =
strategiesInfo.data.strategies;
const strategyInfo = strategiesList.find(
(strat) => strat.id == strategy.id,
);
return strategyInfo ? strategyInfo : null;
}, [strategiesInfo]);

const leverage = useMemo(() => {
if (!strategyInfo) return 0;
return strategyInfo.leverage || 0;
}, [strategyInfo]);

return (
<Box>
<Flex justifyContent="space-between">
Expand All @@ -82,7 +104,7 @@ const HarvestTime: React.FC<HarvestTimeProps> = ({ strategy, balData }) => {
>
<StatLabel>APY</StatLabel>
<StatNumber color="cyan" lineHeight="24px">
{(strategy.netYield * 100).toFixed(2)}%
{((strategyInfo?.apy || 0) * 100).toFixed(2)}%
</StatNumber>
</Stat>
<Flex flexDirection={'column'} justifyContent={'flex-end'}>
Expand All @@ -93,7 +115,10 @@ const HarvestTime: React.FC<HarvestTimeProps> = ({ strategy, balData }) => {
fontSize={'12px'}
padding={'2px 5px'}
>
🔥{strategy.leverage.toFixed(2)}x boosted
🔥{leverage.toFixed(2)}x boosted
{leverage == 0 && (
<Spinner size="xs" color="white" ml={'5px'} />
)}
</Tag>
</Tooltip>
</Flex>
Expand Down
3 changes: 3 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ const CONSTANTS = {
HAIKO: {
BASE_APR_API: 'haiko/markets?network=mainnet',
},
STRKFarm: {
BASE_APR_API: '/api/strategies',
},
MY_SWAP: {
POOLS_API: '/myswap/data/pools/all.json',
BASE_APR_API: '/myswap/data/pools',
Expand Down
20 changes: 10 additions & 10 deletions src/store/protocols.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ import { Category, PoolInfo, PoolType } from './pools';
import { strategiesAtom } from './strategies.atoms';
import strkfarmLogo from '@public/logo.png';
import { IStrategyProps } from '@/strategies/IStrategy';
import STRKFarmAtoms, { strkfarm } from './strkfarm.atoms';

export const PROTOCOLS = [
{
name: strkfarm.name,
class: strkfarm,
atoms: STRKFarmAtoms,
},
{
name: ekubo.name,
class: ekubo,
Expand Down Expand Up @@ -98,16 +104,10 @@ export const PROTOCOLS = [

export const ALL_FILTER = 'All';

const allProtocols = [
{
name: 'STRKFarm',
logo: strkfarmLogo.src,
},
...PROTOCOLS.map((p) => ({
name: p.name,
logo: p.class.logo,
})),
];
const allProtocols = PROTOCOLS.map((p) => ({
name: p.name,
logo: p.class.logo,
}));
export const filters = {
categories: [...Object.values(Category)],
types: [...Object.values(PoolType)],
Expand Down
13 changes: 12 additions & 1 deletion src/store/strategies.atoms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export const strategiesAtom = atom<StrategyInfo[]>((get) => {
return strategies;
});

function getLiveStatusNumber(status: StrategyLiveStatus) {
export function getLiveStatusNumber(status: StrategyLiveStatus) {
if (status == StrategyLiveStatus.NEW) {
return 1;
} else if (status == StrategyLiveStatus.ACTIVE) {
Expand All @@ -120,3 +120,14 @@ function getLiveStatusNumber(status: StrategyLiveStatus) {
}
return 4;
}

export function getLiveStatusEnum(status: number) {
if (status == 1) {
return StrategyLiveStatus.NEW;
} else if (status == 2) {
return StrategyLiveStatus.ACTIVE;
} else if (status == 3) {
return StrategyLiveStatus.COMING_SOON;
}
return StrategyLiveStatus.RETIRED;
}
Loading

0 comments on commit b28ac58

Please sign in to comment.