From 598a659d1400cc0ea9f1cd35a65490efa0963f04 Mon Sep 17 00:00:00 2001 From: devtealeaf Date: Fri, 31 Jan 2025 21:55:43 +0200 Subject: [PATCH] fix: ASF strategy --- src/constants/index.ts | 70 ++-- src/layouts/AppStore.tsx | 4 +- src/modules/Users/components/Rewards.tsx | 385 ++++++++++++++++++ src/modules/Users/components/index.ts | 3 +- src/modules/Users/index.tsx | 383 +---------------- .../Vault/components/InvestForm/index.tsx | 13 +- .../Vault/components/UnderlyingALM.tsx | 4 +- .../Vault/tests/getPlatformBalance.fixTest.ts | 64 --- .../Vault/tests/getPlatformBalance.test.ts | 63 +++ src/utils/functions/getStrategyInfo.ts | 18 +- tests/e2e/vault/vaultBlock.test.ts | 17 +- tests/unit/functions.test.ts | 106 ++--- 12 files changed, 574 insertions(+), 556 deletions(-) create mode 100644 src/modules/Users/components/Rewards.tsx delete mode 100644 src/modules/Vault/tests/getPlatformBalance.fixTest.ts create mode 100644 src/modules/Vault/tests/getPlatformBalance.test.ts diff --git a/src/constants/index.ts b/src/constants/index.ts index ed204bc0..a268777b 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,4 +1,4 @@ -import { chains } from "@stabilitydao/stability"; +import { chains, integrations } from "@stabilitydao/stability"; import { TABLE_FILTERS, @@ -164,108 +164,118 @@ const DEFAULT_TRANSACTION_SETTINGS = { }; const PROTOCOLS = { - quickSwap: { + quickswap: { name: "QuickSwap", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/QuickSwap.svg", - }, + }, // 1 gamma: { name: "Gamma", logoSrc: - "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Gamma.svg", - }, + "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Gamma.png", + }, // 1 compound: { name: "Compound", logoSrc: - "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Compound.svg", - }, - defiedge: { + "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Compound.png", + }, // 1 + defiEdge: { name: "DefiEdge", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/DefiEdge.svg", - }, + }, // 1 merkl: { name: "Merkl", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Merkl.svg", - }, + }, // 0 ichi: { name: "Ichi", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Ichi.svg", - }, + }, // 1 retro: { name: "Retro", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Retro.svg", - }, + }, // 1 curve: { name: "Curve", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Curve.svg", - }, + }, // 1 convex: { name: "Convex", logoSrc: - "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Convex.svg", - }, + "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Convex.png", + }, // 1 lido: { name: "Lido", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Lido.svg", - }, + }, // 1 aave: { name: "Aave", logoSrc: - "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Aave.svg", - }, + "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Aave.png", + }, // 1 stargate: { name: "Stargate", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Stargate.svg", - }, + }, // 1 yearn: { name: "Yearn", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Yearn.svg", - }, + }, // 1 uniswapV3: { name: "UniswapV3", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Uniswap.svg", - }, + }, // 0 pearlV2: { name: "Pearl V2", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Pearl.png", - }, + }, // 0 trident: { name: "Trident", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Trident.png", - }, + }, // 0 beethovenx: { name: "Beets", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/beethovenx.png", - }, + }, // 1 equalizer: { name: "Equalizer", logoSrc: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/equalizer.png", - }, + }, // 1 swapx: { name: "SwapX", logoSrc: - "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/swapx.png?1", - }, + "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/swapx.png", + }, // 1 shadow: { - name: 'Shadow', + name: "Shadow", logoSrc: - "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/shadow.png", - }, + "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/shadow.png", + }, // 1 }; +// const _PROTOCOLS = Object.entries(integrations).reduce((acc, [key, value]) => { +// acc[key] = { +// name: value.name, +// logoSrc: `https://raw.githubusercontent.com/stabilitydao/.github/main/assets/${value.img}`, +// }; +// return acc; +// }, {}); +// console.log(PROTOCOLS); +// console.log(_PROTOCOLS); + const IL = { ASFN: { rate: 8, diff --git a/src/layouts/AppStore.tsx b/src/layouts/AppStore.tsx index 6bfe9a47..dda51bc9 100644 --- a/src/layouts/AppStore.tsx +++ b/src/layouts/AppStore.tsx @@ -517,13 +517,13 @@ const AppStore = (props: React.PropsWithChildren): JSX.Element => { case "aave": yearnProtocols.push({ title: "Aave", - link: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Aave.svg", + link: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Aave.png", }); break; case "compound": yearnProtocols.push({ title: "Compound", - link: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Compound.svg", + link: "https://raw.githubusercontent.com/stabilitydao/.github/main/assets/Compound.png", }); break; case "stargate": diff --git a/src/modules/Users/components/Rewards.tsx b/src/modules/Users/components/Rewards.tsx new file mode 100644 index 00000000..09421a7b --- /dev/null +++ b/src/modules/Users/components/Rewards.tsx @@ -0,0 +1,385 @@ +import { useState, useEffect } from "react"; +import axios from "axios"; +import { useStore } from "@nanostores/react"; + +import { readContract, writeContract } from "@wagmi/core"; +import { formatUnits } from "viem"; + +import { HeadingText } from "@ui"; + +import { formatNumber } from "@utils"; + +import { account, apiData, assetsPrices } from "@store"; + +import { + wagmiConfig, + ERC20ABI, + sGEM1, + IMerkleDistributor, + merkleDistributor, +} from "@web3"; + +import type { TAddress } from "@types"; + +import type { ApiMainReply } from "@stabilitydao/stability"; + +import type { UserRewards } from "@stabilitydao/stability/out/api.types"; + +const Rewards = (): JSX.Element => { + const $apiData: ApiMainReply | undefined = useStore(apiData); + const $assetsPrices = useStore(assetsPrices); + const $account = useStore(account); + + const [userBalance, setUserBalance] = useState({ points: "-", gems: "-" }); + const [userData, setUserData] = useState([]); // todo: change type to user rewards + const [gemsEarned, setGemsEarned] = useState("0"); + const [rewardsTotalSupply, setRewardsTotalSupply] = useState({ + points: "0", + gems: "900k", + }); + + const [gemPrice, setGemPrice] = useState("-"); + + const [contestsToClaim, setContestsToClaim] = useState([]); + + const getSGEMPrice = async () => { + const sonicPrices = $assetsPrices["146"]; + + if (sonicPrices) { + const _sGEM1Price = + Number( + sonicPrices[sGEM1?.toLowerCase() as keyof typeof sonicPrices]?.price + ).toFixed(3) ?? "0.010"; + + setGemPrice(_sGEM1Price); + } + }; + + const getRewardsTotalSupply = async () => { + if ($apiData?.leaderboards?.absolute.length) { + const pointsTotalSupply = $apiData?.leaderboards?.absolute.reduce( + (acc, cur) => (acc += cur?.points ?? 0), + 0 + ); + + const _gems = String(formatNumber(900000, "abbreviate")).slice(1); + + const _points = String( + formatNumber(Number(pointsTotalSupply), "abbreviate") + ).slice(1); + + setRewardsTotalSupply({ points: _points, gems: _gems }); + } + }; + + const getUserData = async () => { + try { + const response = await axios.get( + `https://api.stability.farm/rewards/user/${$account}` + ); + + const gemsEarnedData = response.data.gemsEarned; + + if (gemsEarnedData.length) { + setUserData(gemsEarnedData); + } + } catch (err) { + console.error("Error occurred at getUserData:", err); + } + }; + + const getUserBalance = async () => { + const user = $apiData?.leaderboards?.absolute.find( + ({ address }) => address === $account?.toLowerCase() + ); + + let userPoints = "0"; + let user_sGEM1 = "0"; + + if (user?.points) { + userPoints = String( + formatNumber(Number(user?.points), "abbreviate") + ).slice(1); + } + + try { + const sGEM1Balance = await readContract(wagmiConfig, { + address: sGEM1 as TAddress, + abi: ERC20ABI, + functionName: "balanceOf", + args: [$account as TAddress], + }); + + user_sGEM1 = formatUnits(sGEM1Balance, 18); + + user_sGEM1 = String(formatNumber(Number(user_sGEM1), "abbreviate")).slice( + 1 + ); + } catch (err) { + console.error("Error occurred at getUserBalance:", err); + } + + setUserBalance({ points: userPoints, gems: user_sGEM1 }); + }; + + const getUserEarnedGems = async () => { + if (!userData.length) return; + try { + const allGems = userData.reduce( + (acc: number, cur: UserRewards["gemsEarned"][number]) => + (acc += cur.gems), + 0 + ); + + const abbreviateGems = String( + formatNumber(Number(allGems), "abbreviate") + ).slice(1); + + setGemsEarned(abbreviateGems); + } catch (err) { + console.error("Error occurred at getUserEarnedGems:", err); + } + }; + + const getUserClaimedRewards = async () => { + if (!userData.length) return; + try { + const contestIds = userData.map( + ({ contestId }: { contestId: string }) => contestId + ); + + const claimedData = (await readContract(wagmiConfig, { + address: merkleDistributor as TAddress, + abi: IMerkleDistributor, + functionName: "claimed", + args: [$account as TAddress, contestIds], + })) as boolean[]; + + const claimContests = claimedData.reduce((acc, isClaimed, index) => { + if (!isClaimed) acc.push(contestIds[index] as string); + return acc; + }, []); + + if (claimContests.length) { + setContestsToClaim(claimContests); + } + } catch (err) { + console.error("Error occurred at getUserClaimedRewards:", err); + } + }; + + const claim = async () => { + if (!$account) { + alert("Please connect your wallet!"); + } + + try { + const gemsAmounts: string[] = []; + const proofs: string[][] = []; + + contestsToClaim.forEach((contest) => { + const contestData = userData.find( + ({ contestId }: { contestId: string }) => contest === contestId + ); + + gemsAmounts.push(contestData?.gemsRaw as string); + proofs.push(contestData?.proofs as string[]); + }); + + const claim = await writeContract(wagmiConfig, { + address: merkleDistributor as TAddress, + abi: IMerkleDistributor, + functionName: "claim", + args: [contestsToClaim, gemsAmounts, proofs, $account as TAddress], + }); + console.log(claim); + } catch (err) { + console.error("Error occurred at claim:", err); + } + }; + + useEffect(() => { + getSGEMPrice(); + }, [$assetsPrices]); + + useEffect(() => { + getRewardsTotalSupply(); + }, [$apiData]); + + useEffect(() => { + if ($account) { + getUserData(); + } else if (contestsToClaim.length) { + setContestsToClaim([]); + } + }, [$account]); + + useEffect(() => { + if (userData.length) { + getUserBalance(); + getUserEarnedGems(); + getUserClaimedRewards(); + } + }, [userData]); + return ( +
+ +

+ Earning in our vaults you get additional rewards! +

{" "} +
+
+
+
+
+
+ + sGEM1 + sGEM1 + + + Shadow + +
+

+ + Sonic Gems are app airdrop points that we give away entirely + to our users. + + + + Read Docs + +

+
+
+

+ Balance: + {userBalance.gems} +

+

+ Total Earned: + {gemsEarned} + sGEM1 +

+
+

+ Swap on{" "} + + Shadow + +

+
+
+

+ Price: + ${gemPrice} + USD +

+ +

+ Total Supply:{" "} + {rewardsTotalSupply.gems} +

+
+ {!!contestsToClaim.length && ( + + )} +
+
+
+ sGEM1 reward + {!!contestsToClaim.length && ( + + )} +
+

+ Price: + ${gemPrice} + USD +

+ +

+ Total Supply:{" "} + {rewardsTotalSupply.gems} +

+
+
+
+
+
+
+
+
+ + pSTBL{" "} + pSTBL + +

+ Stability Points will be exchanged for $STBL at TGE 2025. +

+
+ +

+ Balance: + {userBalance.points} +

+

+ Total Supply:{" "} + {rewardsTotalSupply.points} +

+
+
+ pSTBL reward +

+ Total Supply:{" "} + {rewardsTotalSupply.points} +

+
+
+
+
+
+ ); +}; + +export { Rewards }; diff --git a/src/modules/Users/components/index.ts b/src/modules/Users/components/index.ts index 0cf3dc71..f1b585f8 100644 --- a/src/modules/Users/components/index.ts +++ b/src/modules/Users/components/index.ts @@ -1,3 +1,4 @@ import { ContestsOverview } from "./ContestsOverview"; +import { Rewards } from "./Rewards"; -export { ContestsOverview }; +export { ContestsOverview, Rewards }; diff --git a/src/modules/Users/index.tsx b/src/modules/Users/index.tsx index 11c00640..7ca6a976 100644 --- a/src/modules/Users/index.tsx +++ b/src/modules/Users/index.tsx @@ -1,64 +1,33 @@ import { useState, useEffect, useMemo } from "react"; -import axios from "axios"; import { useStore } from "@nanostores/react"; -import { readContract, writeContract } from "@wagmi/core"; -import { formatUnits } from "viem"; - -import { ContestsOverview } from "./components"; +import { ContestsOverview, Rewards } from "./components"; import { FullPageLoader, HeadingText, TableColumnSort } from "@ui"; -import { - getShortAddress, - sortTable, - formatTimestampToDate, - formatNumber, -} from "@utils"; +import { getShortAddress, sortTable, formatTimestampToDate } from "@utils"; import { findAllValidPeriods } from "./functions"; -import { account, apiData, assetsPrices } from "@store"; +import { account, apiData } from "@store"; import { contests } from "@stabilitydao/stability"; -import { - wagmiConfig, - ERC20ABI, - sGEM1, - IMerkleDistributor, - merkleDistributor, -} from "@web3"; - import { USERS_TABLE } from "@constants"; import { TABLE_TYPES } from "./constants"; -import type { TTableColumn, TLeaderboard, TAddress } from "@types"; +import type { TTableColumn, TLeaderboard } from "@types"; import type { ApiMainReply, YieldContest } from "@stabilitydao/stability"; -import type { UserRewards } from "@stabilitydao/stability/out/api.types"; - const Users = (): JSX.Element => { const $apiData: ApiMainReply | undefined = useStore(apiData); - const $assetsPrices = useStore(assetsPrices); const $account = useStore(account); // const activeContestInfo = contests?.[currentPeriod]; // const pastContestInfo = contests?.[previousPeriod]; - const [userBalance, setUserBalance] = useState({ points: "-", gems: "-" }); - const [userData, setUserData] = useState([]); // todo: change type to user rewards - const [gemsEarned, setGemsEarned] = useState("0"); - const [rewardsTotalSupply, setRewardsTotalSupply] = useState({ - points: "0", - gems: "900k", - }); - const [gemPrice, setGemPrice] = useState("-"); - - const [contestsToClaim, setContestsToClaim] = useState([]); - const { currentPeriod, previousPeriod, nextPeriod } = findAllValidPeriods(contests); @@ -94,162 +63,6 @@ const Users = (): JSX.Element => { } }; - const getSGEMPrice = async () => { - const sonicPrices = $assetsPrices["146"]; - - if (sonicPrices) { - const _sGEM1Price = - Number( - sonicPrices[sGEM1?.toLowerCase() as keyof typeof sonicPrices]?.price - ).toFixed(3) ?? "0.010"; - - setGemPrice(_sGEM1Price); - } - }; - - const getRewardsTotalSupply = async () => { - if ($apiData?.leaderboards?.absolute.length) { - const pointsTotalSupply = $apiData?.leaderboards?.absolute.reduce( - (acc, cur) => (acc += cur?.points ?? 0), - 0 - ); - - const _gems = String(formatNumber(900000, "abbreviate")).slice(1); - - const _points = String( - formatNumber(Number(pointsTotalSupply), "abbreviate") - ).slice(1); - - setRewardsTotalSupply({ points: _points, gems: _gems }); - } - }; - - const getUserData = async () => { - try { - const response = await axios.get( - `https://api.stability.farm/rewards/user/${$account}` - ); - - const gemsEarnedData = response.data.gemsEarned; - - if (gemsEarnedData.length) { - setUserData(gemsEarnedData); - } - } catch (err) { - console.error("Error occurred at getUserData:", err); - } - }; - - const getUserBalance = async () => { - const user = $apiData?.leaderboards?.absolute.find( - ({ address }) => address === $account?.toLowerCase() - ); - - let userPoints = "0"; - let user_sGEM1 = "0"; - - if (user?.points) { - userPoints = String( - formatNumber(Number(user?.points), "abbreviate") - ).slice(1); - } - - try { - const sGEM1Balance = await readContract(wagmiConfig, { - address: sGEM1 as TAddress, - abi: ERC20ABI, - functionName: "balanceOf", - args: [$account as TAddress], - }); - - user_sGEM1 = formatUnits(sGEM1Balance, 18); - - user_sGEM1 = String(formatNumber(Number(user_sGEM1), "abbreviate")).slice( - 1 - ); - } catch (err) { - console.error("Error occurred at getUserBalance:", err); - } - - setUserBalance({ points: userPoints, gems: user_sGEM1 }); - }; - - const getUserEarnedGems = async () => { - if (!userData.length) return; - try { - const allGems = userData.reduce( - (acc: number, cur: UserRewards["gemsEarned"][number]) => - (acc += cur.gems), - 0 - ); - - const abbreviateGems = String( - formatNumber(Number(allGems), "abbreviate") - ).slice(1); - - setGemsEarned(abbreviateGems); - } catch (err) { - console.error("Error occurred at getUserEarnedGems:", err); - } - }; - - const getUserClaimedRewards = async () => { - if (!userData.length) return; - try { - const contestIds = userData.map( - ({ contestId }: { contestId: string }) => contestId - ); - - const claimedData = (await readContract(wagmiConfig, { - address: merkleDistributor as TAddress, - abi: IMerkleDistributor, - functionName: "claimed", - args: [$account as TAddress, contestIds], - })) as boolean[]; - - const claimContests = claimedData.reduce((acc, isClaimed, index) => { - if (!isClaimed) acc.push(contestIds[index] as string); - return acc; - }, []); - - if (claimContests.length) { - setContestsToClaim(claimContests); - } - } catch (err) { - console.error("Error occurred at getUserClaimedRewards:", err); - } - }; - - const claim = async () => { - if (!$account) { - alert("Please connect your wallet!"); - } - - try { - const gemsAmounts: string[] = []; - const proofs: string[][] = []; - - contestsToClaim.forEach((contest) => { - const contestData = userData.find( - ({ contestId }: { contestId: string }) => contest === contestId - ); - - gemsAmounts.push(contestData?.gemsRaw as string); - proofs.push(contestData?.proofs as string[]); - }); - - const claim = await writeContract(wagmiConfig, { - address: merkleDistributor as TAddress, - abi: IMerkleDistributor, - functionName: "claim", - args: [contestsToClaim, gemsAmounts, proofs, $account as TAddress], - }); - console.log(claim); - } catch (err) { - console.error("Error occurred at claim:", err); - } - }; - const allContests = useMemo(() => { const absoluteLeaderboard = $apiData?.leaderboards.absolute.map((user) => user?.points ? user : { ...user, points: 0 } @@ -285,195 +98,11 @@ const Users = (): JSX.Element => { initTableData(); }, [activeContest, allContests]); - useEffect(() => { - getSGEMPrice(); - }, [$assetsPrices]); - - useEffect(() => { - getRewardsTotalSupply(); - }, [$apiData]); - - useEffect(() => { - if ($account) { - getUserData(); - } else if (contestsToClaim.length) { - setContestsToClaim([]); - } - }, [$account]); - - useEffect(() => { - if (userData.length) { - getUserBalance(); - getUserEarnedGems(); - getUserClaimedRewards(); - } - }, [userData]); return (
-
- -

- Earning in our vaults you get additional rewards! -

{" "} -
-
-
-
-
-
- - sGEM1 - sGEM1 - - - Shadow - -
-

- - Sonic Gems are app airdrop points that we give away - entirely to our users. - - - - Read Docs - -

-
-
-

- Balance: - {userBalance.gems} -

-

- Total Earned: - {gemsEarned} - sGEM1 -

-
-

- Swap on{" "} - - Shadow - -

-
-
-

- Price: - ${gemPrice} - USD -

- -

- Total Supply:{" "} - - {rewardsTotalSupply.gems} - -

-
- {!!contestsToClaim.length && ( - - )} -
-
-
- sGEM1 reward - {!!contestsToClaim.length && ( - - )} -
-

- Price: - ${gemPrice} - USD -

- -

- Total Supply:{" "} - {rewardsTotalSupply.gems} -

-
-
-
-
-
-
-
-
- - pSTBL{" "} - pSTBL - -

- Stability Points will be exchanged for $STBL at TGE 2025. -

-
- -

- Balance: - {userBalance.points} -

-

- Total Supply:{" "} - {rewardsTotalSupply.points} -

-
-
- pSTBL reward -

- Total Supply:{" "} - {rewardsTotalSupply.points} -

-
-
-
-
-
+ + diff --git a/src/modules/Vault/components/InvestForm/index.tsx b/src/modules/Vault/components/InvestForm/index.tsx index e6083ccf..d88dd1ba 100644 --- a/src/modules/Vault/components/InvestForm/index.tsx +++ b/src/modules/Vault/components/InvestForm/index.tsx @@ -518,7 +518,7 @@ const InvestForm: React.FC = ({ network, vault }) => { if (asset === underlyingToken?.address) { try { let previewDepositAssets; - if (["BSF", "BWF"].includes(shortId)) { + if (["BSF", "BWF", "ASF"].includes(shortId)) { previewDepositAssets = await _publicClient?.simulateContract({ address: vault.address, abi: VaultABI, @@ -1035,7 +1035,7 @@ const InvestForm: React.FC = ({ network, vault }) => { : thisAmount; }); let previewDepositAssets; - if (["BSF", "BWF"].includes(shortId)) { + if (["BSF", "BWF", "ASF"].includes(shortId)) { previewDepositAssets = await _publicClient?.simulateContract({ address: vault.address, abi: VaultABI, @@ -1886,8 +1886,7 @@ const InvestForm: React.FC = ({ network, vault }) => { const previewDeposit = async (asset: string, amount: string) => { // if (!Number(amount)) return; // commented for BSF - - if (shortId === "BSF") { + if (["BSF", "ASF"].includes(shortId)) { const formattedInputs = Object.fromEntries( Object.entries( Object.entries(inputs).length ? inputs : { [asset]: amount } @@ -1949,7 +1948,7 @@ const InvestForm: React.FC = ({ network, vault }) => { parseUnits(amount, Number(getTokenData(asset)?.decimals)) ); } else { - if (["BSF", "BWF", "CCF"].includes(shortId)) { + if (["BSF", "BWF", "CCF", "ASF"].includes(shortId)) { let value; let decimals = 18; for (const key in inputs) { @@ -1976,8 +1975,10 @@ const InvestForm: React.FC = ({ network, vault }) => { } } } + try { let previewDepositAssets: any; + if (shortId === "IQMF" || shortId === "IRMF") { // IQMF & IRMF strategies only let assets: TAddress[] = vault.assets.map((asset) => asset.address); @@ -1992,7 +1993,7 @@ const InvestForm: React.FC = ({ network, vault }) => { args: [assets, IQMFAmounts], }); } else { - if (["BSF", "BWF"].includes(shortId)) { + if (["BSF", "BWF", "ASF"].includes(shortId)) { previewDepositAssets = await _publicClient?.simulateContract({ address: vault.address, abi: VaultABI, diff --git a/src/modules/Vault/components/UnderlyingALM.tsx b/src/modules/Vault/components/UnderlyingALM.tsx index f0de3539..8d64413d 100644 --- a/src/modules/Vault/components/UnderlyingALM.tsx +++ b/src/modules/Vault/components/UnderlyingALM.tsx @@ -140,7 +140,7 @@ const UnderlyingALM: React.FC = memo(({ network, vault }) => { } if (vault.strategy.includes("QuickSwap")) { const ammFee = await readContract(wagmiConfig, { - address: ichiFactories.quickSwap, + address: ichiFactories.quickswap, abi: [ { inputs: [], @@ -155,7 +155,7 @@ const UnderlyingALM: React.FC = memo(({ network, vault }) => { functionName: "ammFee", }); const baseFee = await readContract(wagmiConfig, { - address: ichiFactories.quickSwap, + address: ichiFactories.quickswap, abi: [ { inputs: [], diff --git a/src/modules/Vault/tests/getPlatformBalance.fixTest.ts b/src/modules/Vault/tests/getPlatformBalance.fixTest.ts deleted file mode 100644 index 589965de..00000000 --- a/src/modules/Vault/tests/getPlatformBalance.fixTest.ts +++ /dev/null @@ -1,64 +0,0 @@ -// import { describe, it, expect, vi } from "vitest"; - -// import { getPlatformBalance } from "../functions"; - -// import { addAssetsBalance } from "@utils"; - -// import { assetsBalances } from "@store"; - -// import { platforms, PlatformABI } from "@web3"; - -// const mockPublicClient = { -// readContract: vi.fn(), -// }; - -// const mockNetwork = "137"; - -// const mockAddress = "0x1234567890abcdef1234567890abcdef12345678"; - -// const mockContractBalance = { -// "0xabcdefabcdefabcdefabcdefabcdefabcdef": BigInt(1000), -// }; - -// vi.mock("@utils", () => ({ -// addAssetsBalance: vi.fn(), -// })); - -// vi.mock("@store", () => ({ -// assetsBalances: { -// get: vi.fn().mockReturnValue({}), -// set: vi.fn(), -// }, -// })); - -// describe("getPlatformBalance", () => { -// it("should correctly fetch and update platform balances", async () => { -// const mockCurrentChainBalances = { -// "0xabcdefabcdefabcdefabcdefabcdefabcdef": "1000", -// }; - -// mockPublicClient.readContract.mockResolvedValue(mockContractBalance); -// (addAssetsBalance as vi.Mock).mockReturnValue(mockCurrentChainBalances); - -// const result = await getPlatformBalance( -// mockPublicClient, -// mockNetwork, -// mockAddress -// ); - -// expect(mockPublicClient.readContract).toHaveBeenCalledWith({ -// address: platforms[mockNetwork], -// abi: PlatformABI, -// functionName: "getBalance", -// args: [mockAddress], -// }); - -// expect(addAssetsBalance).toHaveBeenCalledWith(mockContractBalance); - -// expect(assetsBalances.set).toHaveBeenCalledWith({ -// [mockNetwork]: mockCurrentChainBalances, -// }); - -// expect(result).toEqual(mockCurrentChainBalances); -// }); -// }); diff --git a/src/modules/Vault/tests/getPlatformBalance.test.ts b/src/modules/Vault/tests/getPlatformBalance.test.ts new file mode 100644 index 00000000..9b899d0f --- /dev/null +++ b/src/modules/Vault/tests/getPlatformBalance.test.ts @@ -0,0 +1,63 @@ +import { describe, it, expect, vi } from "vitest"; + +import { getPlatformBalance } from "../functions"; + +import { addAssetsBalance, getContractDataWithPagination } from "@utils"; +import { assetsBalances } from "@store"; +import { frontendContracts } from "@web3"; + +const mockPublicClient = { + callContract: vi.fn(), +}; + +const mockNetwork = "137"; +const mockAddress = "0x1234567890abcdef1234567890abcdef12345678"; +const mockContractBalance = { + "0xabcdefabcdefabcdefabcdefabcdefabcdef": BigInt(1000), +}; + +vi.mock("@utils", () => ({ + addAssetsBalance: vi.fn(), + getContractDataWithPagination: vi.fn(), +})); + +vi.mock("@store", () => ({ + assetsBalances: { + get: vi.fn().mockReturnValue({}), + set: vi.fn(), + }, +})); + +describe("getPlatformBalance", () => { + it("should correctly fetch and update platform balances", async () => { + const mockCurrentChainBalances = { + "0xabcdefabcdefabcdefabcdefabcdefabcdef": "1000", + }; + + getContractDataWithPagination.mockResolvedValue(mockContractBalance); + addAssetsBalance.mockReturnValue(mockCurrentChainBalances); + + const result = await getPlatformBalance( + mockPublicClient, + mockNetwork, + mockAddress + ); + + expect(getContractDataWithPagination).toHaveBeenCalledWith( + mockPublicClient, + frontendContracts[mockNetwork], + "getBalanceAssets", + mockAddress, + 0 + ); + + expect(addAssetsBalance).toHaveBeenCalledWith(mockContractBalance); + + expect(assetsBalances.get).toHaveBeenCalled(); + expect(assetsBalances.set).toHaveBeenCalledWith( + expect.objectContaining({ [mockNetwork]: mockCurrentChainBalances }) + ); + + expect(result).toEqual(mockCurrentChainBalances); + }); +}); diff --git a/src/utils/functions/getStrategyInfo.ts b/src/utils/functions/getStrategyInfo.ts index f356c786..5779fb0c 100644 --- a/src/utils/functions/getStrategyInfo.ts +++ b/src/utils/functions/getStrategyInfo.ts @@ -46,10 +46,10 @@ export const getStrategyInfo = ( ); const { - quickSwap, + quickswap, gamma, compound, - defiedge, + defiEdge, merkl, ichi, retro, @@ -72,7 +72,7 @@ export const getStrategyInfo = ( return { id: "", shortId: "", - protocols: [quickSwap, gamma], + protocols: [quickswap, gamma], baseStrategies: [], color: "", bgColor: "", @@ -93,13 +93,13 @@ export const getStrategyInfo = ( strategyInfo = { ...strategyInfo, - protocols: [gamma, quickSwap], + protocols: [gamma, quickswap], il, }; } else if (vaultSymbol.match(/QSF$/)) { strategyInfo = { ...strategyInfo, - protocols: [quickSwap], + protocols: [quickswap], il: IL.QSF, }; } else if (vaultSymbol.match(/CCF$/)) { @@ -117,13 +117,13 @@ export const getStrategyInfo = ( } else if (vaultSymbol.match(/DQMFN?[A-Z0-9]?$/)) { strategyInfo = { ...strategyInfo, - protocols: [defiedge, quickSwap, merkl], + protocols: [defiEdge, quickswap, merkl], il: IL.DQMFN, }; } else if (vaultSymbol.match(/IQMF[a-z0-9]{0,1}$/)) { strategyInfo = { ...strategyInfo, - protocols: [ichi, quickSwap, merkl], + protocols: [ichi, quickswap, merkl], il: IL.IQMF, }; } else if (vaultSymbol.match(/GQMF(S|N|W)?$/)) { @@ -137,7 +137,7 @@ export const getStrategyInfo = ( strategyInfo = { ...strategyInfo, - protocols: [gamma, quickSwap, merkl], + protocols: [gamma, quickswap, merkl], il, }; } else if (vaultSymbol.match(/\bIRMF\b/)) { @@ -162,7 +162,7 @@ export const getStrategyInfo = ( } else if (vaultSymbol.match(/QSMF$/)) { strategyInfo = { ...strategyInfo, - protocols: [quickSwap, merkl], + protocols: [quickswap, merkl], il: IL.QSMF, }; } else if (vaultSymbol.match(/Y$/)) { diff --git a/tests/e2e/vault/vaultBlock.test.ts b/tests/e2e/vault/vaultBlock.test.ts index 9762d5c7..f8a2486b 100644 --- a/tests/e2e/vault/vaultBlock.test.ts +++ b/tests/e2e/vault/vaultBlock.test.ts @@ -136,21 +136,12 @@ test("Should display vault info correctly", async ({ page, context }) => { /* Created should be displayed correctly in d/mm/yyyy format and */ /* summarised days from deployment date */ + const createdText = `${getTimeDifference(vaultData?.created)?.days} days ago`; - const date = getDate(Number(vaultData?.created)); + const pageVaultCreated = + (await page.getByTestId("vaultCreated").textContent()) ?? ""; - const createdData = { - time: date, - days: getTimeDifference(vaultData?.created)?.days, - }; - - const createdText = `${createdData?.time} / ${createdData?.days} days ago`; - - const pageVaultCreated = await page - .getByTestId("vaultCreated") - .textContent(); - - expect(pageVaultCreated).toBe(createdText); + expect(pageVaultCreated.replace(/.*\/\s*/, "")).toBe(createdText); /* Vault version should be displayed correctly based on it's contract version */ diff --git a/tests/unit/functions.test.ts b/tests/unit/functions.test.ts index 70cecf78..74ddfa5c 100644 --- a/tests/unit/functions.test.ts +++ b/tests/unit/functions.test.ts @@ -20,6 +20,7 @@ import { getShortAddress, formatTimestampToDate, extractDomain, + getContractDataWithPagination, } from "@utils"; import { transactionSettings, aprFilter } from "@store"; @@ -34,53 +35,54 @@ vi.mock("@store", () => ({ visible: { set: vi.fn() }, })); -// describe("addAssetsBalance", () => { -// it("should correctly map assets to balances", () => { -// const data = [ -// ["Address1", "Address2", "Address3"], -// [], -// ["Balance1", "Balance2", "Balance3"], -// ]; -// const result = addAssetsBalance(data); - -// expect(result).toEqual({ -// address1: "Balance1", -// address2: "Balance2", -// address3: "Balance3", -// }); -// }); -// }); - -// describe("addVaultData", () => { -// it("should correctly map vault addresses to their data", () => { -// const data = [ -// [], -// [], -// [], -// ["0xAddress1", "0xAddress2", "0xAddress3"], -// [100, 200, 300], -// [10, 20, 30], -// ]; -// const result = addVaultData(data); - -// const expected = { -// "0xaddress1": { -// vaultSharePrice: 100, -// vaultUserBalance: 10, -// }, -// "0xaddress2": { -// vaultSharePrice: 200, -// vaultUserBalance: 20, -// }, -// "0xaddress3": { -// vaultSharePrice: 300, -// vaultUserBalance: 30, -// }, -// }; - -// expect(result).toEqual(expected); -// }); -// }); +describe("addAssetsBalance", () => { + it("should correctly map assets to balances", () => { + const data = [ + 10n, + ["Address1", "Address2", "Address3"], + [], + ["Balance1", "Balance2", "Balance3"], + ]; + + const result = addAssetsBalance(data); + + expect(result).toEqual({ + address1: "Balance1", + address2: "Balance2", + address3: "Balance3", + }); + }); +}); + +describe("addVaultData", () => { + it("should correctly map vault addresses to their data", () => { + const data = [ + 10n, + ["0xAddress1", "0xAddress2", "0xAddress3"], + [100, 200, 300], + [10, 20, 30], + ]; + + const result = addVaultData(data); + + const expected = { + "0xaddress1": { + vaultSharePrice: 100, + vaultUserBalance: 10, + }, + "0xaddress2": { + vaultSharePrice: 200, + vaultUserBalance: 20, + }, + "0xaddress3": { + vaultSharePrice: 300, + vaultUserBalance: 30, + }, + }; + + expect(result).toEqual(expected); + }); +}); describe("calculateAPY", () => { it("should correctly calculate with string || number", () => { @@ -385,7 +387,7 @@ describe("getStrategyInfo", () => { expect(strategyInfo.protocols).toEqual([ PROTOCOLS.gamma, - PROTOCOLS.quickSwap, + PROTOCOLS.quickswap, PROTOCOLS.merkl, ]); @@ -418,7 +420,7 @@ describe("getStrategyInfo", () => { expect(strategyInfo.id).toBe("QuickSwap Static Merkl Farm"); expect(strategyInfo.shortId).toBe("QSMF"); - expect(strategyInfo.protocols).toEqual([PROTOCOLS.quickSwap]); + expect(strategyInfo.protocols).toEqual([PROTOCOLS.quickswap]); expect(strategyInfo.il).toEqual(IL.QSF); }); @@ -431,8 +433,8 @@ describe("getStrategyInfo", () => { expect(strategyInfo.id).toBe("DefiEdge QuickSwap Merkl Farm"); expect(strategyInfo.shortId).toBe("DQMF"); expect(strategyInfo.protocols).toEqual([ - PROTOCOLS.defiedge, - PROTOCOLS.quickSwap, + PROTOCOLS.defiEdge, + PROTOCOLS.quickswap, PROTOCOLS.merkl, ]); expect(strategyInfo.il).toEqual(IL.DQMFN); @@ -500,7 +502,7 @@ describe("getStrategyInfo", () => { expect(strategyInfo.id).toBe(""); expect(strategyInfo.shortId).toBe(""); expect(strategyInfo.protocols).toEqual([ - PROTOCOLS.quickSwap, + PROTOCOLS.quickswap, PROTOCOLS.gamma, ]); expect(strategyInfo.baseStrategies).toEqual([]);