From 9130326a0695ac5ea0381e83a04df53bfc4fb730 Mon Sep 17 00:00:00 2001 From: devtealeaf Date: Sat, 27 Jul 2024 10:54:39 +0300 Subject: [PATCH] fixes & tests update --- .github/workflows/1_lint.yml | 2 +- .github/workflows/2_unit.yml | 1 + .github/workflows/3_e2e.yml | 1 + eslint.config.js | 67 +- package.json | 15 +- .../CreateVaultComponent/BuildForm.tsx | 73 +- src/components/CreateVaultComponent/index.tsx | 62 +- src/components/Footer/index.tsx | 2 +- src/components/Header/Wallet.tsx | 6 +- src/components/Header/index.tsx | 2 +- src/components/Vault/Assets.tsx | 61 +- src/components/Vault/Contracts.tsx | 3 +- src/components/Vault/HistoricalRate/Chart.tsx | 24 +- .../Vault/HistoricalRate/ChartBar.tsx | 20 +- src/components/Vault/HistoricalRate/index.tsx | 142 +-- src/components/Vault/InfoBar.tsx | 8 +- src/components/Vault/LiquidityPool.tsx | 1 - src/components/Vault/SettingsModal.tsx | 4 +- src/components/Vault/Strategy.tsx | 10 +- src/components/Vault/UnderlyingALM.tsx | 11 +- src/components/Vault/VaultActionForm.tsx | 172 ++-- src/components/Vault/VaultInfo.tsx | 12 +- src/components/Vault/YieldBar.tsx | 10 +- src/components/Vault/index.tsx | 4 +- src/components/VaultUtils/APRtimeSwitcher.tsx | 6 +- .../VaultUtils/AssetsProportion.tsx | 9 +- src/components/VaultUtils/AssetsSkeleton.tsx | 2 +- src/components/VaultUtils/ChartSkeleton.tsx | 2 +- src/components/VaultUtils/FeeAPRModal.tsx | 4 +- src/components/VaultUtils/HoldModal.tsx | 4 +- src/components/VaultUtils/Loader.tsx | 4 +- src/components/VaultUtils/ShareSkeleton.tsx | 2 +- src/components/VaultUtils/Skeleton.tsx | 2 +- .../VaultUtils/TimeDifferenceIndicator.tsx | 2 +- src/components/VaultUtils/Toast/index.tsx | 1 + src/components/VaultUtils/VaultType.tsx | 2 +- src/components/Vaults/APRModal.tsx | 8 +- src/components/Vaults/ColumnSort.tsx | 2 +- src/components/Vaults/Filters.tsx | 12 +- src/components/Vaults/PlatformModal.tsx | 6 +- src/components/Vaults/Portfolio.tsx | 4 +- src/components/Vaults/VSHoldModal.tsx | 4 +- src/components/Vaults/index.tsx | 44 +- src/constants/index.ts | 2 +- src/layouts/App.tsx | 2 +- src/layouts/AppStore.tsx | 136 +-- src/layouts/Layout.astro | 6 +- src/layouts/WagmiLayout.tsx | 2 +- src/pages/vault/[network]/[vault].astro | 2 +- src/store/index.ts | 4 +- src/types/index.ts | 68 +- src/utils/functions/addAssetToWallet.ts | 4 +- src/utils/functions/addAssetsBalance.ts | 6 +- src/utils/functions/addVaultData.ts | 6 +- src/utils/functions/calculateAPY.ts | 2 +- src/utils/functions/debounce.ts | 5 +- src/utils/functions/decodeHex.ts | 2 +- src/utils/functions/determineAPR.ts | 2 +- src/utils/functions/formatFromBigInt.ts | 2 +- src/utils/functions/formatNumber.ts | 7 +- src/utils/functions/get1InchRoutes.ts | 22 +- src/utils/functions/getDate.ts | 2 +- src/utils/functions/getProtocolLogo.ts | 2 +- src/utils/functions/getStrategyInfo.ts | 30 +- src/utils/functions/getTimeDifference.ts | 9 +- src/utils/functions/setLocalStoreHash.ts | 10 +- src/web3/abi/ERC20ABI.ts | 2 +- src/web3/abi/ERC20MetadataUpgradeableABI.ts | 2 +- tests/unit/functions.test.ts | 67 +- tsconfig.json | 4 +- yarn.lock | 920 +++++++++++++++++- 71 files changed, 1658 insertions(+), 503 deletions(-) diff --git a/.github/workflows/1_lint.yml b/.github/workflows/1_lint.yml index 389bc678..d4b1722d 100644 --- a/.github/workflows/1_lint.yml +++ b/.github/workflows/1_lint.yml @@ -8,6 +8,7 @@ on: jobs: lint: + timeout-minutes: 60 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -21,4 +22,3 @@ jobs: run: | export NODE_OPTIONS=--max-old-space-size=8192 yarn lint - timeout-minutes: 60 diff --git a/.github/workflows/2_unit.yml b/.github/workflows/2_unit.yml index 708b55b3..f3116ef0 100644 --- a/.github/workflows/2_unit.yml +++ b/.github/workflows/2_unit.yml @@ -4,6 +4,7 @@ on: branches: [main, master] pull_request: branches: [main, master] + jobs: test: timeout-minutes: 60 diff --git a/.github/workflows/3_e2e.yml b/.github/workflows/3_e2e.yml index 3d2591d1..151377e9 100644 --- a/.github/workflows/3_e2e.yml +++ b/.github/workflows/3_e2e.yml @@ -4,6 +4,7 @@ on: branches: [main, master] pull_request: branches: [main, master] + jobs: test: timeout-minutes: 60 diff --git a/eslint.config.js b/eslint.config.js index 0b16cced..582656eb 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -3,6 +3,7 @@ import typescriptPlugin from "@typescript-eslint/eslint-plugin"; import prettierPlugin from "eslint-plugin-prettier"; import eslintPluginAstro from "eslint-plugin-astro"; import astroParser from "astro-eslint-parser"; +import reactPlugin from "eslint-plugin-react"; export default [ { @@ -13,41 +14,65 @@ export default [ "public/**", "test-results/**", "tests/**", + ".cache-synpress/**", ], }, - { - files: ["**/*.astro"], - languageOptions: { - parser: astroParser, - parserOptions: { - extraFileExtensions: [".astro"], - project: "./tsconfig.json", - }, - }, - plugins: { - astro: eslintPluginAstro, - prettier: prettierPlugin, - }, - rules: { - ...eslintPluginAstro.configs.recommended.rules, - "prettier/prettier": "error", - }, - }, + // { + // files: ["**/*.astro"], + // languageOptions: { + // parser: astroParser, + // parserOptions: { + // extraFileExtensions: [".astro"], + // project: "./tsconfig.json", + // }, + // }, + // plugins: { + // astro: eslintPluginAstro, + // prettier: prettierPlugin, + // }, + // rules: { + // ...eslintPluginAstro.configs.recommended.rules, + // "prettier/prettier": "error", + // }, + // }, { files: ["**/*.ts", "**/*.tsx"], languageOptions: { parser: typescriptParser, parserOptions: { + ecmaVersion: "latest", + sourceType: "module", project: "./tsconfig.json", }, }, plugins: { "@typescript-eslint": typescriptPlugin, - prettier: prettierPlugin, + react: reactPlugin, }, rules: { - "@typescript-eslint/no-unused-vars": "warn", - "prettier/prettier": "error", + "@typescript-eslint/no-unused-vars": [ + "error", + { argsIgnorePattern: "^_" }, + ], + "@typescript-eslint/explicit-module-boundary-types": "warn", + "@typescript-eslint/no-explicit-any": "warn", + // "@typescript-eslint/ban-ts-comment": "warn", + "react/no-unescaped-entities": "off", + "react/jsx-no-undef": "error", + "react/jsx-fragments": ["error", "syntax"], + + // "@typescript-eslint/consistent-type-imports": "error", + // "@typescript-eslint/naming-convention": [ + // "error", + // { + // selector: "variable", + // format: ["camelCase", "UPPER_CASE"], + // }, + // { + // selector: "typeLike", + // format: ["PascalCase"], + // }, + // ], }, }, ]; diff --git a/package.json b/package.json index c8b4025f..4b08800a 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "build": "astro build", "preview": "astro preview", "astro": "astro", - "lint": "eslint . --max-warnings 0", + "lint": "eslint .", "test:unit": "vitest", "test:e2e": "playwright test" }, @@ -18,7 +18,9 @@ "@astrojs/tailwind": "^5.0.2", "@astrojs/vercel": "^5.1.0", "@nanostores/react": "^0.7.1", - "@stabilitydao/stability": "=0.9.1", + "@safe-global/safe-apps-sdk": "^9.1.0", + "@safe-global/safe-apps-web3modal": "^23.0.0", + "@stabilitydao/stability": "^0.10.0", "@tanstack/query-sync-storage-persister": "^5.22.2", "@tanstack/react-query": "^5.22.2", "@tanstack/react-query-persist-client": "^5.22.2", @@ -35,11 +37,12 @@ "proxy-middleware": "^0.15.0", "react": "^18.0.0", "react-dom": "^18.0.0", - "recharts": "^2.10.4", + "recharts": "^2.13.0-alpha.4", "tailwindcss": "^3.3.5", "vercel": "^32.5.0", "viem": "^2.13.1", - "wagmi": "^2.5.7" + "wagmi": "^2.5.7", + "web3modal": "^1.9.12" }, "devDependencies": { "@currents/playwright": "1.4.5", @@ -50,8 +53,12 @@ "@vitest/ui": "^2.0.2", "astro-eslint-parser": "^1.0.2", "eslint": "^9.7.0", + "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react": "^7.35.0", + "eslint-plugin-react-hooks": "^4.6.2", "prettier": "^3.3.3", + "typescript": "^5.5.3", "vitest": "^2.0.2" } } diff --git a/src/components/CreateVaultComponent/BuildForm.tsx b/src/components/CreateVaultComponent/BuildForm.tsx index b641e44c..ad6cf46c 100644 --- a/src/components/CreateVaultComponent/BuildForm.tsx +++ b/src/components/CreateVaultComponent/BuildForm.tsx @@ -10,7 +10,10 @@ import { import { Loader } from "@components"; -import { FactoryABI, ERC20ABI } from "@web3"; +import { FactoryABI, ERC20ABI, wagmiConfig } from "@web3"; + +import { getTokenData } from "@utils"; + import { account, platformsData, @@ -22,9 +25,6 @@ import { } from "@store"; import type { TInitParams, TAddress, TInputItem } from "@types"; -import { getTokenData } from "@utils"; - -import { wagmiConfig } from "@web3"; import tokenlist from "@stabilitydao/stability/out/stability.tokenlist.json"; @@ -39,6 +39,16 @@ interface IProps { nftData: { freeVaults: number; nextUpdate: string } | undefined; } +type TTokenData = { + address: string; + allowance: string; + balance: string; + decimals: number; + price: string | undefined; + sum: number; + symbol: string | undefined; +}; + const BuildForm = ({ vaultType, strategyId, @@ -48,24 +58,25 @@ const BuildForm = ({ defaultBoostTokens, minInitialBoostPerDay, nftData, -}: IProps) => { +}: IProps): JSX.Element => { const $account = useStore(account); const $platformsData = useStore(platformsData); const $balance = useStore(userBalance); - const $assetsBalances: any = useStore(assetsBalances); - const $assetsPrices: any = useStore(assetsPrices); + const $assetsBalances = useStore(assetsBalances); + const $assetsPrices = useStore(assetsPrices); const $currentChainID = useStore(currentChainID); // todo implement using const canUsePermitToken = false; const needCheckAllowance = !canUsePermitToken; + const BRT = [ ...new Set([initParams.initVaultAddresses[0], ...defaultBoostTokens]), ].map((addr) => ({ symbol: tokenlist.tokens.find((token) => token.address === addr)?.symbol, address: addr, balance: formatUnits( - $assetsBalances[addr] || "0", + $assetsBalances?.[addr] || 0n, tokenlist.tokens.find((token) => token.address === addr)?.decimals ?? 18 ), price: $assetsPrices[$currentChainID][addr]?.price, @@ -81,8 +92,10 @@ const BuildForm = ({ const [inputValues, setInputValues] = useState>( Array(defaultBoostTokens.length).fill({ inputValue: "", valuePerDay: "" }) ); - const [rewardingVaultApprove, setRewardingVaultApprove]: any = - useState(false); + const [rewardingVaultApprove, setRewardingVaultApprove] = useState< + TTokenData[] + >([]); + const [rewardingVaultDeploy, setRewardingVaultDeploy] = useState(false); const refArray = Array.from({ length: boostRewardsTokens.length }).map(() => useRef(null) @@ -117,33 +130,34 @@ const BuildForm = ({ setInputValues(newInputValues); }; const handleDeploy = () => { - let tokensToAllowance: any = []; + const tokensData: TTokenData[] = []; + inputValues.forEach((value, index) => { if (!value.inputValue) return; if ( Number(boostRewardsTokens[index].balance) >= Number(value.inputValue) && Number(value.valuePerDay) >= Number(minInitialBoostPerDay) ) { - tokensToAllowance.push({ + tokensData.push({ ...boostRewardsTokens[index], - sum: value.inputValue, + sum: Number(value.inputValue), }); } }); - if (tokensToAllowance?.length) { - getTokensAllowance(tokensToAllowance); + if (tokensData?.length) { + getTokensAllowance(tokensData); } else { setRewardingVaultDeploy(false); - setRewardingVaultApprove(false); + setRewardingVaultApprove([]); } }; - const getTokensAllowance = async (tokens: any) => { + const getTokensAllowance = async (tokens: TTokenData[]) => { if ($platformsData[$currentChainID]) { - const allowances: any[] = await Promise.all( - tokens.map(async (token: any) => { - const response: any = await readContract(wagmiConfig, { + const allowances: bigint[] = await Promise.all( + tokens.map(async (token: TTokenData) => { + const response = await readContract(wagmiConfig, { address: token.address as TAddress, abi: ERC20ABI, functionName: "allowance", @@ -152,18 +166,19 @@ const BuildForm = ({ $platformsData[$currentChainID]?.factory, ], }); + return response; }) ); - tokens = tokens.map((item: any, i: any) => ({ - ...item, - allowance: formatUnits(allowances[i], item.decimals), + tokens = tokens.map((token: TTokenData, index: number) => ({ + ...token, + allowance: formatUnits(allowances[index], token.decimals), })); // todo for multiple tokens - if (tokens[0].allowance >= tokens[0].sum) { + if (Number(tokens[0].allowance) >= tokens[0].sum) { setRewardingVaultDeploy(true); - setRewardingVaultApprove(false); + setRewardingVaultApprove([]); } else { setRewardingVaultDeploy(false); setRewardingVaultApprove(tokens); @@ -173,9 +188,9 @@ const BuildForm = ({ const approveRewardingVaultTokens = async () => { if ($platformsData[$currentChainID] && rewardingVaultApprove?.length) { try { - rewardingVaultApprove.map(async (token: any) => { + rewardingVaultApprove.map(async (token: TTokenData) => { const approve = await writeContract(wagmiConfig, { - address: token.address, + address: token.address as TAddress, abi: ERC20ABI, functionName: "approve", args: [$platformsData[$currentChainID]?.factory, maxUint256], @@ -189,7 +204,7 @@ const BuildForm = ({ setLoader(false); // it will be work only with one approve // todo fix approve state - setRewardingVaultApprove(false); + setRewardingVaultApprove([]); setRewardingVaultDeploy(true); } }); @@ -489,7 +504,7 @@ const BuildForm = ({ ) : ( buildResult === undefined && vaultType === "Rewarding" && - (rewardingVaultApprove || rewardingVaultDeploy) && ( + (rewardingVaultApprove?.length || rewardingVaultDeploy) && (
{rewardingVaultApprove && (