Skip to content

Commit

Permalink
fix: deps
Browse files Browse the repository at this point in the history
  • Loading branch information
Majorfi committed Oct 16, 2023
1 parent 849771e commit 943f03a
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 72 deletions.
9 changes: 7 additions & 2 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
'extends': ['./node_modules/@yearn-finance/web-lib/.eslintrc.cjs'],
'extends': ['./node_modules/@yearn-finance/web-lib/.eslintrc.cjs', 'plugin:react-hooks/recommended'],
'parser': '@typescript-eslint/parser',
'parserOptions': {
'ecmaFeatures': {
Expand All @@ -16,6 +16,11 @@ module.exports = {
'@typescript-eslint/indent': ['error', 'tab'],
'no-multi-spaces': ['error', {ignoreEOLComments: false}],
'no-mixed-spaces-and-tabs': 'error',
'react/jsx-max-props-per-line': 'off'
'react/jsx-max-props-per-line': 'off',
'react-hooks/exhaustive-deps': [
'warn', {
'additionalHooks': '(useAsync)'
}
]
}
};
1 change: 1 addition & 0 deletions apps/common/contexts/useWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ export const WalletContextApp = memo(function WalletContextApp({children}: {chil
refresh: onRefresh
}), [balances, cumulatedValueInVaults, isLoading, onRefresh, nonce]);


return (
<WalletContext.Provider value={contextValue}>
{children}
Expand Down
10 changes: 5 additions & 5 deletions apps/common/hooks/useAsyncEffect.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import {useCallback, useEffect} from 'react';
/* eslint-disable react-hooks/exhaustive-deps */

import type {DependencyList} from 'react';
import {type DependencyList, useCallback,useEffect} from 'react';

function useAsyncEffect(effect: () => Promise<void>, deps?: DependencyList): () => Promise<void> {
function useAsync(effect: () => Promise<void>, deps: DependencyList): () => Promise<void> {
const asyncEffectInCallback = useCallback(async (): Promise<void> => {
effect();
}, [deps]);
}, [...deps]);

useEffect((): void => {
asyncEffectInCallback();
Expand All @@ -15,4 +15,4 @@ function useAsyncEffect(effect: () => Promise<void>, deps?: DependencyList): ()
}


export {useAsyncEffect};
export {useAsync};
46 changes: 26 additions & 20 deletions apps/veyfi/components/GaugesTab.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {useCallback, useState} from 'react';
import {useDeepCompareMemo} from '@react-hookz/web';
import {useGauge} from '@veYFI/contexts/useGauge';
import {approveAndStake, stake, unstake} from '@veYFI/utils/actions/gauge';
import {VEYFI_CHAIN_ID} from '@veYFI/utils/constants';
Expand Down Expand Up @@ -127,27 +128,32 @@ export function GaugesTab(): ReactElement {
const {balances} = useWallet();
const userAddress = address as TAddress;

const gaugesData = gaugeAddresses.map((address): TGaugeData => {
const gauge = gaugesMap[address];
const vaultAddress = toAddress(gauge?.vaultAddress);
const vault = vaults[vaultAddress];
const gaugesData = useDeepCompareMemo((): TGaugeData[] => {
return (
gaugeAddresses.map((address): TGaugeData => {
const gauge = gaugesMap[address];
const vaultAddress = toAddress(gauge?.vaultAddress);
const vault = vaults[vaultAddress];

return ({
gaugeAddress: address,
vaultAddress,
decimals: gauge?.decimals ?? 18,
vaultIcon: `${process.env.BASE_YEARN_ASSETS_URI}/1/${vaultAddress}/logo-128.png`,
vaultName: vault?.display_name ?? `Vault ${truncateHex(vaultAddress, 4)}`,
vaultApy: vault?.apy.net_apy ?? 0,
vaultDeposited: balances[vaultAddress],
gaugeApy: 0, // TODO: gauge apy calcs
gaugeBoost: positionsMap[address]?.boost ?? 1,
gaugeStaked: positionsMap[address]?.deposit.balance ?? toNormalizedBN(0),
allowance: allowancesMap[allowanceKey(VEYFI_CHAIN_ID, vaultAddress, address, userAddress)],
isApproved: toBigInt(allowancesMap[allowanceKey(VEYFI_CHAIN_ID, vaultAddress, address, userAddress)]?.raw) >= toBigInt(balances[vaultAddress]?.raw),
actions: undefined
});
})
);
}, [gaugesMap, gaugeAddresses, vaults, balances, positionsMap, allowancesMap, userAddress]);

return {
gaugeAddress: address,
vaultAddress,
decimals: gauge?.decimals ?? 18,
vaultIcon: `${process.env.BASE_YEARN_ASSETS_URI}/1/${vaultAddress}/logo-128.png`,
vaultName: vault?.display_name ?? `Vault ${truncateHex(vaultAddress, 4)}`,
vaultApy: vault?.apy.net_apy ?? 0,
vaultDeposited: balances[vaultAddress],
gaugeApy: 0, // TODO: gauge apy calcs
gaugeBoost: positionsMap[address]?.boost ?? 1,
gaugeStaked: positionsMap[address]?.deposit.balance ?? toNormalizedBN(0),
allowance: allowancesMap[allowanceKey(1, vaultAddress, address, userAddress)],
isApproved: toBigInt(allowancesMap[allowanceKey(1, vaultAddress, address, userAddress)]?.raw) >= toBigInt(balances[vaultAddress]?.raw),
actions: undefined
};
});

return (
<div className={'relative -left-6 w-[calc(100%+48px)]'}>
Expand Down
93 changes: 48 additions & 45 deletions apps/veyfi/contexts/useGauge.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import React, {createContext, memo, useCallback, useContext, useEffect, useMemo, useState} from 'react';
import React, {createContext, memo, useCallback, useContext, useState} from 'react';
import {FixedNumber} from 'ethers';
import {keyBy} from '@veYFI/utils';
import {useDeepCompareMemo} from '@react-hookz/web';
import {VEYFI_GAUGE_ABI} from '@veYFI/utils/abi/veYFIGauge.abi';
import {VEYFI_CHAIN_ID} from '@veYFI/utils/constants';
import {erc20ABI, readContracts} from '@wagmi/core';
import {useWeb3} from '@yearn-finance/web-lib/contexts/useWeb3';
import {allowanceKey, toAddress} from '@yearn-finance/web-lib/utils/address';
import {decodeAsAddress, decodeAsBigInt, decodeAsNumber, decodeAsString} from '@yearn-finance/web-lib/utils/decoder';
import {toNormalizedBN} from '@yearn-finance/web-lib/utils/format.bigNumber';
import {useAsyncEffect} from '@common/hooks/useAsyncEffect';
import {useAsync} from '@common/hooks/useAsyncEffect';
import {keyBy} from '@common/utils';

import type {ReactElement} from 'react';
import type {TAddress, TDict} from '@yearn-finance/web-lib/types';
Expand Down Expand Up @@ -53,10 +54,10 @@ const defaultProps: TGaugeContext = {

const GaugeContext = createContext<TGaugeContext>(defaultProps);
export const GaugeContextApp = memo(function GaugeContextApp({children}: {children: ReactElement}): ReactElement {
const {address: userAddress, isActive} = useWeb3();
const {address, isActive} = useWeb3();
const [gauges, set_gauges] = useState<TGauge[]>([]);
const [allowancesMap, set_allowancesMap] = useState<TDict<TNormalizedBN>>({});
const [positions, set_positions] = useState<TGaugePosition[]>([]);
const [positionsMap, set_positionsMap] = useState<TDict<TGaugePosition>>({});

// const {data: vaultAddresses} = useContractRead({
// address: VEYFI_REGISTRY_ADDRESS,
Expand All @@ -71,48 +72,50 @@ export const GaugeContextApp = memo(function GaugeContextApp({children}: {childr
// toAddress('0x9Cb511D44930c0C3D3114FFAaBedC3e0876D791a')
// ];

const refreshVotingEscrow = useAsyncEffect(async (): Promise<void> => {
const refreshVotingEscrow = useAsync(async (): Promise<void> => {
const gaugeAddresses = [
toAddress('0xbADfbF563C6C85F76e086E7a1915A1A46d683810'),
toAddress('0xd5947C01dBaEFeFF05186FE34A976b2E28d90542'),
toAddress('0x2262ef7F5A0171D9dBC16963727249787575cE42'),
toAddress('0x79a37e400bC591f1B38e4Fe020Ec1f985F670218')
];
const gaugePromises = gaugeAddresses.map(async (address): Promise<TGauge> => {
const gaugePromises = gaugeAddresses.map(async (gaugeAddress): Promise<TGauge> => {
const results = await readContracts({
contracts: [
{address, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'asset'},
{address, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'name'},
{address, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'symbol'},
{address, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'decimals'},
{address, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'totalAssets'}
{address: gaugeAddress, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'asset'},
{address: gaugeAddress, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'name'},
{address: gaugeAddress, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'symbol'},
{address: gaugeAddress, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'decimals'},
{address: gaugeAddress, abi: VEYFI_GAUGE_ABI, chainId: VEYFI_CHAIN_ID, functionName: 'totalAssets'}
]
});
const decimals = Number(decodeAsBigInt(results[3])) || decodeAsNumber(results[3]);
return ({
address: address,
address: gaugeAddress,
vaultAddress: decodeAsAddress(results[0]),
name: decodeAsString(results[1]),
symbol: decodeAsString(results[2]),
decimals: decimals,
totalStaked: toNormalizedBN(decodeAsBigInt(results[4]), decimals)
});
});
set_gauges(await Promise.all(gaugePromises));
});

const refreshAllowances = useAsyncEffect(async (): Promise<void> => {
if (!gauges || !userAddress) {
const allGauges = await Promise.all(gaugePromises);
set_gauges(allGauges);
}, []);

const refreshAllowances = useAsync(async (): Promise<void> => {
if (!gauges || !address) {
return;
}
const calls = [];
for (const gauge of gauges) {
for (const gauge of Object.values(gauges)) {
calls.push({
address: gauge.vaultAddress,
abi: erc20ABI,
chainId: VEYFI_CHAIN_ID,
functionName: 'allowance',
args: [userAddress, gauge.address]
args: [toAddress(address), gauge.address]
});
calls.push({
address: gauge.vaultAddress,
Expand All @@ -125,45 +128,44 @@ export const GaugeContextApp = memo(function GaugeContextApp({children}: {childr
const results = await readContracts({contracts: calls});
const _allowancesMap: TDict<TNormalizedBN> = {};
let index = 0;
for (const gauge of gauges) {
for (const gauge of Object.values(gauges)) {
const allowance = decodeAsBigInt(results[index++]);
const decimals = Number(decodeAsBigInt(results[index++])) || decodeAsNumber(results[index++]);
_allowancesMap[allowanceKey(VEYFI_CHAIN_ID, gauge.vaultAddress, gauge.address, userAddress)] = toNormalizedBN(allowance, decimals);
_allowancesMap[allowanceKey(VEYFI_CHAIN_ID, gauge.vaultAddress, gauge.address, toAddress(address))] = toNormalizedBN(allowance, decimals);
}
set_allowancesMap(_allowancesMap);
});
}, [address, gauges]);

const refreshPositions = useAsyncEffect(async (): Promise<void> => {
if (!gauges|| !isActive|| !userAddress) {
const refreshPositions = useAsync(async (): Promise<void> => {
if (!gauges || !isActive || !address) {
return;
}

const positionPromises = gauges.map(async ({address}): Promise<TGaugePosition> => {
const positionPromises = gauges.map(async (gauge): Promise<TGaugePosition> => {
const results = await readContracts({
contracts: [
{
address: toAddress(address),
address: toAddress(gauge.address),
abi: VEYFI_GAUGE_ABI,
chainId: VEYFI_CHAIN_ID,
functionName: 'balanceOf',
args: [userAddress]
args: [toAddress(address)]
},
{
address: toAddress(address),
address: toAddress(gauge.address),
abi: VEYFI_GAUGE_ABI,
chainId: VEYFI_CHAIN_ID,
functionName: 'earned',
args: [userAddress]
args: [toAddress(address)]
},
{
address: toAddress(address),
address: toAddress(gauge.address),
abi: VEYFI_GAUGE_ABI,
chainId: VEYFI_CHAIN_ID,
functionName: 'nextBoostedBalanceOf',
args: [userAddress]
args: [toAddress(address)]
},
{
address: toAddress(address),
address: toAddress(gauge.address),
abi: VEYFI_GAUGE_ABI,
chainId: VEYFI_CHAIN_ID,
functionName: 'decimals'
Expand Down Expand Up @@ -191,32 +193,33 @@ export const GaugeContextApp = memo(function GaugeContextApp({children}: {childr
const boost = Math.min(1, boostRatio) * 10;

return {
address,
address: gauge.address,
deposit: depositPosition,
reward: rewardPosition,
boost
};
});
set_positions(await Promise.all(positionPromises));
});
const allPositions = await Promise.all(positionPromises);
const allPositionsAsMap: TDict<TGaugePosition> = {};
for (const positions of allPositions) {
allPositionsAsMap[positions.address] = positions;
}
set_positionsMap(allPositionsAsMap);
}, [address, gauges, isActive]);

const refresh = useCallback((): void => {
refreshVotingEscrow();
refreshPositions();
refreshAllowances();
}, [refreshAllowances, refreshPositions, refreshVotingEscrow]);

useEffect((): void => {
refresh();
}, [refresh]);

const contextValue = useMemo((): TGaugeContext => ({
gaugeAddresses: gauges?.map(({address}): TAddress => address) ?? [],
gaugesMap: keyBy(gauges ?? [], 'address'),
positionsMap: keyBy(positions ?? [], 'address'),
const contextValue = useDeepCompareMemo((): TGaugeContext => ({
gaugeAddresses: gauges.map((gauge): TAddress => toAddress(gauge.address)),
gaugesMap: keyBy(gauges, 'address'),
positionsMap: positionsMap,
allowancesMap: allowancesMap ?? {},
refresh
}), [allowancesMap, gauges, positions, refresh]);
}), [allowancesMap, gauges, positionsMap, refresh]);

return (
<GaugeContext.Provider value={contextValue}>
Expand Down

0 comments on commit 943f03a

Please sign in to comment.